From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM10-DM6-obe.outbound.protection.outlook.com (NAM10-DM6-obe.outbound.protection.outlook.com [40.92.41.81]) by mx.groups.io with SMTP id smtpd.web11.402.1601589558256963930 for ; Thu, 01 Oct 2020 14:59:18 -0700 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@outlook.com header.s=selector1 header.b=bBAitrhe; spf=pass (domain: outlook.com, ip: 40.92.41.81, mailfrom: michael.kubacki@outlook.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=csdWtbEQR4LfRNCvCWQT7S2AgBEGA/7q55NDXoN9utKc2Lozbmiew6eqWKoRDmSfArYHkKWDlFvgaoF8fGyCABjd8EK1KYj0vsCMltv6+uhpdSPvKFt8KJbz6KHn6qD4wruKjpH4WUdjADTBygWAmBit08axu2Nb2YA4+ZsDikVw8qVAur9LmRgrHNN+yO+QvHYn1PWdxdoc0kWfaG7Dwyud5YKBcgIqMN0BmtCKWlvrSO/cogfS5dWB/fSarrRspUwVE/KUouX0565lKaf+qKIgaf51vaQD97E20lhAWICcEXwxRfsrMtkcMOesGhdglzULKG5KoLjuZE7jjF73/A== 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=YyX+kwoXhNCgt0XAKZw9ZhWs5CnB2gudvGfjlDGIW+c=; b=oep8EsLn1l7qzxQZNOJbhyP6E0ns4+4u6Sf42DFn/8MfDtuj/gf9zqfyz36D+GF0IuqzzU7dxa+4KH4Zf/BSeQkoBm/7/nC+LFXDEwia4dF0rVI31hMOvm469FDrY8o4KA1MiD4mw14e6IO1EK0ibLUZYEgJjpq4mixjWj3i7Dc69Rsnv5bQyUciArOJOhz3vd3i0jrG4lVBZpRrXhERdbQF0VxWXtrmuthsPU93IIe4igwYOg5ZRleunRn9KDsHP+NMDfpGkyBXcPuX/XoSzeefPxWCXqx8v8b4ikvWbGV3opbcXmbeir5JXVApBbmDQjbFDv0G1TWir9ndAkyCMw== 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=YyX+kwoXhNCgt0XAKZw9ZhWs5CnB2gudvGfjlDGIW+c=; b=bBAitrheexhDTKC60ICcpaGH4IHndSUGB6RdePIfzgz8+U/FmWYCaHCSsX5/lN9rGk4pUug62WhH6eATGJA9ehdv9QY7cuUQ/NFF5gLBzMtxXNz/jh4KmjIOOXW15biV2u2jIXyP8qcTVtbJU69EAAVcjLGHz5vFLRwSKZj2Lp8gNGVwfTYItky8ayRdQsGlUIXNApam45M4swNsCgqxYsice08tIlcQ8K/cjj7CtyMd4IkaMcA2EMucifkHNmyMZJfTVWfz09U2WKzpMpS8euea5SVkreiGmA08H9RYRLj6AO42eQaZMwu7sMjPkfsdlUPS9FGmpviEB/lcQRX9Jw== Received: from DM6NAM10FT017.eop-nam10.prod.protection.outlook.com (2a01:111:e400:7e86::40) by DM6NAM10HT024.eop-nam10.prod.protection.outlook.com (2a01:111:e400:7e86::371) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3433.34; Thu, 1 Oct 2020 21:59:17 +0000 Received: from MWHPR07MB3440.namprd07.prod.outlook.com (2a01:111:e400:7e86::46) by DM6NAM10FT017.mail.protection.outlook.com (2a01:111:e400:7e86::165) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3433.34 via Frontend Transport; Thu, 1 Oct 2020 21:59:17 +0000 X-IncomingTopHeaderMarker: OriginalChecksum:00530AC8F8BC3707196C4ADF5972065D2EEE37105C571E12B8B4F6CA4D677B2D;UpperCasedChecksum:571CAFCC2D50F3B8FDA1B560A12598E883848166F2190D87929BCB0777E530DD;SizeAsReceived:7644;Count:47 Received: from MWHPR07MB3440.namprd07.prod.outlook.com ([fe80::eda9:ccc8:2ef:2471]) by MWHPR07MB3440.namprd07.prod.outlook.com ([fe80::eda9:ccc8:2ef:2471%7]) with mapi id 15.20.3391.026; Thu, 1 Oct 2020 21:59:16 +0000 From: "Michael Kubacki" To: devel@edk2.groups.io CC: Michael D Kinney , Yi Qian , Zailiang Sun Subject: [edk2-platforms][PATCH v1 1/1] Vlv2TbltDevicePkg/FmpDeviceLib: Add LastAttemptStatus compatibility Date: Thu, 1 Oct 2020 14:58:36 -0700 Message-ID: X-Mailer: git-send-email 2.28.0.windows.1 X-ClientProxiedBy: MWHPR19CA0060.namprd19.prod.outlook.com (2603:10b6:300:94::22) To MWHPR07MB3440.namprd07.prod.outlook.com (2603:10b6:301:69::28) Return-Path: michael.kubacki@outlook.com X-Microsoft-Original-Message-ID: <20201001215836.929-1-michael.kubacki@outlook.com> MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from localhost.localdomain (2001:4898:80e8:f:ac4b:2e65:cc1d:844b) by MWHPR19CA0060.namprd19.prod.outlook.com (2603:10b6:300:94::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3391.14 via Frontend Transport; Thu, 1 Oct 2020 21:59:15 +0000 X-Mailer: git-send-email 2.28.0.windows.1 X-Microsoft-Original-Message-ID: <20201001215836.929-1-michael.kubacki@outlook.com> X-TMN: [EenuY7yzs7Q7dxQ1TASIA9x15TrQUQWIETaL7CgVVh/BgxcrL1gl5utuz+P63shZ] X-MS-PublicTrafficType: Email X-IncomingHeaderCount: 47 X-EOPAttributedMessage: 0 X-MS-Office365-Filtering-Correlation-Id: 65db8b3f-8ff1-4193-bd54-08d866553d4e X-MS-TrafficTypeDiagnostic: DM6NAM10HT024: X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: G+3QDE4+XTmsGEdB3fZjQCGwYey0PyN2zRI55BriZUv1b/GP1z6n+yHU0uiZ/PsTg7CgtcfT3TtkUpGKAaoIVTLhn5fnAdtLaiHiBsbzp3ADhcRZ1zF9t/vAeV+UK//8N1UcHQt7d3p03UR4BKIgYge/4+JVck1p2jKZBOFdxoKVOM20bXdN07f//D3Vptv7EbPVFE8GAFSlhG8815VZPw== X-MS-Exchange-AntiSpam-MessageData: 0S/qfOUu5OWbJRjvpi2B4n/+RX4ycYwvHxtE1zhYKZfP/Rzr3Llv/SbVtsmUL/oJeZwxp7XiA78lMEnRpsMXaNexxtz6ZPvELvxHI4fo/6OegHcD9nu1MFWLNKYF8lMza9u7KQx/ngisqrJro1DFr2DPl9UXQlRY2QE4CQWjEJsX841Z7bEvchsEdn8fBt0RRt1uZmx4LK1SrbxOw/DNyA== X-OriginatorOrg: outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 65db8b3f-8ff1-4193-bd54-08d866553d4e X-MS-Exchange-CrossTenant-OriginalArrivalTime: 01 Oct 2020 21:59:16.5895 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 84df9e7f-e9f6-40af-b435-aaaaaaaaaaaa X-MS-Exchange-CrossTenant-AuthSource: DM6NAM10FT017.eop-nam10.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: DM6NAM10HT024 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain 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/FmpD= eviceLib.c | 299 +++++++++++++++----- Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLibSampl= e/FmpDeviceLib.c | 284 ++++++++++++++----- 2 files changed, 446 insertions(+), 137 deletions(-) diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDe= viceLib/FmpDeviceLib.c b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/L= ibrary/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 @@ /** =20 -Copyright (c) 2016, Microsoft Corporation. All rights reserved. +Copyright (c) Microsoft Corporation.
Copyright (c) 2019, Intel Corporation. All rights reserved. =20 SPDX-License-Identifier: BSD-2-Clause-Patent @@ -8,7 +8,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ =20 #include - +#include +#include #include =20 #include @@ -444,20 +445,17 @@ FmpDeviceGetImage ( } =20 /** - Updates the firmware image of the device. - - This function updates the hardware with the new firmware image. This fu= nction - returns EFI_UNSUPPORTED if the firmware image is not updatable. If the - firmware image is updatable, the function should perform the following m= inimal - validations before proceeding to do the firmware image update. - - Validate the image is a supported image for this device. The functi= on - 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 mus= t be - performed before VendorCode data validation. VendorCode data is ign= ored - or considered invalid if image validation failed. The function retu= rns - EFI_ABORTED if the data is invalid. + Updates a firmware device with a new firmware image. This function retu= rns + EFI_UNSUPPORTED if the firmware image is not updatable. If the firmware= image + is updatable, the function should perform the following minimal validati= ons + before proceeding to do the firmware image update. + - Validate that the image is a supported image for this firmware devic= e. + Return EFI_ABORTED if the image is not supported. Additional detail= s + on why the image is not a supported image may be returned in AbortRe= ason. + - 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. =20 VendorCode enables vendor to implement vendor-specific firmware image up= date policy. Null if the caller did not specify the policy or use the defaul= t @@ -470,38 +468,56 @@ FmpDeviceGetImage ( have the option to provide a more detailed description of the abort reas= on to the caller. =20 - @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-sp= ecific - firmware image update policy. Null indicat= es the - caller did not specify the policy or use t= he + firmware image update policy. NULL indica= tes + the caller did not specify the policy or u= se the default policy. - @param[in] Progress A function used by the driver to report th= e - 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-terminate= d - string providing more details for the abor= ted - operation. The buffer is allocated by this - function with AllocatePool(), and it is th= e - 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 firmw= are + image. + @param[out] AbortReason A pointer to a pointer to a Null-terminate= d + Unicode string providing more details on a= n + aborted operation. The buffer is allocated= by + this function with + EFI_BOOT_SERVICES.AllocatePool(). It is t= he + caller's responsibility to free this buffe= r 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. =20 - @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 ra= nge of + LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERR= OR_CODE_VALUE to + LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MAX_ERR= OR_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 upda= ted + with the new firmware image. + @retval EFI_ABORTED The operation is aborted. Additional det= ails + 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. =20 **/ 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, OP= TIONAL + IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress, OP= TIONAL IN UINT32 CapsuleFwVersion, - OUT CHAR16 **AbortReason + OUT CHAR16 **AbortReason, + OUT UINT32 *LastAttemptStatus ) { EFI_STATUS Status; @@ -513,25 +529,27 @@ FmpDeviceSetImage ( UINTN BytesWritten; =20 Updateable =3D 0; - Status =3D FmpDeviceCheckImage (Image, ImageSize, &Updateable); + Status =3D 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; } =20 if (Updateable !=3D IMAGE_UPDATABLE_VALID) { - DEBUG((DEBUG_ERROR, "FmpDeviceSetImage - Check Image returned that the= Image was not valid for update. Updatable value =3D 0x%X.\n", Updateable)= ); + DEBUG((DEBUG_ERROR, "FmpDeviceSetImageWithStatus - Check Image returne= d that the Image was not valid for update. Updatable value =3D 0x%X.\n", U= pdateable)); + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CO= DE_VALUE; return EFI_ABORTED; } =20 if (Progress =3D=3D NULL) { - DEBUG((DEBUG_ERROR, "FmpDeviceSetImage - Invalid progress callback\n")= ); + DEBUG((DEBUG_ERROR, "FmpDeviceSetImageWithStatus - Invalid progress ca= llback\n")); + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CO= DE_VALUE; return EFI_INVALID_PARAMETER; } =20 Status =3D Progress (15); if (EFI_ERROR (Status)) { - DEBUG((DEBUG_ERROR, "FmpDeviceSetImage - Progress Callback failed with= Status %r.\n", Status)); + DEBUG((DEBUG_ERROR, "FmpDeviceSetImageWithStatus - Progress Callback f= ailed with Status %r.\n", Status)); } =20 // @@ -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 f= ailed with Status %r.\n", Status)); } =20 // @@ -553,11 +571,11 @@ FmpDeviceSetImage ( =20 // Progress (Percentage); // if (EFI_ERROR (Status)) { -// DEBUG((DEBUG_ERROR, "FmpDeviceSetImage - Progress Callback failed = with Status %r.\n", Status)); +// DEBUG((DEBUG_ERROR, "FmpDeviceSetImageWithStatus - Progress Callba= ck failed with Status %r.\n", Status)); // } } =20 - DEBUG ((DEBUG_INFO, "FmpDeviceSetImage - %d Images ...\n", ARRAY_SIZE (m= UpdateConfigData))); + DEBUG ((DEBUG_INFO, "FmpDeviceSetImageWithStatus - %d Images ...\n", ARR= AY_SIZE (mUpdateConfigData))); =20 if (ARRAY_SIZE (mUpdateConfigData) =3D=3D 0) { DEBUG((DEBUG_INFO, "PlatformUpdate: BaseAddress - 0x%lx ImageOffset - = 0x%x Length - 0x%x\n", 0, 0, ImageSize)); @@ -605,11 +623,173 @@ FmpDeviceSetImage ( BytesWritten +=3D ConfigData->Length; } =20 - DEBUG ((DEBUG_INFO, "FmpDeviceSetImage - %r\n", Status)); + DEBUG ((DEBUG_INFO, "FmpDeviceSetImageWithStatus - %r\n", Status)); + + if (EFI_ERROR (Status)) { + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CO= DE_VALUE; + } =20 return Status; } =20 +/** + Updates the firmware image of the device. + + This function updates the hardware with the new firmware image. This fu= nction + returns EFI_UNSUPPORTED if the firmware image is not updatable. If the + firmware image is updatable, the function should perform the following m= inimal + validations before proceeding to do the firmware image update. + - Validate the image is a supported image for this device. The functi= on + 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 mus= t be + performed before VendorCode data validation. VendorCode data is ign= ored + or considered invalid if image validation failed. The function retu= rns + EFI_ABORTED if the data is invalid. + + VendorCode enables vendor to implement vendor-specific firmware image up= date + policy. Null if the caller did not specify the policy or use the defaul= t + 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 fi= rmware + image version is older than the current firmware image version or bad im= age + checksum. Sensitive operations such as those wiping the entire firmware= image + and render the device to be non-functional should be encoded in the imag= e + itself rather than passed with the VendorCode. AbortReason enables vend= or to + have the option to provide a more detailed description of the abort reas= on 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-sp= ecific + firmware image update policy. Null indicat= es the + caller did not specify the policy or use t= he + default policy. + @param[in] Progress A function used by the driver to report th= e + 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-terminate= d + string providing more details for the abor= ted + operation. The buffer is allocated by this + function with AllocatePool(), and it is th= e + 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 val= id for + a firmware update to the firmware device= . The + following values from the Firmware Manag= ement + 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 las= t attempt + status to report back to the ESRT table = in case + of error. This value will only be checke= d when this + function returns an error. + + The return status code must fall in the = range of + LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_E= RROR_CODE_VALUE to + LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MAX_E= RROR_CODE_VALUE. + + If the value falls outside this range, i= t will be converted + to LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFU= L. + + @retval EFI_SUCCESS The image was successfully checked. Addi= tional + 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 =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "CheckImageWithStatus - LastAttemptStatus Pointer= Parameter is NULL.\n")); + return EFI_INVALID_PARAMETER; + } + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_SUCCESS; + + if (ImageUpdatable =3D=3D NULL) { + DEBUG((DEBUG_ERROR, "CheckImageWithStatus - ImageUpdatable Pointer Par= ameter is NULL.\n")); + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CO= DE_VALUE; + return EFI_INVALID_PARAMETER; + } + + // + //Set to valid and then if any tests fail it will update this flag. + // + *ImageUpdatable =3D IMAGE_UPDATABLE_VALID; + + if (Image =3D=3D NULL) { + DEBUG((DEBUG_ERROR, "CheckImageWithStatus - Image Pointer Parameter is= NULL.\n")); + // + // Not sure if this is needed + // + *ImageUpdatable =3D IMAGE_UPDATABLE_INVALID; + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CO= DE_VALUE; + return EFI_INVALID_PARAMETER; + } + + // + // Make sure the image size is correct + // + if (ImageSize !=3D PcdGet32 (PcdBiosRomSize)) { + *ImageUpdatable =3D IMAGE_UPDATABLE_INVALID; + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_CO= DE_VALUE; + return EFI_INVALID_PARAMETER; + } + + return EFI_SUCCESS; +} + /** Checks if the firmware image is valid for the device. =20 @@ -633,34 +813,9 @@ FmpDeviceCheckImage ( OUT UINT32 *ImageUpdateable ) { - if (ImageUpdateable =3D=3D NULL) { - DEBUG((DEBUG_ERROR, "CheckImage - ImageUpdateable Pointer Parameter is= NULL.\n")); - return EFI_INVALID_PARAMETER; - } + UINT32 LastAttemptStatus; =20 - // - //Set to valid and then if any tests fail it will update this flag. - // - *ImageUpdateable =3D IMAGE_UPDATABLE_VALID; - - if (Image =3D=3D NULL) { - DEBUG((DEBUG_ERROR, "CheckImage - Image Pointer Parameter is NULL.\n")= ); - // - // Not sure if this is needed - // - *ImageUpdateable =3D IMAGE_UPDATABLE_INVALID; - return EFI_INVALID_PARAMETER; - } - - // - // Make sure the image size is correct - // - if (ImageSize !=3D PcdGet32 (PcdBiosRomSize)) { - *ImageUpdateable =3D IMAGE_UPDATABLE_INVALID; - return EFI_INVALID_PARAMETER; - } - - return EFI_SUCCESS; + return FmpDeviceCheckImageWithStatus (Image, ImageSize, ImageUpdateable,= &LastAttemptStatus); } =20 /** diff --git a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDe= viceLibSample/FmpDeviceLib.c b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Cap= sule/Library/FmpDeviceLibSample/FmpDeviceLib.c index db0f238ea534..132b60844ad4 100644 --- a/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib= Sample/FmpDeviceLib.c +++ b/Platform/Intel/Vlv2TbltDevicePkg/Feature/Capsule/Library/FmpDeviceLib= Sample/FmpDeviceLib.c @@ -1,6 +1,6 @@ /** =20 -Copyright (c) 2016, Microsoft Corporation. All rights reserved.
+Copyright (c) Microsoft Corporation.
Copyright (c) 2019, Intel Corporation. All rights reserved.
=20 SPDX-License-Identifier: BSD-2-Clause-Patent @@ -9,6 +9,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent =20 =20 #include +#include +#include #include #include #include @@ -345,6 +347,131 @@ Return Value: }//GetImage() =20 =20 +/** + Updates a firmware device with a new firmware image. This function retu= rns + EFI_UNSUPPORTED if the firmware image is not updatable. If the firmware= image + is updatable, the function should perform the following minimal validati= ons + before proceeding to do the firmware image update. + - Validate that the image is a supported image for this firmware devic= e. + Return EFI_ABORTED if the image is not supported. Additional detail= s + on why the image is not a supported image may be returned in AbortRe= ason. + - 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 up= date + policy. Null if the caller did not specify the policy or use the defaul= t + 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 fi= rmware + image version is older than the current firmware image version or bad im= age + checksum. Sensitive operations such as those wiping the entire firmware= image + and render the device to be non-functional should be encoded in the imag= e + itself rather than passed with the VendorCode. AbortReason enables vend= or to + have the option to provide a more detailed description of the abort reas= on 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-sp= ecific + firmware image update policy. NULL indica= tes + the caller did not specify the policy or u= se 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 firmw= are + image. + @param[out] AbortReason A pointer to a pointer to a Null-terminate= d + Unicode string providing more details on a= n + aborted operation. The buffer is allocated= by + this function with + EFI_BOOT_SERVICES.AllocatePool(). It is t= he + caller's responsibility to free this buffe= r 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 ra= nge of + LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERR= OR_CODE_VALUE to + LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MAX_ERR= OR_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 upda= ted + with the new firmware image. + @retval EFI_ABORTED The operation is aborted. Additional det= ails + 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, OP= TIONAL + IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress, OP= TIONAL + IN UINT32 CapsuleFwVersion, + OUT CHAR16 **AbortReason, + OUT UINT32 *LastAttemptStatus + ) +{ + EFI_STATUS Status =3D EFI_SUCCESS; + UINT32 Updateable =3D 0; + + Status =3D FmpDeviceCheckImageWithStatus (Image, ImageSize, &Updateabl= e, LastAttemptStatus); + if (EFI_ERROR(Status)) + { + DEBUG((DEBUG_ERROR, "SetImageWithStatus - Check Image failed with= %r.\n", Status)); + goto cleanup; + } + + if (Updateable !=3D IMAGE_UPDATABLE_VALID) + { + DEBUG((DEBUG_ERROR, "SetImageWithStatus - Check Image returned th= at the Image was not valid for update. Updatable value =3D 0x%X.\n", Updat= eable)); + Status =3D EFI_ABORTED; + goto cleanup; + } + + if (Progress =3D=3D NULL) + { + DEBUG((DEBUG_ERROR, "SetImageWithStatus - Invalid progress callba= ck\n")); + Status =3D EFI_INVALID_PARAMETER; + goto cleanup; + } + + Status =3D Progress(15); + if (EFI_ERROR(Status)) + { + DEBUG((DEBUG_ERROR, "SetImageWithStatus - Progress Callback faile= d with Status %r.\n", Status)); + } + + { + UINTN p; + + for (p =3D 20; p < 100; p++) { + gBS->Stall (100000); //us =3D 0.1 seconds + Progress (p); + } + } + + //TODO: add support for VendorCode, and AbortReason +cleanup: + if (EFI_ERROR (Status)) { + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERROR_= CODE_VALUE; + } + + return Status; +}// SetImageWithStatus() + + /** Updates the firmware image of the device. =20 @@ -396,51 +523,98 @@ IN UINT32 = CapsuleFwVersion, OUT CHAR16 **AbortReason ) { - EFI_STATUS Status =3D EFI_SUCCESS; - UINT32 Updateable =3D 0; - - Status =3D FmpDeviceCheckImage(Image, ImageSize, &Updateable); - if (EFI_ERROR(Status)) - { - DEBUG((DEBUG_ERROR, "SetImage - Check Image failed with %r.\n", St= atus)); - goto cleanup; - } - - if (Updateable !=3D IMAGE_UPDATABLE_VALID) - { - DEBUG((DEBUG_ERROR, "SetImage - Check Image returned that the Imag= e was not valid for update. Updatable value =3D 0x%X.\n", Updateable)); - Status =3D EFI_ABORTED; - goto cleanup; - } - - if (Progress =3D=3D NULL) - { - DEBUG((DEBUG_ERROR, "SetImage - Invalid progress callback\n")); - Status =3D EFI_INVALID_PARAMETER; - goto cleanup; - } - - Status =3D Progress(15); - if (EFI_ERROR(Status)) - { - DEBUG((DEBUG_ERROR, "SetImage - Progress Callback failed with Stat= us %r.\n", Status)); - } - - { - UINTN p; - - for (p =3D 20; p < 100; p++) { - gBS->Stall (100000); //us =3D 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() =20 =20 +/** + 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 val= id for + a firmware update to the firmware device= . The + following values from the Firmware Manag= ement + 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 las= t attempt + status to report back to the ESRT table = in case + of error. This value will only be checke= d when this + function returns an error. + + The return status code must fall in the = range of + LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_E= RROR_CODE_VALUE to + LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MAX_E= RROR_CODE_VALUE. + + If the value falls outside this range, i= t will be converted + to LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFU= L. + + @retval EFI_SUCCESS The image was successfully checked. Addi= tional + 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 =3D EFI_SUCCESS; + + if (LastAttemptStatus =3D=3D NULL) { + DEBUG ((DEBUG_ERROR, "CheckImageWithStatus - LastAttemptStatus Point= er Parameter is NULL.\n")); + return EFI_INVALID_PARAMETER; + } + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_SUCCESS; + + if (ImageUpdatable =3D=3D NULL) + { + DEBUG((DEBUG_ERROR, "CheckImageWithStatus - ImageUpdatable Pointer= Parameter is NULL.\n")); + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERRO= R_CODE_VALUE; + status =3D EFI_INVALID_PARAMETER; + goto cleanup; + } + + // + //Set to valid and then if any tests fail it will update this flag. + // + *ImageUpdatable =3D IMAGE_UPDATABLE_VALID; + + if (Image =3D=3D NULL) + { + DEBUG((DEBUG_ERROR, "CheckImageWithStatus - Image Pointer Paramete= r is NULL.\n")); + *ImageUpdatable =3D IMAGE_UPDATABLE_INVALID; //not sure if this is= needed + *LastAttemptStatus =3D LAST_ATTEMPT_STATUS_DEVICE_LIBRARY_MIN_ERRO= R_CODE_VALUE; + return EFI_INVALID_PARAMETER; + } + +cleanup: + return status; +}// CheckImageWithStatus() + =20 /** Checks if the firmware image is valid for the device. @@ -465,29 +639,9 @@ IN UINTN ImageSize, OUT UINT32 *ImageUpdateable ) { - EFI_STATUS status =3D EFI_SUCCESS; + UINT32 LastAttemptStatus; =20 - if (ImageUpdateable =3D=3D NULL) - { - DEBUG((DEBUG_ERROR, "CheckImage - ImageUpdateable Pointer Paramete= r is NULL.\n")); - status =3D EFI_INVALID_PARAMETER; - goto cleanup; - } - - // - //Set to valid and then if any tests fail it will update this flag. - // - *ImageUpdateable =3D IMAGE_UPDATABLE_VALID; - - if (Image =3D=3D NULL) - { - DEBUG((DEBUG_ERROR, "CheckImage - Image Pointer Parameter is NULL.= \n")); - *ImageUpdateable =3D IMAGE_UPDATABLE_INVALID; //not sure if this i= s needed - return EFI_INVALID_PARAMETER; - } - -cleanup: - return status; + return FmpDeviceCheckImageWithStatus (Image, ImageSize, ImageUpdateable,= &LastAttemptStatus); }// CheckImage() =20 /** --=20 2.28.0.windows.1