From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM12-MW2-obe.outbound.protection.outlook.com (NAM12-MW2-obe.outbound.protection.outlook.com [40.92.23.95]) by mx.groups.io with SMTP id smtpd.web10.4161.1603946736076058166 for ; Wed, 28 Oct 2020 21:45:36 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@outlook.com header.s=selector1 header.b=Y9TxkBJn; spf=pass (domain: outlook.com, ip: 40.92.23.95, mailfrom: michael.kubacki@outlook.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=MnWaWq9mb9wryeqrbMWlwlwB3VujN8JFmozt6XzRUmqeEgDu8GfbYdWgdjhP7G2GDTIPdjHj2Wsa+1mfsIjLpYEY1hmKQtDpQiILO3cILE15i7ipVpDCaA/WWchuUa1w4bJQDN7XyIT69pPFiO49kZNHMrPMM+fAxsRA/BEj6KLe/CiQAh591aMGRNZdXKgycAddzb8zxES5o+h9L1MgZTulD3lEuIN0THXVNeSD8wPzlCWXOu81P8SvCx3VkX3rAHFOvR0O0/qjwQMrYzFH+ijAh6/Cv4pbB2+70v8M5NfebuF6XonkeEXyIY6jOBMPeb4xpp+odJKdg9eWuY5ppg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=bD9HmDjL3lRf3hbZ+vWHBUYAnurc76Jzm40m+A2ROjI=; b=asJgKnjA0q+d4I0fpt2rVDlqzULR4COqUzmNv356MQfBV725KNhYuxt25t4B2MkPH6ggtoRklFSGjtVmZ2Ts5DvemDGUp3qa+xCX3mgE9VZnJHwqUIhSiUeV6/9vVCV1/a0GqTBt9/RtUxR2G0qfkkl0NAsYiOjLvAMouajgCP+M73IiB+PwAGEXv6BOkVQG39Rr68pMtAyFpd/YQx4TZ9vPzGS2rk+D6RCwJNasTsL2n8GIpktahGBruklfdt5uy38AgNFLAd0cbvPyx3h6dSHQ6lCk7qrElo6df4j+A+d9ZOxSxzFeBwEKahUz5KxIfhc6PKIIDCQJdhS6F4dmZQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none; dkim=none; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=outlook.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=bD9HmDjL3lRf3hbZ+vWHBUYAnurc76Jzm40m+A2ROjI=; b=Y9TxkBJndlck8RKEVYTM/v09BGRGM8ezRacrmMu9v5vyM6zNspb0p7/ZxVgwRw/7TYotKBk6vI7gpfARdx3QsQybo8utNMpeeahvV+NPplTxkiBtwr4xllVPaJPA3g8lebb2y7mFM0cYgVrtu1XSDLiozu++VajrIyQbfkYWzpYXzyTwOulXlGBMUT2kdwJsZDUtWXS+lykT8UR9ylCHwvxsRNEltgqvzEbsCIJwZ5hKoYbaPwZeMVWWfq8dIAMcfuQShfyxPoDPVq4brS5OwTQs1VonxEBn3UNXuaIoWo1jPjp2Q+ezkalxFGORhEeyx0rzqyEEHmlJrKDygnRx2w== Received: from DM6NAM12FT043.eop-nam12.prod.protection.outlook.com (2a01:111:e400:fc64::40) by DM6NAM12HT097.eop-nam12.prod.protection.outlook.com (2a01:111:e400:fc64::249) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3520.9; Thu, 29 Oct 2020 04:45:34 +0000 Received: from MWHPR07MB3440.namprd07.prod.outlook.com (2a01:111:e400:fc64::50) by DM6NAM12FT043.mail.protection.outlook.com (2a01:111:e400:fc64::418) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3520.9 via Frontend Transport; Thu, 29 Oct 2020 04:45:34 +0000 X-IncomingTopHeaderMarker: OriginalChecksum:B448986016932D440F4F190EFBE489D9B6D927929E192B1A61FB8762DB960AF9;UpperCasedChecksum:CCA86DAB0128E21FA4AEC525838F9AA58AF6A604E56FEDFA13EBE1B456EEFB10;SizeAsReceived:9124;Count:48 Received: from MWHPR07MB3440.namprd07.prod.outlook.com ([fe80::858f:bd50:1b65:e803]) by MWHPR07MB3440.namprd07.prod.outlook.com ([fe80::858f:bd50:1b65:e803%7]) with mapi id 15.20.3477.029; Thu, 29 Oct 2020 04:45:34 +0000 Subject: Re: [edk2-platforms][PATCH v1 1/1] Vlv2TbltDevicePkg/FmpDeviceLib: Add LastAttemptStatus compatibility To: "Kinney, Michael D" , "devel@edk2.groups.io" Cc: "Qian, Yi" , "Sun, Zailiang" References: From: "Michael Kubacki" Message-ID: Date: Wed, 28 Oct 2020 21:45:33 -0700 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Thunderbird/68.12.1 In-Reply-To: X-TMN: [eOQkVeHKR4O+NJ9ZLU1kdJfkrpyDGsVgOyl2vAYAjTbGk7RF/pg3oT/3B1APxlvg] X-ClientProxiedBy: CO2PR04CA0104.namprd04.prod.outlook.com (2603:10b6:104:6::30) To MWHPR07MB3440.namprd07.prod.outlook.com (2603:10b6:301:69::28) Return-Path: michael.kubacki@outlook.com X-Microsoft-Original-Message-ID: MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from [IPv6:2001:4898:d8:39:e1f6:24f3:ca96:e810] (2001:4898:80e8:1:621e:24f3:ca96:e810) by CO2PR04CA0104.namprd04.prod.outlook.com (2603:10b6:104:6::30) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3499.18 via Frontend Transport; Thu, 29 Oct 2020 04:45:33 +0000 X-MS-PublicTrafficType: Email X-IncomingHeaderCount: 48 X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-Correlation-Id: ec0b4477-4f19-4664-a9d6-08d87bc57865 X-MS-TrafficTypeDiagnostic: DM6NAM12HT097: X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 2XG2PLSTtLTYbCiShYaRrsGRlNLigYVFN25bvthylSJkROE1iXiDd6pND67fV/ovscOMrXpe7PcCJqTYOXvSe+Xdtjfarax/er/KhpbyL+Ok4tdZAi4QH51Nj+cNNiKB9s5hSibnzJ8esQVYB+oDfEKqkuTv5ylLrgWTTFi+oYNZkgvUaVOr+macuJ9/p3+wqROLItpzKRK+7bLzVzbwfA== X-MS-Exchange-AntiSpam-MessageData: StKADr+gJLATvH5MmTcT6kMd+6CEf0ciqzQvssJ6l9k7mEV6uo3bA3HpXrHZokMp+6+Qm18ncCxDOMHYzgnX3aO+OkRWYB5/5Ml46lVU7L/fkuw00Bmvzp7U4qsGrJxOUmPPSR8IyyEgR9TNYOrhylZkUR2yrNqqMMqU/Il2dZtxxRA94ZgcDyHpERygJpRH10+rz399Sff7GfD5j+2Mag== X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: ec0b4477-4f19-4664-a9d6-08d87bc57865 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 29 Oct 2020 04:45:34.4210 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-AuthSource: DM6NAM12FT043.eop-nam12.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: Internet X-MS-Exchange-CrossTenant-RMS-PersistedConsumerOrg: 00000000-0000-0000-0000-000000000000 X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM6NAM12HT097 Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit Thank you for the test confirmation. Regards, Michael On 10/28/2020 6:12 PM, Kinney, Michael D wrote: > Reviewed-by: Michael D Kinney > > I also verified build and boot and FMP based capsule updates work as expected. > > Tested-by: Michael D Kinney > > Thanks, > > Mike > > >> -----Original Message----- >> From: michael.kubacki@outlook.com >> Sent: Thursday, October 1, 2020 2:59 PM >> To: devel@edk2.groups.io >> Cc: Kinney, Michael D ; Qian, Yi ; Sun, Zailiang >> Subject: [edk2-platforms][PATCH v1 1/1] Vlv2TbltDevicePkg/FmpDeviceLib: Add LastAttemptStatus compatibility >> >> From: Michael Kubacki >> >> Makes the changes necessary for these library instances of >> FmpDeviceLib to be compatible with new functions added recently >> to FmpDeviceLib. >> >> Two new functions were introduced in FmpDeviceLib to allow a >> library instance to return a Last Attempt Status code during >> check image and set image operations: >> 1. FmpDeviceCheckImageWithStatus ( ) >> 2. FmpDeviceSetImageWithStatus ( ) >> >> FmpDxe (in FmpDevicePkg) will begin calling these new functions >> instead of the previous functions. Therefore, this change: >> 1. Adds these functions to Vlv2TbltDevicePkg implementations >> 2. Moves the main functionality to these new functions >> 3. Updates the old functions to call the new functions >> (for backward compatibility) >> >> Note: As of this commit, the Vlv2TbltDevicePkg build is broken >> due to: >> 1. A required RngLib library instance not defined by the platform >> 2. Other FMP libraries not being defined by the platform >> (e.g. FmpDependencyLib, FmpDependencyCheckLib, etc.) >> >> Those changes were fixed locally to test the changes in this commit >> but maintainers should make the proper changes for those issues. >> >> Cc: Michael D Kinney >> Cc: Yi Qian >> Cc: Zailiang Sun >> Signed-off-by: Michael Kubacki >> --- >> >> Notes: >> Only build was checked, I do not have access to a >> VLV2 device for testing. >> >> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/FmpDeviceLib.c | 299 +++++++++++++++----- >> Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.c | 284 ++++++++++++++----- >> 2 files changed, 446 insertions(+), 137 deletions(-) >> >> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/FmpDeviceLib.c >> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/FmpDeviceLib.c >> index d8c9036012ad..df8a36d9854c 100644 >> --- a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/FmpDeviceLib.c >> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib/FmpDeviceLib.c >> @@ -1,6 +1,6 @@ >> /** >> >> -Copyright (c) 2016, Microsoft Corporation. All rights reserved. >> +Copyright (c) Microsoft Corporation.
>> Copyright (c) 2019, Intel Corporation. All rights reserved. >> >> SPDX-License-Identifier: BSD-2-Clause-Patent >> @@ -8,7 +8,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent >> **/ >> >> #include >> - >> +#include >> +#include >> #include >> >> #include >> @@ -444,20 +445,17 @@ FmpDeviceGetImage ( >> } >> >> /** >> - Updates the firmware image of the device. >> - >> - This function updates the hardware with the 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 the image is a supported image for this device. The function >> - returns EFI_ABORTED if the image is unsupported. The function can >> - optionally provide more detailed information on why the image is not a >> - supported image. >> - - Validate the data from VendorCode if not null. Image validation must be >> - performed before VendorCode data validation. VendorCode data is ignored >> - or considered invalid if image validation failed. The function returns >> - EFI_ABORTED if the data is invalid. >> + 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 >> @@ -470,38 +468,56 @@ FmpDeviceGetImage ( >> have the option to provide a more detailed description of the abort reason to >> the caller. >> >> - @param[in] Image Points to the new image. >> - @param[in] ImageSize Size of the new image in bytes. >> + @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 >> + firmware image update policy. NULL indicates >> + the caller did not specify the policy or use the >> default policy. >> - @param[in] Progress A function used by the driver to report the >> - progress of the firmware update. >> - @param[in] CapsuleFwVersion FMP Payload Header version of the image. >> - @param[out] AbortReason A pointer to a pointer to a null-terminated >> - string providing more details for the aborted >> - operation. The buffer is allocated by this >> - function with AllocatePool(), and it is the >> - caller's responsibility to free it with a call >> - to FreePool(). >> + @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. >> >> - @retval EFI_SUCCESS The device was successfully updated with the >> - new image. >> - @retval EFI_ABORTED The operation is aborted. >> + 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_INVALID_PARAMETER LastAttemptStatus was NULL. >> @retval EFI_UNSUPPORTED The operation is not supported. >> >> **/ >> EFI_STATUS >> EFIAPI >> -FmpDeviceSetImage ( >> +FmpDeviceSetImageWithStatus ( >> IN CONST VOID *Image, >> IN UINTN ImageSize, >> - IN CONST VOID *VendorCode, >> - IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress, >> + IN CONST VOID *VendorCode, OPTIONAL >> + IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress, OPTIONAL >> IN UINT32 CapsuleFwVersion, >> - OUT CHAR16 **AbortReason >> + OUT CHAR16 **AbortReason, >> + OUT UINT32 *LastAttemptStatus >> ) >> { >> EFI_STATUS Status; >> @@ -513,25 +529,27 @@ FmpDeviceSetImage ( >> UINTN BytesWritten; >> >> Updateable = 0; >> - Status = FmpDeviceCheckImage (Image, ImageSize, &Updateable); >> + Status = FmpDeviceCheckImageWithStatus (Image, ImageSize, &Updateable, LastAttemptStatus); >> if (EFI_ERROR (Status)) { >> - DEBUG((DEBUG_ERROR, "FmpDeviceSetImage - Check Image failed with %r.\n", Status)); >> + DEBUG((DEBUG_ERROR, "FmpDeviceSetImageWithStatus - Check Image failed with %r.\n", Status)); >> return Status; >> } >> >> if (Updateable != IMAGE_UPDATABLE_VALID) { >> - DEBUG((DEBUG_ERROR, "FmpDeviceSetImage - Check Image returned that the Image was not valid for update. Updatable >> value = 0x%X.\n", Updateable)); >> + DEBUG((DEBUG_ERROR, "FmpDeviceSetImageWithStatus - Check Image returned that the Image was not valid for update. >> Updatable value = 0x%X.\n", Updateable)); >> + *LastAttemptStatus = LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE; >> return EFI_ABORTED; >> } >> >> if (Progress == NULL) { >> - DEBUG((DEBUG_ERROR, "FmpDeviceSetImage - Invalid progress callback\n")); >> + DEBUG((DEBUG_ERROR, "FmpDeviceSetImageWithStatus - Invalid progress callback\n")); >> + *LastAttemptStatus = LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE; >> return EFI_INVALID_PARAMETER; >> } >> >> Status = Progress (15); >> if (EFI_ERROR (Status)) { >> - DEBUG((DEBUG_ERROR, "FmpDeviceSetImage - Progress Callback failed with Status %r.\n", Status)); >> + DEBUG((DEBUG_ERROR, "FmpDeviceSetImageWithStatus - Progress Callback failed with Status %r.\n", Status)); >> } >> >> // >> @@ -539,7 +557,7 @@ FmpDeviceSetImage ( >> // >> Progress (20); >> if (EFI_ERROR (Status)) { >> - DEBUG((DEBUG_ERROR, "FmpDeviceSetImage - Progress Callback failed with Status %r.\n", Status)); >> + DEBUG((DEBUG_ERROR, "FmpDeviceSetImageWithStatus - Progress Callback failed with Status %r.\n", Status)); >> } >> >> // >> @@ -553,11 +571,11 @@ FmpDeviceSetImage ( >> >> // Progress (Percentage); >> // if (EFI_ERROR (Status)) { >> -// DEBUG((DEBUG_ERROR, "FmpDeviceSetImage - Progress Callback failed with Status %r.\n", Status)); >> +// DEBUG((DEBUG_ERROR, "FmpDeviceSetImageWithStatus - Progress Callback failed with Status %r.\n", Status)); >> // } >> } >> >> - DEBUG ((DEBUG_INFO, "FmpDeviceSetImage - %d Images ...\n", ARRAY_SIZE (mUpdateConfigData))); >> + DEBUG ((DEBUG_INFO, "FmpDeviceSetImageWithStatus - %d Images ...\n", ARRAY_SIZE (mUpdateConfigData))); >> >> if (ARRAY_SIZE (mUpdateConfigData) == 0) { >> DEBUG((DEBUG_INFO, "PlatformUpdate: BaseAddress - 0x%lx ImageOffset - 0x%x Length - 0x%x\n", 0, 0, ImageSize)); >> @@ -605,11 +623,173 @@ FmpDeviceSetImage ( >> BytesWritten += ConfigData->Length; >> } >> >> - DEBUG ((DEBUG_INFO, "FmpDeviceSetImage - %r\n", Status)); >> + DEBUG ((DEBUG_INFO, "FmpDeviceSetImageWithStatus - %r\n", Status)); >> + >> + if (EFI_ERROR (Status)) { >> + *LastAttemptStatus = LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE; >> + } >> >> return Status; >> } >> >> +/** >> + Updates the firmware image of the device. >> + >> + This function updates the hardware with the 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 the image is a supported image for this device. The function >> + returns EFI_ABORTED if the image is unsupported. The function can >> + optionally provide more detailed information on why the image is not a >> + supported image. >> + - Validate the data from VendorCode if not null. Image validation must be >> + performed before VendorCode data validation. VendorCode data is ignored >> + or considered invalid if image validation failed. The function returns >> + EFI_ABORTED if the 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 image. >> + @param[in] ImageSize Size of the new image in bytes. >> + @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 by the driver to report the >> + progress of the firmware update. >> + @param[in] CapsuleFwVersion FMP Payload Header version of the image. >> + @param[out] AbortReason A pointer to a pointer to a null-terminated >> + string providing more details for the aborted >> + operation. The buffer is allocated by this >> + function with AllocatePool(), and it is the >> + caller's responsibility to free it with a call >> + to FreePool(). >> + >> + @retval EFI_SUCCESS The device was successfully updated with the >> + new image. >> + @retval EFI_ABORTED The operation is aborted. >> + @retval EFI_INVALID_PARAMETER The Image was NULL. >> + @retval EFI_UNSUPPORTED The operation is not supported. >> + >> +**/ >> +EFI_STATUS >> +EFIAPI >> +FmpDeviceSetImage ( >> + IN CONST VOID *Image, >> + IN UINTN ImageSize, >> + IN CONST VOID *VendorCode, >> + IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress, >> + IN UINT32 CapsuleFwVersion, >> + OUT CHAR16 **AbortReason >> + ) >> +{ >> + UINT32 LastAttemptStatus; >> + >> + return FmpDeviceSetImageWithStatus ( >> + Image, >> + ImageSize, >> + VendorCode, >> + Progress, >> + CapsuleFwVersion, >> + AbortReason, >> + &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. >> + @retval EFI_INVALID_PARAMETER LastAttemptStatus is NULL. >> + >> +**/ >> +EFI_STATUS >> +EFIAPI >> +FmpDeviceCheckImageWithStatus ( >> + IN CONST VOID *Image, >> + IN UINTN ImageSize, >> + OUT UINT32 *ImageUpdatable, >> + OUT UINT32 *LastAttemptStatus >> + ) >> +{ >> + if (LastAttemptStatus == NULL) { >> + DEBUG ((DEBUG_ERROR, "CheckImageWithStatus - LastAttemptStatus Pointer Parameter is NULL.\n")); >> + return EFI_INVALID_PARAMETER; >> + } >> + *LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS; >> + >> + if (ImageUpdatable == NULL) { >> + DEBUG((DEBUG_ERROR, "CheckImageWithStatus - ImageUpdatable Pointer Parameter is NULL.\n")); >> + *LastAttemptStatus = LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE; >> + return EFI_INVALID_PARAMETER; >> + } >> + >> + // >> + //Set to valid and then if any tests fail it will update this flag. >> + // >> + *ImageUpdatable = IMAGE_UPDATABLE_VALID; >> + >> + if (Image == NULL) { >> + DEBUG((DEBUG_ERROR, "CheckImageWithStatus - Image Pointer Parameter is NULL.\n")); >> + // >> + // Not sure if this is needed >> + // >> + *ImageUpdatable = IMAGE_UPDATABLE_INVALID; >> + *LastAttemptStatus = LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE; >> + return EFI_INVALID_PARAMETER; >> + } >> + >> + // >> + // Make sure the image size is correct >> + // >> + if (ImageSize != PcdGet32 (PcdBiosRomSize)) { >> + *ImageUpdatable = IMAGE_UPDATABLE_INVALID; >> + *LastAttemptStatus = LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE; >> + return EFI_INVALID_PARAMETER; >> + } >> + >> + return EFI_SUCCESS; >> +} >> + >> /** >> Checks if the firmware image is valid for the device. >> >> @@ -633,34 +813,9 @@ FmpDeviceCheckImage ( >> OUT UINT32 *ImageUpdateable >> ) >> { >> - if (ImageUpdateable == NULL) { >> - DEBUG((DEBUG_ERROR, "CheckImage - ImageUpdateable Pointer Parameter is NULL.\n")); >> - return EFI_INVALID_PARAMETER; >> - } >> + UINT32 LastAttemptStatus; >> >> - // >> - //Set to valid and then if any tests fail it will update this flag. >> - // >> - *ImageUpdateable = IMAGE_UPDATABLE_VALID; >> - >> - if (Image == NULL) { >> - DEBUG((DEBUG_ERROR, "CheckImage - Image Pointer Parameter is NULL.\n")); >> - // >> - // Not sure if this is needed >> - // >> - *ImageUpdateable = IMAGE_UPDATABLE_INVALID; >> - return EFI_INVALID_PARAMETER; >> - } >> - >> - // >> - // Make sure the image size is correct >> - // >> - if (ImageSize != PcdGet32 (PcdBiosRomSize)) { >> - *ImageUpdateable = IMAGE_UPDATABLE_INVALID; >> - return EFI_INVALID_PARAMETER; >> - } >> - >> - return EFI_SUCCESS; >> + return FmpDeviceCheckImageWithStatus (Image, ImageSize, ImageUpdateable, &LastAttemptStatus); >> } >> >> /** >> diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.c >> b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.c >> index db0f238ea534..132b60844ad4 100644 >> --- a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.c >> +++ b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSample/FmpDeviceLib.c >> @@ -1,6 +1,6 @@ >> /** >> >> -Copyright (c) 2016, Microsoft Corporation. All rights reserved.
>> +Copyright (c) Microsoft Corporation.
>> Copyright (c) 2019, Intel Corporation. All rights reserved.
>> >> SPDX-License-Identifier: BSD-2-Clause-Patent >> @@ -9,6 +9,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent >> >> >> #include >> +#include >> +#include >> #include >> #include >> #include >> @@ -345,6 +347,131 @@ Return Value: >> }//GetImage() >> >> >> +/** >> + 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_INVALID_PARAMETER LastAttemptStatus 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 >> + ) >> +{ >> + EFI_STATUS Status = EFI_SUCCESS; >> + UINT32 Updateable = 0; >> + >> + Status = FmpDeviceCheckImageWithStatus (Image, ImageSize, &Updateable, LastAttemptStatus); >> + if (EFI_ERROR(Status)) >> + { >> + DEBUG((DEBUG_ERROR, "SetImageWithStatus - Check Image failed with %r.\n", Status)); >> + goto cleanup; >> + } >> + >> + if (Updateable != IMAGE_UPDATABLE_VALID) >> + { >> + DEBUG((DEBUG_ERROR, "SetImageWithStatus - Check Image returned that the Image was not valid for update. >> Updatable value = 0x%X.\n", Updateable)); >> + Status = EFI_ABORTED; >> + goto cleanup; >> + } >> + >> + if (Progress == NULL) >> + { >> + DEBUG((DEBUG_ERROR, "SetImageWithStatus - Invalid progress callback\n")); >> + Status = EFI_INVALID_PARAMETER; >> + goto cleanup; >> + } >> + >> + Status = Progress(15); >> + if (EFI_ERROR(Status)) >> + { >> + DEBUG((DEBUG_ERROR, "SetImageWithStatus - Progress Callback failed with Status %r.\n", Status)); >> + } >> + >> + { >> + UINTN p; >> + >> + for (p = 20; p < 100; p++) { >> + gBS->Stall (100000); //us = 0.1 seconds >> + Progress (p); >> + } >> + } >> + >> + //TODO: add support for VendorCode, and AbortReason >> +cleanup: >> + if (EFI_ERROR (Status)) { >> + *LastAttemptStatus = LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE; >> + } >> + >> + return Status; >> +}// SetImageWithStatus() >> + >> + >> /** >> Updates the firmware image of the device. >> >> @@ -396,51 +523,98 @@ IN UINT32 CapsuleFwVersion, >> OUT CHAR16 **AbortReason >> ) >> { >> - EFI_STATUS Status = EFI_SUCCESS; >> - UINT32 Updateable = 0; >> - >> - Status = FmpDeviceCheckImage(Image, ImageSize, &Updateable); >> - if (EFI_ERROR(Status)) >> - { >> - DEBUG((DEBUG_ERROR, "SetImage - Check Image failed with %r.\n", Status)); >> - goto cleanup; >> - } >> - >> - if (Updateable != IMAGE_UPDATABLE_VALID) >> - { >> - DEBUG((DEBUG_ERROR, "SetImage - Check Image returned that the Image was not valid for update. Updatable value = >> 0x%X.\n", Updateable)); >> - Status = EFI_ABORTED; >> - goto cleanup; >> - } >> - >> - if (Progress == NULL) >> - { >> - DEBUG((DEBUG_ERROR, "SetImage - Invalid progress callback\n")); >> - Status = EFI_INVALID_PARAMETER; >> - goto cleanup; >> - } >> - >> - Status = Progress(15); >> - if (EFI_ERROR(Status)) >> - { >> - DEBUG((DEBUG_ERROR, "SetImage - Progress Callback failed with Status %r.\n", Status)); >> - } >> - >> - { >> - UINTN p; >> - >> - for (p = 20; p < 100; p++) { >> - gBS->Stall (100000); //us = 0.1 seconds >> - Progress (p); >> - } >> - } >> - >> - //TODO: add support for VendorCode, and AbortReason >> -cleanup: >> - return Status; >> + UINT32 LastAttemptStatus; >> + >> + return FmpDeviceSetImageWithStatus ( >> + Image, >> + ImageSize, >> + VendorCode, >> + Progress, >> + CapsuleFwVersion, >> + AbortReason, >> + &LastAttemptStatus >> + ); >> }// SetImage() >> >> >> +/** >> + 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. >> + @retval EFI_INVALID_PARAMETER LastAttemptStatus is NULL. >> + >> +**/ >> +EFI_STATUS >> +EFIAPI >> +FmpDeviceCheckImageWithStatus ( >> + IN CONST VOID *Image, >> + IN UINTN ImageSize, >> + OUT UINT32 *ImageUpdatable, >> + OUT UINT32 *LastAttemptStatus >> + ) >> +{ >> + EFI_STATUS status = EFI_SUCCESS; >> + >> + if (LastAttemptStatus == NULL) { >> + DEBUG ((DEBUG_ERROR, "CheckImageWithStatus - LastAttemptStatus Pointer Parameter is NULL.\n")); >> + return EFI_INVALID_PARAMETER; >> + } >> + *LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS; >> + >> + if (ImageUpdatable == NULL) >> + { >> + DEBUG((DEBUG_ERROR, "CheckImageWithStatus - ImageUpdatable Pointer Parameter is NULL.\n")); >> + *LastAttemptStatus = LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE; >> + status = EFI_INVALID_PARAMETER; >> + goto cleanup; >> + } >> + >> + // >> + //Set to valid and then if any tests fail it will update this flag. >> + // >> + *ImageUpdatable = IMAGE_UPDATABLE_VALID; >> + >> + if (Image == NULL) >> + { >> + DEBUG((DEBUG_ERROR, "CheckImageWithStatus - Image Pointer Parameter is NULL.\n")); >> + *ImageUpdatable = IMAGE_UPDATABLE_INVALID; //not sure if this is needed >> + *LastAttemptStatus = LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CODE_VALUE; >> + return EFI_INVALID_PARAMETER; >> + } >> + >> +cleanup: >> + return status; >> +}// CheckImageWithStatus() >> + >> >> /** >> Checks if the firmware image is valid for the device. >> @@ -465,29 +639,9 @@ IN UINTN ImageSize, >> OUT UINT32 *ImageUpdateable >> ) >> { >> - EFI_STATUS status = EFI_SUCCESS; >> + UINT32 LastAttemptStatus; >> >> - if (ImageUpdateable == NULL) >> - { >> - DEBUG((DEBUG_ERROR, "CheckImage - ImageUpdateable Pointer Parameter is NULL.\n")); >> - status = EFI_INVALID_PARAMETER; >> - goto cleanup; >> - } >> - >> - // >> - //Set to valid and then if any tests fail it will update this flag. >> - // >> - *ImageUpdateable = IMAGE_UPDATABLE_VALID; >> - >> - if (Image == NULL) >> - { >> - DEBUG((DEBUG_ERROR, "CheckImage - Image Pointer Parameter is NULL.\n")); >> - *ImageUpdateable = IMAGE_UPDATABLE_INVALID; //not sure if this is needed >> - return EFI_INVALID_PARAMETER; >> - } >> - >> -cleanup: >> - return status; >> + return FmpDeviceCheckImageWithStatus (Image, ImageSize, ImageUpdateable, &LastAttemptStatus); >> }// CheckImage() >> >> /** >> -- >> 2.28.0.windows.1 >