Author: Alexander Hansen alexander.hansen@9elements.com
Other contributors: Chu Lin linchuyuan@google.com (through their previous works), Amithash Prasad amithash@meta.com
Created: August 26, 2024
Reference: Chu Lin's gpio based cable presence detection
Due to increasing complexity of server designs and different configurations of the same system being possible, there is a need for a simple way to detect the presence of cards, cables and other connected entities which may or may not be plugged into a system. A subset of these entities support presence detection via gpios. This design focuses on those.
Connected entities detectable via other means are out of scope of this design.
The existing design for the gpio based cable presence is partially implemented and focuses on IPMI use-case.
Currently the way to do gpio based presence detection is via phosphor-multi-gpio-presence and phosphor-inventory-manager.
The static inventory is declared and the inventory items are exposed at runtime by phosphor-inventory-manager.
The presence daemon then toggles the 'Present' property on dbus interface xyz.openbmc_project.Inventory.Item.
Additional item-specific properties are statically declared in the phosphor-inventory-manager configuration.
An example of how this is currently done:
phosphor-inventory-manager config
In the example we have inventory item dimm_c0a1 which has following phosphor-multi-gpio-presence configuration:
{ "Name": "DIMM_C0A1", "LineName": "PLUG_DETECT_DIMM_C0A1", "ActiveLow": true, "Bias": "PULL_UP", "Inventory": "/system/chassis/motherboard/dimm_c0a1" }
and phosphor-inventory-manager configuration:
- name: Add DIMMs description: > Add the DIMM inventory path. type: startup actions: - name: createObjects objs: /system/chassis/motherboard/dimm_c0a1: xyz.openbmc_project.Inventory.Decorator.Replaceable: FieldReplaceable: value: true type: boolean xyz.openbmc_project.State.Decorator.OperationalStatus: Functional: value: true type: boolean xyz.openbmc_project.Inventory.Item: PrettyName: value: "DIMM C0A1" type: string Present: value: false type: boolean xyz.openbmc_project.Inventory.Item.Dimm: xyz.openbmc_project.Inventory.Decorator.LocationCode: LocationCode: value: "CPU0_DIMM_A1" type: string
Support the gpio based detection of inventory items without static configuration
Allow configuration of the detectable inventory items through entity-manager configuration
When a device is detected as present using the GPIO configuration published by entity-manager, its probe match data is published to D-Bus, which triggers entity-manager to publish the associated configuration.
Support for re-use of presence information in PROBE statements
The proposed design is to create a new daemon in the entity-manager repository, which is 'gpio-presence-sensor'.
It can be inspired by implementations found in downstream forks such as the NVIDIA gpio presence sensor implementation
sequenceDiagram participant PresenceDaemon participant EM participant AnyService note over PresenceDaemon: cable0 plug %% initial base configuration activate EM EM ->> EM: PROBE true on <br> xyz.openbmc_project.FruDevice <br> PRODUCT_PRODUCT_NAME=Yosemite V4 EM ->> PresenceDaemon: expose Configuration <br> xyz.openbmc_project.Configuration.GPIODeviceDetect <br> Name=com.meta.Hardware.Yv4.cable0 deactivate EM activate PresenceDaemon PresenceDaemon ->> PresenceDaemon: create dbus matcher <br> in case our configuration is removed %% start forward flow PresenceDaemon ->> PresenceDaemon: detect Device present <br> via GPIO Event PresenceDaemon ->> EM: expose <br>xyz.openbmc_project.Inventory.Source.DevicePresence <br> Name=com.meta.Hardware.Yv4.cable0 activate EM deactivate PresenceDaemon EM ->> EM: PROBE true on <br>xyz.openbmc_project.Inventory.Source.DevicePresence <br> Name=com.meta.Hardware.Yv4.cable0 EM ->> AnyService: expose new Configuration <br> Example: Voltage Sensor deactivate EM activate AnyService AnyService ->> AnyService: Example: <br> expose new Voltage Sensor AnyService ->> AnyService: produce Sensor readings %% start reverse flow note over PresenceDaemon: cable0 unplug activate PresenceDaemon PresenceDaemon ->> PresenceDaemon: detect Device absent <br> via GPIO Event PresenceDaemon ->> EM: remove <br>xyz.openbmc_project.Inventory.Source.DevicePresence <br> Name=com.meta.Hardware.Yv4.cable0 deactivate PresenceDaemon activate EM EM ->> EM: PROBE false on <br>xyz.openbmc_project.Inventory.Source.DevicePresence <br> Name=com.meta.Hardware.Yv4.cable0 EM ->> AnyService: remove new Configuration <br> Example: Voltage Sensor deactivate EM AnyService ->> AnyService: remove Sensor deactivate AnyService
'gpio-presence-sensor' should consume configuration via dbus interface
xyz.openbmc_project.Configuration.GPIODeviceDetect
entity-manager already creates the needed dbus interfaces here. So there is no need to make something new.
Below is a PDI yaml file to describe the proposed configuration interface:
description: > Information to enable a daemon to probe hardware based on gpio values properties: - name: Name type: string description: > Used by entity-manager to identify which hardware was detected. For internal use by entity-manager. - name: PresencePinNames type: array[string] description: > Names of the gpio lines. - name: PresencePinValues type: array[uint64] description: > Values of the gpio lines for which the device is considered present. Choosing 'uint64' instead of 'bool' here for compatibility with how EM exposes configuration on dbus.
'gpio-presence-sensor' then exposes xyz.openbmc_project.Inventory.Source.DevicePresence
dbus interface of its own if it detects the hardware:
description: > Information for a daemon to expose if hardware has been detected based on xyz.openbmc_project.Configuration.GPIODeviceDetect interface properties: - name: Name type: string description: > Used by entity-manager to identify which hw was detected. For internal use by entity-manager.
entity-manager can then consider the hardware as present and expose the inventory interfaces for it.
In case the gpio state changes, 'gpio-presence-sensor' can remove the xyz.openbmc_project.Inventory.Source.DevicePresence
interface and entity-manager can have a dbus matcher for that, to then remove the respective inventory items and any inventory items detected below it aswell.
entity-manager needs to be extended to handle a new type 'GPIODeviceDetect' Exposes record. It needs to then create the xyz.openbmc_project.Configuration.GPIODeviceDetect
dbus interface.
{ "$schema": "http://json-schema.org/draft-07/schema#", "$defs": { "GPIODeviceDetect": { "type": "object", "properties": { "Name": { "type": "string" }, "Type": { "type": "string" }, "PresencePinNames": { "type": "array", "items": { "type": "string" } }, "PresencePinValues": { "type": "array", "items": { "type": "number" } } }, "required": ["Name", "Type", "PresencePinNames", "PresencePinValues"] } } }
Below is an incomplete example of how such a config could look like.
The new part is the "Type": "GPIODeviceDetect"
which is conveniently named the same as the Dbus interface.
{ Exposes: [ { "Name": "com.meta.Hardware.Yv4.cable0", "PresencePinNames": ["presence-cable0"], "PresencePinValues": [1], "Type": "GPIODeviceDetect" }, { "Name": "com.meta.Hardware.Yv4.ComputeCard", "PresencePinNames": ["presence-slot0a", "presence-slot0b"], "PresencePinValues": [0, 1], "Type": "GPIODeviceDetect" }, { "Name": "com.meta.Hardware.Yv4.SidecarExpansion", "PresencePinNames": ["presence-slot0a", "presence-slot0b"], "PresencePinValues": [1, 0], "Type": "GPIODeviceDetect" }, { "Name": "com.meta.Hardware.Yv4.AirBlocker", "PresencePinNames": ["presence-slot0a", "presence-slot0b"], "PresencePinValues": [1, 1], "Type": "GPIODeviceDetect" }, { "Name": "com.meta.Hardware.Yv4.fanboard0", "PresencePinNames": ["presence-fanboard0"], "PresencePinValues": [0], "Type": "GPIODeviceDetect" }, ... ], ... "Name": "Chassis", "Probe": "xyz.openbmc_project.FruDevice({'BOARD_PRODUCT_NAME': 'MYBOARDPRODUCT*'})", "Type": "Board", }
Another configuration can then contain additional records for the newly detected e.g. fan board.
{ Exposes: [ { "Address": "0x28", "Bus": 5, "EntityId": 7, "EntityInstance": 0, "Name": "fanboard_air_inlet", "Name1": "fanboard_air_outlet", "Type": "NCT7802" }, ... ], ... "Name": "My Fan Board 0", "Probe": "xyz.openbmc_project.Inventory.Source.DevicePresence({'Name': 'com.meta.Hardware.Yv4.fanboard0'})", "Type": "Board", }
There is a need to namespace configuration for devices probed via gpios, according to their vendor or location in the system. "Name" is just a string but it can be used to create namespacing with dots. This will prevent accidental probing of unrelated configuration.
The existing approach with phosphor-inventory-manager and static configuration Leaning away from that because it cannot support multiple different chassis configurations in one fw image.
Presence detection integrated into entity-manager. There already exists a presence daemon, and it's an explicit non-goal of EM to implement any presence detection. Maintainers have confirmed that EM should not implement this feature internally.
Another daemon which would expose inventory items based on EM configuration. This would mean EM does not need to expose the item-specific inventory interfaces and properties.
Exposing the item-specific interfaces and properties in a generic way. This means EM would lose any semantic knowledge of the entities it exposes and become more like phosphor-inventory-manager
Preventing duplication in case of multiple instances of e.g. fan board/daughter board/cable through an additional variable besides "Name" that could then be used in the the configuration file of the entity. This is already covered partially by $index
but $index
is not stable and depends on order and count of the devices probed successfully. But this feature is left out intentionally here to limit the scope. So multiple instances of a daughter board may need multiple slightly different configuration files.
Comparing to Chu Lin's design, this design is not focused on the IPMI or redfish use-case. It is separate from the external interface. It is assumed the external interfaces can expose a cable inventory based on the cable dbus interface which was created as part of Chu Lin's design.
Comparing to Chu Lin's design, this design does not directly provide a cable inventory. So there is another daemon or configuration decorator needed to expose a cable inventory item.
Comparing to Chu Lin's design, this design is not limited to cables.
How will this be tested? How will this feature impact CI testing?
The feature can be tested in the entity-manager repository. We can use dbus-run-session to run an actual entity-manager to provide the configuration or simply provide a hardcoded configuration for 'gpio-presence-sensor'. For the gpio interactions, we can use CONFIG_GPIO_SIM
or alternatively abstract the gpio interactions into a separate class which can then be stubbed.