-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'introduce-PLDM-firmware-update-library'
Jacob Keller says: ==================== introduce PLDM firmware update library This series goal is to enable support for updating the ice hardware flash using the devlink flash command. The ice firmware update files are distributed using the file format described by the "PLDM for Firmware Update" standard: https://www.dmtf.org/documents/pmci/pldm-firmware-update-specification-100 Because this file format is standard, this series introduces a new library that handles the generic logic for parsing the PLDM file header. The library uses a design that is very similar to the Mellanox mlxfw module. That is, a simple ops table is setup and device drivers instantiate an instance of the pldmfw library with the device specific operations. Doing so allows for each device to implement the low level behavior for how to interact with its firmware. This series includes the library and an implementation for the ice hardware. I've removed all of the parameters, and the proposed changes to support overwrite mode. I'll be working on the overwrite mask suggestion from Jakub as a follow-up series. Because the PLDM file format is a standard and not something that is specific to the Intel hardware, I opted to place this update library in lib/pldmfw. I should note that while I tried to make the library generic, it does not attempt to mimic the complete "Update Agent" as defined in the standard. This is mostly due to the fact that the actual interfaces exposed to software for the ice hardware would not allow this. This series depends on some work just recently and is based on top of the patch series sent by Tony published at: https://lore.kernel.org/netdev/20200723234720.1547308-1-anthony.l.nguyen@intel.com/T/#t Changes since v2 RFC * Removed overwrite mode patches, as this can become a follow up series with a separate discussion * Fixed a minor bug in the pldm_timestamp structure not being packed. * Dropped Cc for other driver maintainers, as this series no longer includes changes to the core flash update command. * Re-ordered patches slightly. Changes since v1 RFC * Removed the "allow_downgrade_on_flash_update" parameter. Instead, the driver will always attempt to flash the device, even when firmware indicates that it would be a downgrade. A dev_warn is used to indicate when this occurs. * Removed the "ignore_pending_flash_update". Instead, the driver will always check for and cancel any previous pending update. A devlink flash status message will be sent when this cancellation occurs. * Removed the "reset_after_flash_update" parameter. This will instead be implemented as part of a devlink reset interface, work left for a future change. * Replaced the "flash_update_preservation_level" parameter with a new "overwrite" mode attribute on the flash update command. For ice, this mode will select the preservation level. For all other drivers, I modified them to check that the mode is "OVERWRITE_NOTHING", and have Cc'd the maintainers to get their input. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
- Loading branch information
Showing
24 changed files
with
2,953 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
.. SPDX-License-Identifier: GPL-2.0-only | ||
========================= | ||
Driver-specific callbacks | ||
========================= | ||
|
||
The ``pldmfw`` module relies on the device driver for implementing device | ||
specific behavior using the following operations. | ||
|
||
``.match_record`` | ||
----------------- | ||
|
||
The ``.match_record`` operation is used to determine whether a given PLDM | ||
record matches the device being updated. This requires comparing the record | ||
descriptors in the record with information from the device. Many record | ||
descriptors are defined by the PLDM standard, but it is also allowed for | ||
devices to implement their own descriptors. | ||
|
||
The ``.match_record`` operation should return true if a given record matches | ||
the device. | ||
|
||
``.send_package_data`` | ||
---------------------- | ||
|
||
The ``.send_package_data`` operation is used to send the device-specific | ||
package data in a record to the device firmware. If the matching record | ||
provides package data, ``pldmfw`` will call the ``.send_package_data`` | ||
function with a pointer to the package data and with the package data | ||
length. The device driver should send this data to firmware. | ||
|
||
``.send_component_table`` | ||
------------------------- | ||
|
||
The ``.send_component_table`` operation is used to forward component | ||
information to the device. It is called once for each applicable component, | ||
that is, for each component indicated by the matching record. The | ||
device driver should send the component information to the device firmware, | ||
and wait for a response. The provided transfer flag indicates whether this | ||
is the first, last, or a middle component, and is expected to be forwarded | ||
to firmware as part of the component table information. The driver should an | ||
error in the case when the firmware indicates that the component cannot be | ||
updated, or return zero if the component can be updated. | ||
|
||
``.flash_component`` | ||
-------------------- | ||
|
||
The ``.flash_component`` operation is used to inform the device driver to | ||
flash a given component. The driver must perform any steps necessary to send | ||
the component data to the device. | ||
|
||
``.finalize_update`` | ||
-------------------- | ||
|
||
The ``.finalize_update`` operation is used by the ``pldmfw`` library in | ||
order to allow the device driver to perform any remaining device specific | ||
logic needed to finish the update. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
.. SPDX-License-Identifier: GPL-2.0-only | ||
================================== | ||
PLDM Firmware file format overview | ||
================================== | ||
|
||
A PLDM firmware package is a binary file which contains a header that | ||
describes the contents of the firmware package. This includes an initial | ||
package header, one or more firmware records, and one or more components | ||
describing the actual flash contents to program. | ||
|
||
This diagram provides an overview of the file format:: | ||
|
||
overall file layout | ||
+----------------------+ | ||
| | | ||
| Package Header | | ||
| | | ||
+----------------------+ | ||
| | | ||
| Device Records | | ||
| | | ||
+----------------------+ | ||
| | | ||
| Component Info | | ||
| | | ||
+----------------------+ | ||
| | | ||
| Package Header CRC | | ||
| | | ||
+----------------------+ | ||
| | | ||
| Component Image 1 | | ||
| | | ||
+----------------------+ | ||
| | | ||
| Component Image 2 | | ||
| | | ||
+----------------------+ | ||
| | | ||
| ... | | ||
| | | ||
+----------------------+ | ||
| | | ||
| Component Image N | | ||
| | | ||
+----------------------+ | ||
|
||
Package Header | ||
============== | ||
|
||
The package header begins with the UUID of the PLDM file format, and | ||
contains information about the version of the format that the file uses. It | ||
also includes the total header size, a release date, the size of the | ||
component bitmap, and an overall package version. | ||
|
||
The following diagram provides an overview of the package header:: | ||
|
||
header layout | ||
+-------------------------+ | ||
| PLDM UUID | | ||
+-------------------------+ | ||
| Format Revision | | ||
+-------------------------+ | ||
| Header Size | | ||
+-------------------------+ | ||
| Release Date | | ||
+-------------------------+ | ||
| Component Bitmap Length | | ||
+-------------------------+ | ||
| Package Version Info | | ||
+-------------------------+ | ||
|
||
Device Records | ||
============== | ||
|
||
The device firmware records area starts with a count indicating the total | ||
number of records in the file, followed by each record. A single device | ||
record describes what device matches this record. All valid PLDM firmware | ||
files must contain at least one record, but optionally may contain more than | ||
one record if they support multiple devices. | ||
|
||
Each record will identify the device it supports via TLVs that describe the | ||
device, such as the PCI device and vendor information. It will also indicate | ||
which set of components that are used by this device. It is possible that | ||
only subset of provided components will be used by a given record. A record | ||
may also optionally contain device-specific package data that will be used | ||
by the device firmware during the update process. | ||
|
||
The following diagram provides an overview of the device record area:: | ||
|
||
area layout | ||
+---------------+ | ||
| | | ||
| Record Count | | ||
| | | ||
+---------------+ | ||
| | | ||
| Record 1 | | ||
| | | ||
+---------------+ | ||
| | | ||
| Record 2 | | ||
| | | ||
+---------------+ | ||
| | | ||
| ... | | ||
| | | ||
+---------------+ | ||
| | | ||
| Record N | | ||
| | | ||
+---------------+ | ||
|
||
record layout | ||
+-----------------------+ | ||
| Record Length | | ||
+-----------------------+ | ||
| Descriptor Count | | ||
+-----------------------+ | ||
| Option Flags | | ||
+-----------------------+ | ||
| Version Settings | | ||
+-----------------------+ | ||
| Package Data Length | | ||
+-----------------------+ | ||
| Applicable Components | | ||
+-----------------------+ | ||
| Version String | | ||
+-----------------------+ | ||
| Descriptor TLVs | | ||
+-----------------------+ | ||
| Package Data | | ||
+-----------------------+ | ||
|
||
Component Info | ||
============== | ||
|
||
The component information area begins with a count of the number of | ||
components. Following this count is a description for each component. The | ||
component information points to the location in the file where the component | ||
data is stored, and includes version data used to identify the version of | ||
the component. | ||
|
||
The following diagram provides an overview of the component area:: | ||
|
||
area layout | ||
+-----------------+ | ||
| | | ||
| Component Count | | ||
| | | ||
+-----------------+ | ||
| | | ||
| Component 1 | | ||
| | | ||
+-----------------+ | ||
| | | ||
| Component 2 | | ||
| | | ||
+-----------------+ | ||
| | | ||
| ... | | ||
| | | ||
+-----------------+ | ||
| | | ||
| Component N | | ||
| | | ||
+-----------------+ | ||
|
||
component layout | ||
+------------------------+ | ||
| Classification | | ||
+------------------------+ | ||
| Component Identifier | | ||
+------------------------+ | ||
| Comparison Stamp | | ||
+------------------------+ | ||
| Component Options | | ||
+------------------------+ | ||
| Activation Method | | ||
+------------------------+ | ||
| Location Offset | | ||
+------------------------+ | ||
| Component Size | | ||
+------------------------+ | ||
| Component Version Info | | ||
+------------------------+ | ||
| Package Data | | ||
+------------------------+ | ||
|
||
|
||
Package Header CRC | ||
================== | ||
|
||
Following the component information is a short 4-byte CRC calculated over | ||
the contents of all of the header information. | ||
|
||
Component Images | ||
================ | ||
|
||
The component images follow the package header information in the PLDM | ||
firmware file. Each of these is simply a binary chunk with its start and | ||
size defined by the matching component structure in the component info area. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
.. SPDX-License-Identifier: GPL-2.0-only | ||
================================== | ||
PLDM Firmware Flash Update Library | ||
================================== | ||
|
||
``pldmfw`` implements functionality for updating the flash on a device using | ||
the PLDM for Firmware Update standard | ||
<https://www.dmtf.org/documents/pmci/pldm-firmware-update-specification-100>. | ||
|
||
.. toctree:: | ||
:maxdepth: 1 | ||
|
||
file-format | ||
driver-ops | ||
|
||
================================== | ||
Overview of the ``pldmfw`` library | ||
================================== | ||
|
||
The ``pldmfw`` library is intended to be used by device drivers for | ||
implementing device flash update based on firmware files following the PLDM | ||
firwmare file format. | ||
|
||
It is implemented using an ops table that allows device drivers to provide | ||
the underlying device specific functionality. | ||
|
||
``pldmfw`` implements logic to parse the packed binary format of the PLDM | ||
firmware file into data structures, and then uses the provided function | ||
operations to determine if the firmware file is a match for the device. If | ||
so, it sends the record and component data to the firmware using the device | ||
specific implementations provided by device drivers. Once the device | ||
firmware indicates that the update may be performed, the firmware data is | ||
sent to the device for programming. | ||
|
||
Parsing the PLDM file | ||
===================== | ||
|
||
The PLDM file format uses packed binary data, with most multi-byte fields | ||
stored in the Little Endian format. Several pieces of data are variable | ||
length, including version strings and the number of records and components. | ||
Due to this, it is not straight forward to index the record, record | ||
descriptors, or components. | ||
|
||
To avoid proliferating access to the packed binary data, the ``pldmfw`` | ||
library parses and extracts this data into simpler structures for ease of | ||
access. | ||
|
||
In order to safely process the firmware file, care is taken to avoid | ||
unaligned access of multi-byte fields, and to properly convert from Little | ||
Endian to CPU host format. Additionally the records, descriptors, and | ||
components are stored in linked lists. | ||
|
||
Performing a flash update | ||
========================= | ||
|
||
To perform a flash update, the ``pldmfw`` module performs the following | ||
steps | ||
|
||
1. Parse the firmware file for record and component information | ||
2. Scan through the records and determine if the device matches any record | ||
in the file. The first matched record will be used. | ||
3. If the matching record provides package data, send this package data to | ||
the device. | ||
4. For each component that the record indicates, send the component data to | ||
the device. For each component, the firmware may respond with an | ||
indication of whether the update is suitable or not. If any component is | ||
not suitable, the update is canceled. | ||
5. For each component, send the binary data to the device firmware for | ||
updating. | ||
6. After all components are programmed, perform any final device-specific | ||
actions to finalize the update. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.