xref: /openbmc/docs/designs/inventory/gpio-based-hardware-inventory.md (revision 9168592c88de40c802823ba9ed6267f1b54a4002)
1# GPIO based hardware inventory
2
3Author: Alexander Hansen <alexander.hansen@9elements.com>
4
5Other contributors: Chu Lin <linchuyuan@google.com> (through their previous
6works), Amithash Prasad <amithash@meta.com>
7
8Created: August 26, 2024
9
10Reference:
11[Chu Lin's gpio based cable presence detection](https://github.com/openbmc/docs/blob/46902afd6ebd20d1148379df99fe2c0c591f56ba/designs/gpio-based-cable-presence.md)
12
13## Problem Description
14
15Due to increasing complexity of server designs and different configurations of
16the same system being possible, there is a need for a simple way to detect the
17presence of cards, cables and other connected entities which may or may not be
18plugged into a system. A subset of these entities support presence detection via
19gpios. This design focuses on those.
20
21Connected entities detectable via other means are out of scope of this design.
22
23## Background and References
24
25The existing design for the gpio based cable presence is partially implemented
26and focuses on IPMI use-case.
27
28[existing design by Chu Lin](https://github.com/openbmc/docs/blob/879601d92becfa1dbc082f487abfb5e0151a5091/designs/gpio-based-cable-presence.md)
29
30Currently the way to do gpio based presence detection is via
31phosphor-multi-gpio-presence and phosphor-inventory-manager.
32
33The static inventory is declared and the inventory items are exposed at runtime
34by phosphor-inventory-manager.
35
36The presence daemon then toggles the 'Present' property on dbus interface
37xyz.openbmc_project.Inventory.Item.
38
39Additional item-specific properties are statically declared in the
40phosphor-inventory-manager configuration.
41
42An example of how this is currently done:
43
44[presence daemon config](https://github.com/openbmc/openbmc/blob/1d438f68277cdb37e8062ae298402e9685882acb/meta-ibm/meta-sbp1/recipes-phosphor/gpio/phosphor-gpio-monitor/phosphor-multi-gpio-presence.json)
45
46[phosphor-inventory-manager config](https://github.com/openbmc/openbmc/blob/1d438f68277cdb37e8062ae298402e9685882acb/meta-ibm/meta-sbp1/recipes-phosphor/inventory/static-inventory/static-inventory.yaml)
47
48In the example we have inventory item **dimm_c0a1** which has following
49phosphor-multi-gpio-presence configuration:
50
51```json
52{
53  "Name": "DIMM_C0A1",
54  "LineName": "PLUG_DETECT_DIMM_C0A1",
55  "ActiveLow": true,
56  "Bias": "PULL_UP",
57  "Inventory": "/system/chassis/motherboard/dimm_c0a1"
58}
59```
60
61and phosphor-inventory-manager configuration:
62
63```yaml
64- name: Add DIMMs
65  description: >
66    Add the DIMM inventory path.
67  type: startup
68  actions:
69    - name: createObjects
70      objs:
71        /system/chassis/motherboard/dimm_c0a1:
72          xyz.openbmc_project.Inventory.Decorator.Replaceable:
73            FieldReplaceable:
74              value: true
75              type: boolean
76          xyz.openbmc_project.State.Decorator.OperationalStatus:
77            Functional:
78              value: true
79              type: boolean
80          xyz.openbmc_project.Inventory.Item:
81            PrettyName:
82              value: "DIMM C0A1"
83              type: string
84            Present:
85              value: false
86              type: boolean
87          xyz.openbmc_project.Inventory.Item.Dimm:
88          xyz.openbmc_project.Inventory.Decorator.LocationCode:
89            LocationCode:
90              value: "CPU0_DIMM_A1"
91              type: string
92```
93
94## Requirements
95
96- Support the gpio based detection of inventory items without static
97  configuration
98
99- Allow configuration of the detectable inventory items through entity-manager
100  configuration
101
102  - e.g. cable
103  - e.g. fan board
104  - e.g. daughter board
105  - entity-manager should expose all required Inventory interfaces
106  - the properties for these inventory interfaces can be obtained through the
107    exposes record in the json configuration
108
109- When a device is detected as present using the GPIO configuration published by
110  entity-manager, its probe match data is published to D-Bus, which triggers
111  entity-manager to publish the associated configuration.
112
113- Support for re-use of presence information in PROBE statements
114  - detecting one entity as 'Present' should enable detecting other entities
115    based on that info
116
117## Proposed Design
118
119The proposed design is to create a new daemon in the entity-manager repository,
120which is 'gpio-presence-sensor'.
121
122It can be inspired by implementations found in downstream forks such as the
123[NVIDIA gpio presence sensor implementation](https://github.com/NVIDIA/dbus-sensors/blob/889abc1c9bfae9395690d1562f3e08453dfa12ba/src/GPIOPresenceSensorMain.cpp)
124
125### Diagram
126
127```mermaid
128sequenceDiagram
129
130participant PresenceDaemon
131participant EM
132participant AnyService
133
134note over PresenceDaemon: cable0 plug
135
136%% initial base configuration
137
138activate EM
139EM ->> EM: PROBE true on <br> xyz.openbmc_project.FruDevice <br> PRODUCT_PRODUCT_NAME=Yosemite V4
140EM ->> PresenceDaemon: expose Configuration <br> xyz.openbmc_project.Configuration.GPIODeviceDetect <br> Name=com.meta.Hardware.Yv4.cable0
141deactivate EM
142activate PresenceDaemon
143PresenceDaemon ->> PresenceDaemon: create dbus matcher <br> in case our configuration is removed
144
145%% start forward flow
146
147PresenceDaemon ->> PresenceDaemon: detect Device present <br> via GPIO Event
148PresenceDaemon ->> EM: expose <br>xyz.openbmc_project.Inventory.Source.DevicePresence <br> Name=com.meta.Hardware.Yv4.cable0
149activate EM
150deactivate PresenceDaemon
151EM ->> EM: PROBE true on <br>xyz.openbmc_project.Inventory.Source.DevicePresence <br> Name=com.meta.Hardware.Yv4.cable0
152EM ->> AnyService: expose new Configuration <br> Example: Voltage Sensor
153deactivate EM
154
155activate AnyService
156AnyService ->> AnyService: Example: <br> expose new Voltage Sensor
157AnyService ->> AnyService: produce Sensor readings
158
159%% start reverse flow
160note over PresenceDaemon: cable0 unplug
161
162activate PresenceDaemon
163PresenceDaemon ->> PresenceDaemon: detect Device absent <br> via GPIO Event
164PresenceDaemon ->> EM: remove <br>xyz.openbmc_project.Inventory.Source.DevicePresence <br> Name=com.meta.Hardware.Yv4.cable0
165deactivate PresenceDaemon
166
167activate EM
168EM ->> EM: PROBE false on <br>xyz.openbmc_project.Inventory.Source.DevicePresence <br> Name=com.meta.Hardware.Yv4.cable0
169EM ->> AnyService: remove new Configuration <br> Example: Voltage Sensor
170deactivate EM
171AnyService ->> AnyService: remove Sensor
172deactivate AnyService
173```
174
175### Forward flow summary
176
177- EM exposes configuration for 'gpio-presence-sensor'
178- 'gpio-presence-sensor' creates a dbus matcher to watch for removal of it's
179  configuration
180- 'gpio-presence-sensor' uses gpios to detect hardware
181- 'gpio-presence-sensor' creates a dbus interface when it detects hardware
182- EM can probe new configuration files based on that dbus interface, via PROBE
183  statement
184- EM exposes the new configuration for the detected hardware
185
186### Reverse flow summary
187
188- 'gpio-presence-sensor' detects that the hardware is gone
189- 'gpio-presence-sensor' takes down the respective dbus interface
190- EM detects that via dbus matcher
191- EM removes the configuration for that hardware from dbus
192
193### Reverse flow summary (removal of configuration)
194
195- EM exposes configuration for 'gpio-presence-sensor'
196- 'gpio-presence-sensor' creates a dbus matcher to watch for removal of it's
197  configuration
198- 'gpio-presence-sensor' uses gpios to detect hardware
199- 'gpio-presence-sensor' creates a dbus interface when it detects hardware
200- EM removes the config for 'gpio-presence-sensor'
201- 'gpio-presence-sensor' takes down any dbus interfaces it created for detecting
202  hardware
203- EM detects that via dbus matcher
204- EM removes the configuration for that hardware from dbus
205
206### Proposed DBus Interfaces
207
208'gpio-presence-sensor' should consume configuration via dbus interface
209
210`xyz.openbmc_project.Configuration.GPIODeviceDetect`
211
212entity-manager already creates the needed dbus interfaces here. So there is no
213need to make something new.
214
215Below is a PDI yaml file to describe the proposed configuration interface:
216
217```yaml
218description: >
219  Information to enable a daemon to probe hardware based on gpio values
220properties:
221  - name: Name
222    type: string
223    description: >
224      Used by entity-manager to identify which hardware was detected. For
225      internal use by entity-manager.
226  - name: PresencePinNames
227    type: array[string]
228    description: >
229      Names of the gpio lines.
230  - name: PresencePinValues
231    type: array[uint64]
232    description: >
233      Values of the gpio lines for which the device is considered present.
234      Choosing 'uint64' instead of 'bool' here for compatibility with how EM
235      exposes configuration on dbus.
236```
237
238'gpio-presence-sensor' then exposes
239`xyz.openbmc_project.Inventory.Source.DevicePresence` dbus interface of its own
240if it detects the hardware:
241
242```yaml
243description: >
244  Information for a daemon to expose if hardware has been detected based on
245  xyz.openbmc_project.Configuration.GPIODeviceDetect interface
246properties:
247  - name: Name
248    type: string
249    description: >
250      Used by entity-manager to identify which hw was detected. For internal use
251      by entity-manager.
252```
253
254entity-manager can then consider the hardware as present and expose the
255inventory interfaces for it.
256
257### Handling removal of the device
258
259In case the gpio state changes, 'gpio-presence-sensor' can remove the
260`xyz.openbmc_project.Inventory.Source.DevicePresence` interface and
261entity-manager can have a dbus matcher for that, to then remove the respective
262inventory items and any inventory items detected below it aswell.
263
264### Proposed changes in entity-manager
265
266entity-manager needs to be extended to handle a new type 'GPIODeviceDetect'
267Exposes record. It needs to then create the
268`xyz.openbmc_project.Configuration.GPIODeviceDetect` dbus interface.
269
270#### Proposed EM Configuration Schema
271
272```json
273{
274  "$schema": "http://json-schema.org/draft-07/schema#",
275  "$defs": {
276    "GPIODeviceDetect": {
277      "type": "object",
278      "properties": {
279        "Name": {
280          "type": "string"
281        },
282        "Type": {
283          "type": "string"
284        },
285        "PresencePinNames": {
286          "type": "array",
287          "items": {
288            "type": "string"
289          }
290        },
291        "PresencePinValues": {
292          "type": "array",
293          "items": {
294            "type": "number"
295          }
296        }
297      },
298      "required": ["Name", "Type", "PresencePinNames", "PresencePinValues"]
299    }
300  }
301}
302```
303
304### Example EM Config Fragments
305
306Below is an incomplete example of how such a config could look like.
307
308The new part is the `"Type": "GPIODeviceDetect"` which is conveniently named the
309same as the Dbus interface.
310
311```json
312{
313  Exposes:
314  [
315    {
316      "Name": "com.meta.Hardware.Yv4.cable0",
317      "PresencePinNames": ["presence-cable0"],
318      "PresencePinValues": [1],
319      "Type": "GPIODeviceDetect"
320    },
321    {
322      "Name": "com.meta.Hardware.Yv4.ComputeCard",
323      "PresencePinNames": ["presence-slot0a", "presence-slot0b"],
324      "PresencePinValues": [0, 1],
325      "Type": "GPIODeviceDetect"
326    },
327    {
328      "Name": "com.meta.Hardware.Yv4.SidecarExpansion",
329      "PresencePinNames": ["presence-slot0a", "presence-slot0b"],
330      "PresencePinValues": [1, 0],
331      "Type": "GPIODeviceDetect"
332    },
333    {
334      "Name": "com.meta.Hardware.Yv4.AirBlocker",
335      "PresencePinNames": ["presence-slot0a", "presence-slot0b"],
336      "PresencePinValues": [1, 1],
337      "Type": "GPIODeviceDetect"
338    },
339    {
340      "Name": "com.meta.Hardware.Yv4.fanboard0",
341      "PresencePinNames": ["presence-fanboard0"],
342      "PresencePinValues": [0],
343      "Type": "GPIODeviceDetect"
344    },
345    ...
346  ],
347  ...
348  "Name": "Chassis",
349  "Probe": "xyz.openbmc_project.FruDevice({'BOARD_PRODUCT_NAME': 'MYBOARDPRODUCT*'})",
350  "Type": "Board",
351}
352```
353
354Another configuration can then contain additional records for the newly detected
355e.g. fan board.
356
357```json
358{
359  Exposes:
360  [
361      {
362        "Address": "0x28",
363        "Bus": 5,
364        "EntityId": 7,
365        "EntityInstance": 0,
366        "Name": "fanboard_air_inlet",
367        "Name1": "fanboard_air_outlet",
368        "Type": "NCT7802"
369    },
370    ...
371  ],
372  ...
373  "Name": "My Fan Board 0",
374  "Probe": "xyz.openbmc_project.Inventory.Source.DevicePresence({'Name': 'com.meta.Hardware.Yv4.fanboard0'})",
375  "Type": "Board",
376}
377```
378
379### Uniqueness of the "Name" property
380
381There is a need to namespace configuration for devices probed via gpios,
382according to their vendor or location in the system. "Name" is just a string but
383it can be used to create namespacing with dots. This will prevent accidental
384probing of unrelated configuration.
385
386## Alternatives Considered
387
388- The existing approach with phosphor-inventory-manager and static configuration
389  Leaning away from that because it cannot support multiple different chassis
390  configurations in one fw image.
391
392- Presence detection integrated into entity-manager. There already exists a
393  presence daemon, and it's an explicit non-goal of EM to implement any presence
394  detection. Maintainers have confirmed that EM should not implement this
395  feature internally.
396
397- Another daemon which would expose inventory items based on EM configuration.
398  This would mean EM does not need to expose the item-specific inventory
399  interfaces and properties.
400
401- Exposing the item-specific interfaces and properties in a generic way. This
402  means EM would lose any semantic knowledge of the entities it exposes and
403  become more like phosphor-inventory-manager
404
405- Preventing duplication in case of multiple instances of e.g. fan
406  board/daughter board/cable through an additional variable besides "Name" that
407  could then be used in the the configuration file of the entity. This is
408  already covered partially by `$index` but `$index` is not stable and depends
409  on order and count of the devices probed successfully. But this feature is
410  left out intentionally here to limit the scope. So multiple instances of a
411  daughter board may need multiple slightly different configuration files.
412
413- Comparing to Chu Lin's design, this design is not focused on the IPMI or
414  redfish use-case. It is separate from the external interface. It is assumed
415  the external interfaces can expose a cable inventory based on the
416  [cable dbus interface](https://github.com/openbmc/phosphor-dbus-interfaces/commit/3c5b76491afb8401627fc343077fe420f8a5e7f9)
417  which was created as part of Chu Lin's design.
418
419- Comparing to Chu Lin's design, this design does not directly provide a cable
420  inventory. So there is another daemon or configuration decorator needed to
421  expose a cable inventory item.
422
423- Comparing to Chu Lin's design, this design is not limited to cables.
424
425## Impacts
426
427### Organizational
428
429- Does this repository require a new repository? No
430- Who will be the initial maintainer(s) of this repository?
431- Which repositories are expected to be modified to execute this design?
432  - entity-manager
433- Make a list, and add listed repository maintainers to the gerrit review.
434
435## Testing
436
437How will this be tested? How will this feature impact CI testing?
438
439The feature can be tested in the entity-manager repository. We can use
440dbus-run-session to run an actual entity-manager to provide the configuration or
441simply provide a hardcoded configuration for 'gpio-presence-sensor'. For the
442gpio interactions, we can use `CONFIG_GPIO_SIM` or alternatively abstract the
443gpio interactions into a separate class which can then be stubbed.
444