From 6ad819c1abe3c49b9648769f5111eca491c0add3 Mon Sep 17 00:00:00 2001 From: Michael Kubacki Date: Tue, 20 Oct 2020 07:59:39 +0800 Subject: FmpDevicePkg/FmpDeviceLib: Add Last Attempt Status to Check/Set API Provides the ability for a given FMP device library instance to return a Last Attempt Status code during check image and set image operations with FmpDeviceCheckImageEx() and FmpDeviceSetImageEx(). Cc: Liming Gao Cc: Michael D Kinney Cc: Guomin Jiang Cc: Wei6 Xu Signed-off-by: Michael Kubacki Acked-by: Liming Gao Reviewed-by: Wei6 Xu Reviewed-by: Michael D Kinney --- FmpDevicePkg/Include/Library/FmpDeviceLib.h | 121 ++++++++++++++++- .../Library/FmpDeviceLibNull/FmpDeviceLib.c | 144 ++++++++++++++++++++- 2 files changed, 263 insertions(+), 2 deletions(-) (limited to 'FmpDevicePkg') diff --git a/FmpDevicePkg/Include/Library/FmpDeviceLib.h b/FmpDevicePkg/Include/Library/FmpDeviceLib.h index 9a89f5c2ee..6abd99fa1f 100644 --- a/FmpDevicePkg/Include/Library/FmpDeviceLib.h +++ b/FmpDevicePkg/Include/Library/FmpDeviceLib.h @@ -2,7 +2,7 @@ Provides firmware device specific services to support updates of a firmware image stored in a firmware device. - Copyright (c) 2016, Microsoft Corporation. All rights reserved.
+ Copyright (c) Microsoft Corporation.
Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -403,6 +403,50 @@ FmpDeviceCheckImage ( OUT UINT32 *ImageUpdatable ); +/** + Checks if a new firmware image is valid for the firmware device. This + function allows firmware update operation to validate the firmware image + before FmpDeviceSetImage() is called. + + @param[in] Image Points to a new firmware image. + @param[in] ImageSize Size, in bytes, of a new firmware image. + @param[out] ImageUpdatable Indicates if a new firmware image is valid for + a firmware update to the firmware device. The + following values from the Firmware Management + Protocol are supported: + IMAGE_UPDATABLE_VALID + IMAGE_UPDATABLE_INVALID + IMAGE_UPDATABLE_INVALID_TYPE + IMAGE_UPDATABLE_INVALID_OLD + IMAGE_UPDATABLE_VALID_WITH_VENDOR_CODE + @param[out] LastAttemptStatus A pointer to a UINT32 that holds the last attempt + status to report back to the ESRT table in case + of error. This value will only be checked when this + function returns an error. + + The return status code must fall in the range of + LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE to + LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MAX_ERROR_CODE_VALUE. + + If the value falls outside this range, it will be converted + to LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL. + + @retval EFI_SUCCESS The image was successfully checked. Additional + status information is returned in + ImageUpdatable. + @retval EFI_INVALID_PARAMETER Image is NULL. + @retval EFI_INVALID_PARAMETER ImageUpdatable is NULL. + +**/ +EFI_STATUS +EFIAPI +FmpDeviceCheckImageWithStatus ( + IN CONST VOID *Image, + IN UINTN ImageSize, + OUT UINT32 *ImageUpdatable, + OUT UINT32 *LastAttemptStatus + ); + /** Updates a firmware device with a new firmware image. This function returns EFI_UNSUPPORTED if the firmware image is not updatable. If the firmware image @@ -466,6 +510,81 @@ FmpDeviceSetImage ( OUT CHAR16 **AbortReason ); +/** + Updates a firmware device with a new firmware image. This function returns + EFI_UNSUPPORTED if the firmware image is not updatable. If the firmware image + is updatable, the function should perform the following minimal validations + before proceeding to do the firmware image update. + - Validate that the image is a supported image for this firmware device. + Return EFI_ABORTED if the image is not supported. Additional details + on why the image is not a supported image may be returned in AbortReason. + - Validate the data from VendorCode if is not NULL. Firmware image + validation must be performed before VendorCode data validation. + VendorCode data is ignored or considered invalid if image validation + fails. Return EFI_ABORTED if the VendorCode data is invalid. + + VendorCode enables vendor to implement vendor-specific firmware image update + policy. Null if the caller did not specify the policy or use the default + policy. As an example, vendor can implement a policy to allow an option to + force a firmware image update when the abort reason is due to the new firmware + image version is older than the current firmware image version or bad image + checksum. Sensitive operations such as those wiping the entire firmware image + and render the device to be non-functional should be encoded in the image + itself rather than passed with the VendorCode. AbortReason enables vendor to + have the option to provide a more detailed description of the abort reason to + the caller. + + @param[in] Image Points to the new firmware image. + @param[in] ImageSize Size, in bytes, of the new firmware image. + @param[in] VendorCode This enables vendor to implement vendor-specific + firmware image update policy. NULL indicates + the caller did not specify the policy or use the + default policy. + @param[in] Progress A function used to report the progress of + updating the firmware device with the new + firmware image. + @param[in] CapsuleFwVersion The version of the new firmware image from the + update capsule that provided the new firmware + image. + @param[out] AbortReason A pointer to a pointer to a Null-terminated + Unicode string providing more details on an + aborted operation. The buffer is allocated by + this function with + EFI_BOOT_SERVICES.AllocatePool(). It is the + caller's responsibility to free this buffer with + EFI_BOOT_SERVICES.FreePool(). + @param[out] LastAttemptStatus A pointer to a UINT32 that holds the last attempt + status to report back to the ESRT table in case + of error. This value will only be checked when this + function returns an error. + + The return status code must fall in the range of + LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE to + LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MAX_ERROR_CODE_VALUE. + + If the value falls outside this range, it will be converted + to LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL. + + @retval EFI_SUCCESS The firmware device was successfully updated + with the new firmware image. + @retval EFI_ABORTED The operation is aborted. Additional details + are provided in AbortReason. + @retval EFI_INVALID_PARAMETER The Image was NULL. + @retval EFI_UNSUPPORTED The operation is not supported. + +**/ +EFI_STATUS +EFIAPI +FmpDeviceSetImageWithStatus ( + IN CONST VOID *Image, + IN UINTN ImageSize, + IN CONST VOID *VendorCode, OPTIONAL + IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress, OPTIONAL + IN UINT32 CapsuleFwVersion, + OUT CHAR16 **AbortReason, + OUT UINT32 *LastAttemptStatus + ); + /** Lock the firmware device that contains a firmware image. Once a firmware device is locked, any attempts to modify the firmware image contents in the diff --git a/FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLib.c b/FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLib.c index 316de12e91..f4f57b29bd 100644 --- a/FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLib.c +++ b/FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLib.c @@ -2,7 +2,7 @@ Provides firmware device specific services to support updates of a firmware image stored in a firmware device. - Copyright (c) 2016, Microsoft Corporation. All rights reserved.
+ Copyright (c) Microsoft Corporation.
Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -10,6 +10,7 @@ **/ #include +#include #include /** @@ -407,6 +408,57 @@ FmpDeviceCheckImage ( OUT UINT32 *ImageUpdatable ) { + UINT32 LastAttemptStatus; + + return FmpDeviceCheckImageWithStatus (Image, ImageSize, ImageUpdatable, &LastAttemptStatus); +} + +/** + Checks if a new firmware image is valid for the firmware device. This + function allows firmware update operation to validate the firmware image + before FmpDeviceSetImage() is called. + + @param[in] Image Points to a new firmware image. + @param[in] ImageSize Size, in bytes, of a new firmware image. + @param[out] ImageUpdatable Indicates if a new firmware image is valid for + a firmware update to the firmware device. The + following values from the Firmware Management + Protocol are supported: + IMAGE_UPDATABLE_VALID + IMAGE_UPDATABLE_INVALID + IMAGE_UPDATABLE_INVALID_TYPE + IMAGE_UPDATABLE_INVALID_OLD + IMAGE_UPDATABLE_VALID_WITH_VENDOR_CODE + @param[out] LastAttemptStatus A pointer to a UINT32 that holds the last attempt + status to report back to the ESRT table in case + of error. This value will only be checked when this + function returns an error. + + The return status code must fall in the range of + LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE to + LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MAX_ERROR_CODE_VALUE. + + If the value falls outside this range, it will be converted + to LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL. + + @retval EFI_SUCCESS The image was successfully checked. Additional + status information is returned in + ImageUpdatable. + @retval EFI_INVALID_PARAMETER Image is NULL. + @retval EFI_INVALID_PARAMETER ImageUpdatable is NULL. + +**/ +EFI_STATUS +EFIAPI +FmpDeviceCheckImageWithStatus ( + IN CONST VOID *Image, + IN UINTN ImageSize, + OUT UINT32 *ImageUpdatable, + OUT UINT32 *LastAttemptStatus + ) +{ + *LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS; + return EFI_SUCCESS; } @@ -473,6 +525,96 @@ FmpDeviceSetImage ( OUT CHAR16 **AbortReason ) { + UINT32 LastAttemptStatus; + + return FmpDeviceSetImageWithStatus ( + Image, + ImageSize, + VendorCode, + Progress, + CapsuleFwVersion, + AbortReason, + &LastAttemptStatus + ); +} + +/** + Updates a firmware device with a new firmware image. This function returns + EFI_UNSUPPORTED if the firmware image is not updatable. If the firmware image + is updatable, the function should perform the following minimal validations + before proceeding to do the firmware image update. + - Validate that the image is a supported image for this firmware device. + Return EFI_ABORTED if the image is not supported. Additional details + on why the image is not a supported image may be returned in AbortReason. + - Validate the data from VendorCode if is not NULL. Firmware image + validation must be performed before VendorCode data validation. + VendorCode data is ignored or considered invalid if image validation + fails. Return EFI_ABORTED if the VendorCode data is invalid. + + VendorCode enables vendor to implement vendor-specific firmware image update + policy. Null if the caller did not specify the policy or use the default + policy. As an example, vendor can implement a policy to allow an option to + force a firmware image update when the abort reason is due to the new firmware + image version is older than the current firmware image version or bad image + checksum. Sensitive operations such as those wiping the entire firmware image + and render the device to be non-functional should be encoded in the image + itself rather than passed with the VendorCode. AbortReason enables vendor to + have the option to provide a more detailed description of the abort reason to + the caller. + + @param[in] Image Points to the new firmware image. + @param[in] ImageSize Size, in bytes, of the new firmware image. + @param[in] VendorCode This enables vendor to implement vendor-specific + firmware image update policy. NULL indicates + the caller did not specify the policy or use the + default policy. + @param[in] Progress A function used to report the progress of + updating the firmware device with the new + firmware image. + @param[in] CapsuleFwVersion The version of the new firmware image from the + update capsule that provided the new firmware + image. + @param[out] AbortReason A pointer to a pointer to a Null-terminated + Unicode string providing more details on an + aborted operation. The buffer is allocated by + this function with + EFI_BOOT_SERVICES.AllocatePool(). It is the + caller's responsibility to free this buffer with + EFI_BOOT_SERVICES.FreePool(). + @param[out] LastAttemptStatus A pointer to a UINT32 that holds the last attempt + status to report back to the ESRT table in case + of error. This value will only be checked when this + function returns an error. + + The return status code must fall in the range of + LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE to + LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MAX_ERROR_CODE_VALUE. + + If the value falls outside this range, it will be converted + to LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL. + + @retval EFI_SUCCESS The firmware device was successfully updated + with the new firmware image. + @retval EFI_ABORTED The operation is aborted. Additional details + are provided in AbortReason. + @retval EFI_INVALID_PARAMETER The Image was NULL. + @retval EFI_UNSUPPORTED The operation is not supported. + +**/ +EFI_STATUS +EFIAPI +FmpDeviceSetImageWithStatus ( + IN CONST VOID *Image, + IN UINTN ImageSize, + IN CONST VOID *VendorCode, OPTIONAL + IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress, OPTIONAL + IN UINT32 CapsuleFwVersion, + OUT CHAR16 **AbortReason, + OUT UINT32 *LastAttemptStatus + ) +{ + *LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS; + return EFI_UNSUPPORTED; } -- cgit v1.2.3