xref: /openbmc/docs/designs/firmware-update-via-blobs.md (revision f4febd002df578bad816239b70950f84ea4567e8)
12654988cSPatrick Williams# In-Band Update of BMC Firmware (and others) using OEM IPMI Blob Transport
22654988cSPatrick Williams
32654988cSPatrick WilliamsAuthor: Patrick Venture <venture!>
42654988cSPatrick Williams
52654988cSPatrick WilliamsCreated: 2018-10-18
62654988cSPatrick Williams
72654988cSPatrick Williams## Problem Description
82654988cSPatrick Williams
92654988cSPatrick WilliamsThe BMC needs a mechanism for receiving a new firmware image from the host
102654988cSPatrick Williamsthrough a variety of mechanisms. This can best be served with one protocol into
112654988cSPatrick Williamswhich multiple approaches can be routed.
122654988cSPatrick Williams
132654988cSPatrick Williams## Background and References
142654988cSPatrick Williams
152654988cSPatrick WilliamsBMC hardware provides at a minimum some interface for sending and receiving IPMI
162654988cSPatrick Williamsmessages. This hardware may also provide regions that can be memory mapped for
172654988cSPatrick Williamshigher speed communication between the BMC and the host. Certain infrastructures
182654988cSPatrick Williamsdo not provide network access to the BMC, therefore it is required to provide an
192654988cSPatrick Williamsupdate mechanism that can be done in-band between the host and the BMC.
202654988cSPatrick Williams
212654988cSPatrick WilliamsIn-band here refers to a communications channel that is directly connected
222654988cSPatrick Williamsbetween the host and BMC.
232654988cSPatrick Williams
242654988cSPatrick Williams1.  Serial
252654988cSPatrick Williams1.  IPMI over LPC
262654988cSPatrick Williams1.  IPMI over i2c
272654988cSPatrick Williams1.  LPC Memory-Mapped Region
282654988cSPatrick Williams1.  P2A bridge
292654988cSPatrick Williams
302654988cSPatrick Williams## Primer
312654988cSPatrick Williams
322654988cSPatrick WilliamsPlease read the IPMI BLOB protocol design as primer
332654988cSPatrick Williams[here](https://github.com/openbmc/phosphor-ipmi-blobs/blob/master/README.md).
342654988cSPatrick Williams
352654988cSPatrick Williams## Requirements
362654988cSPatrick Williams
372654988cSPatrick WilliamsThe following statements are reflective of the initial requirements.
382654988cSPatrick Williams
39*f4febd00SPatrick Williams- Any update mechanism must provide support for UBI tarballs and legacy (static
40*f4febd00SPatrick Williams  layout) flash images. Leveraging the BLOB protocol allows a system to provide
41*f4febd00SPatrick Williams  support for any image type simply by implementing a mechanism for handling it.
422654988cSPatrick Williams
43*f4febd00SPatrick Williams- Any update mechanism must allow for triggering an image verification step
442654988cSPatrick Williams  before the image is used.
452654988cSPatrick Williams
46*f4febd00SPatrick Williams- Any update mechanism must allow implementing the data staging via different
472654988cSPatrick Williams  in-band mechanisms.
482654988cSPatrick Williams
49*f4febd00SPatrick Williams- Any update mechanism must provide a handshake or equivalent protocol for
502654988cSPatrick Williams  coordinating the data transfer. For instance, whether the BMC should enable
51*f4febd00SPatrick Williams  the P2A bridge and what region to use or whether to turn on the LPC memory map
52*f4febd00SPatrick Williams  bridge.
532654988cSPatrick Williams
54*f4febd00SPatrick Williams- Any update mechanism must attempt to maintain security, insomuch as not
552654988cSPatrick Williams  leaving a memory region open by default. For example, before starting the
562654988cSPatrick Williams  verification step, access to the staged firmware image must not be still
572654988cSPatrick Williams  accessible from the host.
582654988cSPatrick Williams
592654988cSPatrick Williams## Proposed Design
602654988cSPatrick Williams
612654988cSPatrick WilliamsOpenBMC supports a BLOB protocol that provides primitives. These primitives
622654988cSPatrick Williamsallow a variety of different "handlers" to exist that implement those primitives
632654988cSPatrick Williamsfor specific "blobs." A blob in this context is a file path that is strictly
642654988cSPatrick Williamsunique.
652654988cSPatrick Williams
662654988cSPatrick WilliamsSending the firmware image over the BLOB protocol will be done via routing the
672654988cSPatrick Williams[phosphor-ipmi-flash design](https://github.com/openbmc/phosphor-ipmi-flash/blob/master/README.md)
682654988cSPatrick Williamsthrough a BLOB handler. This is meant to supplant `phosphor-ipmi-flash`'s
692654988cSPatrick Williamscurrent approach to centralize on one flexible handler.
702654988cSPatrick Williams
712654988cSPatrick Williams### Sequencing Control
722654988cSPatrick Williams
732654988cSPatrick WilliamsTo enforce sequencing control, the design requires that only one blob be open at
742654988cSPatrick Williamsa time. If the verification blob is open, the other blobs cannot be opened, and
752654988cSPatrick Williamslikewise if a client has a data blob open, the verification blob cannot be
762654988cSPatrick Williamsopened.
772654988cSPatrick Williams
782654988cSPatrick Williams### Defining Blobs
792654988cSPatrick Williams
802654988cSPatrick WilliamsThe BLOB protocol allows a handler to specify a list of blob ids. This list will
812654988cSPatrick Williamsbe leveraged to specify whether the platform supports either the legacy (static
822654988cSPatrick Williamslayout) or the UBI mechanism, or both. The flags provided to the open command
832654988cSPatrick Williamsidentify the mechanism selected by the client-side. The stat command will return
842654988cSPatrick Williamsthe list of supported mechanisms for the blob.
852654988cSPatrick Williams
862654988cSPatrick WilliamsThe blob ids for the mechanisms will be as follows:
872654988cSPatrick Williams
88*f4febd00SPatrick Williams| Flash Blob Id    | Type            |
89*f4febd00SPatrick Williams| ---------------- | --------------- |
90*f4febd00SPatrick Williams| `/flash/image`   | Static Layout   |
91*f4febd00SPatrick Williams| `/flash/tarball` | UBI             |
92*f4febd00SPatrick Williams| `/flash/bios`    | Host BIOS image |
932654988cSPatrick Williams
942654988cSPatrick WilliamsThe flash handler will determine what commands it should expect to receive and
952654988cSPatrick Williamsresponses it will return given the blob opened, based on the flags provided to
962654988cSPatrick Williamsopen.
972654988cSPatrick Williams
982654988cSPatrick WilliamsThe flash handler will only allow one of the above blobs to be opened for a
992654988cSPatrick Williamssequence of commands, such that you cannot open `/flash/image` and then open
1002654988cSPatrick Williams`/flash/bios` without completing (or later aborting) the first update process
1012654988cSPatrick Williamsstarted.
1022654988cSPatrick Williams
1032654988cSPatrick WilliamsThe following blob ids are defined for storing the hash for the image:
1042654988cSPatrick Williams
105*f4febd00SPatrick Williams| Hash Blob     | Id Mechanism                    |
106*f4febd00SPatrick Williams| ------------- | ------------------------------- |
107*f4febd00SPatrick Williams| `/flash/hash` | Whichever flash blob was opened |
1082654988cSPatrick Williams
1092654988cSPatrick WilliamsThe flash handler will only allow one open file at a time, such that if the host
1102654988cSPatrick Williamsattempts to send a firmware image down over IPMI BlockTransfer, it won't allow
1112654988cSPatrick Williamsthe host to start a PCI send until the BlockTransfer file is closed.
1122654988cSPatrick Williams
1132654988cSPatrick WilliamsThere is only one hash "file" mechanism. The exact hash used will only be
1142654988cSPatrick Williamsimportant to your verification service. The value provided will be written to a
1152654988cSPatrick Williamsknown place.
1162654988cSPatrick Williams
1172654988cSPatrick WilliamsWhen a transfer is active, it'll create a blob_id of `/flash/active/image` and
1182654988cSPatrick Williams`/flash/active/hash`.
1192654988cSPatrick Williams
1202654988cSPatrick Williams#### Verification Blob
1212654988cSPatrick Williams
1222654988cSPatrick WilliamsThe following blob id is defined once the image or hash upload has started. Its
1232654988cSPatrick Williamspurpose is to trigger and monitor the firmware verification process. Therefore,
1242654988cSPatrick Williamsthe BmcBlobOpen command will fail until both the hash and image file are closed.
1252654988cSPatrick WilliamsFurther on the ideal command sequence below.
1262654988cSPatrick Williams
127*f4febd00SPatrick Williams| Trigger Blob    | Note                     |
128*f4febd00SPatrick Williams| --------------- | ------------------------ |
129*f4febd00SPatrick Williams| `/flash/verify` | Verify Trigger Mechanism |
1302654988cSPatrick Williams
1312654988cSPatrick WilliamsWhen the verification file is closed, if verification was completed
1322654988cSPatrick Williamssuccessfully, it'll add an update blob id, defined below.
1332654988cSPatrick Williams
1342654988cSPatrick WilliamsThe verification process used is not defined by this design.
1352654988cSPatrick Williams
1362654988cSPatrick Williams#### Update Blob
1372654988cSPatrick Williams
138*f4febd00SPatrick WilliamsThe update blob id is available once `/flash/verify` is closed with a valid
139*f4febd00SPatrick Williamsimage or tarball. The update blob needs to be opened and commit() called on that
140*f4febd00SPatrick Williamsblob id to trigger the update mechanism.
1412654988cSPatrick Williams
1422654988cSPatrick WilliamsThe update process can be checked periodically by calling stat() on the update
1432654988cSPatrick Williamsblob id.
1442654988cSPatrick Williams
145*f4febd00SPatrick Williams| Update Blob     | Note                     |
146*f4febd00SPatrick Williams| --------------- | ------------------------ |
147*f4febd00SPatrick Williams| `/flash/update` | Trigger Update Mechanism |
1482654988cSPatrick Williams
1492654988cSPatrick WilliamsThe update process used is not defined by this design.
1502654988cSPatrick Williams
1512654988cSPatrick Williams#### Cleanup Blob
1522654988cSPatrick Williams
1532654988cSPatrick WilliamsThe cleanup blob id is always present. The goal of this blob is to handle
154*f4febd00SPatrick Williamsdeletion of update artifacts on failure, or success. It can be implemented to do
155*f4febd00SPatrick Williamsany manner of cleanup required, but for systems under memory pressure, it is a
156*f4febd00SPatrick Williamsconvenient cleanup mechanism.
1572654988cSPatrick Williams
1582654988cSPatrick WilliamsThe cleanup blob has no state or knowledge and is meant to provide a simple
159*f4febd00SPatrick Williamssystem cleanup mechanism. This could also be accomplished by warm rebooting the
160*f4febd00SPatrick WilliamsBMC. The cleanup blob will delete a list of files. The cleanup blob has no state
161*f4febd00SPatrick Williamsrecognition for the update process, and therefore can interfere with an update
162*f4febd00SPatrick Williamsprocess. The host tool will only use it on failure cases. Any other tool
163*f4febd00SPatrick Williamsdeveloped should respect this and not employ it unless the goal is to cleanup
164*f4febd00SPatrick Williamsartifacts.
1652654988cSPatrick Williams
1662654988cSPatrick WilliamsTo trigger the cleanup, simply open the blob, commit, and close. It has no
167*f4febd00SPatrick Williamsknowledge of the update process. This simplification is done through the design
168*f4febd00SPatrick Williamsof a convenience mechanism instead of a required mechanism.
1692654988cSPatrick Williams
170*f4febd00SPatrick Williams| Cleanup Blob     | Note                      |
171*f4febd00SPatrick Williams| ---------------- | ------------------------- |
172*f4febd00SPatrick Williams| `/flash/cleanup` | Trigger Cleanup Mechanism |
1732654988cSPatrick Williams
1742654988cSPatrick Williams### Caching Images
1752654988cSPatrick Williams
1762654988cSPatrick WilliamsSimilarly to the OEM IPMI Flash protocol, the flash image will be staged in a
1772654988cSPatrick Williamscompile-time configured location.
1782654988cSPatrick Williams
1792654988cSPatrick WilliamsOther mechanisms can readily be added by adding more blob ids or flags to the
1802654988cSPatrick Williamshandler.
1812654988cSPatrick Williams
1822654988cSPatrick Williams### Commands
1832654988cSPatrick Williams
1842654988cSPatrick WilliamsThe update mechanism will expect a specific sequence of commands depending on
1852654988cSPatrick Williamsthe transport mechanism selected. Some mechanisms require a handshake.
1862654988cSPatrick Williams
1872654988cSPatrick Williams#### BlockTransfer Sequence
1882654988cSPatrick Williams
1892654988cSPatrick Williams1.  Open (for Image or tarball)
1902654988cSPatrick Williams1.  Write
1912654988cSPatrick Williams1.  Close
1922654988cSPatrick Williams1.  Open (`/flash/hash`)
1932654988cSPatrick Williams1.  Write
1942654988cSPatrick Williams1.  Close
1952654988cSPatrick Williams1.  Open (`/flash/verify`)
1962654988cSPatrick Williams1.  Commit
1972654988cSPatrick Williams1.  SessionStat (to read back verification status)
1982654988cSPatrick Williams1.  Close
1992654988cSPatrick Williams1.  Open (`/flash/update`)
2002654988cSPatrick Williams1.  Commit
2012654988cSPatrick Williams1.  SessionStat (to read back update status)
2022654988cSPatrick Williams1.  Close
2032654988cSPatrick Williams
2042654988cSPatrick Williams#### P2A Sequence
2052654988cSPatrick Williams
2062654988cSPatrick Williams1.  Open (for Image or tarball)
2072654988cSPatrick Williams1.  SessionStat (P2A Region for P2A mapping)
2082654988cSPatrick Williams1.  Write
2092654988cSPatrick Williams1.  Close
2102654988cSPatrick Williams1.  Open (`/flash/hash`)
2112654988cSPatrick Williams1.  SessionStat (P2A Region)
2122654988cSPatrick Williams1.  Write
2132654988cSPatrick Williams1.  Close
2142654988cSPatrick Williams1.  Open (`/flash/verify`)
2152654988cSPatrick Williams1.  Commit
2162654988cSPatrick Williams1.  SessionStat (to read back verification status)
2172654988cSPatrick Williams1.  Close
2182654988cSPatrick Williams1.  Open (`/flash/update`)
2192654988cSPatrick Williams1.  Commit
2202654988cSPatrick Williams1.  SessionStat (to read back update status)
2212654988cSPatrick Williams1.  Close
2222654988cSPatrick Williams
2232654988cSPatrick Williams#### LPC Sequence
2242654988cSPatrick Williams
2252654988cSPatrick Williams1.  Open (for image or tarball)
2262654988cSPatrick Williams1.  WriteMeta (specify region information from host for LPC)
2272654988cSPatrick Williams1.  SessionStat (verify the contents from the above)
2282654988cSPatrick Williams1.  Write
2292654988cSPatrick Williams1.  Close
2302654988cSPatrick Williams1.  Open (`/flash/hash`)
2312654988cSPatrick Williams1.  WriteMeta (LPC Region)
2322654988cSPatrick Williams1.  SessionStat (verify LPC config)
2332654988cSPatrick Williams1.  Write
2342654988cSPatrick Williams1.  Close
2352654988cSPatrick Williams1.  Open (`/flash/verify`)
2362654988cSPatrick Williams1.  Commit
2372654988cSPatrick Williams1.  SessionStat (to read back verification status)
2382654988cSPatrick Williams1.  Close
2392654988cSPatrick Williams1.  Open (`/flash/update`)
2402654988cSPatrick Williams1.  Commit
2412654988cSPatrick Williams1.  SessionStat (to read back update status)
2422654988cSPatrick Williams1.  Close
2432654988cSPatrick Williams
2442654988cSPatrick Williams### Stale Images
2452654988cSPatrick Williams
2462654988cSPatrick WilliamsIf an image update process is started but goes stale there are multiple
2472654988cSPatrick Williamsmechanisms in place to ensure cleanup. If a session is left open after the blob
2482654988cSPatrick Williamstimeout period it'll be closed. Because expiration is not the same action as
2492654988cSPatrick Williamsclosing, the cache will be flushed and any staged pieces deleted.
2502654988cSPatrick Williams
2512654988cSPatrick WilliamsThe image itself, in legacy (static layout) mode will be placed and named in
2522654988cSPatrick Williamssuch a way that it will disappear if the BMC reboots. In the UBI case, the file
2532654988cSPatrick Williamswill be stored in `/tmp` and deleted accordingly.
2542654988cSPatrick Williams
2552654988cSPatrick WilliamsAt any point during the upload process, one can abort by closing the open blobs
2562654988cSPatrick Williamsand deleting them by name.
2572654988cSPatrick Williams
2582654988cSPatrick Williams### Blob Primitives
2592654988cSPatrick Williams
2602654988cSPatrick WilliamsThe update mechanism will implement the Blob primitives as follows.
2612654988cSPatrick Williams
2622654988cSPatrick Williams#### BmcBlobOpen
2632654988cSPatrick Williams
2642654988cSPatrick WilliamsThe blob open primitive allows supplying blob specific flags. These flags are
2652654988cSPatrick Williamsused for specifying the transport mechanism. To obtain the list of supported
2662654988cSPatrick Williamsmechanisms on a platform, see the `Stat` command below.
2672654988cSPatrick Williams
2682654988cSPatrick Williams```
2692654988cSPatrick Williamsenum OpenFlags
2702654988cSPatrick Williams{
2712654988cSPatrick Williams    read = (1 << 0),
2722654988cSPatrick Williams    write = (1 << 1),
2732654988cSPatrick Williams};
2742654988cSPatrick Williams
2752654988cSPatrick Williams/* These bits start in the blob specific range of the flags. */
2762654988cSPatrick Williamsenum FirmwareUpdateFlags
2772654988cSPatrick Williams{
2782654988cSPatrick Williams    bt = (1 << 8),   /* Expect to send contents over IPMI BlockTransfer. */
2792654988cSPatrick Williams    p2a = (1 << 9),  /* Expect to send contents over P2A bridge. */
2802654988cSPatrick Williams    lpc = (1 << 10), /* Expect to send contents over LPC bridge. */
2812654988cSPatrick Williams};
2822654988cSPatrick Williams```
2832654988cSPatrick Williams
2842654988cSPatrick WilliamsAn open request must specify that it is opening for writing and one transport
2852654988cSPatrick Williamsmechanism, otherwise it is rejected. If the request is also set for reading,
2862654988cSPatrick Williamsthis is not rejected but currently provides no additional value.
2872654988cSPatrick Williams
2882654988cSPatrick WilliamsOnce opened a new file will appear in the blob_id list (for both the image and
2892654988cSPatrick Williamshash) indicating they are in progress. The name will be `flash/active/image` and
2902654988cSPatrick Williams`flash/active/hash` which has no meaning beyond representing the current update
2912654988cSPatrick Williamsin progress. Closing the file does not delete the staged images. Only delete
2922654988cSPatrick Williamswill.
2932654988cSPatrick Williams
294*f4febd00SPatrick Williams**_Note_** The active image blob_ids cannot be opened. This can be reconsidered
2952654988cSPatrick Williamslater.
2962654988cSPatrick Williams
2972654988cSPatrick Williams#### BmcBlobRead
2982654988cSPatrick Williams
2992654988cSPatrick WilliamsThis will initially not perform any function and will return success with 0
3002654988cSPatrick Williamsbytes.
3012654988cSPatrick Williams
3022654988cSPatrick Williams#### BmcBlobWrite
3032654988cSPatrick Williams
3042654988cSPatrick WilliamsThe write command's contents will depend on the transport mechanism. This
3052654988cSPatrick Williamscommand must not return until it has copied the data out of the mapped region
3062654988cSPatrick Williamsinto either a staging buffer or written down to a staging file. How the command
3072654988cSPatrick Williamsreads from the mapped region is beyond the scope of this design.
3082654988cSPatrick Williams
3092654988cSPatrick Williams##### If BT
3102654988cSPatrick Williams
3112654988cSPatrick WilliamsThe data section of the payload is only data.
3122654988cSPatrick Williams
3132654988cSPatrick Williams##### If P2A
3142654988cSPatrick Williams
3152654988cSPatrick WilliamsThe data section of the payload is the following structure:
3162654988cSPatrick Williams
3172654988cSPatrick Williams```
3182654988cSPatrick Williamsstruct ExtChunkHdr
3192654988cSPatrick Williams{
3202654988cSPatrick Williams    uint32_t length; /* Length of the data queued (little endian). */
3212654988cSPatrick Williams};
3222654988cSPatrick Williams```
3232654988cSPatrick Williams
3242654988cSPatrick Williams##### If LPC
3252654988cSPatrick Williams
3262654988cSPatrick WilliamsThe data section of the payload is the following structure:
3272654988cSPatrick Williams
3282654988cSPatrick Williams```
3292654988cSPatrick Williamsstruct ExtChunkHdr
3302654988cSPatrick Williams{
3312654988cSPatrick Williams    uint32_t length; /* Length of the data queued (little endian). */
3322654988cSPatrick Williams};
3332654988cSPatrick Williams```
3342654988cSPatrick Williams
3352654988cSPatrick Williams#### BmcBlobCommit
3362654988cSPatrick Williams
3372654988cSPatrick WilliamsIf this command is called on the session of the firmware image itself, nothing
3382654988cSPatrick Williamswill happen at present. It will return a no-op success.
3392654988cSPatrick Williams
3402654988cSPatrick WilliamsIf this command is called on the session for the hash image, nothing will happen
3412654988cSPatrick Williamsat present. It will return a no-op success.
3422654988cSPatrick Williams
3432654988cSPatrick WilliamsIf this command is called on the session for the verify blob id, it'll trigger a
3442654988cSPatrick Williamssystemd service `verify_image.service` to attempt to verify the image. Before
3452654988cSPatrick Williamsdoing this, if the transport mechanism is not IPMI BT, it'll shut down the
3462654988cSPatrick Williamsmechanism used for transport preventing the host from updating anything.
3472654988cSPatrick Williams
3482654988cSPatrick WilliamsWhen this is started, only the BmcBlobSessionStat command will respond. Details
3492654988cSPatrick Williamson that response are below under BmcBlobSessionStat.
3502654988cSPatrick Williams
3512654988cSPatrick Williams#### BmcBlobClose
3522654988cSPatrick Williams
3532654988cSPatrick WilliamsClose must be called on the firmware image and the hash file before opening the
3542654988cSPatrick Williamsverify blob.
3552654988cSPatrick Williams
3562654988cSPatrick WilliamsIf the `verify_image.service` returned success, closing the verify file will
3572654988cSPatrick Williamshave a specific behavior depending on the update. If it's UBI, it'll perform the
3582654988cSPatrick Williamsinstall. If it's legacy (static layout), it'll do nothing. The verify_image
3592654988cSPatrick Williamsservice in the legacy case is responsible for placing the file in the correct
3602654988cSPatrick Williamsstaging position. A BMC warm reset command will initiate the firmware update
3612654988cSPatrick Williamsprocess.
3622654988cSPatrick Williams
3632654988cSPatrick WilliamsIf the image verification fails, it will automatically delete any files
3642654988cSPatrick Williamsassociated with the update.
3652654988cSPatrick Williams
366*f4febd00SPatrick Williams**_Note:_** During development testing, a developer will want to upload files
3672654988cSPatrick Williamsthat are not signed. Therefore, an additional bit will be added to the flags to
3682654988cSPatrick Williamschange this behavior.
3692654988cSPatrick Williams
3702654988cSPatrick Williams#### BmcBlobDelete
3712654988cSPatrick Williams
3722654988cSPatrick WilliamsAborts any update that's in progress:
3732654988cSPatrick Williams
3742654988cSPatrick Williams1.  Stops the verify_image.service if started.
3752654988cSPatrick Williams1.  Deletes any staged files.
3762654988cSPatrick Williams
3772654988cSPatrick WilliamsIn the event the update is already in progress, such as the tarball mechanism is
3782654988cSPatrick Williamsused and in the middle of updating the files, it cannot be aborted.
3792654988cSPatrick Williams
3802654988cSPatrick Williams#### BmcBlobStat
3812654988cSPatrick Williams
3822654988cSPatrick WilliamsBlob stat on a blob_id (not SessionStat) will return the capabilities of the
3832654988cSPatrick Williamsblob_id handler.
3842654988cSPatrick Williams
3852654988cSPatrick Williams```
3862654988cSPatrick Williamsstruct BmcBlobStatRx {
3872654988cSPatrick Williams    uint16_t crc16;
3882654988cSPatrick Williams    /* This will have the bits set from the FirmwareUpdateFlags enum. */
3892654988cSPatrick Williams    uint16_t blob_state;
3902654988cSPatrick Williams    uint32_t size; /* 0 - it's set to zero when there's no session */
3912654988cSPatrick Williams    uint8_t  metadata_len; /* 0 */
3922654988cSPatrick Williams};
3932654988cSPatrick Williams```
3942654988cSPatrick Williams
3952654988cSPatrick Williams#### BmcBlobSessionStat
3962654988cSPatrick Williams
3972654988cSPatrick WilliamsIf called pre-commit, it'll return the following information:
3982654988cSPatrick Williams
3992654988cSPatrick Williams```
4002654988cSPatrick Williamsstruct BmcBlobStatRx {
4012654988cSPatrick Williams    uint16_t crc16;
4022654988cSPatrick Williams    uint16_t blob_state; /* OpenFlags::write | (one of the interfaces) */
4032654988cSPatrick Williams    uint32_t size; /* Size in bytes so far written */
4042654988cSPatrick Williams    uint8_t  metadata_len; /* 0. */
4052654988cSPatrick Williams};
4062654988cSPatrick Williams```
4072654988cSPatrick Williams
4082654988cSPatrick WilliamsIf it's called and the data transport mechanism is P2A, it'll return a 32-bit
4092654988cSPatrick Williamsaddress for use to configure the P2A region as part of the metadata portion of
4102654988cSPatrick Williamsthe `BmcBlobStatRx`.
4112654988cSPatrick Williams
4122654988cSPatrick Williams```
4132654988cSPatrick Williamsstruct BmcBlobStatRx {
4142654988cSPatrick Williams    uint16_t crc16;
4152654988cSPatrick Williams    uint16_t blob_state; /* OpenFlags::write | (one of the interfaces) */
4162654988cSPatrick Williams    uint32_t size; /* Size in bytes so far written */
4172654988cSPatrick Williams    uint8_t  metadata_len = sizeof(struct P2ARegion);
4182654988cSPatrick Williams    struct P2ARegion {
4192654988cSPatrick Williams        uint32_t address;
4202654988cSPatrick Williams    };
4212654988cSPatrick Williams};
4222654988cSPatrick Williams```
4232654988cSPatrick Williams
4242654988cSPatrick WilliamsIf called post-commit on the verify file session, it'll return:
4252654988cSPatrick Williams
4262654988cSPatrick Williams```
4272654988cSPatrick Williamsstruct BmcBlobStatRx {
4282654988cSPatrick Williams    uint16_t crc16;
4292654988cSPatrick Williams    uint16_t blob_state; /* OPEN_W | (one of the interfaces) */
4302654988cSPatrick Williams    uint32_t size; /* Size in bytes so far written */
4312654988cSPatrick Williams    uint8_t  metadata_len; /* 1. */
4322654988cSPatrick Williams    uint8_t  verify_response; /* one byte from the below enum */
4332654988cSPatrick Williams};
4342654988cSPatrick Williams
4352654988cSPatrick Williamsenum VerifyCheckResponses
4362654988cSPatrick Williams{
4372654988cSPatrick Williams    VerifyRunning = 0x00,
4382654988cSPatrick Williams    VerifySuccess = 0x01,
4392654988cSPatrick Williams    VerifyFailed  = 0x02,
4402654988cSPatrick Williams    VerifyOther   = 0x03,
4412654988cSPatrick Williams};
4422654988cSPatrick Williams```
4432654988cSPatrick Williams
4442654988cSPatrick WilliamsIf called post-commit on the update file session, it'll return:
4452654988cSPatrick Williams
4462654988cSPatrick Williams```
4472654988cSPatrick Williamsstruct BmcBlobStatRx {
4482654988cSPatrick Williams    uint16_t crc16;
4492654988cSPatrick Williams    uint16_t blob_state; /* OPEN_W | (one of the interfaces) */
4502654988cSPatrick Williams    uint32_t size; /* Size in bytes so far written */
4512654988cSPatrick Williams    uint8_t  metadata_len; /* 1. */
4522654988cSPatrick Williams    uint8_t  update_response; /* one by from the below enum */
4532654988cSPatrick Williams};
4542654988cSPatrick Williams
4552654988cSPatrick Williamsenum UpdateStatus
4562654988cSPatrick Williams{
4572654988cSPatrick Williams    UpdateRunning = 0x00,
4582654988cSPatrick Williams    UpdateSuccessful = 0x01,
4592654988cSPatrick Williams    UpdateFailed = 0x02,
4602654988cSPatrick Williams    UpdateStatusUnknown = 0x03
4612654988cSPatrick Williams};
4622654988cSPatrick Williams```
4632654988cSPatrick Williams
4642654988cSPatrick WilliamsThe `UpdateStatus` and `VerifyCheckResponses` are currently identical, but this
4652654988cSPatrick Williamsmay change over time.
4662654988cSPatrick Williams
4672654988cSPatrick Williams#### BmcBlobWriteMeta
4682654988cSPatrick Williams
4692654988cSPatrick WilliamsThe write metadata command is meant to allow the host to provide specific
4702654988cSPatrick Williamsconfiguration data to the BMC for the in-band update. Currently that is only
4712654988cSPatrick Williamsaimed at LPC which needs to be told the memory address so it can configure the
4722654988cSPatrick Williamswindow.
4732654988cSPatrick Williams
4742654988cSPatrick WilliamsThe write meta command's blob will be this structure:
4752654988cSPatrick Williams
4762654988cSPatrick Williams```
4772654988cSPatrick Williamsstruct LpcRegion
4782654988cSPatrick Williams{
4792654988cSPatrick Williams    uint32_t address; /* Host LPC address where the chunk is to be mapped. */
4802654988cSPatrick Williams    uint32_t length; /* Size of the chunk to be mapped. */
4812654988cSPatrick Williams};
4822654988cSPatrick Williams```
4832654988cSPatrick Williams
4842654988cSPatrick Williams## Alternatives Considered
4852654988cSPatrick Williams
4862654988cSPatrick WilliamsThere is currently another implementation in-use by Google that leverages the
4872654988cSPatrick Williamssame mechanisms, however, it's not as flexible because every command is a custom
4882654988cSPatrick Williamspiece. Mapping it into blobs primitives allows for easier future modification
4892654988cSPatrick Williamswhile maintaining backwards compatibility (without simply adding a separate OEM
4902654988cSPatrick Williamslibrary to handle a new process, etc).
4912654988cSPatrick Williams
4922654988cSPatrick Williams## Impacts
4932654988cSPatrick Williams
4942654988cSPatrick WilliamsThis impacts security because it can leverage the memory mapped windows. There
4952654988cSPatrick Williamsis not an expected performance impact, as the blob handler existing only
4962654988cSPatrick Williamsgenerates a couple extra entries during the blob enumerate command's response.
4972654988cSPatrick Williams
4982654988cSPatrick Williams## Testing
4992654988cSPatrick Williams
5002654988cSPatrick WilliamsWhere possible (nearly everywhere), mockable interfaces will be used such that
5012654988cSPatrick Williamsthe entire process has individual unit-tests that verify flags are checked, as
5022654988cSPatrick Williamswell as states and sequences.
5032654988cSPatrick Williams
5042654988cSPatrick Williams### Scenarios
5052654988cSPatrick Williams
5062654988cSPatrick Williams#### Sending an image with a bad hash
5072654988cSPatrick Williams
5082654988cSPatrick WilliamsA required functional test is one whereby an image is sent down to the BMC,
5092654988cSPatrick Williamshowever the signature is invalid for that image. The expected result is that the
5102654988cSPatrick Williamsverification step will return failure and the files will be deleted from the BMC
5112654988cSPatrick Williamswithout user intervention.
5122654988cSPatrick Williams
5132654988cSPatrick Williams#### Sending an image with a good hash
5142654988cSPatrick Williams
5152654988cSPatrick WilliamsA required functional test is one whereby an image is sent down to the BMC with
5162654988cSPatrick Williamsa valid signature. The expected result is that the verification step will return
5172654988cSPatrick Williamssuccess.
5182654988cSPatrick Williams
5192654988cSPatrick Williams## Configuration
5202654988cSPatrick Williams
5212654988cSPatrick WilliamsSee the configuration section of
5222654988cSPatrick Williams[Secure Flash Update Mechanism](https://github.com/openbmc/phosphor-ipmi-flash/blob/master/README.md)
523