# Firmware Management Protocol (FMP) DXE For an overview of how FmpDxe fits into the overall FmpDevicePkg architecture, including capsule authentication, capsule versioning, device-specific dispatch, dependency evaluation, and update policy, see [FmpDevicePkg/Readme.md](../Readme.md). This document tracks impactful design changes to FmpDxe for the benefit of capsule implementers and platform integrators to see when and why these changes were made. --- ## Design Changes - **Date:** 07/20/2026 - **Description/Rationale:** PopulateDescriptor () previously read the FmpControllerState NV variable multiple times per call through several getters such as GetVersionFromVariable () and GetLowestSupportedVersionFromVariable (), each independently invoking GetFmpControllerState (). This caused redundant GetVariable () calls and repeated failed-read debug messages when the variable did not yet exist. - **Changes:** The getter functions were renamed (for example, to GetVersionFromFmpControllerState ()) and simplified to pure field extractors that operate on a FMP_CONTROLLER_STATE pointer supplied by the caller instead of independently reading the variable. PopulateDescriptor () now calls GetFmpControllerState () once, passes the result to each getter, and frees it after the last use. - **Impact/Mitigation:** This is an internal implementation change local to FmpDxe. It does not modify the FmpDeviceLib, FmpDependencyLib, FmpDependencyCheckLib, FmpDependencyDeviceLib, or CapsuleUpdatePolicyLib APIs, so existing library instances are unaffected. --- - **Date:** 09/24/2025 - **Description/Rationale:** XDR-encoded certificate list handling in FmpDxe assumed the PublicKeyDataXdr buffer (populated from PcdFmpDevicePkcs7CertBufferXdr) is 4-byte aligned, which is not always the case. For example, if PublicKeyDataXdr = 0x02 and a certificate's length is 0x05, the correct offset to the next certificate is 0x2 + align_up (0x5, 4) = 0xA, but the prior logic computed align_up (0x2 + 0x5, 4) = 0x8. - **Changes:** The offset calculation used to walk the XDR-encoded certificate list was corrected to align up each certificate's length independently rather than aligning the running (potentially already unaligned) offset. - **Impact/Mitigation:** Platforms that supply a PcdFmpDevicePkcs7CertBufferXdr value containing more than one certificate, where an earlier certificate's length is not a multiple of 4 bytes, will see corrected certificate parsing behavior. --- - **Date:** 01/20/2022 - **Description/Rationale:** CheckTheImageInternal () did not force ImageUpdatable to an invalid value when FmpDeviceCheckImageWithStatus () returned an error but left ImageUpdatable set to IMAGE_UPDATABLE_VALID. In addition, the FmpDeviceCheckImageWithStatus () LastAttemptStatus parameter description could be misread as meaning the value is only inspected when the function returns an error. - **Changes:** CheckTheImageInternal () now forces ImageUpdatable to IMAGE_UPDATABLE_INVALID if FmpDeviceCheckImageWithStatus () returns an error, and only validates/converts the returned LastAttemptStatus value when the image is not updatable so a valid LAST_ATTEMPT_STATUS_SUCCESS is not overwritten for an updatable image. The API documentation for FmpDeviceCheckImageWithStatus () was updated to remove the sentence limiting LastAttemptStatus inspection to error cases. - **Impact/Mitigation:** FmpDeviceLib instances should always set LastAttemptStatus to a value in the designated range (or LAST_ATTEMPT_STATUS_SUCCESS) whenever FmpDeviceCheckImageWithStatus () is called, not only when it returns an error. --- - **Date:** 10/26/2021 - **Description/Rationale:** FmpDxe used the deprecated EDKII_VARIABLE_LOCK_PROTOCOL (RequestToLock ()) to lock its NV variables. - **Changes:** FmpDxe was updated to lock its NV variables using EDKII_VARIABLE_POLICY_PROTOCOL and RegisterBasicVariablePolicy () from the new VariablePolicyHelperLib dependency. The module Depex was intended to change from gEdkiiVariableLockProtocolGuid to gEdkiiVariablePolicyProtocolGuid at the same time. This was missed and corrected in a follow-up fix on 07/09/2024. - **Impact/Mitigation:** Platforms must produce gEdkiiVariablePolicyProtocolGuid for FmpDxe to start. Platforms that only produce the deprecated gEdkiiVariableLockProtocolGuid protocol will need to update their variable services accordingly. --- - **Date:** 06/15/2020 - **Description/Rationale:** Extending on the more granular LastAttemptStatus support added in FmpDeviceSetImage (), FmpDeviceCheckImage () also has a LastAttemptStatus parameter added. An image check is always performed by a set image operation. A more granular status code from the check image path greatly improves overall error isolation when applying an image. - **Changes:** This change allows the FmpDeviceLib implementation to return a last attempt status code in the range LAST_ATTEMPT_STATUS_LIBRARY_ERROR_MIN_ERROR_CODE to LAST_ATTEMPT_STATUS_LIBRARY_ERROR_MAX_ERROR_CODE. Furthermore, an internal wrapper for CheckTheImage () in FmpDxe was added called CheckTheImageInternal (). This function can return a last attempt status code for an error in the driver prior to invoking FmpDeviceCheckImage (). These driver error codes will be in the range of LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL_VENDOR_RANGE_MIN to LAST_ATTEMPT_STATUS_DRIVER_ERROR_MAX_ERROR_CODE. - **Impact/Mitigation:** The change break the build for all FmpDeviceLib instances due to the API change. Each FmpDeviceLib should change to the new API definition and implement support to return unique values for LastAttemptStatus when appropriate. --- - **Date:** 10/07/2019 - **Description/Rationale:** Capsule update is the process where each OEM has a lot of interest. Especially when there is capsule update failure, it is helpful to gather more information of the failure. With existing implementations, the SetImage routine from FmpDxe driver, which performs most heavy lifting during capsule update, will only populate LastAttemptStatus with limited pre-defined error codes which could be consumed/inspected by the OS when it recovers and boots. Thus our proposal is to update the SetImage routine and leverage the LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL_VENDOR_RANGE range newly defined in UEFI Spec 2.8 Section 23.4, so that the error code will provide better granularity when viewing capsule update failure from OS device manager. - **Changes:** A few error codes (128 total) are reserved from LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL_VENDOR_RANGE range for FmpDxe driver usage, which ranges from thermal and power API failure to capsule payload header check failure. Furthermore, *an output pointer of the LastAttemptStatus is added as an input argument for FmpDeviceSetImage function in FmpDeviceLib to allow platform to provide their own platform specific error codes*. (SPI write failure, SVN checking failure, and more). - **Impact/Mitigation:** The italic text above will cause a breaking change for all the FmpDeviceLib instances due to API being modified. This is to provide better visibility to OEMs to decode capsule update failures more efficiently. Each FmpDeviceLib should change to the new API definition and populate proper LastAttemptStatus values when applicable.