xref: /openbmc/docs/designs/psu-firmware-update.md (revision ba560cc31297caddfc157c540ae9e6d760d630e5)
1# PSU firmware update
2
3Author: Lei YU <mine260309@gmail.com> `LeiYU`
4
5Other contributors:
6
7- Su Xiao <suxiao@inspur.com>
8- Derek Howard <derekh@us.ibm.com>
9
10Created: 2019-06-03
11
12## Problem Description
13
14There is no support in OpenBMC to update the firmware for PSUs.
15
16## Background and References
17
18In OpenBMC, there is an existing interface for [software update][1].
19
20The update process consists of:
21
221. Uploading an image to the BMC;
232. Processing the image to check the version and purpose of the image;
243. Verifying and activating the image.
25
26Currently, BMC and BIOS firmware update are supported:
27
28- [phosphor-bmc-code-mgmt][2] implements BMC code update, and it supports all
29  the above 3 processes.
30- [openpower-pnor-code-mgmt][3] implements BIOS code update, and it only
31  implements "verifying and activating" the image. It shares the function of the
32  above 1 & 2 processes.
33- Both of the above use the same [Software DBus interface][1].
34
35For PSU firmware update, it is preferred to re-use the same function for the
36above 1 & 2.
37
38## Requirements
39
40The PSU firmware shall be updated in the below cases:
41
421. The user manually invokes the APIs to do the update;
432. After BMC code update and if there is a newer PSU image in the BMC's
44   filesystem, BMC shall update the PSU firmware;
453. When a PSU is replaced and the version is older than the one in BMC's
46   filesystem, BMC shall update the PSU firmware.
474. An optional 'override' parameter may be specified to do the update in the
48   above cases regardless of which PSU image is newer.
495. There are cases that a system could use different models of PSUs, and thus
50   different PSU firmware images need to be supported.
51
52For some PSUs, it is risky to do PSU code update while the host is running to
53avoid power loss. This shall be handled by PSU vendor-specific tools, but not in
54the generic framework.
55
56Note: The "vendor-specific" referred below is the PSU vendor-specific.
57
58So the below checks are optional and expected to be handled by vendor-specific
59tool:
60
611. If the host is powered off;
622. If the redundant PSUs are all connected;
633. If the AC input and DC standby output is OK on all the PSUs;
64
65## Proposed Design
66
67As described in the above requirements, there are different cases where the PSU
68firmware is updated:
69
70- When the APIs are invoked;
71- When a new version is updated together with BMC code update;
72- When a PSU is replaced with an old version of the firmware.
73
74### Update by API
75
76This method is usually used by users who manually update PSU firmware.
77
78It will re-use the current interfaces to upload, verify, and activate the image.
79
801. The "Version" interface needs to be extended:
81   - Add a new [VersionPurpose][4] for PSU;
82   - Re-use the existing `ExtendedVersion` as an additional string for
83     vendor-specific purpose, e.g. to indicate the PSU model.
842. Re-use the existing functions implemented by [phosphor-bmc-code-mgmt][2] for
85   uploading and processing the image.
86   - The PSU update image shall be a tarball that consists of a MANIFEST,
87     images, and signatures.
88   - When the PSU image is uploaded and processed, a `VersionObject` shall be
89     created to indicate the version and its purpose.
903. There will be a new service that implements the [Activation][5] interface to
91   update the PSU firmware.
92   - The service will be started by default when BMC starts;
93   - On start, the service will check the PSU's existing firmware and create the
94     `Version` and `Activation` interfaces.
95   - The service shall watch the interface added on
96     `/xyz/openbmc_project/Software`.
97   - When a new object with PSU `VersionPurpose` is added, the service will
98     verify the signature of the image;
99   - The service shall check the `ExtendedVersion` to make sure the image
100     matches the PSU model.
101   - The service will have a configuration file to describe the PSU model and
102     its related vendor-specific tools.
103   - The service will find the matched vendor-specific tool to perform the code
104     update. For example, if a vendor specific tool `foo` is configured in
105     `psu-update@foo.service` which executes `foo psu.bin`, the service will
106     find the `psu-update@foo.service` and start it by systemd, which performs
107     the update.
108   - When the PSU code update is completed, an informational event log shall be
109     created.
110   - When the PSU code update is completed, the image, MANIFEST, and optionally
111     the signature will be saved to a pre-defined directory in read-write
112     filesystem for future use, in case a new PSU with old firmware is plugged.
1134. The vendor-specific tool shall run all the checks it needs to be run, before
114   and after the PSU update, and return a status to the above service to
115   indicate the result.
1165. When the vendor-specific tool returns errors, the PSU update will be aborted
117   and an error event log shall be created.
1186. During the update, the service shall set the related sensors to
119   non-functional, and when the update is done, it shall set the related sensors
120   back to functional.
121
122### Update by new BMC image
123
124When BMC is updated and a new version of PSU firmware is included, it shall be
125updated to the PSU. This will be done by the same service described above.
126
1271. On start, the service will check the PSU image, model and version in its
128   filesystem, compare with the ones in PSU hardware and decide if PSU firmware
129   update shall be performed.
1302. There could be two places containing the PSU images:
131   - The pre-defined directory in read-only filesystem, which is part of BMC
132     image.
133   - The other pre-defined directory in read-write filesystem, which is the
134     location for the saved PSU images by API update. Both places shall be
135     checked and a newer version will be selected to compare with the PSU
136     hardware.
1373. If PSU update is needed, the service will find the matched vendor-specific
138   tool to perform the code update.
1394. The following process will be the same as [Update by API].
140
141### Update on replaced PSU
142
143When a PSU is replaced, and the firmware version is older than the one in BMC
144filesystem (or if the optional 'override' parameter is specified), it shall be
145updated. This will be done by the same service described above.
146
1471. On start, the service will subscribe to the PropertiesChanged signal to the
148   PSU object path to monitor the PSU presence status. (Or maybe subscribe the
149   InterfacesAdded/Removed signal?)
1502. When a PSU's presence status is changed from false to true (or the
151   PropertiesChanged event occurs), the service will check the new PSU's model
152   and firmware version to decide if the firmware needs to be updated.
1533. If yes, the service will find the matched vendor-specific tool to perform the
154   code update.
1554. The following process will be the same as [Update by API].
156
157## Alternatives Considered
158
159### General implementation
160
161The PSU firmware update could be implemented by separated recipes that only call
162vendor-specific tools. It will be a bit simpler but loses the unified interface
163provided by OpenBMC's existing [software update interface][1], and thus it will
164become difficult to use a standard API to the PSU firmware update.
165
166### VersionPurpose
167
168It is possible to re-use the `VersionPurpose.Other` to represent the PSU image's
169version purpose. But that requires additional information about the image,
170otherwise, there is no way to tell if the image is for PSU, or CPLD, or other
171peripherals. A new `VersionPurpose.PSU` is more specific and makes it easier to
172implement and friendly for the user.
173
174### Additional string
175
176The design proposal uses `ExtendedVersion` as the additional string for
177vendor-specific purpose, e.g. to indicate the PSU model, so the implementation
178could check and compare if the image matches the PSU model. It is possible to
179make it optional or remove this additional string, then the implementation will
180not verify if the image matches the PSU. It could be OK if we trust the user who
181is uploading the correct image, especially the image shall be signed. But it is
182always risky in case the image does not match the PSU, and cause unintended
183damage if the incorrect PSU firmware is updated.
184
185## Impacts
186
187This design only introduces a new `VersionPurpose` enum into the dbus
188interfaces. The newly introduced PSU firmware update service will be a new
189service that implements existing [Activation][5] interface. There will be new
190configuration files for the service to:
191
192- Link the vendor specific tool with PSU models.
193- Get the sensors related to the PSU.
194- etc.
195
196So the impacts are minimal to existing systems.
197
198## Testing
199
200It requires the manual tests to verify the PSU code update process.
201
202- Verify the PSU code update is done on all PSUs successfully;
203- Verify the PSU code update will fail if the vendor-specific tool fails on
204  pre-condition check, of fails on updating PSU.
205- Verify the PSU code update is performed after a new BMC image is updated
206  containing a new (or different, if 'override' used) version of PSU firmware.
207- Verify the PSU code update is performed after a PSU with old (or different, if
208  'override' is used) firmware is plugged in.
209
210[1]:
211  https://github.com/openbmc/phosphor-dbus-interfaces/tree/master/yaml/xyz/openbmc_project/Software
212[2]: https://github.com/openbmc/phosphor-bmc-code-mgmt/
213[3]: https://github.com/openbmc/openpower-pnor-code-mgmt/
214[4]:
215  https://github.com/openbmc/phosphor-dbus-interfaces/blob/57b878d048f929643276f1bf7fdf750abc4bde8b/xyz/openbmc_project/Software/Version.interface.yaml#L14
216[5]:
217  https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/yaml/xyz/openbmc_project/Software/Activation.interface.yaml
218