diff options
author | Angelos Mouzakitis <a.mouzakitis@virtualopensystems.com> | 2023-10-10 14:33:42 +0000 |
---|---|---|
committer | Angelos Mouzakitis <a.mouzakitis@virtualopensystems.com> | 2023-10-10 14:33:42 +0000 |
commit | af1a266670d040d2f4083ff309d732d648afba2a (patch) | |
tree | 2fc46203448ddcc6f81546d379abfaeb323575e9 /roms/edk2/FmpDevicePkg | |
parent | e02cda008591317b1625707ff8e115a4841aa889 (diff) |
Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
Diffstat (limited to 'roms/edk2/FmpDevicePkg')
54 files changed, 7914 insertions, 0 deletions
diff --git a/roms/edk2/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.c b/roms/edk2/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.c new file mode 100644 index 000000000..1035fd67d --- /dev/null +++ b/roms/edk2/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.c @@ -0,0 +1,173 @@ +/** @file
+ Provides platform policy services used during a capsule update that uses the
+ services of the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL.
+
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CapsuleUpdatePolicyDxe.h"
+
+///
+/// Handle for the Capsule Update Policy Protocol
+///
+EFI_HANDLE mHandle = NULL;
+
+///
+/// Capsule Update Policy Protocol instance
+///
+EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL mCapsuleUpdatePolicy = {
+ CapsuleUpdatePolicyCheckSystemPower,
+ CapsuleUpdatePolicyCheckSystemThermal,
+ CapsuleUpdatePolicyCheckSystemEnvironment,
+ CapsuleUpdatePolicyIsLowestSupportedVersionCheckRequired,
+ CapsuleUpdatePolicyIsLockFmpDeviceAtLockEventGuidRequired
+};
+
+/**
+ Determine if the system power state supports a capsule update.
+
+ @param[in] This A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL instance.
+ @param[out] Good Returns TRUE if system power state supports a capsule
+ update. Returns FALSE if system power state does not
+ support a capsule update. Return value is only valid if
+ return status is EFI_SUCCESS.
+
+ @retval EFI_SUCCESS Good parameter has been updated with result.
+ @retval EFI_INVALID_PARAMETER Good is NULL.
+ @retval EFI_DEVICE_ERROR System power state can not be determined.
+
+**/
+EFI_STATUS
+EFIAPI
+CapsuleUpdatePolicyCheckSystemPower (
+ IN EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL *This,
+ OUT BOOLEAN *Good
+ )
+{
+ return CheckSystemPower (Good);
+}
+
+
+/**
+ Determines if the system thermal state supports a capsule update.
+
+ @param[in] This A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL instance.
+ @param[out] Good Returns TRUE if system thermal state supports a capsule
+ update. Returns FALSE if system thermal state does not
+ support a capsule update. Return value is only valid if
+ return status is EFI_SUCCESS.
+
+ @retval EFI_SUCCESS Good parameter has been updated with result.
+ @retval EFI_INVALID_PARAMETER Good is NULL.
+ @retval EFI_DEVICE_ERROR System thermal state can not be determined.
+
+**/
+EFI_STATUS
+EFIAPI
+CapsuleUpdatePolicyCheckSystemThermal (
+ IN EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL *This,
+ OUT BOOLEAN *Good
+ )
+{
+ return CheckSystemThermal (Good);
+}
+
+/**
+ Determines if the system environment state supports a capsule update.
+
+ @param[in] This A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL instance.
+ @param[out] Good Returns TRUE if system environment state supports a capsule
+ update. Returns FALSE if system environment state does not
+ support a capsule update. Return value is only valid if
+ return status is EFI_SUCCESS.
+
+ @retval EFI_SUCCESS Good parameter has been updated with result.
+ @retval EFI_INVALID_PARAMETER Good is NULL.
+ @retval EFI_DEVICE_ERROR System environment state can not be determined.
+
+**/
+EFI_STATUS
+EFIAPI
+CapsuleUpdatePolicyCheckSystemEnvironment (
+ IN EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL *This,
+ OUT BOOLEAN *Good
+ )
+{
+ return CheckSystemEnvironment (Good);
+}
+
+/**
+ Determines if the Lowest Supported Version checks should be performed. The
+ expected result from this function is TRUE. A platform can choose to return
+ FALSE (e.g. during manufacturing or servicing) to allow a capsule update to a
+ version below the current Lowest Supported Version.
+
+ @param[in] This A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL instance.
+
+ @retval TRUE The lowest supported version check is required.
+ @retval FALSE Do not perform lowest support version check.
+
+**/
+BOOLEAN
+EFIAPI
+CapsuleUpdatePolicyIsLowestSupportedVersionCheckRequired (
+ IN EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL *This
+ )
+{
+ return IsLowestSupportedVersionCheckRequired ();
+}
+
+/**
+ Determines if the FMP device should be locked when the event specified by
+ PcdFmpDeviceLockEventGuid is signaled. The expected result from this function
+ is TRUE so the FMP device is always locked. A platform can choose to return
+ FALSE (e.g. during manufacturing) to allow FMP devices to remain unlocked.
+
+ @param[in] This A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL instance.
+
+ @retval TRUE The FMP device lock action is required at lock event guid.
+ @retval FALSE Do not perform FMP device lock at lock event guid.
+
+**/
+BOOLEAN
+EFIAPI
+CapsuleUpdatePolicyIsLockFmpDeviceAtLockEventGuidRequired (
+ IN EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL *This
+ )
+{
+ return IsLockFmpDeviceAtLockEventGuidRequired ();
+}
+
+/**
+ The user Entry Point for module CapsuleUpdatePolicyDxe. The user code starts
+ with this function.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+CapsuleUpdatePolicyInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEdkiiCapsuleUpdatePolicyProtocolGuid);
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mHandle,
+ &gEdkiiCapsuleUpdatePolicyProtocolGuid, &mCapsuleUpdatePolicy,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/roms/edk2/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.h b/roms/edk2/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.h new file mode 100644 index 000000000..1be15a40d --- /dev/null +++ b/roms/edk2/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.h @@ -0,0 +1,140 @@ +/** @file
+ Provides platform policy services used during a capsule update that uses the
+ services of the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL.
+
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __CAPSULE_UPDATE_POLICY_DXE_H__
+#define __CAPSULE_UPDATE_POLICY_DXE_H__
+
+#include <PiDxe.h>
+
+#include <Protocol/CapsuleUpdatePolicy.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/CapsuleUpdatePolicyLib.h>
+
+/**
+ Determine if the system power state supports a capsule update.
+
+ @param[in] This A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL instance.
+ @param[out] Good Returns TRUE if system power state supports a capsule
+ update. Returns FALSE if system power state does not
+ support a capsule update. Return value is only valid if
+ return status is EFI_SUCCESS.
+
+ @retval EFI_SUCCESS Good parameter has been updated with result.
+ @retval EFI_INVALID_PARAMETER Good is NULL.
+ @retval EFI_DEVICE_ERROR System power state can not be determined.
+
+**/
+EFI_STATUS
+EFIAPI
+CapsuleUpdatePolicyCheckSystemPower (
+ IN EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL *This,
+ OUT BOOLEAN *Good
+ );
+
+/**
+ Determines if the system thermal state supports a capsule update.
+
+ @param[in] This A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL instance.
+ @param[out] Good Returns TRUE if system thermal state supports a capsule
+ update. Returns FALSE if system thermal state does not
+ support a capsule update. Return value is only valid if
+ return status is EFI_SUCCESS.
+
+ @retval EFI_SUCCESS Good parameter has been updated with result.
+ @retval EFI_INVALID_PARAMETER Good is NULL.
+ @retval EFI_DEVICE_ERROR System thermal state can not be determined.
+
+**/
+EFI_STATUS
+EFIAPI
+CapsuleUpdatePolicyCheckSystemThermal (
+ IN EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL *This,
+ OUT BOOLEAN *Good
+ );
+
+/**
+ Determines if the system environment state supports a capsule update.
+
+ @param[in] This A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL instance.
+ @param[out] Good Returns TRUE if system environment state supports a capsule
+ update. Returns FALSE if system environment state does not
+ support a capsule update. Return value is only valid if
+ return status is EFI_SUCCESS.
+
+ @retval EFI_SUCCESS Good parameter has been updated with result.
+ @retval EFI_INVALID_PARAMETER Good is NULL.
+ @retval EFI_DEVICE_ERROR System environment state can not be determined.
+
+**/
+EFI_STATUS
+EFIAPI
+CapsuleUpdatePolicyCheckSystemEnvironment (
+ IN EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL *This,
+ OUT BOOLEAN *Good
+ );
+
+/**
+ Determines if the Lowest Supported Version checks should be performed. The
+ expected result from this function is TRUE. A platform can choose to return
+ FALSE (e.g. during manufacturing or servicing) to allow a capsule update to a
+ version below the current Lowest Supported Version.
+
+ @param[in] This A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL instance.
+
+ @retval TRUE The lowest supported version check is required.
+ @retval FALSE Do not perform lowest support version check.
+
+**/
+BOOLEAN
+EFIAPI
+CapsuleUpdatePolicyIsLowestSupportedVersionCheckRequired (
+ IN EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL *This
+ );
+
+/**
+ Determines if the FMP device should be locked when the event specified by
+ PcdFmpDeviceLockEventGuid is signaled. The expected result from this function
+ is TRUE so the FMP device is always locked. A platform can choose to return
+ FALSE (e.g. during manufacturing) to allow FMP devices to remain unlocked.
+
+ @param[in] This A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL instance.
+
+ @retval TRUE The FMP device lock action is required at lock event guid.
+ @retval FALSE Do not perform FMP device lock at lock event guid.
+
+**/
+BOOLEAN
+EFIAPI
+CapsuleUpdatePolicyIsLockFmpDeviceAtLockEventGuidRequired (
+ IN EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL *This
+ );
+
+/**
+ The user Entry Point for module CapsuleUpdatePolicyDxe. The user code starts
+ with this function.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+CapsuleUpdatePolicyInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+#endif
diff --git a/roms/edk2/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.inf b/roms/edk2/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.inf new file mode 100644 index 000000000..5ed7086b9 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.inf @@ -0,0 +1,48 @@ +## @file
+# Produce the Capsule Update Policy Protocol using the services of the Capsule
+# Update Policy Library.
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = CapsuleUpdatePolicyDxe
+ MODULE_UNI_FILE = CapsuleUpdatePolicyDxe.uni
+ FILE_GUID = 86F67A12-2E32-44FC-8D6C-7901E2B5649A
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = CapsuleUpdatePolicyInitialize
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[Sources]
+ CapsuleUpdatePolicyDxe.c
+ CapsuleUpdatePolicyDxe.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ FmpDevicePkg/FmpDevicePkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ BaseLib
+ DebugLib
+ UefiBootServicesTableLib
+ CapsuleUpdatePolicyLib
+
+[Protocols]
+ gEdkiiCapsuleUpdatePolicyProtocolGuid ## PRODUCES
+
+[Depex]
+ TRUE
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ CapsuleUpdatePolicyDxeExtra.uni
diff --git a/roms/edk2/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.uni b/roms/edk2/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.uni new file mode 100644 index 000000000..12f50c0f4 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.uni @@ -0,0 +1,14 @@ +// /** @file
+// Produce the Capsule Update Policy Protocol using the services of the Capsule
+// Update Policy Library.
+//
+// Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_MODULE_ABSTRACT #language en-US "Produce the Capsule Update Policy Protocol using the services of the Capsule Update Policy Library"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Produce the Capsule Update Policy Protocol using the services of the Capsule Update Policy Library."
+
diff --git a/roms/edk2/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxeExtra.uni b/roms/edk2/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxeExtra.uni new file mode 100644 index 000000000..46d8f34cf --- /dev/null +++ b/roms/edk2/FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxeExtra.uni @@ -0,0 +1,14 @@ +// /** @file
+// CapsuleUpdatePolicyDxe Localized Strings and Content
+//
+// Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"Capsule Update Policy DXE Driver"
+
+
diff --git a/roms/edk2/FmpDevicePkg/FmpDevicePkg.ci.yaml b/roms/edk2/FmpDevicePkg/FmpDevicePkg.ci.yaml new file mode 100644 index 000000000..1b3e21873 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/FmpDevicePkg.ci.yaml @@ -0,0 +1,68 @@ +## @file
+# CI configuration for FmpDevicePkg
+#
+# Copyright (c) Microsoft Corporation
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+{
+ "LicenseCheck": {
+ "IgnoreFiles": []
+ },
+ "EccCheck": {
+ ## Exception sample looks like below:
+ ## "ExceptionList": [
+ ## "<ErrorID>", "<KeyWord>"
+ ## ]
+ "ExceptionList": [
+ ],
+ ## Both file path and directory path are accepted.
+ "IgnoreFiles": [
+ ]
+ },
+ "CompilerPlugin": {
+ "DscPath": "FmpDevicePkg.dsc"
+ },
+ "HostUnitTestCompilerPlugin": {
+ "DscPath": "Test/FmpDeviceHostPkgTest.dsc"
+ },
+ "CharEncodingCheck": {
+ "IgnoreFiles": []
+ },
+ "DependencyCheck": {
+ "AcceptableDependencies": [
+ "MdePkg/MdePkg.dec",
+ "MdeModulePkg/MdeModulePkg.dec",
+ "FmpDevicePkg/FmpDevicePkg.dec",
+ "CryptoPkg/CryptoPkg.dec"
+ ],
+ "AcceptableDependencies-HOST_APPLICATION":[
+ "UnitTestFrameworkPkg/UnitTestFrameworkPkg.dec"
+ ],
+ "IgnoreInf": []
+ },
+ "DscCompleteCheck": {
+ "DscPath": "FmpDevicePkg.dsc",
+ "IgnoreInf": []
+ },
+ "HostUnitTestDscCompleteCheck": {
+ "IgnoreInf": [],
+ "DscPath": "Test/FmpDeviceHostPkgTest.dsc"
+ },
+ "GuidCheck": {
+ "IgnoreGuidName": [],
+ "IgnoreGuidValue": [],
+ "IgnoreFoldersAndFiles": []
+ },
+ "LibraryClassCheck": {
+ "IgnoreHeaderFile": []
+ },
+ "SpellCheck": {
+ "ExtendWords": [
+ "FMPSTATE",
+ ]
+ },
+ "Defines": {
+ "BLD_*_CONTINUOUS_INTEGRATION": "TRUE",
+ }
+}
diff --git a/roms/edk2/FmpDevicePkg/FmpDevicePkg.dec b/roms/edk2/FmpDevicePkg/FmpDevicePkg.dec new file mode 100644 index 000000000..cab63f5a4 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/FmpDevicePkg.dec @@ -0,0 +1,146 @@ +## @file
+# Firmware Management Protocol Device Package
+#
+# This package provides an implementation of a Firmware Management Protocol
+# instance that supports the update of firmware storage devices using UEFI
+# Capsules. The behavior of the Firmware Management Protocol instance is
+# customized using libraries and PCDs.
+#
+# Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
+# Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ DEC_SPECIFICATION = 0x00010005
+ PACKAGE_NAME = FmpDevicePkg
+ PACKAGE_UNI_FILE = FmpDevicePkg.uni
+ PACKAGE_GUID = 080b5b4f-27c6-11e8-84d1-f8597177a00a
+ PACKAGE_VERSION = 0.1
+
+[Includes]
+ Include
+
+[Includes.Common.Private]
+ PrivateInclude
+
+[LibraryClasses]
+ ## @libraryclass Provides platform policy services used during a capsule
+ # update.
+ CapsuleUpdatePolicyLib|Include/Library/CapsuleUpdatePolicyLib.h
+
+ ## @libraryclass Provides firmware device specific services to support
+ # updates of a firmware image stored in a firmware device.
+ FmpDeviceLib|Include/Library/FmpDeviceLib.h
+
+ ## @libraryclass Provides generic services to support capsule dependency
+ # expression evaluation.
+ FmpDependencyLib|Include/Library/FmpDependencyLib.h
+
+ ## @libraryclass Provides platform specific services to support dependency
+ # check during update of firmware image.
+ FmpDependencyCheckLib|Include/Library/FmpDependencyCheckLib.h
+
+ ## @libraryclass Provides firmware device specific services to support
+ # saving dependency to firmware device and getting dependency
+ # from firmware device.
+ FmpDependencyDeviceLib|Include/Library/FmpDependencyDeviceLib.h
+
+[LibraryClasses.Common.Private]
+ ## @libraryclass Provides services to retrieve values from a capsule's FMP
+ # Payload Header. The structure is not included in the
+ # library class. Instead, services are provided to retrieve
+ # information from the FMP Payload Header. If information is
+ # added to the FMP Payload Header, then new services may be
+ # added to this library class to retrieve the new information.
+ FmpPayloadHeaderLib|PrivateInclude/Library/FmpPayloadHeaderLib.h
+
+[Guids]
+ ## Firmware Management Protocol Device Package Token Space GUID
+ gFmpDevicePkgTokenSpaceGuid = { 0x40b2d964, 0xfe11, 0x40dc, { 0x82, 0x83, 0x2e, 0xfb, 0xda, 0x29, 0x53, 0x56 } }
+
+[Protocols.Common.Private]
+ ## Capsule Update Policy Protocol
+ gEdkiiCapsuleUpdatePolicyProtocolGuid = { 0x487784c5, 0x6299, 0x4ba6, { 0xb0, 0x96, 0x5c, 0xc5, 0x27, 0x7c, 0xf7, 0x57 } }
+
+[PcdsFeatureFlag]
+ ## Indicates if the Firmware Management Protocol supports access to
+ # to a firmware storage device. If set to FALSE, then only GetImageInfo()
+ # is supported. This is used by FMP drivers that require the smallest
+ # possible Firmware Management Protocol implementation that supports
+ # advertising the updatable firmware device in the ESRT.<BR>
+ # TRUE - All Firmware Management Protocol services supported.<BR>
+ # FALSE - Firmware Management Protocol returns EFI_UNSUPPORTED for
+ # all services except GetImageInfo().<BR>
+ # @Prompt Firmware Device Storage Access Enabled.
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceStorageAccessEnable|TRUE|BOOLEAN|0x40000011
+
+[PcdsFixedAtBuild]
+ ## The SHA-256 hash of a PKCS7 test key that is used to detect if a test key
+ # is being used to authenticate capsules. Test key detection is disabled by
+ # setting the value to {0}.
+ # @Prompt SHA-256 hash of PKCS7 test key.
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceTestKeySha256Digest|{0x2E, 0x97, 0x89, 0x1B, 0xDB, 0xE7, 0x08, 0xAA, 0x8C, 0xB2, 0x8F, 0xAD, 0x20, 0xA9, 0x83, 0xC7, 0x84, 0x7D, 0x4F, 0xEE, 0x48, 0x25, 0xE9, 0x4D, 0x39, 0xFA, 0x34, 0x9A, 0xB8, 0xB1, 0xC4, 0x26}|VOID*|0x40000009
+
+[PcdsFixedAtBuild, PcdsPatchableInModule]
+ ## The color of the progress bar during a firmware update. Each firmware
+ # device can set its own color. The default color is white.<BR><BR>
+ # Bits 7..0 - Red<BR>
+ # Bits 15..8 - Green<BR>
+ # Bits 23..16 - Blue<BR>
+ # @Prompt Firmware Device Progress Bar Color.
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceProgressColor|0x00FFFFFF|UINT32|0x40000004
+
+ ## The Null-terminated Unicode string used to fill in the ImageIdName field of
+ # the EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the
+ # GetImageInfo() service of the Firmware Management Protocol for the firmware
+ # device. An ImageIdName string must be provided for each firmware device.
+ # The default value is an empty string.
+ # @Prompt Firmware Device ImageIdName string.
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageIdName|L""|VOID*|0x40000007
+
+ ## The build time value used to fill in the LowestSupportedVersion field of
+ # the EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the
+ # GetImageInfo() service of the Firmware Management Protocol. This value is
+ # only used if the firmware device does not provide a method to report the
+ # lowest supported version value from the current firmware image and the
+ # UEFI variable used to provide the lowest supported version value does not
+ # exist. The default value is 0.
+ # @Prompt Build Time Firmware Device Lowest Support Version.
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceBuildTimeLowestSupportedVersion|0x0|UINT32|0x4000000C
+
+ ## The time in seconds to arm a watchdog timer during the update of a firmware
+ # device. The watchdog is re-armed each time the FmpDeviceLib calls the
+ # Progress() function passed into FmpDeviceSetImage() function. The
+ # FmpDeviceLib calls Progress() to update the percent completion of a
+ # firmware update. If the watchdog timer expires, the system reboots. A
+ # value of 0 disables the watchdog timer. The default value is 0 (watchdog
+ # disabled).
+ # @Prompt Firmware Device Watchdog Time in Seconds.
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceProgressWatchdogTimeInSeconds|0x0|UINT8|0x4000000D
+
+ ## The Image Type ID to use if one is not provided by FmpDeviceLib. If this
+ # PCD is not a valid GUID value, then gEfiCallerIdGuid is used.
+ # @Prompt Firmware Device Image Type ID
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageTypeIdGuid|{0}|VOID*|0x40000010
+
+[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
+ ## One or more PKCS7 certificates used to verify a firmware device capsule
+ # update image. Encoded using the Variable-Length Opaque Data format of RFC
+ # 4506 External Data Representation Standard (XDR). The default value is
+ # empty with 0 certificates.
+ # @Prompt One or more XDR encoded PKCS7 certificates used to verify firmware device capsule update images.
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr|{0x0}|VOID*|0x4000000E
+
+ ## An event GUID that locks the firmware device when the event is signaled.
+ # If this PCD is not a valid GUID value, then the firmware device is locked
+ # when gEfiEndOfDxeEventGroupGuid (End of DXE Phase) is signaled. The
+ # default value is empty, so by default the firmware device is locked at the
+ # end of the DXE phase.
+ # @Prompt Firmware Device Lock Event GUID.
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceLockEventGuid|{0}|VOID*|0x4000000F
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ FmpDevicePkgExtra.uni
diff --git a/roms/edk2/FmpDevicePkg/FmpDevicePkg.dsc b/roms/edk2/FmpDevicePkg/FmpDevicePkg.dsc new file mode 100644 index 000000000..bdb73f282 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/FmpDevicePkg.dsc @@ -0,0 +1,179 @@ +## @file
+# Firmware Management Protocol Device Package
+#
+# This package provides an implementation of a Firmware Management Protocol
+# instance that supports the update of firmware storage devices using UEFI
+# Capsules. The behavior of the Firmware Management Protocol instance is
+# customized using libraries and PCDs.
+#
+# Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
+# Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ PLATFORM_NAME = FmpDevicePkg
+ PLATFORM_GUID = 0af3d540-27c6-11e8-828b-f8597177a00a
+ PLATFORM_VERSION = 0.1
+ DSC_SPECIFICATION = 0x00010005
+ OUTPUT_DIRECTORY = Build/FmpDevicePkg
+ SUPPORTED_ARCHITECTURES = IA32|X64|ARM|AARCH64|RISCV64
+ BUILD_TARGETS = DEBUG|RELEASE|NOOPT
+ SKUID_IDENTIFIER = DEFAULT
+
+ #
+ # Define ESRT GUIDs for Firmware Management Protocol instances
+ #
+ DEFINE SYSTEM_FMP_ESRT_GUID = B461B3BD-E62A-4A71-841C-50BA4E500267
+ DEFINE DEVICE_FMP_ESRT_GUID = 226034C4-8B67-4536-8653-D6EE7CE5A316
+
+ #
+ # TRUE - Build FmpDxe module for with storage access enabled
+ # FALSE - Build FmpDxe module for with storage access disabled
+ #
+ DEFINE DEVICE_FMP_STORAGE_ACCESS_ENABLE = TRUE
+
+!include UnitTestFrameworkPkg/UnitTestFrameworkPkgTarget.dsc.inc
+
+[LibraryClasses]
+ UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+ UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+ UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+ UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+ MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+ DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+ BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+ BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+ PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+ DebugLib|MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf
+ DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+!ifdef CONTINUOUS_INTEGRATION
+ BaseCryptLib|CryptoPkg/Library/BaseCryptLibNull/BaseCryptLibNull.inf
+!else
+ IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+ OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+ BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+!endif
+ FmpAuthenticationLib|SecurityPkg/Library/FmpAuthenticationLibPkcs7/FmpAuthenticationLibPkcs7.inf
+ CapsuleUpdatePolicyLib|FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.inf
+ FmpPayloadHeaderLib|FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLibV1.inf
+ FmpDeviceLib|FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLibNull.inf
+ FmpDependencyLib|FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.inf
+ FmpDependencyCheckLib|FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.inf
+ FmpDependencyDeviceLib|FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLibNull.inf
+ TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
+
+[LibraryClasses.ARM, LibraryClasses.AARCH64]
+ #
+ # It is not possible to prevent the ARM compiler for generic intrinsic functions.
+ # This library provides the intrinsic functions generate by a given compiler.
+ # [LibraryClasses.ARM, LibraryClasses.AARCH64] and NULL mean link this library
+ # into all ARM and AARCH64 images.
+ #
+ NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+
+ # Add support for stack protector
+ NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
+
+[LibraryClasses.ARM]
+ ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf
+
+[PcdsPatchableInModule]
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageTypeIdGuid|{0}
+
+[Components]
+ #
+ # Libraries
+ #
+ FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.inf
+ FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolicyLibOnProtocol.inf
+ FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLibV1.inf
+ FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLibNull.inf
+ FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.inf
+ FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.inf
+ FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.inf
+ FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLibNull.inf
+ FmpDevicePkg/FmpDxe/FmpDxeLib.inf
+
+ #
+ # Modules
+ #
+ FmpDevicePkg/CapsuleUpdatePolicyDxe/CapsuleUpdatePolicyDxe.inf {
+ <LibraryClasses>
+ CapsuleUpdatePolicyLib|FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.inf
+ }
+ FmpDevicePkg/FmpDxe/FmpDxe.inf {
+ <Defines>
+ #
+ # FILE_GUID is used as ESRT GUID
+ #
+ FILE_GUID = $(SYSTEM_FMP_ESRT_GUID)
+ <PcdsFixedAtBuild>
+ #
+ # Unicode name string that is used to populate FMP Image Descriptor for this capsule update module
+ #
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageIdName|L"Sample Firmware Device"
+ #
+ # Certificates used to authenticate capsule update image
+ #
+ !include BaseTools/Source/Python/Pkcs7Sign/TestRoot.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
+ <PcdsPatchableInModule>
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageTypeIdGuid|{GUID("$(SYSTEM_FMP_ESRT_GUID)")}
+ <LibraryClasses>
+ #
+ # Use CapsuleUpdatePolicyLib that calls the Capsule Update Policy Protocol.
+ # Depends on the CapsuleUpdatePolicyDxe module to produce the protocol.
+ # Required for FmpDxe modules that are intended to be platform independent.
+ #
+ CapsuleUpdatePolicyLib|FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolicyLibOnProtocol.inf
+ }
+
+ FmpDevicePkg/FmpDxe/FmpDxe.inf {
+ <Defines>
+ #
+ # FILE_GUID is used as ESRT GUID
+ #
+ FILE_GUID = $(DEVICE_FMP_ESRT_GUID)
+ <PcdsFeatureFlag>
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceStorageAccessEnable|$(DEVICE_FMP_STORAGE_ACCESS_ENABLE)
+ <PcdsFixedAtBuild>
+!if $(DEVICE_FMP_STORAGE_ACCESS_ENABLE) == FALSE
+ #
+ # Disable test key detection
+ #
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceTestKeySha256Digest|{0}
+!endif
+ #
+ # Unicode name string that is used to populate FMP Image Descriptor for this capsule update module
+ #
+!if $(DEVICE_FMP_STORAGE_ACCESS_ENABLE) == TRUE
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageIdName|L"Sample Firmware Device"
+!else
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageIdName|L"Sample Firmware Device No Storage Access"
+!endif
+ #
+ # Certificates used to authenticate capsule update image
+ #
+ !include BaseTools/Source/Python/Pkcs7Sign/TestRoot.cer.gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr.inc
+ <PcdsPatchableInModule>
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageTypeIdGuid|{GUID("$(DEVICE_FMP_ESRT_GUID)")}
+ <LibraryClasses>
+ #
+ # Directly use a platform specific CapsuleUpdatePolicyLib instance.
+ # Only works for FmpDxe modules that are build from sources and included
+ # in a system firmware image.
+ #
+ CapsuleUpdatePolicyLib|FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.inf
+ }
+
+ #
+ # Add UEFI Target Based Unit Tests
+ #
+ FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/FmpDependencyLibUnitTestsUefi.inf
+
+[BuildOptions]
+ *_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES
diff --git a/roms/edk2/FmpDevicePkg/FmpDevicePkg.uni b/roms/edk2/FmpDevicePkg/FmpDevicePkg.uni new file mode 100644 index 000000000..263f88078 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/FmpDevicePkg.uni @@ -0,0 +1,83 @@ +// /** @file
+// Firmware Management Protocol Device Package
+//
+// This package provides an implementation of a Firmware Management Protocol
+// instance that supports the update of firmware storage devices using UEFI
+// Capsules. The behavior of the Firmware Management Protocol instance is
+// customized using libraries and PCDs.
+//
+// Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PACKAGE_ABSTRACT #language en-US "Firmware Management Protocol Software Development Kit"
+
+#string STR_PACKAGE_DESCRIPTION #language en-US "This package provides libraries that support the implementation of a module that produces the Firmware Management Protocol to support the update of a system firmware component."
+
+#string STR_gFmpDevicePkgTokenSpaceGuid_PcdFmpDeviceStorageAccessEnable_PROMPT #language en-US "Firmware Device Storage Access Enabled."
+#string STR_gFmpDevicePkgTokenSpaceGuid_PcdFmpDeviceStorageAccessEnable_HELP #language en-US "Indicates if the Firmware Management Protocol supports access to"
+ "to a firmware storage device. If set to FALSE, then only GetImageInfo()"
+ "is supported. This is used by FMP drivers that require the smallest"
+ "possible Firmware Management Protocol implementation that supports"
+ "advertising the updatable firmware device in the ESRT.<BR>"
+ " TRUE - All Firmware Management Protocol services supported.<BR>"
+ " FALSE - Firmware Management Protocol returns EFI_UNSUPPORTED for"
+ " all services except GetImageInfo().<BR>"
+
+#string STR_gFmpDevicePkgTokenSpaceGuid_PcdFmpDeviceTestKeySha256Digest_PROMPT #language en-US "SHA-256 hash of PKCS7 test key."
+#string STR_gFmpDevicePkgTokenSpaceGuid_PcdFmpDeviceTestKeySha256Digest_HELP #language en-US "The SHA-256 hash of a PKCS7 test key that is used to detect if a test key"
+ "is being used to authenticate capsules. Test key detection can be disabled"
+ "by setting the value to {0}"
+
+#string STR_gFmpDevicePkgTokenSpaceGuid_PcdFmpDeviceProgressColor_PROMPT #language en-US "Firmware Device Progress Bar Color."
+#string STR_gFmpDevicePkgTokenSpaceGuid_PcdFmpDeviceProgressColor_HELP #language en-US "The color of the progress bar during a firmware update. Each firmware"
+ "device can set its own color. The default color is white.<BR><BR>\n"
+ "Bits 7..0 - Red<BR>\n"
+ "Bits 15..8 - Green<BR>\n"
+ "Bits 23..16 - Blue<BR>\n"
+
+#string STR_gFmpDevicePkgTokenSpaceGuid_PcdFmpDeviceImageIdName_PROMPT #language en-US "Firmware Device ImageIdName string."
+#string STR_gFmpDevicePkgTokenSpaceGuid_PcdFmpDeviceImageIdName_HELP #language en-US "The Null-terminated Unicode string used to fill in the ImageIdName field of"
+ "the EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the"
+ "GetImageInfo() service of the Firmware Management Protocol for the firmware"
+ "device. An ImageIdName string must be provided for each firmware device."
+ "The default value is an empty string."
+
+#string STR_gFmpDevicePkgTokenSpaceGuid_PcdFmpDeviceBuildTimeLowestSupportedVersion_PROMPT #language en-US "Build Time Firmware Device Lowest Support Version."
+#string STR_gFmpDevicePkgTokenSpaceGuid_PcdFmpDeviceBuildTimeLowestSupportedVersion_HELP #language en-US "The build time value used to fill in the LowestSupportedVersion field of"
+ "the EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the"
+ "GetImageInfo() service of the Firmware Management Protocol. This value is"
+ "only used if the firmware device does not provide a method to report the"
+ "lowest supported version value from the current firmware image and the"
+ "UEFI variable used to provide the lowest supported version value does not"
+ "exist. The default value is 0."
+
+#string STR_gFmpDevicePkgTokenSpaceGuid_PcdFmpDeviceProgressWatchdogTimeInSeconds_PROMPT #language en-US "Firmware Device Watchdog Time in Seconds."
+#string STR_gFmpDevicePkgTokenSpaceGuid_PcdFmpDeviceProgressWatchdogTimeInSeconds_HELP #language en-US "Indicates the time in seconds to arm a watchdog timer during the update of"
+ "a firmware device. The watchdog is re-armed each time the FmpDeviceLib"
+ "calls the Progress() function passed into FmpDeviceSetImage() function."
+ "The FmpDeviceLib calls Progress() to update the percent completion of a"
+ "firmware update. If the watchdog timer expires, the system reboots. A"
+ "value of 0 disables the watchdog timer. The default value is 0 (watchdog"
+ "disabled)."
+
+#string STR_gFmpDevicePkgTokenSpaceGuid_PcdFmpDeviceImageTypeIdGuid_PROMPT #language en-US "Firmware Device Image Type ID."
+#string STR_gFmpDevicePkgTokenSpaceGuid_PcdFmpDeviceImageTypeIdGuid_HELP #language en-US "The Image Type ID to use if one is not provided by FmpDeviceLib. If this"
+ "PCD is not a valid GUID value, then gEfiCallerIdGuid is used."
+
+#string STR_gFmpDevicePkgTokenSpaceGuid_PcdFmpDevicePkcs7CertBufferXdr_PROMPT #language en-US "One or more XDR encoded PKCS7 certificates used to verify firmware device capsule update images"
+#string STR_gFmpDevicePkgTokenSpaceGuid_PcdFmpDevicePkcs7CertBufferXdr_HELP #language en-US "Provides one or more PKCS7 certificates used to verify a firmware device"
+ "capsule update image. This PCD is encoded using the Variable-Length Opaque"
+ "Data format of RFC 4506 External Data Representation Standard (XDR)."
+ "The default value is empty with 0 certificates."
+
+#string STR_gFmpDevicePkgTokenSpaceGuid_PcdFmpDeviceLockEventGuid_PROMPT #language en-US "Firmware Device Lock Event GUID."
+#string STR_gFmpDevicePkgTokenSpaceGuid_PcdFmpDeviceLockEventGuid_HELP #language en-US "An event GUID that locks the firmware device when the event is signaled."
+ "If this PCD is not a valid GUID value, then the firmware device is locked"
+ "when gEfiEndOfDxeEventGroupGuid (End of DXE Phase) is signaled. The"
+ "default value is empty, so by default the firmware device is locked at the"
+ "end of the DXE phase."
+
+
diff --git a/roms/edk2/FmpDevicePkg/FmpDevicePkgExtra.uni b/roms/edk2/FmpDevicePkg/FmpDevicePkgExtra.uni new file mode 100644 index 000000000..3d05570ce --- /dev/null +++ b/roms/edk2/FmpDevicePkg/FmpDevicePkgExtra.uni @@ -0,0 +1,12 @@ +// /** @file
+// Firmware Management Protocol Device Package Localized Strings and Content.
+//
+// Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_PACKAGE_NAME
+#language en-US
+"Firmware Management Protocol Device package"
diff --git a/roms/edk2/FmpDevicePkg/FmpDxe/DetectTestKey.c b/roms/edk2/FmpDevicePkg/FmpDxe/DetectTestKey.c new file mode 100644 index 000000000..0e10d5ee1 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/FmpDxe/DetectTestKey.c @@ -0,0 +1,145 @@ +/** @file
+ Detects if PcdFmpDevicePkcs7CertBufferXdr contains a test key.
+
+ Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "FmpDxe.h"
+
+/**
+ Check to see if any of the keys in PcdFmpDevicePkcs7CertBufferXdr matches
+ the test key. PcdFmpDeviceTestKeySha256Digest contains the SHA256 hash of
+ the test key. For each key in PcdFmpDevicePkcs7CertBufferXdr, compute the
+ SHA256 hash and compare it to PcdFmpDeviceTestKeySha256Digest. If the
+ SHA256 hash matches or there is then error computing the SHA256 hash, then
+ set PcdTestKeyUsed to TRUE. Skip this check if PcdTestKeyUsed is already
+ TRUE or PcdFmpDeviceTestKeySha256Digest is not exactly SHA256_DIGEST_SIZE
+ bytes.
+**/
+VOID
+DetectTestKey (
+ VOID
+ )
+{
+ BOOLEAN TestKeyUsed;
+ UINTN PublicKeyDataLength;
+ UINT8 *PublicKeyDataXdr;
+ UINT8 *PublicKeyDataXdrEnd;
+ VOID *HashContext;
+ UINT8 Digest[SHA256_DIGEST_SIZE];
+ UINTN TestKeyDigestSize;
+
+ //
+ // If PcdFmpDeviceTestKeySha256Digest is not exactly SHA256_DIGEST_SIZE bytes,
+ // then skip the test key detection.
+ //
+ TestKeyDigestSize = PcdGetSize (PcdFmpDeviceTestKeySha256Digest);
+ if (TestKeyDigestSize != SHA256_DIGEST_SIZE) {
+ return;
+ }
+
+ //
+ // If PcdTestKeyUsed is already TRUE, then skip test key detection
+ //
+ TestKeyUsed = PcdGetBool (PcdTestKeyUsed);
+ if (TestKeyUsed) {
+ return;
+ }
+
+ //
+ // If PcdFmpDevicePkcs7CertBufferXdr is invalid, then skip test key detection
+ //
+ PublicKeyDataXdr = PcdGetPtr (PcdFmpDevicePkcs7CertBufferXdr);
+ PublicKeyDataXdrEnd = PublicKeyDataXdr + PcdGetSize (PcdFmpDevicePkcs7CertBufferXdr);
+ if (PublicKeyDataXdr == NULL || PublicKeyDataXdr == PublicKeyDataXdrEnd) {
+ return;
+ }
+
+ //
+ // Allocate hash context buffer required for SHA 256
+ //
+ HashContext = AllocatePool (Sha256GetContextSize ());
+ if (HashContext == NULL) {
+ TestKeyUsed = TRUE;
+ }
+
+ //
+ // Loop through all keys in PcdFmpDevicePkcs7CertBufferXdr
+ //
+ while (!TestKeyUsed && PublicKeyDataXdr < PublicKeyDataXdrEnd) {
+ if (PublicKeyDataXdr + sizeof (UINT32) > PublicKeyDataXdrEnd) {
+ //
+ // Key data extends beyond end of PCD
+ //
+ break;
+ }
+ //
+ // Read key length stored in big endian format
+ //
+ PublicKeyDataLength = SwapBytes32 (*(UINT32 *)(PublicKeyDataXdr));
+ //
+ // Point to the start of the key data
+ //
+ PublicKeyDataXdr += sizeof (UINT32);
+ if (PublicKeyDataXdr + PublicKeyDataLength > PublicKeyDataXdrEnd) {
+ //
+ // Key data extends beyond end of PCD
+ //
+ break;
+ }
+
+ //
+ // Hash public key from PcdFmpDevicePkcs7CertBufferXdr using SHA256.
+ // If error occurs computing SHA256, then assume test key is in use.
+ //
+ ZeroMem (Digest, SHA256_DIGEST_SIZE);
+ if (!Sha256Init (HashContext)) {
+ TestKeyUsed = TRUE;
+ break;
+ }
+ if (!Sha256Update (HashContext, PublicKeyDataXdr, PublicKeyDataLength)) {
+ TestKeyUsed = TRUE;
+ break;
+ }
+ if (!Sha256Final (HashContext, Digest)) {
+ TestKeyUsed = TRUE;
+ break;
+ }
+
+ //
+ // Check if SHA256 hash of public key matches SHA256 hash of test key
+ //
+ if (CompareMem (Digest, PcdGetPtr (PcdFmpDeviceTestKeySha256Digest), SHA256_DIGEST_SIZE) == 0) {
+ TestKeyUsed = TRUE;
+ break;
+ }
+
+ //
+ // Point to start of next key
+ //
+ PublicKeyDataXdr += PublicKeyDataLength;
+ PublicKeyDataXdr = (UINT8 *)ALIGN_POINTER (PublicKeyDataXdr, sizeof (UINT32));
+ }
+
+ //
+ // Free hash context buffer required for SHA 256
+ //
+ if (HashContext != NULL) {
+ FreePool (HashContext);
+ HashContext = NULL;
+ }
+
+ //
+ // If test key detected or an error occurred checking for the test key, then
+ // set PcdTestKeyUsed to TRUE.
+ //
+ if (TestKeyUsed) {
+ DEBUG ((DEBUG_INFO, "FmpDxe(%s): Test key detected in PcdFmpDevicePkcs7CertBufferXdr.\n", mImageIdName));
+ PcdSetBoolS (PcdTestKeyUsed, TRUE);
+ } else {
+ DEBUG ((DEBUG_INFO, "FmpDxe(%s): No test key detected in PcdFmpDevicePkcs7CertBufferXdr.\n", mImageIdName));
+ }
+}
diff --git a/roms/edk2/FmpDevicePkg/FmpDxe/FmpDxe.c b/roms/edk2/FmpDevicePkg/FmpDxe/FmpDxe.c new file mode 100644 index 000000000..427b215dd --- /dev/null +++ b/roms/edk2/FmpDevicePkg/FmpDxe/FmpDxe.c @@ -0,0 +1,1790 @@ +/** @file
+ Produces a Firmware Management Protocol that supports updates to a firmware
+ image stored in a firmware device with platform and firmware device specific
+ information provided through PCDs and libraries.
+
+ Copyright (c) Microsoft Corporation.<BR>
+ Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "FmpDxe.h"
+#include "VariableSupport.h"
+
+///
+/// FILE_GUID from FmpDxe.inf. When FmpDxe.inf is used in a platform, the
+/// FILE_GUID must always be overridden in the <Defines> section to provide
+/// the ESRT GUID value associated with the updatable firmware image. A
+/// check is made in this module's driver entry point to verify that a
+/// new FILE_GUID value has been defined.
+///
+const EFI_GUID mDefaultModuleFileGuid = {
+ 0x78ef0a56, 0x1cf0, 0x4535, { 0xb5, 0xda, 0xf6, 0xfd, 0x2f, 0x40, 0x5a, 0x11 }
+};
+
+///
+/// TRUE if FmpDeviceLib manages a single firmware storage device.
+///
+BOOLEAN mFmpSingleInstance = FALSE;
+
+///
+/// Firmware Management Protocol instance that is initialized in the entry
+/// point from PCD settings.
+///
+EDKII_FIRMWARE_MANAGEMENT_PROGRESS_PROTOCOL mFmpProgress;
+
+//
+// Template of the private context structure for the Firmware Management
+// Protocol instance
+//
+const FIRMWARE_MANAGEMENT_PRIVATE_DATA mFirmwareManagementPrivateDataTemplate = {
+ FIRMWARE_MANAGEMENT_PRIVATE_DATA_SIGNATURE, // Signature
+ NULL, // Handle
+ { // Fmp
+ GetTheImageInfo,
+ GetTheImage,
+ SetTheImage,
+ CheckTheImage,
+ GetPackageInfo,
+ SetPackageInfo
+ },
+ FALSE, // DescriptorPopulated
+ { // Desc
+ 1, // ImageIndex
+ //
+ // ImageTypeId
+ //
+ { 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} },
+ 1, // ImageId
+ NULL, // ImageIdName
+ 0, // Version
+ NULL, // VersionName
+ 0, // Size
+ 0, // AttributesSupported
+ 0, // AttributesSetting
+ 0, // Compatibilities
+ 0, // LowestSupportedImageVersion
+ 0, // LastAttemptVersion
+ 0, // LastAttemptStatus
+ 0 // HardwareInstance
+ },
+ NULL, // ImageIdName
+ NULL, // VersionName
+ TRUE, // RuntimeVersionSupported
+ NULL, // FmpDeviceLockEvent
+ FALSE, // FmpDeviceLocked
+ NULL, // FmpDeviceContext
+ NULL, // VersionVariableName
+ NULL, // LsvVariableName
+ NULL, // LastAttemptStatusVariableName
+ NULL, // LastAttemptVersionVariableName
+ NULL, // FmpStateVariableName
+ TRUE // DependenciesSatisfied
+};
+
+///
+/// GUID that is used to create event used to lock the firmware storage device.
+///
+EFI_GUID *mLockGuid = NULL;
+
+///
+/// Progress() function pointer passed into SetTheImage()
+///
+EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS mProgressFunc = NULL;
+
+///
+/// Null-terminated Unicode string retrieved from PcdFmpDeviceImageIdName.
+///
+CHAR16 *mImageIdName = NULL;
+
+/**
+ Callback function to report the process of the firmware updating.
+
+ Wrap the caller's version in this so that progress from the device lib is
+ within the expected range. Convert device lib 0% - 100% to 6% - 98%.
+
+ FmpDxe 1% - 5% for validation
+ FmpDeviceLib 6% - 98% for flashing/update
+ FmpDxe 99% - 100% finish
+
+ @param[in] Completion A value between 1 and 100 indicating the current
+ completion progress of the firmware update. Completion
+ progress is reported as from 1 to 100 percent. A value
+ of 0 is used by the driver to indicate that progress
+ reporting is not supported.
+
+ @retval EFI_SUCCESS The progress was updated.
+ @retval EFI_UNSUPPORTED Updating progress is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDxeProgress (
+ IN UINTN Completion
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_UNSUPPORTED;
+
+ if (mProgressFunc == NULL) {
+ return Status;
+ }
+
+ //
+ // Reserve 6% - 98% for the FmpDeviceLib. Call the real progress function.
+ //
+ Status = mProgressFunc (((Completion * 92) / 100) + 6);
+
+ if (Status == EFI_UNSUPPORTED) {
+ mProgressFunc = NULL;
+ }
+
+ return Status;
+}
+
+/**
+ Returns a pointer to the ImageTypeId GUID value. An attempt is made to get
+ the GUID value from the FmpDeviceLib. If the FmpDeviceLib does not provide
+ a GUID value, then PcdFmpDeviceImageTypeIdGuid is used. If the size of
+ PcdFmpDeviceImageTypeIdGuid is not the size of EFI_GUID, then gEfiCallerIdGuid
+ is returned.
+
+ @retval The ImageTypeId GUID
+
+**/
+EFI_GUID *
+GetImageTypeIdGuid (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_GUID *FmpDeviceLibGuid;
+ UINTN ImageTypeIdGuidSize;
+
+ FmpDeviceLibGuid = NULL;
+ Status = FmpDeviceGetImageTypeIdGuidPtr (&FmpDeviceLibGuid);
+ if (EFI_ERROR (Status)) {
+ if (Status != EFI_UNSUPPORTED) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): FmpDeviceLib GetImageTypeIdGuidPtr() returned invalid error %r\n", mImageIdName, Status));
+ }
+ } else if (FmpDeviceLibGuid == NULL) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): FmpDeviceLib GetImageTypeIdGuidPtr() returned invalid GUID\n", mImageIdName));
+ Status = EFI_NOT_FOUND;
+ }
+ if (EFI_ERROR (Status)) {
+ ImageTypeIdGuidSize = PcdGetSize (PcdFmpDeviceImageTypeIdGuid);
+ if (ImageTypeIdGuidSize == sizeof (EFI_GUID)) {
+ FmpDeviceLibGuid = (EFI_GUID *)PcdGetPtr (PcdFmpDeviceImageTypeIdGuid);
+ } else {
+ DEBUG ((DEBUG_WARN, "FmpDxe(%s): Fall back to ImageTypeIdGuid of gEfiCallerIdGuid\n", mImageIdName));
+ FmpDeviceLibGuid = &gEfiCallerIdGuid;
+ }
+ }
+ return FmpDeviceLibGuid;
+}
+
+/**
+ Returns a pointer to the Null-terminated Unicode ImageIdName string.
+
+ @retval Null-terminated Unicode ImageIdName string.
+
+**/
+CHAR16 *
+GetImageTypeNameString (
+ VOID
+ )
+{
+ return mImageIdName;
+}
+
+/**
+ Lowest supported version is a combo of three parts.
+ 1. Check if the device lib has a lowest supported version
+ 2. Check if we have a variable for lowest supported version (this will be updated with each capsule applied)
+ 3. Check Fixed at build PCD
+
+ @param[in] Private Pointer to the private context structure for the
+ Firmware Management Protocol instance.
+
+ @retval The largest value
+
+**/
+UINT32
+GetLowestSupportedVersion (
+ FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DeviceLibLowestSupportedVersion;
+ UINT32 VariableLowestSupportedVersion;
+ UINT32 ReturnLsv;
+
+ //
+ // Get the LowestSupportedVersion.
+ //
+
+ if (!IsLowestSupportedVersionCheckRequired ()) {
+ //
+ // Any Version can pass the 0 LowestSupportedVersion check.
+ //
+ return 0;
+ }
+
+ ReturnLsv = PcdGet32 (PcdFmpDeviceBuildTimeLowestSupportedVersion);
+
+ //
+ // Check the FmpDeviceLib
+ //
+ DeviceLibLowestSupportedVersion = DEFAULT_LOWESTSUPPORTEDVERSION;
+ Status = FmpDeviceGetLowestSupportedVersion (&DeviceLibLowestSupportedVersion);
+ if (EFI_ERROR (Status)) {
+ DeviceLibLowestSupportedVersion = DEFAULT_LOWESTSUPPORTEDVERSION;
+ }
+
+ if (DeviceLibLowestSupportedVersion > ReturnLsv) {
+ ReturnLsv = DeviceLibLowestSupportedVersion;
+ }
+
+ //
+ // Check the lowest supported version UEFI variable for this device
+ //
+ VariableLowestSupportedVersion = GetLowestSupportedVersionFromVariable (Private);
+ if (VariableLowestSupportedVersion > ReturnLsv) {
+ ReturnLsv = VariableLowestSupportedVersion;
+ }
+
+ //
+ // Return the largest value
+ //
+ return ReturnLsv;
+}
+
+/**
+ Populates the EFI_FIRMWARE_IMAGE_DESCRIPTOR structure in the private
+ context structure.
+
+ @param[in] Private Pointer to the private context structure for the
+ Firmware Management Protocol instance.
+
+**/
+VOID
+PopulateDescriptor (
+ FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+ UINT32 DependenciesSize;
+
+ if (Private == NULL) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): PopulateDescriptor() - Private is NULL.\n", mImageIdName));
+ return;
+ }
+
+ if (Private->DescriptorPopulated) {
+ return;
+ }
+
+ Private->Descriptor.ImageIndex = 1;
+ CopyGuid (&Private->Descriptor.ImageTypeId, GetImageTypeIdGuid());
+ Private->Descriptor.ImageId = Private->Descriptor.ImageIndex;
+ Private->Descriptor.ImageIdName = GetImageTypeNameString();
+
+ //
+ // Get the hardware instance from FmpDeviceLib
+ //
+ Status = FmpDeviceGetHardwareInstance (&Private->Descriptor.HardwareInstance);
+ if (Status == EFI_UNSUPPORTED) {
+ Private->Descriptor.HardwareInstance = 0;
+ }
+
+ //
+ // Generate UEFI Variable names used to store status information for this
+ // FMP instance.
+ //
+ GenerateFmpVariableNames (Private);
+
+ //
+ // Get the version. Some devices don't support getting the firmware version
+ // at runtime. If FmpDeviceLib does not support returning a version, then
+ // it is stored in a UEFI variable.
+ //
+ Status = FmpDeviceGetVersion (&Private->Descriptor.Version);
+ if (Status == EFI_UNSUPPORTED) {
+ Private->RuntimeVersionSupported = FALSE;
+ Private->Descriptor.Version = GetVersionFromVariable (Private);
+ } else if (EFI_ERROR (Status)) {
+ //
+ // Unexpected error. Use default version.
+ //
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetVersion() from FmpDeviceLib (%s) returned %r\n", mImageIdName, GetImageTypeNameString(), Status));
+ Private->Descriptor.Version = DEFAULT_VERSION;
+ }
+
+ //
+ // Free the current version name. Shouldn't really happen but this populate
+ // function could be called multiple times (to refresh).
+ //
+ if (Private->Descriptor.VersionName != NULL) {
+ FreePool (Private->Descriptor.VersionName);
+ Private->Descriptor.VersionName = NULL;
+ }
+
+ //
+ // Attempt to get the version string from the FmpDeviceLib
+ //
+ Status = FmpDeviceGetVersionString (&Private->Descriptor.VersionName);
+ if (Status == EFI_UNSUPPORTED) {
+ DEBUG ((DEBUG_INFO, "FmpDxe(%s): GetVersionString() unsupported in FmpDeviceLib.\n", mImageIdName));
+ Private->Descriptor.VersionName = AllocateCopyPool (
+ sizeof (VERSION_STRING_NOT_SUPPORTED),
+ VERSION_STRING_NOT_SUPPORTED
+ );
+ } else if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_INFO, "FmpDxe(%s): GetVersionString() not available in FmpDeviceLib.\n", mImageIdName));
+ Private->Descriptor.VersionName = AllocateCopyPool (
+ sizeof (VERSION_STRING_NOT_AVAILABLE),
+ VERSION_STRING_NOT_AVAILABLE
+ );
+ }
+
+ Private->Descriptor.LowestSupportedImageVersion = GetLowestSupportedVersion (Private);
+
+ //
+ // Get attributes from the FmpDeviceLib
+ //
+ FmpDeviceGetAttributes (
+ &Private->Descriptor.AttributesSupported,
+ &Private->Descriptor.AttributesSetting
+ );
+
+ //
+ // Force set the updatable bits in the attributes;
+ //
+ Private->Descriptor.AttributesSupported |= IMAGE_ATTRIBUTE_IMAGE_UPDATABLE;
+ Private->Descriptor.AttributesSetting |= IMAGE_ATTRIBUTE_IMAGE_UPDATABLE;
+
+ //
+ // Force set the authentication bits in the attributes;
+ //
+ Private->Descriptor.AttributesSupported |= (IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);
+ Private->Descriptor.AttributesSetting |= (IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED);
+
+ Private->Descriptor.Compatibilities = 0;
+
+ //
+ // Get the size of the firmware image from the FmpDeviceLib
+ //
+ Status = FmpDeviceGetSize (&Private->Descriptor.Size);
+ if (EFI_ERROR (Status)) {
+ Private->Descriptor.Size = 0;
+ }
+
+ Private->Descriptor.LastAttemptVersion = GetLastAttemptVersionFromVariable (Private);
+ Private->Descriptor.LastAttemptStatus = GetLastAttemptStatusFromVariable (Private);
+
+ //
+ // Get the dependency from the FmpDependencyDeviceLib.
+ //
+ Private->Descriptor.Dependencies = NULL;
+
+ //
+ // Check the attribute IMAGE_ATTRIBUTE_DEPENDENCY
+ //
+ if (Private->Descriptor.AttributesSetting & IMAGE_ATTRIBUTE_DEPENDENCY) {
+ Private->Descriptor.Dependencies = GetFmpDependency (&DependenciesSize);
+ }
+
+ Private->DescriptorPopulated = TRUE;
+}
+
+/**
+ Returns information about the current firmware image(s) of the device.
+
+ This function allows a copy of the current firmware image to be created and saved.
+ The saved copy could later been used, for example, in firmware image recovery or rollback.
+
+ @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
+ @param[in, out] ImageInfoSize A pointer to the size, in bytes, of the ImageInfo buffer.
+ On input, this is the size of the buffer allocated by the caller.
+ On output, it is the size of the buffer returned by the firmware
+ if the buffer was large enough, or the size of the buffer needed
+ to contain the image(s) information if the buffer was too small.
+ @param[in, out] ImageInfo A pointer to the buffer in which firmware places the current image(s)
+ information. The information is an array of EFI_FIRMWARE_IMAGE_DESCRIPTORs.
+ @param[out] DescriptorVersion A pointer to the location in which firmware returns the version number
+ associated with the EFI_FIRMWARE_IMAGE_DESCRIPTOR.
+ @param[out] DescriptorCount A pointer to the location in which firmware returns the number of
+ descriptors or firmware images within this device.
+ @param[out] DescriptorSize A pointer to the location in which firmware returns the size, in bytes,
+ of an individual EFI_FIRMWARE_IMAGE_DESCRIPTOR.
+ @param[out] PackageVersion A version number that represents all the firmware images in the device.
+ The format is vendor specific and new version must have a greater value
+ than the old version. If PackageVersion is not supported, the value is
+ 0xFFFFFFFF. A value of 0xFFFFFFFE indicates that package version comparison
+ is to be performed using PackageVersionName. A value of 0xFFFFFFFD indicates
+ that package version update is in progress.
+ @param[out] PackageVersionName A pointer to a pointer to a null-terminated string representing the
+ package version name. 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_BUFFER_TOO_SMALL The ImageInfo buffer was too small. The current buffer size
+ needed to hold the image(s) information is returned in ImageInfoSize.
+ @retval EFI_INVALID_PARAMETER ImageInfoSize is NULL.
+ @retval EFI_DEVICE_ERROR Valid information could not be returned. Possible corrupted image.
+
+**/
+EFI_STATUS
+EFIAPI
+GetTheImageInfo (
+ IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
+ IN OUT UINTN *ImageInfoSize,
+ IN OUT EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageInfo,
+ OUT UINT32 *DescriptorVersion,
+ OUT UINT8 *DescriptorCount,
+ OUT UINTN *DescriptorSize,
+ OUT UINT32 *PackageVersion,
+ OUT CHAR16 **PackageVersionName
+ )
+{
+ EFI_STATUS Status;
+ FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private;
+
+ Status = EFI_SUCCESS;
+
+ if (This == NULL) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetImageInfo() - This is NULL.\n", mImageIdName));
+ Status = EFI_INVALID_PARAMETER;
+ goto cleanup;
+ }
+
+ //
+ // Retrieve the private context structure
+ //
+ Private = FIRMWARE_MANAGEMENT_PRIVATE_DATA_FROM_THIS (This);
+ FmpDeviceSetContext (Private->Handle, &Private->FmpDeviceContext);
+
+ //
+ // Check for valid pointer
+ //
+ if (ImageInfoSize == NULL) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetImageInfo() - ImageInfoSize is NULL.\n", mImageIdName));
+ Status = EFI_INVALID_PARAMETER;
+ goto cleanup;
+ }
+
+ //
+ // Check the buffer size
+ // NOTE: Check this first so caller can get the necessary memory size it must allocate.
+ //
+ if (*ImageInfoSize < (sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR))) {
+ *ImageInfoSize = sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR);
+ DEBUG ((DEBUG_VERBOSE, "FmpDxe(%s): GetImageInfo() - ImageInfoSize is to small.\n", mImageIdName));
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto cleanup;
+ }
+
+ //
+ // Confirm that buffer isn't null
+ //
+ if ( (ImageInfo == NULL) || (DescriptorVersion == NULL) || (DescriptorCount == NULL) || (DescriptorSize == NULL)
+ || (PackageVersion == NULL)) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetImageInfo() - Pointer Parameter is NULL.\n", mImageIdName));
+ Status = EFI_INVALID_PARAMETER;
+ goto cleanup;
+ }
+
+ //
+ // Set the size to whatever we need
+ //
+ *ImageInfoSize = sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR);
+
+ //
+ // Make sure the descriptor has already been loaded or refreshed
+ //
+ PopulateDescriptor (Private);
+
+ //
+ // Copy the image descriptor
+ //
+ CopyMem (ImageInfo, &Private->Descriptor, sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR));
+
+ *DescriptorVersion = EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION;
+ *DescriptorCount = 1;
+ *DescriptorSize = sizeof (EFI_FIRMWARE_IMAGE_DESCRIPTOR);
+ //
+ // means unsupported
+ //
+ *PackageVersion = 0xFFFFFFFF;
+
+ //
+ // Do not update PackageVersionName since it is not supported in this instance.
+ //
+
+cleanup:
+
+ return Status;
+}
+
+/**
+ Retrieves a copy of the current firmware image of the device.
+
+ This function allows a copy of the current firmware image to be created and saved.
+ The saved copy could later been used, for example, in firmware image recovery or rollback.
+
+ @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
+ @param[in] ImageIndex A unique number identifying the firmware image(s) within the device.
+ The number is between 1 and DescriptorCount.
+ @param[in, out] Image Points to the buffer where the current image is copied to.
+ @param[in, out] ImageSize On entry, points to the size of the buffer pointed to by Image, in bytes.
+ On return, points to the length of the image, in bytes.
+
+ @retval EFI_SUCCESS The device was successfully updated with the new image.
+ @retval EFI_BUFFER_TOO_SMALL The buffer specified by ImageSize is too small to hold the
+ image. The current buffer size needed to hold the image is returned
+ in ImageSize.
+ @retval EFI_INVALID_PARAMETER The Image was NULL.
+ @retval EFI_NOT_FOUND The current image is not copied to the buffer.
+ @retval EFI_UNSUPPORTED The operation is not supported.
+ @retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.
+
+**/
+EFI_STATUS
+EFIAPI
+GetTheImage (
+ IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
+ IN UINT8 ImageIndex,
+ IN OUT VOID *Image,
+ IN OUT UINTN *ImageSize
+ )
+{
+ EFI_STATUS Status;
+ FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private;
+ UINTN Size;
+
+ if (!FeaturePcdGet (PcdFmpDeviceStorageAccessEnable)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = EFI_SUCCESS;
+
+ if (This == NULL) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetImage() - This is NULL.\n", mImageIdName));
+ Status = EFI_INVALID_PARAMETER;
+ goto cleanup;
+ }
+
+ //
+ // Retrieve the private context structure
+ //
+ Private = FIRMWARE_MANAGEMENT_PRIVATE_DATA_FROM_THIS (This);
+ FmpDeviceSetContext (Private->Handle, &Private->FmpDeviceContext);
+
+ //
+ // Check to make sure index is 1 (only 1 image for this device)
+ //
+ if (ImageIndex != 1) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetImage() - Image Index Invalid.\n", mImageIdName));
+ Status = EFI_INVALID_PARAMETER;
+ goto cleanup;
+ }
+
+ if (ImageSize == NULL) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetImage() - ImageSize Pointer Parameter is NULL.\n", mImageIdName));
+ Status = EFI_INVALID_PARAMETER;
+ goto cleanup;
+ }
+
+ //
+ // Check the buffer size
+ //
+ Status = FmpDeviceGetSize (&Size);
+ if (EFI_ERROR (Status)) {
+ Size = 0;
+ }
+ if (*ImageSize < Size) {
+ *ImageSize = Size;
+ DEBUG ((DEBUG_VERBOSE, "FmpDxe(%s): GetImage() - ImageSize is to small.\n", mImageIdName));
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto cleanup;
+ }
+
+ if (Image == NULL) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetImage() - Image Pointer Parameter is NULL.\n", mImageIdName));
+ Status = EFI_INVALID_PARAMETER;
+ goto cleanup;
+ }
+
+ Status = FmpDeviceGetImage (Image, ImageSize);
+cleanup:
+
+ return Status;
+}
+
+/**
+ Helper function to safely retrieve the FMP header from
+ within an EFI_FIRMWARE_IMAGE_AUTHENTICATION structure.
+
+ @param[in] Image Pointer to the image.
+ @param[in] ImageSize Size of the image.
+ @param[in] AdditionalHeaderSize Size of any headers that cannot be calculated by this function.
+ @param[out] PayloadSize An optional pointer to a UINTN that holds the size of the payload
+ (image size minus headers)
+
+ @retval !NULL Valid pointer to the header.
+ @retval NULL Structure is bad and pointer cannot be found.
+
+**/
+VOID *
+GetFmpHeader (
+ IN CONST EFI_FIRMWARE_IMAGE_AUTHENTICATION *Image,
+ IN CONST UINTN ImageSize,
+ IN CONST UINTN AdditionalHeaderSize,
+ OUT UINTN *PayloadSize OPTIONAL
+ )
+{
+ //
+ // Check to make sure that operation can be safely performed.
+ //
+ if (((UINTN)Image + sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr.dwLength) + AdditionalHeaderSize < (UINTN)Image || \
+ ((UINTN)Image + sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr.dwLength) + AdditionalHeaderSize >= (UINTN)Image + ImageSize) {
+ //
+ // Pointer overflow. Invalid image.
+ //
+ return NULL;
+ }
+
+ if (PayloadSize != NULL) {
+ *PayloadSize = ImageSize - (sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr.dwLength + AdditionalHeaderSize);
+ }
+
+ return (VOID *)((UINT8 *)Image + sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr.dwLength + AdditionalHeaderSize);
+}
+
+/**
+ Helper function to safely calculate the size of all headers
+ within an EFI_FIRMWARE_IMAGE_AUTHENTICATION structure.
+
+ @param[in] Image Pointer to the image.
+ @param[in] AdditionalHeaderSize Size of any headers that cannot be calculated by this function.
+
+ @retval UINT32>0 Valid size of all the headers.
+ @retval 0 Structure is bad and size cannot be found.
+
+**/
+UINT32
+GetAllHeaderSize (
+ IN CONST EFI_FIRMWARE_IMAGE_AUTHENTICATION *Image,
+ IN UINT32 AdditionalHeaderSize
+ )
+{
+ UINT32 CalculatedSize;
+
+ if (Image == NULL) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetAllHeaderSize() - Image is NULL.\n", mImageIdName));
+ return 0;
+ }
+
+ CalculatedSize = sizeof (Image->MonotonicCount) +
+ AdditionalHeaderSize +
+ Image->AuthInfo.Hdr.dwLength;
+
+ //
+ // Check to make sure that operation can be safely performed.
+ //
+ if (CalculatedSize < sizeof (Image->MonotonicCount) ||
+ CalculatedSize < AdditionalHeaderSize ||
+ CalculatedSize < Image->AuthInfo.Hdr.dwLength ) {
+ //
+ // Integer overflow. Invalid image.
+ //
+ return 0;
+ }
+
+ return CalculatedSize;
+}
+
+/**
+ Checks if the firmware image is valid for the device.
+
+ This function allows firmware update application to validate the firmware image without
+ invoking the SetImage() first.
+
+ @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
+ @param[in] ImageIndex A unique number identifying the firmware image(s) within the device.
+ The number is between 1 and DescriptorCount.
+ @param[in] Image Points to the new image.
+ @param[in] ImageSize Size of the new image in bytes.
+ @param[out] ImageUpdatable Indicates if the new image is valid for update. It also provides,
+ if available, additional information if the image is invalid.
+
+ @retval EFI_SUCCESS The image was successfully checked.
+ @retval EFI_ABORTED The operation is aborted.
+ @retval EFI_INVALID_PARAMETER The Image was NULL.
+ @retval EFI_UNSUPPORTED The operation is not supported.
+ @retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.
+
+**/
+EFI_STATUS
+EFIAPI
+CheckTheImage (
+ IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
+ IN UINT8 ImageIndex,
+ IN CONST VOID *Image,
+ IN UINTN ImageSize,
+ OUT UINT32 *ImageUpdatable
+ )
+{
+ EFI_STATUS Status;
+ FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private;
+ UINTN RawSize;
+ VOID *FmpPayloadHeader;
+ UINTN FmpPayloadSize;
+ UINT32 Version;
+ UINT32 FmpHeaderSize;
+ UINTN AllHeaderSize;
+ UINT32 Index;
+ VOID *PublicKeyData;
+ UINTN PublicKeyDataLength;
+ UINT8 *PublicKeyDataXdr;
+ UINT8 *PublicKeyDataXdrEnd;
+ EFI_FIRMWARE_IMAGE_DEP *Dependencies;
+ UINT32 DependenciesSize;
+
+ Status = EFI_SUCCESS;
+ RawSize = 0;
+ FmpPayloadHeader = NULL;
+ FmpPayloadSize = 0;
+ Version = 0;
+ FmpHeaderSize = 0;
+ AllHeaderSize = 0;
+ Dependencies = NULL;
+ DependenciesSize = 0;
+
+ if (!FeaturePcdGet (PcdFmpDeviceStorageAccessEnable)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (This == NULL) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckImage() - This is NULL.\n", mImageIdName));
+ Status = EFI_INVALID_PARAMETER;
+ goto cleanup;
+ }
+
+ //
+ // Retrieve the private context structure
+ //
+ Private = FIRMWARE_MANAGEMENT_PRIVATE_DATA_FROM_THIS (This);
+ FmpDeviceSetContext (Private->Handle, &Private->FmpDeviceContext);
+
+ //
+ // Make sure the descriptor has already been loaded or refreshed
+ //
+ PopulateDescriptor (Private);
+
+ if (ImageUpdatable == NULL) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckImage() - ImageUpdatable Pointer Parameter is NULL.\n", mImageIdName));
+ Status = EFI_INVALID_PARAMETER;
+ goto cleanup;
+ }
+
+ //
+ //Set to valid and then if any tests fail it will update this flag.
+ //
+ *ImageUpdatable = IMAGE_UPDATABLE_VALID;
+
+ //
+ // Set to satisfied and then if dependency evaluates to false it will update this flag.
+ //
+ Private->DependenciesSatisfied = TRUE;
+
+ if (Image == NULL) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckImage() - Image Pointer Parameter is NULL.\n", mImageIdName));
+ //
+ // not sure if this is needed
+ //
+ *ImageUpdatable = IMAGE_UPDATABLE_INVALID;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PublicKeyDataXdr = PcdGetPtr (PcdFmpDevicePkcs7CertBufferXdr);
+ PublicKeyDataXdrEnd = PublicKeyDataXdr + PcdGetSize (PcdFmpDevicePkcs7CertBufferXdr);
+
+ if (PublicKeyDataXdr == NULL || (PublicKeyDataXdr == PublicKeyDataXdrEnd)) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Invalid certificate, skipping it.\n", mImageIdName));
+ Status = EFI_ABORTED;
+ } else {
+ //
+ // Try each key from PcdFmpDevicePkcs7CertBufferXdr
+ //
+ for (Index = 1; PublicKeyDataXdr < PublicKeyDataXdrEnd; Index++) {
+ Index++;
+ DEBUG (
+ (DEBUG_INFO,
+ "FmpDxe(%s): Certificate #%d [%p..%p].\n",
+ mImageIdName,
+ Index,
+ PublicKeyDataXdr,
+ PublicKeyDataXdrEnd
+ )
+ );
+
+ if ((PublicKeyDataXdr + sizeof (UINT32)) > PublicKeyDataXdrEnd) {
+ //
+ // Key data extends beyond end of PCD
+ //
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Certificate size extends beyond end of PCD, skipping it.\n", mImageIdName));
+ Status = EFI_ABORTED;
+ break;
+ }
+ //
+ // Read key length stored in big-endian format
+ //
+ PublicKeyDataLength = SwapBytes32 (*(UINT32 *)(PublicKeyDataXdr));
+ //
+ // Point to the start of the key data
+ //
+ PublicKeyDataXdr += sizeof (UINT32);
+ if (PublicKeyDataXdr + PublicKeyDataLength > PublicKeyDataXdrEnd) {
+ //
+ // Key data extends beyond end of PCD
+ //
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Certificate extends beyond end of PCD, skipping it.\n", mImageIdName));
+ Status = EFI_ABORTED;
+ break;
+ }
+ PublicKeyData = PublicKeyDataXdr;
+ Status = AuthenticateFmpImage (
+ (EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image,
+ ImageSize,
+ PublicKeyData,
+ PublicKeyDataLength
+ );
+ if (!EFI_ERROR (Status)) {
+ break;
+ }
+ PublicKeyDataXdr += PublicKeyDataLength;
+ PublicKeyDataXdr = (UINT8 *)ALIGN_POINTER (PublicKeyDataXdr, sizeof (UINT32));
+ }
+ }
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - Authentication Failed %r.\n", mImageIdName, Status));
+ goto cleanup;
+ }
+
+ //
+ // Check to make sure index is 1
+ //
+ if (ImageIndex != 1) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckImage() - Image Index Invalid.\n", mImageIdName));
+ *ImageUpdatable = IMAGE_UPDATABLE_INVALID_TYPE;
+ Status = EFI_INVALID_PARAMETER;
+ goto cleanup;
+ }
+
+ //
+ // Get the dependency from Image.
+ //
+ Dependencies = GetImageDependency ((EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, ImageSize, &DependenciesSize);
+
+ //
+ // Check the FmpPayloadHeader
+ //
+ FmpPayloadHeader = GetFmpHeader ( (EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, ImageSize, DependenciesSize, &FmpPayloadSize );
+ if (FmpPayloadHeader == NULL) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - GetFmpHeader failed.\n", mImageIdName));
+ Status = EFI_ABORTED;
+ goto cleanup;
+ }
+ Status = GetFmpPayloadHeaderVersion (FmpPayloadHeader, FmpPayloadSize, &Version);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - GetFmpPayloadHeaderVersion failed %r.\n", mImageIdName, Status));
+ *ImageUpdatable = IMAGE_UPDATABLE_INVALID;
+ Status = EFI_SUCCESS;
+ goto cleanup;
+ }
+
+ //
+ // Check the lowest supported version
+ //
+ if (Version < Private->Descriptor.LowestSupportedImageVersion) {
+ DEBUG (
+ (DEBUG_ERROR,
+ "FmpDxe(%s): CheckTheImage() - Version Lower than lowest supported version. 0x%08X < 0x%08X\n",
+ mImageIdName, Version, Private->Descriptor.LowestSupportedImageVersion)
+ );
+ *ImageUpdatable = IMAGE_UPDATABLE_INVALID_OLD;
+ Status = EFI_SUCCESS;
+ goto cleanup;
+ }
+
+ //
+ // Evaluate dependency expression
+ //
+ Private->DependenciesSatisfied = CheckFmpDependency (Private->Descriptor.ImageTypeId, Version, Dependencies, DependenciesSize);
+ if (!Private->DependenciesSatisfied) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - Dependency check failed.\n", mImageIdName));
+ *ImageUpdatable = IMAGE_UPDATABLE_INVALID;
+ Status = EFI_SUCCESS;
+ goto cleanup;
+ }
+
+ //
+ // Get the FmpHeaderSize so we can determine the real payload size
+ //
+ Status = GetFmpPayloadHeaderSize (FmpPayloadHeader, FmpPayloadSize, &FmpHeaderSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe: CheckTheImage() - GetFmpPayloadHeaderSize failed %r.\n", Status));
+ *ImageUpdatable = IMAGE_UPDATABLE_INVALID;
+ Status = EFI_SUCCESS;
+ goto cleanup;
+ }
+
+ //
+ // Call FmpDevice Lib Check Image on the
+ // Raw payload. So all headers need stripped off
+ //
+ AllHeaderSize = GetAllHeaderSize ( (EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, FmpHeaderSize + DependenciesSize);
+ if (AllHeaderSize == 0) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - GetAllHeaderSize failed.\n", mImageIdName));
+ Status = EFI_ABORTED;
+ goto cleanup;
+ }
+ RawSize = ImageSize - AllHeaderSize;
+
+ //
+ // FmpDeviceLib CheckImage function to do any specific checks
+ //
+ Status = FmpDeviceCheckImage ((((UINT8 *)Image) + AllHeaderSize), RawSize, ImageUpdatable);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - FmpDeviceLib CheckImage failed. Status = %r\n", mImageIdName, Status));
+ }
+
+cleanup:
+ 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 authentication if image has attribute
+ IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED. The function returns
+ EFI_SECURITY_VIOLATION if the validation fails.
+ - 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] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
+ @param[in] ImageIndex A unique number identifying the firmware image(s) within the device.
+ The number is between 1 and DescriptorCount.
+ @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[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.
+ @retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.
+
+**/
+EFI_STATUS
+EFIAPI
+SetTheImage (
+ IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
+ IN UINT8 ImageIndex,
+ IN CONST VOID *Image,
+ IN UINTN ImageSize,
+ IN CONST VOID *VendorCode,
+ IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress,
+ OUT CHAR16 **AbortReason
+ )
+{
+ EFI_STATUS Status;
+ FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private;
+ UINT32 Updateable;
+ BOOLEAN BooleanValue;
+ UINT32 FmpHeaderSize;
+ VOID *FmpHeader;
+ UINTN FmpPayloadSize;
+ UINT32 AllHeaderSize;
+ UINT32 IncomingFwVersion;
+ UINT32 LastAttemptStatus;
+ UINT32 Version;
+ UINT32 LowestSupportedVersion;
+ EFI_FIRMWARE_IMAGE_DEP *Dependencies;
+ UINT32 DependenciesSize;
+
+ Status = EFI_SUCCESS;
+ Private = NULL;
+ Updateable = 0;
+ BooleanValue = FALSE;
+ FmpHeaderSize = 0;
+ FmpHeader = NULL;
+ FmpPayloadSize = 0;
+ AllHeaderSize = 0;
+ IncomingFwVersion = 0;
+ LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL;
+ Dependencies = NULL;
+ DependenciesSize = 0;
+
+ if (!FeaturePcdGet (PcdFmpDeviceStorageAccessEnable)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (This == NULL) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - This is NULL.\n", mImageIdName));
+ Status = EFI_INVALID_PARAMETER;
+ goto cleanup;
+ }
+
+ //
+ // Retrieve the private context structure
+ //
+ Private = FIRMWARE_MANAGEMENT_PRIVATE_DATA_FROM_THIS (This);
+ FmpDeviceSetContext (Private->Handle, &Private->FmpDeviceContext);
+
+ //
+ // Make sure the descriptor has already been loaded or refreshed
+ //
+ PopulateDescriptor (Private);
+
+ //
+ // Set to 0 to clear any previous results.
+ //
+ SetLastAttemptVersionInVariable (Private, IncomingFwVersion);
+
+ //
+ // if we have locked the device, then skip the set operation.
+ // it should be blocked by hardware too but we can catch here even faster
+ //
+ if (Private->FmpDeviceLocked) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - Device is already locked. Can't update.\n", mImageIdName));
+ Status = EFI_UNSUPPORTED;
+ goto cleanup;
+ }
+
+ //
+ // Call check image to verify the image
+ //
+ Status = CheckTheImage (This, ImageIndex, Image, ImageSize, &Updateable);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - Check The Image failed with %r.\n", mImageIdName, Status));
+ if (Status == EFI_SECURITY_VIOLATION) {
+ LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_AUTH_ERROR;
+ }
+ goto cleanup;
+ }
+
+ //
+ // Get the dependency from Image.
+ //
+ Dependencies = GetImageDependency ((EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, ImageSize, &DependenciesSize);
+
+ //
+ // No functional error in CheckTheImage. Attempt to get the Version to
+ // support better error reporting.
+ //
+ FmpHeader = GetFmpHeader ( (EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, ImageSize, DependenciesSize, &FmpPayloadSize );
+ if (FmpHeader == NULL) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - GetFmpHeader failed.\n", mImageIdName));
+ Status = EFI_ABORTED;
+ goto cleanup;
+ }
+ Status = GetFmpPayloadHeaderVersion (FmpHeader, FmpPayloadSize, &IncomingFwVersion);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Set to actual value
+ //
+ SetLastAttemptVersionInVariable (Private, IncomingFwVersion);
+ }
+
+
+ if (Updateable != IMAGE_UPDATABLE_VALID) {
+ DEBUG (
+ (DEBUG_ERROR,
+ "FmpDxe(%s): SetTheImage() - Check The Image returned that the Image was not valid for update. Updatable value = 0x%X.\n",
+ mImageIdName, Updateable)
+ );
+ if (Private->DependenciesSatisfied == FALSE) {
+ LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_UNSATISFIED_DEPENDENCIES;
+ }
+ Status = EFI_ABORTED;
+ goto cleanup;
+ }
+
+ if (Progress == NULL) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - Invalid progress callback\n", mImageIdName));
+ Status = EFI_INVALID_PARAMETER;
+ goto cleanup;
+ }
+
+ mProgressFunc = Progress;
+
+ //
+ // Checking the image is at least 1%
+ //
+ Status = Progress (1);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - Progress Callback failed with Status %r.\n", mImageIdName, Status));
+ }
+
+ //
+ //Check System Power
+ //
+ Status = CheckSystemPower (&BooleanValue);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - CheckSystemPower - API call failed %r.\n", mImageIdName, Status));
+ goto cleanup;
+ }
+ if (!BooleanValue) {
+ Status = EFI_ABORTED;
+ DEBUG (
+ (DEBUG_ERROR,
+ "FmpDxe(%s): SetTheImage() - CheckSystemPower - returned False. Update not allowed due to System Power.\n", mImageIdName)
+ );
+ LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_PWR_EVT_BATT;
+ goto cleanup;
+ }
+
+ Progress (2);
+
+ //
+ //Check System Thermal
+ //
+ Status = CheckSystemThermal (&BooleanValue);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - CheckSystemThermal - API call failed %r.\n", mImageIdName, Status));
+ goto cleanup;
+ }
+ if (!BooleanValue) {
+ Status = EFI_ABORTED;
+ DEBUG (
+ (DEBUG_ERROR,
+ "FmpDxe(%s): SetTheImage() - CheckSystemThermal - returned False. Update not allowed due to System Thermal.\n", mImageIdName)
+ );
+ goto cleanup;
+ }
+
+ Progress (3);
+
+ //
+ //Check System Environment
+ //
+ Status = CheckSystemEnvironment (&BooleanValue);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - CheckSystemEnvironment - API call failed %r.\n", mImageIdName, Status));
+ goto cleanup;
+ }
+ if (!BooleanValue) {
+ Status = EFI_ABORTED;
+ DEBUG (
+ (DEBUG_ERROR,
+ "FmpDxe(%s): SetTheImage() - CheckSystemEnvironment - returned False. Update not allowed due to System Environment.\n", mImageIdName)
+ );
+ goto cleanup;
+ }
+
+ Progress (4);
+
+ //
+ // Save LastAttemptStatus as error so that if SetImage never returns the error
+ // state is recorded.
+ //
+ SetLastAttemptStatusInVariable (Private, LastAttemptStatus);
+
+ //
+ // Strip off all the headers so the device can process its firmware
+ //
+ Status = GetFmpPayloadHeaderSize (FmpHeader, FmpPayloadSize, &FmpHeaderSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - GetFmpPayloadHeaderSize failed %r.\n", mImageIdName, Status));
+ goto cleanup;
+ }
+
+ AllHeaderSize = GetAllHeaderSize ((EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, FmpHeaderSize + DependenciesSize);
+ if (AllHeaderSize == 0) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - GetAllHeaderSize failed.\n", mImageIdName));
+ Status = EFI_ABORTED;
+ goto cleanup;
+ }
+
+ //
+ // Indicate that control is handed off to FmpDeviceLib
+ //
+ Progress (5);
+
+ //
+ //Copy the requested image to the firmware using the FmpDeviceLib
+ //
+ Status = FmpDeviceSetImage (
+ (((UINT8 *)Image) + AllHeaderSize),
+ ImageSize - AllHeaderSize,
+ VendorCode,
+ FmpDxeProgress,
+ IncomingFwVersion,
+ AbortReason
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() SetImage from FmpDeviceLib failed. Status = %r.\n", mImageIdName, Status));
+ goto cleanup;
+ }
+
+ //
+ // Store the dependency
+ //
+ if (Private->Descriptor.AttributesSetting & IMAGE_ATTRIBUTE_DEPENDENCY) {
+ Status = SaveFmpDependency (Dependencies, DependenciesSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() SaveFmpDependency from FmpDependencyCheckLib failed. (%r)\n", mImageIdName, Status));
+ }
+ Status = EFI_SUCCESS;
+ }
+
+ //
+ // Finished the update without error
+ // Indicate that control has been returned from FmpDeviceLib
+ //
+ Progress (99);
+
+ //
+ // Update the version stored in variable
+ //
+ if (!Private->RuntimeVersionSupported) {
+ Version = DEFAULT_VERSION;
+ GetFmpPayloadHeaderVersion (FmpHeader, FmpPayloadSize, &Version);
+ SetVersionInVariable (Private, Version);
+ }
+
+ //
+ // Update lowest supported variable
+ //
+ LowestSupportedVersion = DEFAULT_LOWESTSUPPORTEDVERSION;
+ GetFmpPayloadHeaderLowestSupportedVersion (FmpHeader, FmpPayloadSize, &LowestSupportedVersion);
+ SetLowestSupportedVersionInVariable (Private, LowestSupportedVersion);
+
+ LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;
+
+cleanup:
+ mProgressFunc = NULL;
+
+ if (Private != NULL) {
+ SetLastAttemptStatusInVariable (Private, LastAttemptStatus);
+ }
+
+ if (Progress != NULL) {
+ //
+ // Set progress to 100 after everything is done including recording Status.
+ //
+ Progress (100);
+ }
+
+ //
+ // Need repopulate after SetImage is called to
+ // update LastAttemptVersion and LastAttemptStatus.
+ //
+ if (Private != NULL) {
+ Private->DescriptorPopulated = FALSE;
+ }
+
+ return Status;
+}
+
+/**
+ Returns information about the firmware package.
+
+ This function returns package information.
+
+ @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
+ @param[out] PackageVersion A version number that represents all the firmware images in the device.
+ The format is vendor specific and new version must have a greater value
+ than the old version. If PackageVersion is not supported, the value is
+ 0xFFFFFFFF. A value of 0xFFFFFFFE indicates that package version
+ comparison is to be performed using PackageVersionName. A value of
+ 0xFFFFFFFD indicates that package version update is in progress.
+ @param[out] PackageVersionName A pointer to a pointer to a null-terminated string representing
+ the package version name. 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[out] PackageVersionNameMaxLen The maximum length of package version name if device supports update of
+ package version name. A value of 0 indicates the device does not support
+ update of package version name. Length is the number of Unicode characters,
+ including the terminating null character.
+ @param[out] AttributesSupported Package attributes that are supported by this device. See 'Package Attribute
+ Definitions' for possible returned values of this parameter. A value of 1
+ indicates the attribute is supported and the current setting value is
+ indicated in AttributesSetting. A value of 0 indicates the attribute is not
+ supported and the current setting value in AttributesSetting is meaningless.
+ @param[out] AttributesSetting Package attributes. See 'Package Attribute Definitions' for possible returned
+ values of this parameter
+
+ @retval EFI_SUCCESS The package information was successfully returned.
+ @retval EFI_UNSUPPORTED The operation is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+GetPackageInfo (
+ IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
+ OUT UINT32 *PackageVersion,
+ OUT CHAR16 **PackageVersionName,
+ OUT UINT32 *PackageVersionNameMaxLen,
+ OUT UINT64 *AttributesSupported,
+ OUT UINT64 *AttributesSetting
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Updates information about the firmware package.
+
+ This function updates package information.
+ This function returns EFI_UNSUPPORTED if the package information is not updatable.
+ VendorCode enables vendor to implement vendor-specific package information update policy.
+ Null if the caller did not specify this policy or use the default policy.
+
+ @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
+ @param[in] Image Points to the authentication image.
+ Null if authentication is not required.
+ @param[in] ImageSize Size of the authentication image in bytes.
+ 0 if authentication is not required.
+ @param[in] VendorCode This enables vendor to implement vendor-specific firmware
+ image update policy.
+ Null indicates the caller did not specify this policy or use
+ the default policy.
+ @param[in] PackageVersion The new package version.
+ @param[in] PackageVersionName A pointer to the new null-terminated Unicode string representing
+ the package version name.
+ The string length is equal to or less than the value returned in
+ PackageVersionNameMaxLen.
+
+ @retval EFI_SUCCESS The device was successfully updated with the new package
+ information.
+ @retval EFI_INVALID_PARAMETER The PackageVersionName length is longer than the value
+ returned in PackageVersionNameMaxLen.
+ @retval EFI_UNSUPPORTED The operation is not supported.
+ @retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.
+
+**/
+EFI_STATUS
+EFIAPI
+SetPackageInfo (
+ IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
+ IN CONST VOID *Image,
+ IN UINTN ImageSize,
+ IN CONST VOID *VendorCode,
+ IN UINT32 PackageVersion,
+ IN CONST CHAR16 *PackageVersionName
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Event notification function that is invoked when the event GUID specified by
+ PcdFmpDeviceLockEventGuid is signaled.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context The pointer to the notification function's context,
+ which is implementation-dependent.
+**/
+VOID
+EFIAPI
+FmpDxeLockEventNotify (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private;
+
+ if (Context == NULL) {
+ ASSERT (Context != NULL);
+ return;
+ }
+
+ Private = (FIRMWARE_MANAGEMENT_PRIVATE_DATA *)Context;
+
+ if (!Private->FmpDeviceLocked) {
+ //
+ // Lock the firmware device
+ //
+ FmpDeviceSetContext (Private->Handle, &Private->FmpDeviceContext);
+ Status = FmpDeviceLock();
+ if (EFI_ERROR (Status)) {
+ if (Status != EFI_UNSUPPORTED) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): FmpDeviceLock() returned error. Status = %r\n", mImageIdName, Status));
+ } else {
+ DEBUG ((DEBUG_WARN, "FmpDxe(%s): FmpDeviceLock() returned error. Status = %r\n", mImageIdName, Status));
+ }
+ }
+ Private->FmpDeviceLocked = TRUE;
+ }
+}
+
+/**
+ Function to install FMP instance.
+
+ @param[in] Handle The device handle to install a FMP instance on.
+
+ @retval EFI_SUCCESS FMP Installed
+ @retval EFI_INVALID_PARAMETER Handle was invalid
+ @retval other Error installing FMP
+
+**/
+EFI_STATUS
+EFIAPI
+InstallFmpInstance (
+ IN EFI_HANDLE Handle
+ )
+{
+ EFI_STATUS Status;
+ EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;
+ FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private;
+
+ //
+ // Only allow a single FMP Protocol instance to be installed
+ //
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEfiFirmwareManagementProtocolGuid,
+ (VOID **)&Fmp,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (!EFI_ERROR (Status)) {
+ return EFI_ALREADY_STARTED;
+ }
+
+ //
+ // Allocate FMP Protocol instance
+ //
+ Private = AllocateCopyPool (
+ sizeof (mFirmwareManagementPrivateDataTemplate),
+ &mFirmwareManagementPrivateDataTemplate
+ );
+ if (Private == NULL) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Failed to allocate memory for private structure.\n", mImageIdName));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto cleanup;
+ }
+
+ //
+ // Initialize private context data structure
+ //
+ Private->Handle = Handle;
+ Private->FmpDeviceContext = NULL;
+ Status = FmpDeviceSetContext (Private->Handle, &Private->FmpDeviceContext);
+ if (Status == EFI_UNSUPPORTED) {
+ Private->FmpDeviceContext = NULL;
+ } else if (EFI_ERROR (Status)) {
+ goto cleanup;
+ }
+
+ //
+ // Make sure the descriptor has already been loaded or refreshed
+ //
+ PopulateDescriptor (Private);
+
+ if (IsLockFmpDeviceAtLockEventGuidRequired ()) {
+ //
+ // Register all UEFI Variables used by this module to be locked.
+ //
+ Status = LockAllFmpVariables (Private);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Failed to register variables to lock. Status = %r.\n", mImageIdName, Status));
+ } else {
+ DEBUG ((DEBUG_INFO, "FmpDxe(%s): All variables registered to lock\n", mImageIdName));
+ }
+
+ //
+ // Create and register notify function to lock the FMP device.
+ //
+ Status = gBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ FmpDxeLockEventNotify,
+ Private,
+ mLockGuid,
+ &Private->FmpDeviceLockEvent
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Failed to register notification. Status = %r\n", mImageIdName, Status));
+ }
+ ASSERT_EFI_ERROR (Status);
+ } else {
+ DEBUG ((DEBUG_VERBOSE, "FmpDxe(%s): Not registering notification to call FmpDeviceLock() because mfg mode\n", mImageIdName));
+ }
+
+ //
+ // Install FMP Protocol and FMP Progress Protocol
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Private->Handle,
+ &gEfiFirmwareManagementProtocolGuid, &Private->Fmp,
+ &gEdkiiFirmwareManagementProgressProtocolGuid, &mFmpProgress,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Protocol install error. Status = %r.\n", mImageIdName, Status));
+ goto cleanup;
+ }
+
+cleanup:
+
+ if (EFI_ERROR (Status)) {
+ if (Private != NULL) {
+ if (Private->FmpDeviceLockEvent != NULL) {
+ gBS->CloseEvent (Private->FmpDeviceLockEvent);
+ }
+ if (Private->Descriptor.VersionName != NULL) {
+ FreePool (Private->Descriptor.VersionName);
+ }
+ if (Private->FmpDeviceContext != NULL) {
+ FmpDeviceSetContext (NULL, &Private->FmpDeviceContext);
+ }
+ if (Private->VersionVariableName != NULL) {
+ FreePool (Private->VersionVariableName);
+ }
+ if (Private->LsvVariableName != NULL) {
+ FreePool (Private->LsvVariableName);
+ }
+ if (Private->LastAttemptStatusVariableName != NULL) {
+ FreePool (Private->LastAttemptStatusVariableName);
+ }
+ if (Private->LastAttemptVersionVariableName != NULL) {
+ FreePool (Private->LastAttemptVersionVariableName);
+ }
+ if (Private->FmpStateVariableName != NULL) {
+ FreePool (Private->FmpStateVariableName);
+ }
+ FreePool (Private);
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Function to uninstall FMP instance.
+
+ @param[in] Handle The device handle to install a FMP instance on.
+
+ @retval EFI_SUCCESS FMP Installed
+ @retval EFI_INVALID_PARAMETER Handle was invalid
+ @retval other Error installing FMP
+
+**/
+EFI_STATUS
+EFIAPI
+UninstallFmpInstance (
+ IN EFI_HANDLE Handle
+ )
+{
+ EFI_STATUS Status;
+ EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;
+ FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private;
+
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEfiFirmwareManagementProtocolGuid,
+ (VOID **)&Fmp,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Protocol open error. Status = %r.\n", mImageIdName, Status));
+ return Status;
+ }
+
+ Private = FIRMWARE_MANAGEMENT_PRIVATE_DATA_FROM_THIS (Fmp);
+ FmpDeviceSetContext (Private->Handle, &Private->FmpDeviceContext);
+
+ if (Private->FmpDeviceLockEvent != NULL) {
+ gBS->CloseEvent (Private->FmpDeviceLockEvent);
+ }
+
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ Private->Handle,
+ &gEfiFirmwareManagementProtocolGuid, &Private->Fmp,
+ &gEdkiiFirmwareManagementProgressProtocolGuid, &mFmpProgress,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Protocol uninstall error. Status = %r.\n", mImageIdName, Status));
+ return Status;
+ }
+
+ if (Private->Descriptor.VersionName != NULL) {
+ FreePool (Private->Descriptor.VersionName);
+ }
+ if (Private->FmpDeviceContext != NULL) {
+ FmpDeviceSetContext (NULL, &Private->FmpDeviceContext);
+ }
+ if (Private->VersionVariableName != NULL) {
+ FreePool (Private->VersionVariableName);
+ }
+ if (Private->LsvVariableName != NULL) {
+ FreePool (Private->LsvVariableName);
+ }
+ if (Private->LastAttemptStatusVariableName != NULL) {
+ FreePool (Private->LastAttemptStatusVariableName);
+ }
+ if (Private->LastAttemptVersionVariableName != NULL) {
+ FreePool (Private->LastAttemptVersionVariableName);
+ }
+ if (Private->FmpStateVariableName != NULL) {
+ FreePool (Private->FmpStateVariableName);
+ }
+ FreePool (Private);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Unloads the application and its installed protocol.
+
+ @param ImageHandle Handle that identifies the image to be unloaded.
+ @param SystemTable The system table.
+
+ @retval EFI_SUCCESS The image has been unloaded.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDxeLibDestructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ if (mFmpSingleInstance) {
+ return UninstallFmpInstance (ImageHandle);
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Main entry for this driver/library.
+
+ @param[in] ImageHandle Image handle this driver.
+ @param[in] SystemTable Pointer to SystemTable.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDxeEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Verify that a new FILE_GUID value has been provided in the <Defines>
+ // section of this module. The FILE_GUID is the ESRT GUID that must be
+ // unique for each updatable firmware image.
+ //
+ if (CompareGuid (&mDefaultModuleFileGuid, &gEfiCallerIdGuid)) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe: Use of default FILE_GUID detected. FILE_GUID must be set to a unique value.\n"));
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Get the ImageIdName value for the EFI_FIRMWARE_IMAGE_DESCRIPTOR from a PCD.
+ //
+ mImageIdName = (CHAR16 *) PcdGetPtr (PcdFmpDeviceImageIdName);
+ if (PcdGetSize (PcdFmpDeviceImageIdName) <= 2 || mImageIdName[0] == 0) {
+ //
+ // PcdFmpDeviceImageIdName must be set to a non-empty Unicode string
+ //
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%g): PcdFmpDeviceImageIdName is an empty string.\n", &gEfiCallerIdGuid));
+ ASSERT (FALSE);
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Detects if PcdFmpDevicePkcs7CertBufferXdr contains a test key.
+ //
+ DetectTestKey ();
+
+ //
+ // Fill in FMP Progress Protocol fields for Version 1
+ //
+ mFmpProgress.Version = 1;
+ mFmpProgress.ProgressBarForegroundColor.Raw = PcdGet32 (PcdFmpDeviceProgressColor);
+ mFmpProgress.WatchdogSeconds = PcdGet8 (PcdFmpDeviceProgressWatchdogTimeInSeconds);
+
+ // The lock event GUID is retrieved from PcdFmpDeviceLockEventGuid.
+ // If PcdFmpDeviceLockEventGuid is not the size of an EFI_GUID, then
+ // gEfiEndOfDxeEventGroupGuid is used.
+ //
+ mLockGuid = &gEfiEndOfDxeEventGroupGuid;
+ if (PcdGetSize (PcdFmpDeviceLockEventGuid) == sizeof (EFI_GUID)) {
+ mLockGuid = (EFI_GUID *)PcdGetPtr (PcdFmpDeviceLockEventGuid);
+ }
+ DEBUG ((DEBUG_INFO, "FmpDxe(%s): Lock GUID: %g\n", mImageIdName, mLockGuid));
+
+ //
+ // Register with library the install function so if the library uses
+ // UEFI driver model/driver binding protocol it can install FMP on its device handle
+ // If library is simple lib that does not use driver binding then it should return
+ // unsupported and this will install the FMP instance on the ImageHandle
+ //
+ Status = RegisterFmpInstaller (InstallFmpInstance);
+ if (Status == EFI_UNSUPPORTED) {
+ mFmpSingleInstance = TRUE;
+ DEBUG ((DEBUG_INFO, "FmpDxe(%s): FmpDeviceLib registration returned EFI_UNSUPPORTED. Installing single FMP instance.\n", mImageIdName));
+ Status = RegisterFmpUninstaller (UninstallFmpInstance);
+ if (Status == EFI_UNSUPPORTED) {
+ Status = InstallFmpInstance (ImageHandle);
+ } else {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): FmpDeviceLib RegisterFmpInstaller and RegisterFmpUninstaller do not match.\n", mImageIdName));
+ Status = EFI_UNSUPPORTED;
+ }
+ } else if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): FmpDeviceLib registration returned %r. No FMP installed.\n", mImageIdName, Status));
+ } else {
+ DEBUG ((
+ DEBUG_INFO,
+ "FmpDxe(%s): FmpDeviceLib registration returned EFI_SUCCESS. Expect FMP to be installed during the BDS/Device connection phase.\n",
+ mImageIdName
+ ));
+ Status = RegisterFmpUninstaller (UninstallFmpInstance);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): FmpDeviceLib RegisterFmpInstaller and RegisterFmpUninstaller do not match.\n", mImageIdName));
+ }
+ }
+
+ return Status;
+}
diff --git a/roms/edk2/FmpDevicePkg/FmpDxe/FmpDxe.h b/roms/edk2/FmpDevicePkg/FmpDxe/FmpDxe.h new file mode 100644 index 000000000..30754dea4 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/FmpDxe/FmpDxe.h @@ -0,0 +1,359 @@ +/** @file
+ Produces a Firmware Management Protocol that supports updates to a firmware
+ image stored in a firmware device with platform and firmware device specific
+ information provided through PCDs and libraries.
+
+ Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
+ Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _FMP_DXE_H_
+#define _FMP_DXE_H_
+
+#include <PiDxe.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseCryptLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiLib.h>
+#include <Library/PrintLib.h>
+#include <Library/FmpAuthenticationLib.h>
+#include <Library/FmpDeviceLib.h>
+#include <Library/FmpPayloadHeaderLib.h>
+#include <Library/CapsuleUpdatePolicyLib.h>
+#include <Library/FmpDependencyLib.h>
+#include <Library/FmpDependencyCheckLib.h>
+#include <Library/FmpDependencyDeviceLib.h>
+#include <Protocol/FirmwareManagement.h>
+#include <Protocol/FirmwareManagementProgress.h>
+#include <Protocol/VariableLock.h>
+#include <Guid/SystemResourceTable.h>
+#include <Guid/EventGroup.h>
+
+#define VERSION_STRING_NOT_SUPPORTED L"VERSION STRING NOT SUPPORTED"
+#define VERSION_STRING_NOT_AVAILABLE L"VERSION STRING NOT AVAILABLE"
+
+///
+///
+///
+#define FIRMWARE_MANAGEMENT_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('f','m','p','p')
+
+typedef struct {
+ UINTN Signature;
+ EFI_HANDLE Handle;
+ EFI_FIRMWARE_MANAGEMENT_PROTOCOL Fmp;
+ BOOLEAN DescriptorPopulated;
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR Descriptor;
+ CHAR16 *ImageIdName;
+ CHAR16 *VersionName;
+ BOOLEAN RuntimeVersionSupported;
+ EFI_EVENT FmpDeviceLockEvent;
+ //
+ // Indicates if an attempt has been made to lock a
+ // FLASH storage device by calling FmpDeviceLock().
+ // A FLASH storage device may not support being locked,
+ // so this variable is set to TRUE even if FmpDeviceLock()
+ // returns an error.
+ //
+ BOOLEAN FmpDeviceLocked;
+ VOID *FmpDeviceContext;
+ CHAR16 *VersionVariableName;
+ CHAR16 *LsvVariableName;
+ CHAR16 *LastAttemptStatusVariableName;
+ CHAR16 *LastAttemptVersionVariableName;
+ CHAR16 *FmpStateVariableName;
+ BOOLEAN DependenciesSatisfied;
+} FIRMWARE_MANAGEMENT_PRIVATE_DATA;
+
+///
+///
+///
+#define FIRMWARE_MANAGEMENT_PRIVATE_DATA_FROM_THIS(a) \
+ CR (a, FIRMWARE_MANAGEMENT_PRIVATE_DATA, Fmp, FIRMWARE_MANAGEMENT_PRIVATE_DATA_SIGNATURE)
+
+///
+/// Null-terminated Unicode string retrieved from PcdFmpDeviceImageIdName.
+///
+extern CHAR16 *mImageIdName;
+
+/**
+ Check to see if any of the keys in PcdFmpDevicePkcs7CertBufferXdr matches
+ the test key. PcdFmpDeviceTestKeySha256Digest contains the SHA256 hash of
+ the test key. For each key in PcdFmpDevicePkcs7CertBufferXdr, compute the
+ SHA256 hash and compare it to PcdFmpDeviceTestKeySha256Digest. If the
+ SHA256 hash matches or there is then error computing the SHA256 hash, then
+ set PcdTestKeyUsed to TRUE. Skip this check if PcdTestKeyUsed is already
+ TRUE or PcdFmpDeviceTestKeySha256Digest is not exactly SHA256_DIGEST_SIZE
+ bytes.
+**/
+VOID
+DetectTestKey (
+ VOID
+ );
+
+/**
+ Returns information about the current firmware image(s) of the device.
+
+ This function allows a copy of the current firmware image to be created and saved.
+ The saved copy could later been used, for example, in firmware image recovery or rollback.
+
+ @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
+ @param[in, out] ImageInfoSize A pointer to the size, in bytes, of the ImageInfo buffer.
+ On input, this is the size of the buffer allocated by the caller.
+ On output, it is the size of the buffer returned by the firmware
+ if the buffer was large enough, or the size of the buffer needed
+ to contain the image(s) information if the buffer was too small.
+ @param[in, out] ImageInfo A pointer to the buffer in which firmware places the current image(s)
+ information. The information is an array of EFI_FIRMWARE_IMAGE_DESCRIPTORs.
+ @param[out] DescriptorVersion A pointer to the location in which firmware returns the version number
+ associated with the EFI_FIRMWARE_IMAGE_DESCRIPTOR.
+ @param[out] DescriptorCount A pointer to the location in which firmware returns the number of
+ descriptors or firmware images within this device.
+ @param[out] DescriptorSize A pointer to the location in which firmware returns the size, in bytes,
+ of an individual EFI_FIRMWARE_IMAGE_DESCRIPTOR.
+ @param[out] PackageVersion A version number that represents all the firmware images in the device.
+ The format is vendor specific and new version must have a greater value
+ than the old version. If PackageVersion is not supported, the value is
+ 0xFFFFFFFF. A value of 0xFFFFFFFE indicates that package version comparison
+ is to be performed using PackageVersionName. A value of 0xFFFFFFFD indicates
+ that package version update is in progress.
+ @param[out] PackageVersionName A pointer to a pointer to a null-terminated string representing the
+ package version name. 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_BUFFER_TOO_SMALL The ImageInfo buffer was too small. The current buffer size
+ needed to hold the image(s) information is returned in ImageInfoSize.
+ @retval EFI_INVALID_PARAMETER ImageInfoSize is NULL.
+ @retval EFI_DEVICE_ERROR Valid information could not be returned. Possible corrupted image.
+
+**/
+EFI_STATUS
+EFIAPI
+GetTheImageInfo (
+ IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
+ IN OUT UINTN *ImageInfoSize,
+ IN OUT EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageInfo,
+ OUT UINT32 *DescriptorVersion,
+ OUT UINT8 *DescriptorCount,
+ OUT UINTN *DescriptorSize,
+ OUT UINT32 *PackageVersion,
+ OUT CHAR16 **PackageVersionName
+ );
+
+/**
+ Retrieves a copy of the current firmware image of the device.
+
+ This function allows a copy of the current firmware image to be created and saved.
+ The saved copy could later been used, for example, in firmware image recovery or rollback.
+
+ @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
+ @param[in] ImageIndex A unique number identifying the firmware image(s) within the device.
+ The number is between 1 and DescriptorCount.
+ @param[in, out] Image Points to the buffer where the current image is copied to.
+ @param[in, out] ImageSize On entry, points to the size of the buffer pointed to by Image, in bytes.
+ On return, points to the length of the image, in bytes.
+
+ @retval EFI_SUCCESS The device was successfully updated with the new image.
+ @retval EFI_BUFFER_TOO_SMALL The buffer specified by ImageSize is too small to hold the
+ image. The current buffer size needed to hold the image is returned
+ in ImageSize.
+ @retval EFI_INVALID_PARAMETER The Image was NULL.
+ @retval EFI_NOT_FOUND The current image is not copied to the buffer.
+ @retval EFI_UNSUPPORTED The operation is not supported.
+ @retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.
+
+**/
+EFI_STATUS
+EFIAPI
+GetTheImage (
+ IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
+ IN UINT8 ImageIndex,
+ IN OUT VOID *Image,
+ IN OUT UINTN *ImageSize
+ );
+
+
+/**
+ Checks if the firmware image is valid for the device.
+
+ This function allows firmware update application to validate the firmware image without
+ invoking the SetImage() first.
+
+ @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
+ @param[in] ImageIndex A unique number identifying the firmware image(s) within the device.
+ The number is between 1 and DescriptorCount.
+ @param[in] Image Points to the new image.
+ @param[in] ImageSize Size of the new image in bytes.
+ @param[out] ImageUpdatable Indicates if the new image is valid for update. It also provides,
+ if available, additional information if the image is invalid.
+
+ @retval EFI_SUCCESS The image was successfully checked.
+ @retval EFI_ABORTED The operation is aborted.
+ @retval EFI_INVALID_PARAMETER The Image was NULL.
+ @retval EFI_UNSUPPORTED The operation is not supported.
+ @retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.
+
+**/
+EFI_STATUS
+EFIAPI
+CheckTheImage (
+ IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
+ IN UINT8 ImageIndex,
+ IN CONST VOID *Image,
+ IN UINTN ImageSize,
+ OUT UINT32 *ImageUpdatable
+ );
+
+/**
+ 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 authentication if image has attribute
+ IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED. The function returns
+ EFI_SECURITY_VIOLATION if the validation fails.
+ - 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] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
+ @param[in] ImageIndex A unique number identifying the firmware image(s) within the device.
+ The number is between 1 and DescriptorCount.
+ @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[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.
+ @retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.
+
+**/
+EFI_STATUS
+EFIAPI
+SetTheImage (
+ IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
+ IN UINT8 ImageIndex,
+ IN CONST VOID *Image,
+ IN UINTN ImageSize,
+ IN CONST VOID *VendorCode,
+ IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress,
+ OUT CHAR16 **AbortReason
+ );
+
+/**
+ Returns information about the firmware package.
+
+ This function returns package information.
+
+ @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
+ @param[out] PackageVersion A version number that represents all the firmware images in the device.
+ The format is vendor specific and new version must have a greater value
+ than the old version. If PackageVersion is not supported, the value is
+ 0xFFFFFFFF. A value of 0xFFFFFFFE indicates that package version
+ comparison is to be performed using PackageVersionName. A value of
+ 0xFFFFFFFD indicates that package version update is in progress.
+ @param[out] PackageVersionName A pointer to a pointer to a null-terminated string representing
+ the package version name. 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[out] PackageVersionNameMaxLen The maximum length of package version name if device supports update of
+ package version name. A value of 0 indicates the device does not support
+ update of package version name. Length is the number of Unicode characters,
+ including the terminating null character.
+ @param[out] AttributesSupported Package attributes that are supported by this device. See 'Package Attribute
+ Definitions' for possible returned values of this parameter. A value of 1
+ indicates the attribute is supported and the current setting value is
+ indicated in AttributesSetting. A value of 0 indicates the attribute is not
+ supported and the current setting value in AttributesSetting is meaningless.
+ @param[out] AttributesSetting Package attributes. See 'Package Attribute Definitions' for possible returned
+ values of this parameter
+
+ @retval EFI_SUCCESS The package information was successfully returned.
+ @retval EFI_UNSUPPORTED The operation is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+GetPackageInfo (
+ IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
+ OUT UINT32 *PackageVersion,
+ OUT CHAR16 **PackageVersionName,
+ OUT UINT32 *PackageVersionNameMaxLen,
+ OUT UINT64 *AttributesSupported,
+ OUT UINT64 *AttributesSetting
+ );
+
+/**
+ Updates information about the firmware package.
+
+ This function updates package information.
+ This function returns EFI_UNSUPPORTED if the package information is not updatable.
+ VendorCode enables vendor to implement vendor-specific package information update policy.
+ Null if the caller did not specify this policy or use the default policy.
+
+ @param[in] This A pointer to the EFI_FIRMWARE_MANAGEMENT_PROTOCOL instance.
+ @param[in] Image Points to the authentication image.
+ Null if authentication is not required.
+ @param[in] ImageSize Size of the authentication image in bytes.
+ 0 if authentication is not required.
+ @param[in] VendorCode This enables vendor to implement vendor-specific firmware
+ image update policy.
+ Null indicates the caller did not specify this policy or use
+ the default policy.
+ @param[in] PackageVersion The new package version.
+ @param[in] PackageVersionName A pointer to the new null-terminated Unicode string representing
+ the package version name.
+ The string length is equal to or less than the value returned in
+ PackageVersionNameMaxLen.
+
+ @retval EFI_SUCCESS The device was successfully updated with the new package
+ information.
+ @retval EFI_INVALID_PARAMETER The PackageVersionName length is longer than the value
+ returned in PackageVersionNameMaxLen.
+ @retval EFI_UNSUPPORTED The operation is not supported.
+ @retval EFI_SECURITY_VIOLATION The operation could not be performed due to an authentication failure.
+
+**/
+EFI_STATUS
+EFIAPI
+SetPackageInfo (
+ IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
+ IN CONST VOID *Image,
+ IN UINTN ImageSize,
+ IN CONST VOID *VendorCode,
+ IN UINT32 PackageVersion,
+ IN CONST CHAR16 *PackageVersionName
+ );
+
+#endif
diff --git a/roms/edk2/FmpDevicePkg/FmpDxe/FmpDxe.inf b/roms/edk2/FmpDevicePkg/FmpDxe/FmpDxe.inf new file mode 100644 index 000000000..eeb904a09 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/FmpDxe/FmpDxe.inf @@ -0,0 +1,83 @@ +## @file
+# Produces a Firmware Management Protocol that supports updates to a firmware
+# image stored in a firmware device with platform and firmware device specific
+# information provided through PCDs and libraries.
+#
+# Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
+# Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FmpDxe
+ MODULE_UNI_FILE = FmpDxe.uni
+ FILE_GUID = 78EF0A56-1CF0-4535-B5DA-F6FD2F405A11
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = FmpDxeEntryPoint
+ UNLOAD_IMAGE = UninstallFmpInstance
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
+#
+
+[Sources]
+ FmpDxe.c
+ FmpDxe.h
+ DetectTestKey.c
+ VariableSupport.h
+ VariableSupport.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ CryptoPkg/CryptoPkg.dec
+ FmpDevicePkg/FmpDevicePkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ DebugLib
+ BaseLib
+ BaseMemoryLib
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+ PrintLib
+ UefiLib
+ BaseCryptLib
+ FmpAuthenticationLib
+ FmpDeviceLib
+ FmpPayloadHeaderLib
+ CapsuleUpdatePolicyLib
+ FmpDependencyLib
+ FmpDependencyCheckLib
+ FmpDependencyDeviceLib
+
+[Guids]
+ gEfiEndOfDxeEventGroupGuid
+
+[Protocols]
+ gEdkiiVariableLockProtocolGuid ## CONSUMES
+ gEfiFirmwareManagementProtocolGuid ## PRODUCES
+ gEdkiiFirmwareManagementProgressProtocolGuid ## PRODUCES
+
+[Pcd]
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceStorageAccessEnable ## CONSUMES
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageIdName ## CONSUMES
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceBuildTimeLowestSupportedVersion ## CONSUMES
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceLockEventGuid ## CONSUMES
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceProgressWatchdogTimeInSeconds ## CONSUMES
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceProgressColor ## CONSUMES
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr ## CONSUMES
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceTestKeySha256Digest ## CONSUMES
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageTypeIdGuid ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdTestKeyUsed ## SOMETIMES_PRODUCES
+
+[Depex]
+ gEfiVariableWriteArchProtocolGuid AND gEdkiiVariableLockProtocolGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ FmpDxeExtra.uni
diff --git a/roms/edk2/FmpDevicePkg/FmpDxe/FmpDxe.uni b/roms/edk2/FmpDevicePkg/FmpDxe/FmpDxe.uni new file mode 100644 index 000000000..6f6f7f2cf --- /dev/null +++ b/roms/edk2/FmpDevicePkg/FmpDxe/FmpDxe.uni @@ -0,0 +1,14 @@ +// /** @file
+// Produces a Firmware Management Protocol that supports updates to a firmware
+// image stored in a firmware device with platform and firmware device specific
+// information provided through PCDs and libraries.
+//
+// Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_MODULE_ABSTRACT #language en-US "Produces a Firmware Management Protocol to support firmware updates"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Produces a Firmware Management Protocol that supports updates to a firmware image stored in a firmware device with platform and firmware device specific information provided through PCDs and libraries."
diff --git a/roms/edk2/FmpDevicePkg/FmpDxe/FmpDxeExtra.uni b/roms/edk2/FmpDevicePkg/FmpDxe/FmpDxeExtra.uni new file mode 100644 index 000000000..8877ae80f --- /dev/null +++ b/roms/edk2/FmpDevicePkg/FmpDxe/FmpDxeExtra.uni @@ -0,0 +1,12 @@ +// /** @file
+// FmpDxe Localized Strings and Content
+//
+// Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"Firmware Management Protocol DXE DXE Driver"
diff --git a/roms/edk2/FmpDevicePkg/FmpDxe/FmpDxeLib.inf b/roms/edk2/FmpDevicePkg/FmpDxe/FmpDxeLib.inf new file mode 100644 index 000000000..9a93b5e6a --- /dev/null +++ b/roms/edk2/FmpDevicePkg/FmpDxe/FmpDxeLib.inf @@ -0,0 +1,80 @@ +## @file
+# Produces a Firmware Management Protocol that supports updates to a firmware
+# image stored in a firmware device with platform and firmware device specific
+# information provided through PCDs and libraries.
+#
+# Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
+# Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FmpDxeLib
+ MODULE_UNI_FILE = FmpDxe.uni
+ FILE_GUID = 4B11717A-30B3-4122-8C69-8E0D5E141C32
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = NULL
+ CONSTRUCTOR = FmpDxeEntryPoint
+ DESTRUCTOR = FmpDxeLibDestructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
+#
+
+[Sources]
+ FmpDxe.c
+ FmpDxe.h
+ DetectTestKey.c
+ VariableSupport.h
+ VariableSupport.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ CryptoPkg/CryptoPkg.dec
+ FmpDevicePkg/FmpDevicePkg.dec
+
+[LibraryClasses]
+ DebugLib
+ BaseLib
+ BaseMemoryLib
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+ PrintLib
+ UefiLib
+ BaseCryptLib
+ FmpAuthenticationLib
+ FmpDeviceLib
+ FmpPayloadHeaderLib
+ CapsuleUpdatePolicyLib
+ FmpDependencyLib
+ FmpDependencyCheckLib
+ FmpDependencyDeviceLib
+
+[Guids]
+ gEfiEndOfDxeEventGroupGuid
+
+[Protocols]
+ gEdkiiVariableLockProtocolGuid ## CONSUMES
+ gEfiFirmwareManagementProtocolGuid ## PRODUCES
+ gEdkiiFirmwareManagementProgressProtocolGuid ## PRODUCES
+
+[Pcd]
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceStorageAccessEnable ## CONSUMES
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageIdName ## CONSUMES
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceBuildTimeLowestSupportedVersion ## CONSUMES
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceLockEventGuid ## CONSUMES
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceProgressWatchdogTimeInSeconds ## CONSUMES
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceProgressColor ## CONSUMES
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDevicePkcs7CertBufferXdr ## CONSUMES
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceTestKeySha256Digest ## CONSUMES
+ gFmpDevicePkgTokenSpaceGuid.PcdFmpDeviceImageTypeIdGuid ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdTestKeyUsed ## SOMETIMES_PRODUCES
+
+[Depex]
+ gEfiVariableWriteArchProtocolGuid AND gEdkiiVariableLockProtocolGuid
diff --git a/roms/edk2/FmpDevicePkg/FmpDxe/VariableSupport.c b/roms/edk2/FmpDevicePkg/FmpDxe/VariableSupport.c new file mode 100644 index 000000000..86dd5b203 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/FmpDxe/VariableSupport.c @@ -0,0 +1,798 @@ +/** @file
+ UEFI variable support functions for Firmware Management Protocol based
+ firmware updates.
+
+ Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
+ Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "FmpDxe.h"
+#include "VariableSupport.h"
+
+/**
+ Retrieve the value of a 32-bit UEFI Variable specified by VariableName and
+ a GUID of gEfiCallerIdGuid.
+
+ @param[in] VariableName Pointer to the UEFI Variable name to retrieve.
+ @param[out] Valid Set to TRUE if UEFI Variable is present and the size
+ of the UEFI Variable value is 32-bits. Otherwise
+ FALSE.
+ @param[out] Value If Valid is set to TRUE, then the 32-bit value of
+ the UEFI Variable. Otherwise 0.
+**/
+static
+VOID
+GetFmpVariable (
+ IN CHAR16 *VariableName,
+ OUT BOOLEAN *Valid,
+ OUT UINT32 *Value
+ )
+{
+ EFI_STATUS Status;
+ UINTN Size;
+ UINT32 *Buffer;
+
+ *Valid = FALSE;
+ *Value = 0;
+ Size = 0;
+ Buffer = NULL;
+ Status = GetVariable2 (
+ VariableName,
+ &gEfiCallerIdGuid,
+ (VOID **)&Buffer,
+ &Size
+ );
+ if (!EFI_ERROR (Status) && Size == sizeof (*Value) && Buffer != NULL) {
+ *Valid = TRUE;
+ *Value = *Buffer;
+ }
+ if (Buffer != NULL) {
+ FreePool (Buffer);
+ }
+}
+
+/**
+ Delete the UEFI Variable with name specified by VariableName and GUID of
+ gEfiCallerIdGuid. If the variable can not be deleted, then print a
+ DEBUG_ERROR message.
+
+ @param[in] VariableName Pointer to the UEFI Variable name to delete.
+**/
+static
+VOID
+DeleteFmpVariable (
+ IN CHAR16 *VariableName
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN Valid;
+ UINT32 Value;
+
+ GetFmpVariable (VariableName, &Valid, &Value);
+ if (Valid) {
+ Status = gRT->SetVariable (VariableName, &gEfiCallerIdGuid, 0, 0, NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Failed to delete variable %s. Status = %r\n", mImageIdName, VariableName, Status));
+ } else {
+ DEBUG ((DEBUG_INFO, "FmpDxe(%s): Deleted variable %s\n", mImageIdName, VariableName));
+ }
+ }
+}
+
+/**
+ Retrieve the FMP Controller State UEFI Variable value. Return NULL if
+ the variable does not exist or if the size of the UEFI Variable is not the
+ size of FMP_CONTROLLER_STATE. The buffer for the UEFI Variable value
+ if allocated using the UEFI Boot Service AllocatePool().
+
+ @param[in] Private Private context structure for the managed controller.
+
+ @return Pointer to the allocated FMP Controller State. Returns NULL
+ if the variable does not exist or is a different size than expected.
+**/
+static
+FMP_CONTROLLER_STATE *
+GetFmpControllerState (
+ IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+ FMP_CONTROLLER_STATE *FmpControllerState;
+ UINTN Size;
+
+ FmpControllerState = NULL;
+ Size = 0;
+ Status = GetVariable2 (
+ Private->FmpStateVariableName,
+ &gEfiCallerIdGuid,
+ (VOID **)&FmpControllerState,
+ &Size
+ );
+ if (EFI_ERROR (Status) || FmpControllerState == NULL) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Failed to get the controller state. Status = %r\n", mImageIdName, Status));
+ } else {
+ if (Size == sizeof (*FmpControllerState)) {
+ return FmpControllerState;
+ }
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Getting controller state returned a size different than expected. Size = 0x%x\n", mImageIdName, Size));
+ }
+ if (FmpControllerState != NULL) {
+ FreePool (FmpControllerState);
+ }
+ return NULL;
+}
+
+/**
+ Generates a Null-terminated Unicode string UEFI Variable name from a base name
+ and a hardware instance. If the hardware instance value is 0, then the base
+ name is returned. If the hardware instance value is non-zero, then the 64-bit
+ hardware instance value is converted to a 16 character hex string and appended
+ to base name. The UEFI Variable name returned is allocated using the UEFI
+ Boot Service AllocatePool().
+
+ @param[in] HardwareInstance 64-bit hardware instance value.
+ @param[in] BaseVariableName Null-terminated Unicode string that is the base
+ name of the UEFI Variable.
+
+ @return Pointer to the allocated UEFI Variable name. Returns NULL if the
+ UEFI Variable can not be allocated.
+**/
+static
+CHAR16 *
+GenerateFmpVariableName (
+ IN UINT64 HardwareInstance,
+ IN CHAR16 *BaseVariableName
+ )
+{
+ UINTN Size;
+ CHAR16 *VariableName;
+
+ //
+ // Allocate Unicode string with room for BaseVariableName and a 16 digit
+ // hexadecimal value for the HardwareInstance value.
+ //
+ Size = StrSize (BaseVariableName) + 16 * sizeof (CHAR16);
+ VariableName = AllocateCopyPool (Size, BaseVariableName);
+ if (VariableName == NULL) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Failed to generate variable name %s.\n", mImageIdName, BaseVariableName));
+ return VariableName;
+ }
+ if (HardwareInstance == 0) {
+ return VariableName;
+ }
+ UnicodeValueToStringS (
+ &VariableName[StrLen(BaseVariableName)],
+ Size,
+ PREFIX_ZERO | RADIX_HEX,
+ HardwareInstance,
+ 16
+ );
+ return VariableName;
+}
+
+/**
+ Generate the names of the UEFI Variables used to store state information for
+ a managed controller. The UEFI Variables names are a combination of a base
+ name and an optional hardware instance value as a 16 character hex value. If
+ the hardware instance value is 0, then the 16 character hex value is not
+ included. These storage for the UEFI Variable names are allocated using the
+ UEFI Boot Service AllocatePool() and the pointers are stored in the Private.
+ The following are examples of variable names produces for hardware instance
+ value 0 and value 0x1234567812345678.
+
+ FmpVersion
+ FmpLsv
+ LastAttemptStatus
+ LastAttemptVersion
+ FmpState
+
+ FmpVersion1234567812345678
+ FmpLsv1234567812345678
+ LastAttemptStatus1234567812345678
+ LastAttemptVersion1234567812345678
+ FmpState1234567812345678
+
+ @param[in,out] Private Private context structure for the managed controller.
+**/
+VOID
+GenerateFmpVariableNames (
+ IN OUT FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+ VOID *Buffer;
+ FMP_CONTROLLER_STATE FmpControllerState;
+
+ if (Private->VersionVariableName != NULL) {
+ FreePool (Private->VersionVariableName);
+ }
+ if (Private->LsvVariableName != NULL) {
+ FreePool (Private->LsvVariableName);
+ }
+ if (Private->LastAttemptStatusVariableName != NULL) {
+ FreePool (Private->LastAttemptStatusVariableName);
+ }
+ if (Private->LastAttemptVersionVariableName != NULL) {
+ FreePool (Private->LastAttemptVersionVariableName);
+ }
+ if (Private->FmpStateVariableName != NULL) {
+ FreePool (Private->FmpStateVariableName);
+ }
+
+ Private->VersionVariableName = GenerateFmpVariableName (
+ Private->Descriptor.HardwareInstance,
+ VARNAME_VERSION
+ );
+ Private->LsvVariableName = GenerateFmpVariableName (
+ Private->Descriptor.HardwareInstance,
+ VARNAME_LSV
+ );
+ Private->LastAttemptStatusVariableName = GenerateFmpVariableName (
+ Private->Descriptor.HardwareInstance,
+ VARNAME_LASTATTEMPTSTATUS
+ );
+ Private->LastAttemptVersionVariableName = GenerateFmpVariableName (
+ Private->Descriptor.HardwareInstance,
+ VARNAME_LASTATTEMPTVERSION
+ );
+ Private->FmpStateVariableName = GenerateFmpVariableName (
+ Private->Descriptor.HardwareInstance,
+ VARNAME_FMPSTATE
+ );
+
+ DEBUG ((DEBUG_INFO, "FmpDxe(%s): Variable %g %s\n", mImageIdName, &gEfiCallerIdGuid, Private->VersionVariableName));
+ DEBUG ((DEBUG_INFO, "FmpDxe(%s): Variable %g %s\n", mImageIdName, &gEfiCallerIdGuid, Private->LsvVariableName));
+ DEBUG ((DEBUG_INFO, "FmpDxe(%s): Variable %g %s\n", mImageIdName, &gEfiCallerIdGuid, Private->LastAttemptStatusVariableName));
+ DEBUG ((DEBUG_INFO, "FmpDxe(%s): Variable %g %s\n", mImageIdName, &gEfiCallerIdGuid, Private->LastAttemptVersionVariableName));
+ DEBUG ((DEBUG_INFO, "FmpDxe(%s): Variable %g %s\n", mImageIdName, &gEfiCallerIdGuid, Private->FmpStateVariableName));
+
+ Buffer = GetFmpControllerState (Private);
+ if (Buffer != NULL) {
+ //
+ // FMP Controller State was found with correct size.
+ // Delete old variables if they exist.
+ //
+ FreePool (Buffer);
+ DeleteFmpVariable (Private->VersionVariableName);
+ DeleteFmpVariable (Private->LsvVariableName);
+ DeleteFmpVariable (Private->LastAttemptStatusVariableName);
+ DeleteFmpVariable (Private->LastAttemptVersionVariableName);
+ return;
+ }
+
+ //
+ // FMP Controller State was either not found or is wrong size.
+ // Create a new FMP Controller State variable with the correct size.
+ //
+ DEBUG ((DEBUG_INFO, "FmpDxe(%s): Create controller state\n", mImageIdName));
+ GetFmpVariable (
+ Private->VersionVariableName,
+ &FmpControllerState.VersionValid,
+ &FmpControllerState.Version
+ );
+ GetFmpVariable (
+ Private->LsvVariableName,
+ &FmpControllerState.LsvValid,
+ &FmpControllerState.Lsv
+ );
+ GetFmpVariable (
+ Private->LastAttemptStatusVariableName,
+ &FmpControllerState.LastAttemptStatusValid,
+ &FmpControllerState.LastAttemptStatus
+ );
+ GetFmpVariable (
+ Private->LastAttemptVersionVariableName,
+ &FmpControllerState.LastAttemptVersionValid,
+ &FmpControllerState.LastAttemptVersion
+ );
+ Status = gRT->SetVariable (
+ Private->FmpStateVariableName,
+ &gEfiCallerIdGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof (FmpControllerState),
+ &FmpControllerState
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // Failed to create FMP Controller State. In this case, do not
+ // delete the individual variables. They can be used again on next boot
+ // to create the FMP Controller State.
+ //
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Failed to create controller state. Status = %r\n", mImageIdName, Status));
+ } else {
+ DeleteFmpVariable (Private->VersionVariableName);
+ DeleteFmpVariable (Private->LsvVariableName);
+ DeleteFmpVariable (Private->LastAttemptStatusVariableName);
+ DeleteFmpVariable (Private->LastAttemptVersionVariableName);
+ }
+}
+
+/**
+ Returns the value used to fill in the Version field of the
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo()
+ service of the Firmware Management Protocol. The value is read from a UEFI
+ variable. If the UEFI variables does not exist, then a default version value
+ is returned.
+
+ UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpState"
+
+ @param[in] Private Private context structure for the managed controller.
+
+ @return The version of the firmware image in the firmware device.
+**/
+UINT32
+GetVersionFromVariable (
+ IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private
+ )
+{
+ FMP_CONTROLLER_STATE *FmpControllerState;
+ UINT32 Value;
+
+ Value = DEFAULT_VERSION;
+ FmpControllerState = GetFmpControllerState (Private);
+ if (FmpControllerState != NULL) {
+ if (FmpControllerState->VersionValid) {
+ Value = FmpControllerState->Version;
+ DEBUG ((DEBUG_INFO, "FmpDxe(%s): Get variable %g %s Version %08x\n",
+ mImageIdName,
+ &gEfiCallerIdGuid,
+ Private->FmpStateVariableName,
+ Value
+ ));
+ }
+ FreePool (FmpControllerState);
+ }
+ return Value;
+}
+
+/**
+ Returns the value used to fill in the LowestSupportedVersion field of the
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo()
+ service of the Firmware Management Protocol. The value is read from a UEFI
+ variable. If the UEFI variables does not exist, then a default lowest
+ supported version value is returned.
+
+ UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpState"
+
+ @param[in] Private Private context structure for the managed controller.
+
+ @return The lowest supported version of the firmware image in the firmware
+ device.
+**/
+UINT32
+GetLowestSupportedVersionFromVariable (
+ IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private
+ )
+{
+ FMP_CONTROLLER_STATE *FmpControllerState;
+ UINT32 Value;
+
+ Value = DEFAULT_LOWESTSUPPORTEDVERSION;
+ FmpControllerState = GetFmpControllerState (Private);
+ if (FmpControllerState != NULL) {
+ if (FmpControllerState->LsvValid) {
+ Value = FmpControllerState->Lsv;
+ DEBUG ((DEBUG_INFO, "FmpDxe(%s): Get variable %g %s LowestSupportedVersion %08x\n",
+ mImageIdName,
+ &gEfiCallerIdGuid,
+ Private->FmpStateVariableName,
+ Value
+ ));
+ }
+ FreePool (FmpControllerState);
+ }
+ return Value;
+}
+
+/**
+ Returns the value used to fill in the LastAttemptStatus field of the
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo()
+ service of the Firmware Management Protocol. The value is read from a UEFI
+ variable. If the UEFI variables does not exist, then a default last attempt
+ status value is returned.
+
+ UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpState"
+
+ @param[in] Private Private context structure for the managed controller.
+
+ @return The last attempt status value for the most recent capsule update.
+**/
+UINT32
+GetLastAttemptStatusFromVariable (
+ IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private
+ )
+{
+ FMP_CONTROLLER_STATE *FmpControllerState;
+ UINT32 Value;
+
+ Value = DEFAULT_LASTATTEMPTSTATUS;
+ FmpControllerState = GetFmpControllerState (Private);
+ if (FmpControllerState != NULL) {
+ if (FmpControllerState->LastAttemptStatusValid) {
+ Value = FmpControllerState->LastAttemptStatus;
+ DEBUG ((DEBUG_INFO, "FmpDxe(%s): Get variable %g %s LastAttemptStatus %08x\n",
+ mImageIdName,
+ &gEfiCallerIdGuid,
+ Private->FmpStateVariableName,
+ Value
+ ));
+ }
+ FreePool (FmpControllerState);
+ }
+ return Value;
+}
+
+/**
+ Returns the value used to fill in the LastAttemptVersion field of the
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo()
+ service of the Firmware Management Protocol. The value is read from a UEFI
+ variable. If the UEFI variables does not exist, then a default last attempt
+ version value is returned.
+
+ UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpState"
+
+ @param[in] Private Private context structure for the managed controller.
+
+ @return The last attempt version value for the most recent capsule update.
+**/
+UINT32
+GetLastAttemptVersionFromVariable (
+ IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private
+ )
+{
+ FMP_CONTROLLER_STATE *FmpControllerState;
+ UINT32 Value;
+
+ Value = DEFAULT_LASTATTEMPTVERSION;
+ FmpControllerState = GetFmpControllerState (Private);
+ if (FmpControllerState != NULL) {
+ if (FmpControllerState->LastAttemptVersionValid) {
+ Value = FmpControllerState->LastAttemptVersion;
+ DEBUG ((DEBUG_INFO, "FmpDxe(%s): Get variable %g %s LastAttemptVersion %08x\n",
+ mImageIdName,
+ &gEfiCallerIdGuid,
+ Private->FmpStateVariableName,
+ Value
+ ));
+ }
+ FreePool (FmpControllerState);
+ }
+ return Value;
+}
+
+/**
+ Saves the version current of the firmware image in the firmware device to a
+ UEFI variable.
+
+ UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpState"
+
+ @param[in] Private Private context structure for the managed controller.
+ @param[in] Version The version of the firmware image in the firmware device.
+**/
+VOID
+SetVersionInVariable (
+ IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private,
+ IN UINT32 Version
+ )
+{
+ EFI_STATUS Status;
+ FMP_CONTROLLER_STATE *FmpControllerState;
+ BOOLEAN Update;
+
+ FmpControllerState = GetFmpControllerState (Private);
+ if (FmpControllerState == NULL) {
+ //
+ // Can not update value if FMP Controller State does not exist.
+ // This variable is guaranteed to be created by GenerateFmpVariableNames().
+ //
+ return;
+ }
+
+ Update = FALSE;
+ if (!FmpControllerState->VersionValid) {
+ Update = TRUE;
+ }
+ if (FmpControllerState->Version != Version) {
+ Update = TRUE;
+ }
+ if (!Update) {
+ DEBUG ((DEBUG_INFO, "FmpDxe(%s): No need to update controller state. Same value as before.\n", mImageIdName));
+ } else {
+ FmpControllerState->VersionValid = TRUE;
+ FmpControllerState->Version = Version;
+ Status = gRT->SetVariable (
+ Private->FmpStateVariableName,
+ &gEfiCallerIdGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof (*FmpControllerState),
+ FmpControllerState
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Failed to update controller state. Status = %r\n", mImageIdName, Status));
+ } else {
+ DEBUG ((DEBUG_INFO, "FmpDxe(%s): Set variable %g %s Version %08x\n",
+ mImageIdName,
+ &gEfiCallerIdGuid,
+ Private->FmpStateVariableName,
+ Version
+ ));
+ }
+ }
+ FreePool (FmpControllerState);
+}
+
+/**
+ Saves the lowest supported version current of the firmware image in the
+ firmware device to a UEFI variable.
+
+ UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpState"
+
+ @param[in] Private Private context structure for the managed
+ controller.
+ @param[in] LowestSupportedVersion The lowest supported version of the
+ firmware image in the firmware device.
+**/
+VOID
+SetLowestSupportedVersionInVariable (
+ IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private,
+ IN UINT32 LowestSupportedVersion
+ )
+{
+ EFI_STATUS Status;
+ FMP_CONTROLLER_STATE *FmpControllerState;
+ BOOLEAN Update;
+
+ FmpControllerState = GetFmpControllerState (Private);
+ if (FmpControllerState == NULL) {
+ //
+ // Can not update value if FMP Controller State does not exist.
+ // This variable is guaranteed to be created by GenerateFmpVariableNames().
+ //
+ return;
+ }
+
+ Update = FALSE;
+ if (!FmpControllerState->LsvValid) {
+ Update = TRUE;
+ }
+ if (FmpControllerState->Lsv < LowestSupportedVersion) {
+ Update = TRUE;
+ }
+ if (!Update) {
+ DEBUG ((DEBUG_INFO, "FmpDxe(%s): No need to update controller state. Same value as before.\n", mImageIdName));
+ } else {
+ FmpControllerState->LsvValid = TRUE;
+ FmpControllerState->Lsv = LowestSupportedVersion;
+ Status = gRT->SetVariable (
+ Private->FmpStateVariableName,
+ &gEfiCallerIdGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof (*FmpControllerState),
+ FmpControllerState
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Failed to update controller state. Status = %r\n", mImageIdName, Status));
+ } else {
+ DEBUG ((DEBUG_INFO, "FmpDxe(%s): Set variable %g %s LowestSupportedVersion %08x\n",
+ mImageIdName,
+ &gEfiCallerIdGuid,
+ Private->FmpStateVariableName,
+ LowestSupportedVersion
+ ));
+ }
+ }
+ FreePool (FmpControllerState);
+}
+
+/**
+ Saves the last attempt status value of the most recent FMP capsule update to a
+ UEFI variable.
+
+ UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpState"
+
+ @param[in] Private Private context structure for the managed
+ controller.
+ @param[in] LastAttemptStatus The last attempt status of the most recent FMP
+ capsule update.
+**/
+VOID
+SetLastAttemptStatusInVariable (
+ IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private,
+ IN UINT32 LastAttemptStatus
+ )
+{
+ EFI_STATUS Status;
+ FMP_CONTROLLER_STATE *FmpControllerState;
+ BOOLEAN Update;
+
+ FmpControllerState = GetFmpControllerState (Private);
+ if (FmpControllerState == NULL) {
+ //
+ // Can not update value if FMP Controller State does not exist.
+ // This variable is guaranteed to be created by GenerateFmpVariableNames().
+ //
+ return;
+ }
+
+ Update = FALSE;
+ if (!FmpControllerState->LastAttemptStatusValid) {
+ Update = TRUE;
+ }
+ if (FmpControllerState->LastAttemptStatus != LastAttemptStatus) {
+ Update = TRUE;
+ }
+ if (!Update) {
+ DEBUG ((DEBUG_INFO, "FmpDxe(%s): No need to update controller state. Same value as before.\n", mImageIdName));
+ } else {
+ FmpControllerState->LastAttemptStatusValid = TRUE;
+ FmpControllerState->LastAttemptStatus = LastAttemptStatus;
+ Status = gRT->SetVariable (
+ Private->FmpStateVariableName,
+ &gEfiCallerIdGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof (*FmpControllerState),
+ FmpControllerState
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Failed to update controller state. Status = %r\n", mImageIdName, Status));
+ } else {
+ DEBUG ((DEBUG_INFO, "FmpDxe(%s): Set variable %g %s LastAttemptStatus %08x\n",
+ mImageIdName,
+ &gEfiCallerIdGuid,
+ Private->FmpStateVariableName,
+ LastAttemptStatus
+ ));
+ }
+ }
+ FreePool (FmpControllerState);
+}
+
+/**
+ Saves the last attempt version value of the most recent FMP capsule update to
+ a UEFI variable.
+
+ UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpState"
+
+ @param[in] Private Private context structure for the managed
+ controller.
+ @param[in] LastAttemptVersion The last attempt version value of the most
+ recent FMP capsule update.
+**/
+VOID
+SetLastAttemptVersionInVariable (
+ IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private,
+ IN UINT32 LastAttemptVersion
+ )
+{
+ EFI_STATUS Status;
+ FMP_CONTROLLER_STATE *FmpControllerState;
+ BOOLEAN Update;
+
+ FmpControllerState = GetFmpControllerState (Private);
+ if (FmpControllerState == NULL) {
+ //
+ // Can not update value if FMP Controller State does not exist.
+ // This variable is guaranteed to be created by GenerateFmpVariableNames().
+ //
+ return;
+ }
+
+ Update = FALSE;
+ if (!FmpControllerState->LastAttemptVersionValid) {
+ Update = TRUE;
+ }
+ if (FmpControllerState->LastAttemptVersion != LastAttemptVersion) {
+ Update = TRUE;
+ }
+ if (!Update) {
+ DEBUG ((DEBUG_INFO, "FmpDxe(%s): No need to update controller state. Same value as before.\n", mImageIdName));
+ } else {
+ FmpControllerState->LastAttemptVersionValid = TRUE;
+ FmpControllerState->LastAttemptVersion = LastAttemptVersion;
+ Status = gRT->SetVariable (
+ Private->FmpStateVariableName,
+ &gEfiCallerIdGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof (*FmpControllerState),
+ FmpControllerState
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Failed to update controller state. Status = %r\n", mImageIdName, Status));
+ } else {
+ DEBUG ((DEBUG_INFO, "FmpDxe(%s): Set variable %g %s LastAttemptVersion %08x\n",
+ mImageIdName,
+ &gEfiCallerIdGuid,
+ Private->FmpStateVariableName,
+ LastAttemptVersion
+ ));
+ }
+ }
+ FreePool (FmpControllerState);
+}
+
+/**
+ Attempts to lock a single UEFI Variable propagating the error state of the
+ first lock attempt that fails. Uses gEfiCallerIdGuid as the variable GUID.
+
+ @param[in] PreviousStatus The previous UEFI Variable lock attempt status.
+ @param[in] VariableLock The EDK II Variable Lock Protocol instance.
+ @param[in] VariableName The name of the UEFI Variable to lock.
+
+ @retval EFI_SUCCESS The UEFI Variable was locked and the previous variable
+ lock attempt also succeeded.
+ @retval Other The UEFI Variable could not be locked or the previous
+ variable lock attempt failed.
+**/
+static
+EFI_STATUS
+LockFmpVariable (
+ IN EFI_STATUS PreviousStatus,
+ IN EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock,
+ IN CHAR16 *VariableName
+ )
+{
+ EFI_STATUS Status;
+
+ Status = VariableLock->RequestToLock (
+ VariableLock,
+ VariableName,
+ &gEfiCallerIdGuid
+ );
+ if (!EFI_ERROR (Status)) {
+ return PreviousStatus;
+ }
+
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Failed to lock variable %g %s. Status = %r\n",
+ mImageIdName,
+ &gEfiCallerIdGuid,
+ VariableName,
+ Status
+ ));
+
+ if (EFI_ERROR (PreviousStatus)) {
+ return PreviousStatus;
+ }
+ return Status;
+}
+
+/**
+ Locks all the UEFI Variables that use gEfiCallerIdGuid of the currently
+ executing module.
+
+ @param[in] Private Private context structure for the managed controller.
+
+ @retval EFI_SUCCESS All UEFI variables are locked.
+ @retval EFI_UNSUPPORTED Variable Lock Protocol not found.
+ @retval Other One of the UEFI variables could not be locked.
+**/
+EFI_STATUS
+LockAllFmpVariables (
+ FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+ EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock;
+
+ VariableLock = NULL;
+ Status = gBS->LocateProtocol (
+ &gEdkiiVariableLockProtocolGuid,
+ NULL,
+ (VOID **)&VariableLock
+ );
+ if (EFI_ERROR (Status) || VariableLock == NULL) {
+ DEBUG ((DEBUG_ERROR, "FmpDxe(%s): Failed to locate Variable Lock Protocol (%r).\n", mImageIdName, Status));
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = EFI_SUCCESS;
+ Status = LockFmpVariable (Status, VariableLock, Private->VersionVariableName);
+ Status = LockFmpVariable (Status, VariableLock, Private->LsvVariableName);
+ Status = LockFmpVariable (Status, VariableLock, Private->LastAttemptStatusVariableName);
+ Status = LockFmpVariable (Status, VariableLock, Private->LastAttemptVersionVariableName);
+ Status = LockFmpVariable (Status, VariableLock, Private->FmpStateVariableName);
+
+ return Status;
+}
diff --git a/roms/edk2/FmpDevicePkg/FmpDxe/VariableSupport.h b/roms/edk2/FmpDevicePkg/FmpDxe/VariableSupport.h new file mode 100644 index 000000000..23f24f2a1 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/FmpDxe/VariableSupport.h @@ -0,0 +1,238 @@ +/** @file
+ UEFI variable support functions for Firmware Management Protocol based
+ firmware updates.
+
+ Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
+ Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __VARIABLE_SUPPORT_H__
+#define __VARIABLE_SUPPORT_H__
+
+///
+/// Default values for FMP Controller State information
+///
+#define DEFAULT_VERSION 0x1
+#define DEFAULT_LOWESTSUPPORTEDVERSION 0x0
+#define DEFAULT_LASTATTEMPTSTATUS 0x0
+#define DEFAULT_LASTATTEMPTVERSION 0x0
+
+///
+/// Base UEFI Variable names for FMP Controller State information stored in
+/// separate variables.
+///
+#define VARNAME_VERSION L"FmpVersion"
+#define VARNAME_LSV L"FmpLsv"
+#define VARNAME_LASTATTEMPTSTATUS L"LastAttemptStatus"
+#define VARNAME_LASTATTEMPTVERSION L"LastAttemptVersion"
+
+///
+/// Base UEFI Variable name for FMP Controller State information stored in a
+/// merged UEFI Variable. If the separate UEFI Variables above are detected,
+/// then they are merged into a single variable and the separate variables are
+/// deleted.
+///
+#define VARNAME_FMPSTATE L"FmpState"
+
+///
+/// FMP Controller State structure that is used to store the state of
+/// a controller in one combined UEFI Variable.
+///
+typedef struct {
+ BOOLEAN VersionValid;
+ BOOLEAN LsvValid;
+ BOOLEAN LastAttemptStatusValid;
+ BOOLEAN LastAttemptVersionValid;
+ UINT32 Version;
+ UINT32 Lsv;
+ UINT32 LastAttemptStatus;
+ UINT32 LastAttemptVersion;
+} FMP_CONTROLLER_STATE;
+
+/**
+ Generate the names of the UEFI Variables used to store state information for
+ a managed controller. The UEFI Variables names are a combination of a base
+ name and an optional hardware instance value as a 16 character hex value. If
+ the hardware instance value is 0, then the 16 character hex value is not
+ included. These storage for the UEFI Variable names are allocated using the
+ UEFI Boot Service AllocatePool() and the pointers are stored in the Private.
+ The following are examples of variable names produces for hardware instance
+ value 0 and value 0x1234567812345678.
+
+ FmpVersion
+ FmpLsv
+ LastAttemptStatus
+ LastAttemptVersion
+ FmpDxe
+
+ FmpVersion1234567812345678
+ FmpLsv1234567812345678
+ LastAttemptStatus1234567812345678
+ LastAttemptVersion1234567812345678
+ FmpDxe1234567812345678
+
+ @param[in,out] Private Private context structure for the managed controller.
+**/
+VOID
+GenerateFmpVariableNames (
+ IN OUT FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private
+ );
+
+/**
+ Returns the value used to fill in the Version field of the
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo()
+ service of the Firmware Management Protocol. The value is read from a UEFI
+ variable. If the UEFI variables does not exist, then a default version value
+ is returned.
+
+ UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpDxe"
+
+ @param[in] Private Private context structure for the managed controller.
+
+ @return The version of the firmware image in the firmware device.
+**/
+UINT32
+GetVersionFromVariable (
+ IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private
+ );
+
+/**
+ Returns the value used to fill in the LowestSupportedVersion field of the
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo()
+ service of the Firmware Management Protocol. The value is read from a UEFI
+ variable. If the UEFI variables does not exist, then a default lowest
+ supported version value is returned.
+
+ UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpDxe"
+
+ @param[in] Private Private context structure for the managed controller.
+
+ @return The lowest supported version of the firmware image in the firmware
+ device.
+**/
+UINT32
+GetLowestSupportedVersionFromVariable (
+ IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private
+ );
+
+/**
+ Returns the value used to fill in the LastAttemptStatus field of the
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo()
+ service of the Firmware Management Protocol. The value is read from a UEFI
+ variable. If the UEFI variables does not exist, then a default last attempt
+ status value is returned.
+
+ UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpDxe"
+
+ @param[in] Private Private context structure for the managed controller.
+
+ @return The last attempt status value for the most recent capsule update.
+**/
+UINT32
+GetLastAttemptStatusFromVariable (
+ IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private
+ );
+
+/**
+ Returns the value used to fill in the LastAttemptVersion field of the
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo()
+ service of the Firmware Management Protocol. The value is read from a UEFI
+ variable. If the UEFI variables does not exist, then a default last attempt
+ version value is returned.
+
+ UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpDxe"
+
+ @param[in] Private Private context structure for the managed controller.
+
+ @return The last attempt version value for the most recent capsule update.
+**/
+UINT32
+GetLastAttemptVersionFromVariable (
+ IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private
+ );
+
+/**
+ Saves the version current of the firmware image in the firmware device to a
+ UEFI variable.
+
+ UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpDxe"
+
+ @param[in] Private Private context structure for the managed controller.
+ @param[in] Version The version of the firmware image in the firmware device.
+**/
+VOID
+SetVersionInVariable (
+ IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private,
+ IN UINT32 Version
+ );
+
+/**
+ Saves the lowest supported version current of the firmware image in the
+ firmware device to a UEFI variable.
+
+ UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpDxe"
+
+ @param[in] Private Private context structure for the managed
+ controller.
+ @param[in] LowestSupportedVersion The lowest supported version of the
+ firmware image in the firmware device.
+**/
+VOID
+SetLowestSupportedVersionInVariable (
+ IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private,
+ IN UINT32 LowestSupportedVersion
+ );
+
+/**
+ Saves the last attempt status value of the most recent FMP capsule update to a
+ UEFI variable.
+
+ UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpDxe"
+
+ @param[in] Private Private context structure for the managed
+ controller.
+ @param[in] LastAttemptStatus The last attempt status of the most recent FMP
+ capsule update.
+**/
+VOID
+SetLastAttemptStatusInVariable (
+ IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private,
+ IN UINT32 LastAttemptStatus
+ );
+
+/**
+ Saves the last attempt version value of the most recent FMP capsule update to
+ a UEFI variable.
+
+ UEFI Variable accessed: GUID = gEfiCallerIdGuid, Name = L"FmpDxe"
+
+ @param[in] Private Private context structure for the managed
+ controller.
+ @param[in] LastAttemptVersion The last attempt version value of the most
+ recent FMP capsule update.
+**/
+VOID
+SetLastAttemptVersionInVariable (
+ IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private,
+ IN UINT32 LastAttemptVersion
+ );
+
+/**
+ Locks all the UEFI Variables that use gEfiCallerIdGuid of the currently
+ executing module.
+
+ @param[in] Private Private context structure for the managed controller.
+
+ @retval EFI_SUCCESS All UEFI variables are locked.
+ @retval EFI_UNSUPPORTED Variable Lock Protocol not found.
+ @retval Other One of the UEFI variables could not be locked.
+**/
+EFI_STATUS
+LockAllFmpVariables (
+ IN FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private
+ );
+
+#endif
diff --git a/roms/edk2/FmpDevicePkg/Include/Library/CapsuleUpdatePolicyLib.h b/roms/edk2/FmpDevicePkg/Include/Library/CapsuleUpdatePolicyLib.h new file mode 100644 index 000000000..5ec4d487e --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Include/Library/CapsuleUpdatePolicyLib.h @@ -0,0 +1,103 @@ +/** @file
+ Provides platform policy services used during a capsule update.
+
+ Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
+ Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __CAPSULE_UPDATE_POLICY_LIB__
+#define __CAPSULE_UPDATE_POLICY_LIB__
+
+/**
+ Determine if the system power state supports a capsule update.
+
+ @param[out] Good Returns TRUE if system power state supports a capsule
+ update. Returns FALSE if system power state does not
+ support a capsule update. Return value is only valid if
+ return status is EFI_SUCCESS.
+
+ @retval EFI_SUCCESS Good parameter has been updated with result.
+ @retval EFI_INVALID_PARAMETER Good is NULL.
+ @retval EFI_DEVICE_ERROR System power state can not be determined.
+
+**/
+EFI_STATUS
+EFIAPI
+CheckSystemPower (
+ OUT BOOLEAN *Good
+ );
+
+/**
+ Determines if the system thermal state supports a capsule update.
+
+ @param[out] Good Returns TRUE if system thermal state supports a capsule
+ update. Returns FALSE if system thermal state does not
+ support a capsule update. Return value is only valid if
+ return status is EFI_SUCCESS.
+
+ @retval EFI_SUCCESS Good parameter has been updated with result.
+ @retval EFI_INVALID_PARAMETER Good is NULL.
+ @retval EFI_DEVICE_ERROR System thermal state can not be determined.
+
+**/
+EFI_STATUS
+EFIAPI
+CheckSystemThermal (
+ OUT BOOLEAN *Good
+ );
+
+/**
+ Determines if the system environment state supports a capsule update.
+
+ @param[out] Good Returns TRUE if system environment state supports a capsule
+ update. Returns FALSE if system environment state does not
+ support a capsule update. Return value is only valid if
+ return status is EFI_SUCCESS.
+
+ @retval EFI_SUCCESS Good parameter has been updated with result.
+ @retval EFI_INVALID_PARAMETER Good is NULL.
+ @retval EFI_DEVICE_ERROR System environment state can not be determined.
+
+**/
+EFI_STATUS
+EFIAPI
+CheckSystemEnvironment (
+ OUT BOOLEAN *Good
+ );
+
+/**
+ Determines if the Lowest Supported Version checks should be performed. The
+ expected result from this function is TRUE. A platform can choose to return
+ FALSE (e.g. during manufacturing or servicing) to allow a capsule update to a
+ version below the current Lowest Supported Version.
+
+ @retval TRUE The lowest supported version check is required.
+ @retval FALSE Do not perform lowest support version check.
+
+**/
+BOOLEAN
+EFIAPI
+IsLowestSupportedVersionCheckRequired (
+ VOID
+ );
+
+/**
+ Determines if the FMP device should be locked when the event specified by
+ PcdFmpDeviceLockEventGuid is signaled. The expected result from this function
+ is TRUE so the FMP device is always locked. A platform can choose to return
+ FALSE (e.g. during manufacturing) to allow FMP devices to remain unlocked.
+
+ @retval TRUE The FMP device lock action is required at lock event guid.
+ @retval FALSE Do not perform FMP device lock at lock event guid.
+
+**/
+BOOLEAN
+EFIAPI
+IsLockFmpDeviceAtLockEventGuidRequired (
+ VOID
+ );
+
+#endif
diff --git a/roms/edk2/FmpDevicePkg/Include/Library/FmpDependencyCheckLib.h b/roms/edk2/FmpDevicePkg/Include/Library/FmpDependencyCheckLib.h new file mode 100644 index 000000000..ec380c494 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Include/Library/FmpDependencyCheckLib.h @@ -0,0 +1,38 @@ +/** @file
+ Fmp Capsule Dependency check functions for Firmware Management Protocol based
+ firmware updates.
+
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __FMP_DEPENDENCY_CHECK_LIB__
+#define __FMP_DEPENDENCY_CHECK_LIB__
+
+#include <PiDxe.h>
+#include <Protocol/FirmwareManagement.h>
+
+/**
+ Check dependency for firmware update.
+
+ @param[in] ImageTypeId Image Type Id.
+ @param[in] Version New version.
+ @param[in] Dependencies Fmp dependency.
+ @param[in] DependenciesSize Size, in bytes, of the Fmp dependency.
+
+ @retval TRUE Dependencies are satisfied.
+ @retval FALSE Dependencies are unsatisfied or dependency check fails.
+
+**/
+BOOLEAN
+EFIAPI
+CheckFmpDependency (
+ IN EFI_GUID ImageTypeId,
+ IN UINT32 Version,
+ IN EFI_FIRMWARE_IMAGE_DEP *Dependencies, OPTIONAL
+ IN UINT32 DependenciesSize
+ );
+
+#endif
diff --git a/roms/edk2/FmpDevicePkg/Include/Library/FmpDependencyDeviceLib.h b/roms/edk2/FmpDevicePkg/Include/Library/FmpDependencyDeviceLib.h new file mode 100644 index 000000000..4351173b7 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Include/Library/FmpDependencyDeviceLib.h @@ -0,0 +1,51 @@ +/** @file
+ Provides firmware device specific services to support saving dependency to
+ firmware device and getting dependency from firmware device.
+
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __FMP_DEPENDENCY_DEVICE_LIB__
+#define __FMP_DEPENDENCY_DEVICE_LIB__
+
+#include <PiDxe.h>
+#include <Protocol/FirmwareManagement.h>
+
+/**
+ Save dependency to Fmp device.
+
+ @param[in] Depex Fmp dependency.
+ @param[in] DepexSize Size, in bytes, of the Fmp dependency.
+
+ @retval EFI_SUCCESS Save Fmp dependency succeeds.
+ @retval EFI_UNSUPPORTED Save Fmp dependency is not supported.
+ @retval Others Save Fmp dependency fails.
+
+**/
+EFI_STATUS
+EFIAPI
+SaveFmpDependency (
+ IN EFI_FIRMWARE_IMAGE_DEP *Depex,
+ IN UINT32 DepexSize
+ );
+
+/**
+ Get dependency from the Fmp device.
+ This caller is responsible for freeing the dependency buffer.
+
+ @param[out] DepexSize Size, in bytes, of the dependency.
+
+ @retval The pointer to dependency.
+ @retval NULL
+
+**/
+EFI_FIRMWARE_IMAGE_DEP*
+EFIAPI
+GetFmpDependency (
+ OUT UINT32 *DepexSize
+ );
+
+#endif
diff --git a/roms/edk2/FmpDevicePkg/Include/Library/FmpDependencyLib.h b/roms/edk2/FmpDevicePkg/Include/Library/FmpDependencyLib.h new file mode 100644 index 000000000..c73290342 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Include/Library/FmpDependencyLib.h @@ -0,0 +1,90 @@ +/** @file
+ Fmp Capsule Dependency support functions for Firmware Management Protocol based
+ firmware updates.
+
+ Copyright (c) Microsoft Corporation.<BR>
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __FMP_DEPENDENCY_LIB__
+#define __FMP_DEPENDENCY_LIB__
+
+#include <PiDxe.h>
+#include <Protocol/FirmwareManagement.h>
+
+//
+// Data struct to store FMP ImageType and version for dependency check.
+//
+typedef struct {
+ EFI_GUID ImageTypeId;
+ UINT32 Version;
+} FMP_DEPEX_CHECK_VERSION_DATA;
+
+/**
+ Validate the dependency expression and output its size.
+
+ @param[in] Dependencies Pointer to the EFI_FIRMWARE_IMAGE_DEP.
+ @param[in] MaxDepexSize Max size of the dependency.
+ @param[out] DepexSize Size of dependency.
+
+ @retval TRUE The dependency expression is valid.
+ @retval FALSE The dependency expression is invalid.
+
+**/
+BOOLEAN
+EFIAPI
+ValidateDependency (
+ IN EFI_FIRMWARE_IMAGE_DEP *Dependencies,
+ IN UINTN MaxDepexSize,
+ OUT UINT32 *DepexSize
+ );
+
+/**
+ Get dependency from firmware image.
+
+ @param[in] Image Points to the firmware image.
+ @param[in] ImageSize Size, in bytes, of the firmware image.
+ @param[out] DepexSize Size, in bytes, of the dependency.
+
+ @retval The pointer to dependency.
+ @retval Null
+
+**/
+EFI_FIRMWARE_IMAGE_DEP*
+EFIAPI
+GetImageDependency (
+ IN EFI_FIRMWARE_IMAGE_AUTHENTICATION *Image,
+ IN UINTN ImageSize,
+ OUT UINT32 *DepexSize
+ );
+
+/**
+ Evaluate the dependencies. The caller must search all the Fmp instances and
+ gather their versions into FmpVersions parameter. If there is PUSH_GUID opcode
+ in dependency expression with no FmpVersions provided, the dependency will
+ evaluate to FALSE.
+
+ @param[in] Dependencies Dependency expressions.
+ @param[in] DependenciesSize Size of Dependency expressions.
+ @param[in] FmpVersions Array of Fmp ImageTypeId and version. This
+ parameter is optional and can be set to NULL.
+ @param[in] FmpVersionsCount Element count of the array. When FmpVersions
+ is NULL, FmpVersionsCount must be 0.
+
+ @retval TRUE Dependency expressions evaluate to TRUE.
+ @retval FALSE Dependency expressions evaluate to FALSE.
+
+**/
+BOOLEAN
+EFIAPI
+EvaluateDependency (
+ IN EFI_FIRMWARE_IMAGE_DEP *Dependencies,
+ IN UINTN DependenciesSize,
+ IN FMP_DEPEX_CHECK_VERSION_DATA *FmpVersions OPTIONAL,
+ IN UINTN FmpVersionsCount
+ );
+
+#endif
diff --git a/roms/edk2/FmpDevicePkg/Include/Library/FmpDeviceLib.h b/roms/edk2/FmpDevicePkg/Include/Library/FmpDeviceLib.h new file mode 100644 index 000000000..9a89f5c2e --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Include/Library/FmpDeviceLib.h @@ -0,0 +1,490 @@ +/** @file
+ 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.<BR>
+ Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __FMP_DEVICE_LIB__
+#define __FMP_DEVICE_LIB__
+
+#include <Protocol/FirmwareManagement.h>
+
+/**
+ Callback function that installs a Firmware Management Protocol instance onto
+ a handle.
+
+ @param[in] Handle The device handle to install a Firmware Management
+ Protocol instance.
+
+ @retval EFI_SUCCESS A Firmware Management Protocol instance was
+ installed onto Handle.
+ @retval EFI_INVALID_PARAMETER Handle is invalid
+ @retval other A Firmware Management Protocol instance could
+ not be installed onto Handle.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *FMP_DEVICE_LIB_REGISTER_FMP_INSTALLER)(
+ IN EFI_HANDLE Handle
+ );
+
+/**
+ Callback function that uninstalls a Firmware Management Protocol instance from
+ a handle.
+
+ @param[in] Handle The device handle to uninstall a Firmware Management
+ Protocol instance.
+
+ @retval EFI_SUCCESS A Firmware Management Protocol instance was
+ uninstalled from Handle.
+ @retval EFI_INVALID_PARAMETER Handle is invalid
+ @retval other A Firmware Management Protocol instance could
+ not be uninstalled from Handle.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *FMP_DEVICE_LIB_REGISTER_FMP_UNINSTALLER)(
+ IN EFI_HANDLE Handle
+ );
+
+/**
+ Provide a function to install the Firmware Management Protocol instance onto a
+ device handle when the device is managed by a driver that follows the UEFI
+ Driver Model. If the device is not managed by a driver that follows the UEFI
+ Driver Model, then EFI_UNSUPPORTED is returned.
+
+ @param[in] FmpInstaller Function that installs the Firmware Management
+ Protocol.
+
+ @retval EFI_SUCCESS The device is managed by a driver that follows the
+ UEFI Driver Model. FmpInstaller must be called on
+ each Driver Binding Start().
+ @retval EFI_UNSUPPORTED The device is not managed by a driver that follows
+ the UEFI Driver Model.
+ @retval other The Firmware Management Protocol for this firmware
+ device is not installed. The firmware device is
+ still locked using FmpDeviceLock().
+
+**/
+EFI_STATUS
+EFIAPI
+RegisterFmpInstaller (
+ IN FMP_DEVICE_LIB_REGISTER_FMP_INSTALLER FmpInstaller
+ );
+
+/**
+ Provide a function to uninstall the Firmware Management Protocol instance from a
+ device handle when the device is managed by a driver that follows the UEFI
+ Driver Model. If the device is not managed by a driver that follows the UEFI
+ Driver Model, then EFI_UNSUPPORTED is returned.
+
+ @param[in] FmpUninstaller Function that installs the Firmware Management
+ Protocol.
+
+ @retval EFI_SUCCESS The device is managed by a driver that follows the
+ UEFI Driver Model. FmpUninstaller must be called on
+ each Driver Binding Stop().
+ @retval EFI_UNSUPPORTED The device is not managed by a driver that follows
+ the UEFI Driver Model.
+ @retval other The Firmware Management Protocol for this firmware
+ device is not installed. The firmware device is
+ still locked using FmpDeviceLock().
+
+**/
+EFI_STATUS
+EFIAPI
+RegisterFmpUninstaller (
+ IN FMP_DEVICE_LIB_REGISTER_FMP_UNINSTALLER FmpUninstaller
+ );
+
+/**
+ Set the device context for the FmpDeviceLib services when the device is
+ managed by a driver that follows the UEFI Driver Model. If the device is not
+ managed by a driver that follows the UEFI Driver Model, then EFI_UNSUPPORTED
+ is returned. Once a device context is set, the FmpDeviceLib services
+ operate on the currently set device context.
+
+ @param[in] Handle Device handle for the FmpDeviceLib services.
+ If Handle is NULL, then Context is freed.
+ @param[in, out] Context Device context for the FmpDeviceLib services.
+ If Context is NULL, then a new context is allocated
+ for Handle and the current device context is set and
+ returned in Context. If Context is not NULL, then
+ the current device context is set.
+
+ @retval EFI_SUCCESS The device is managed by a driver that follows the
+ UEFI Driver Model.
+ @retval EFI_UNSUPPORTED The device is not managed by a driver that follows
+ the UEFI Driver Model.
+ @retval other The Firmware Management Protocol for this firmware
+ device is not installed. The firmware device is
+ still locked using FmpDeviceLock().
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceSetContext (
+ IN EFI_HANDLE Handle,
+ IN OUT VOID **Context
+ );
+
+/**
+ Returns the size, in bytes, of the firmware image currently stored in the
+ firmware device. This function is used to by the GetImage() and
+ GetImageInfo() services of the Firmware Management Protocol. If the image
+ size can not be determined from the firmware device, then 0 must be returned.
+
+ @param[out] Size Pointer to the size, in bytes, of the firmware image
+ currently stored in the firmware device.
+
+ @retval EFI_SUCCESS The size of the firmware image currently
+ stored in the firmware device was returned.
+ @retval EFI_INVALID_PARAMETER Size is NULL.
+ @retval EFI_UNSUPPORTED The firmware device does not support reporting
+ the size of the currently stored firmware image.
+ @retval EFI_DEVICE_ERROR An error occurred attempting to determine the
+ size of the firmware image currently stored in
+ in the firmware device.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetSize (
+ OUT UINTN *Size
+ );
+
+/**
+ Returns the GUID value used to fill in the ImageTypeId field of the
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo()
+ service of the Firmware Management Protocol. If EFI_UNSUPPORTED is returned,
+ then the ImageTypeId field is set to gEfiCallerIdGuid. If EFI_SUCCESS is
+ returned, then ImageTypeId is set to the Guid returned from this function.
+
+ @param[out] Guid Double pointer to a GUID value that is updated to point to
+ to a GUID value. The GUID value is not allocated and must
+ not be modified or freed by the caller.
+
+ @retval EFI_SUCCESS EFI_FIRMWARE_IMAGE_DESCRIPTOR ImageTypeId GUID is set
+ to the returned Guid value.
+ @retval EFI_UNSUPPORTED EFI_FIRMWARE_IMAGE_DESCRIPTOR ImageTypeId GUID is set
+ to gEfiCallerIdGuid.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetImageTypeIdGuidPtr (
+ OUT EFI_GUID **Guid
+ );
+
+/**
+ Returns values used to fill in the AttributesSupported and AttributesSettings
+ fields of the EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the
+ GetImageInfo() service of the Firmware Management Protocol. The following
+ bit values from the Firmware Management Protocol may be combined:
+ IMAGE_ATTRIBUTE_IMAGE_UPDATABLE
+ IMAGE_ATTRIBUTE_RESET_REQUIRED
+ IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED
+ IMAGE_ATTRIBUTE_IN_USE
+ IMAGE_ATTRIBUTE_UEFI_IMAGE
+
+ @param[out] Supported Attributes supported by this firmware device.
+ @param[out] Setting Attributes settings for this firmware device.
+
+ @retval EFI_SUCCESS The attributes supported by the firmware
+ device were returned.
+ @retval EFI_INVALID_PARAMETER Supported is NULL.
+ @retval EFI_INVALID_PARAMETER Setting is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetAttributes (
+ OUT UINT64 *Supported,
+ OUT UINT64 *Setting
+ );
+
+/**
+ Returns the value used to fill in the LowestSupportedVersion field of the
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo()
+ service of the Firmware Management Protocol. If EFI_SUCCESS is returned, then
+ the firmware device supports a method to report the LowestSupportedVersion
+ value from the currently stored firmware image. If the value can not be
+ reported for the firmware image currently stored in the firmware device, then
+ EFI_UNSUPPORTED must be returned. EFI_DEVICE_ERROR is returned if an error
+ occurs attempting to retrieve the LowestSupportedVersion value for the
+ currently stored firmware image.
+
+ @note It is recommended that all firmware devices support a method to report
+ the LowestSupportedVersion value from the currently stored firmware
+ image.
+
+ @param[out] LowestSupportedVersion LowestSupportedVersion value retrieved
+ from the currently stored firmware image.
+
+ @retval EFI_SUCCESS The lowest supported version of currently stored
+ firmware image was returned in LowestSupportedVersion.
+ @retval EFI_UNSUPPORTED The firmware device does not support a method to
+ report the lowest supported version of the currently
+ stored firmware image.
+ @retval EFI_DEVICE_ERROR An error occurred attempting to retrieve the lowest
+ supported version of the currently stored firmware
+ image.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetLowestSupportedVersion (
+ OUT UINT32 *LowestSupportedVersion
+ );
+
+/**
+ Returns the Null-terminated Unicode string that is used to fill in the
+ VersionName field of the EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is
+ returned by the GetImageInfo() service of the Firmware Management Protocol.
+ The returned string must be allocated using EFI_BOOT_SERVICES.AllocatePool().
+
+ @note It is recommended that all firmware devices support a method to report
+ the VersionName string from the currently stored firmware image.
+
+ @param[out] VersionString The version string retrieved from the currently
+ stored firmware image.
+
+ @retval EFI_SUCCESS The version string of currently stored
+ firmware image was returned in Version.
+ @retval EFI_INVALID_PARAMETER VersionString is NULL.
+ @retval EFI_UNSUPPORTED The firmware device does not support a method
+ to report the version string of the currently
+ stored firmware image.
+ @retval EFI_DEVICE_ERROR An error occurred attempting to retrieve the
+ version string of the currently stored
+ firmware image.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources to allocate the
+ buffer for the version string of the currently
+ stored firmware image.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetVersionString (
+ OUT CHAR16 **VersionString
+ );
+
+/**
+ Returns the value used to fill in the Version field of the
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo()
+ service of the Firmware Management Protocol. If EFI_SUCCESS is returned, then
+ the firmware device supports a method to report the Version value from the
+ currently stored firmware image. If the value can not be reported for the
+ firmware image currently stored in the firmware device, then EFI_UNSUPPORTED
+ must be returned. EFI_DEVICE_ERROR is returned if an error occurs attempting
+ to retrieve the LowestSupportedVersion value for the currently stored firmware
+ image.
+
+ @note It is recommended that all firmware devices support a method to report
+ the Version value from the currently stored firmware image.
+
+ @param[out] Version The version value retrieved from the currently stored
+ firmware image.
+
+ @retval EFI_SUCCESS The version of currently stored firmware image was
+ returned in Version.
+ @retval EFI_UNSUPPORTED The firmware device does not support a method to
+ report the version of the currently stored firmware
+ image.
+ @retval EFI_DEVICE_ERROR An error occurred attempting to retrieve the version
+ of the currently stored firmware image.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetVersion (
+ OUT UINT32 *Version
+ );
+
+/**
+ Returns the value used to fill in the HardwareInstance field of the
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo()
+ service of the Firmware Management Protocol. If EFI_SUCCESS is returned, then
+ the firmware device supports a method to report the HardwareInstance value.
+ If the value can not be reported for the firmware device, then EFI_UNSUPPORTED
+ must be returned. EFI_DEVICE_ERROR is returned if an error occurs attempting
+ to retrieve the HardwareInstance value for the firmware device.
+
+ @param[out] HardwareInstance The hardware instance value for the firmware
+ device.
+
+ @retval EFI_SUCCESS The hardware instance for the current firmware
+ device is returned in HardwareInstance.
+ @retval EFI_UNSUPPORTED The firmware device does not support a method to
+ report the hardware instance value.
+ @retval EFI_DEVICE_ERROR An error occurred attempting to retrieve the hardware
+ instance value.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetHardwareInstance (
+ OUT UINT64 *HardwareInstance
+ );
+
+/**
+ Returns a copy of the firmware image currently stored in the firmware device.
+
+ @note It is recommended that all firmware devices support a method to retrieve
+ a copy currently stored firmware image. This can be used to support
+ features such as recovery and rollback.
+
+ @param[out] Image Pointer to a caller allocated buffer where the
+ currently stored firmware image is copied to.
+ @param[in, out] ImageSize Pointer the size, in bytes, of the Image buffer.
+ On return, points to the size, in bytes, of firmware
+ image currently stored in the firmware device.
+
+ @retval EFI_SUCCESS Image contains a copy of the firmware image
+ currently stored in the firmware device, and
+ ImageSize contains the size, in bytes, of the
+ firmware image currently stored in the
+ firmware device.
+ @retval EFI_BUFFER_TOO_SMALL The buffer specified by ImageSize is too small
+ to hold the firmware image currently stored in
+ the firmware device. The buffer size required
+ is returned in ImageSize.
+ @retval EFI_INVALID_PARAMETER The Image is NULL.
+ @retval EFI_INVALID_PARAMETER The ImageSize is NULL.
+ @retval EFI_UNSUPPORTED The operation is not supported.
+ @retval EFI_DEVICE_ERROR An error occurred attempting to retrieve the
+ firmware image currently stored in the firmware
+ device.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetImage (
+ OUT VOID *Image,
+ IN OUT UINTN *ImageSize
+ );
+
+/**
+ 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
+
+ @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
+FmpDeviceCheckImage (
+ IN CONST VOID *Image,
+ IN UINTN ImageSize,
+ OUT UINT32 *ImageUpdatable
+ );
+
+/**
+ 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().
+
+ @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
+FmpDeviceSetImage (
+ 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
+ );
+
+/**
+ 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
+ firmware device must fail.
+
+ @note It is recommended that all firmware devices support a lock method to
+ prevent modifications to a stored firmware image.
+
+ @note A firmware device lock mechanism is typically only cleared by a full
+ system reset (not just sleep state/low power mode).
+
+ @retval EFI_SUCCESS The firmware device was locked.
+ @retval EFI_UNSUPPORTED The firmware device does not support locking
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceLock (
+ VOID
+ );
+
+#endif
diff --git a/roms/edk2/FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.c b/roms/edk2/FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.c new file mode 100644 index 000000000..0cb1d775c --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.c @@ -0,0 +1,119 @@ +/** @file
+ Provides platform policy services used during a capsule update.
+
+ Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
+ Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+#include <Library/CapsuleUpdatePolicyLib.h>
+
+/**
+ Determine if the system power state supports a capsule update.
+
+ @param[out] Good Returns TRUE if system power state supports a capsule
+ update. Returns FALSE if system power state does not
+ support a capsule update. Return value is only valid if
+ return status is EFI_SUCCESS.
+
+ @retval EFI_SUCCESS Good parameter has been updated with result.
+ @retval EFI_INVALID_PARAMETER Good is NULL.
+ @retval EFI_DEVICE_ERROR System power state can not be determined.
+
+**/
+EFI_STATUS
+EFIAPI
+CheckSystemPower (
+ OUT BOOLEAN *Good
+ )
+{
+ *Good = TRUE;
+ return EFI_SUCCESS;
+}
+
+/**
+ Determines if the system thermal state supports a capsule update.
+
+ @param[out] Good Returns TRUE if system thermal state supports a capsule
+ update. Returns FALSE if system thermal state does not
+ support a capsule update. Return value is only valid if
+ return status is EFI_SUCCESS.
+
+ @retval EFI_SUCCESS Good parameter has been updated with result.
+ @retval EFI_INVALID_PARAMETER Good is NULL.
+ @retval EFI_DEVICE_ERROR System thermal state can not be determined.
+
+**/
+EFI_STATUS
+EFIAPI
+CheckSystemThermal (
+ OUT BOOLEAN *Good
+ )
+{
+ *Good = TRUE;
+ return EFI_SUCCESS;
+}
+
+/**
+ Determines if the system environment state supports a capsule update.
+
+ @param[out] Good Returns TRUE if system environment state supports a capsule
+ update. Returns FALSE if system environment state does not
+ support a capsule update. Return value is only valid if
+ return status is EFI_SUCCESS.
+
+ @retval EFI_SUCCESS Good parameter has been updated with result.
+ @retval EFI_INVALID_PARAMETER Good is NULL.
+ @retval EFI_DEVICE_ERROR System environment state can not be determined.
+
+**/
+EFI_STATUS
+EFIAPI
+CheckSystemEnvironment (
+ OUT BOOLEAN *Good
+ )
+{
+ *Good = TRUE;
+ return EFI_SUCCESS;
+}
+
+/**
+ Determines if the Lowest Supported Version checks should be performed. The
+ expected result from this function is TRUE. A platform can choose to return
+ FALSE (e.g. during manufacturing or servicing) to allow a capsule update to a
+ version below the current Lowest Supported Version.
+
+ @retval TRUE The lowest supported version check is required.
+ @retval FALSE Do not perform lowest support version check.
+
+**/
+BOOLEAN
+EFIAPI
+IsLowestSupportedVersionCheckRequired (
+ VOID
+ )
+{
+ return TRUE;
+}
+
+/**
+ Determines if the FMP device should be locked when the event specified by
+ PcdFmpDeviceLockEventGuid is signaled. The expected result from this function
+ is TRUE so the FMP device is always locked. A platform can choose to return
+ FALSE (e.g. during manufacturing) to allow FMP devices to remain unlocked.
+
+ @retval TRUE The FMP device lock action is required at lock event guid.
+ @retval FALSE Do not perform FMP device lock at lock event guid.
+
+**/
+BOOLEAN
+EFIAPI
+IsLockFmpDeviceAtLockEventGuidRequired (
+ VOID
+ )
+{
+ return TRUE;
+}
diff --git a/roms/edk2/FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.inf b/roms/edk2/FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.inf new file mode 100644 index 000000000..56678ffd3 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.inf @@ -0,0 +1,28 @@ +## @file
+# Provides platform policy services used during a capsule update.
+#
+# Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
+# Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = CapsuleUpdatePolicyLibNull
+ MODULE_UNI_FILE = CapsuleUpdatePolicyLibNull.uni
+ FILE_GUID = 8E36EC87-440D-44F9-AB2F-AA806C61A1A6
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = CapsuleUpdatePolicyLib
+
+#
+# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
+#
+
+[Sources]
+ CapsuleUpdatePolicyLibNull.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ FmpDevicePkg/FmpDevicePkg.dec
diff --git a/roms/edk2/FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.uni b/roms/edk2/FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.uni new file mode 100644 index 000000000..d26e716b1 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Library/CapsuleUpdatePolicyLibNull/CapsuleUpdatePolicyLibNull.uni @@ -0,0 +1,12 @@ +// /** @file
+// Provides platform policy services used during a capsule update.
+//
+// Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_MODULE_ABSTRACT #language en-US "Provides platform policy services used during a capsule update."
+
+#string STR_MODULE_DESCRIPTION #language en-US "Provides platform policy services used during a capsule update."
diff --git a/roms/edk2/FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolicyLibOnProtocol.c b/roms/edk2/FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolicyLibOnProtocol.c new file mode 100644 index 000000000..6f916888c --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolicyLibOnProtocol.c @@ -0,0 +1,171 @@ +/** @file
+ Provides platform policy services used during a capsule update that uses the
+ services of the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL. If the
+ EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL is not available, then assume the
+ platform is in a state that supports a firmware update.
+
+ Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
+ Copyright (c) 2018-2019, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+#include <Library/CapsuleUpdatePolicyLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/CapsuleUpdatePolicy.h>
+
+///
+/// Pointer to the EDK II Capsule Update Policy Protocol instances that is
+/// optionally installed by a platform.
+///
+EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL *mCapsuleUpdatePolicy = NULL;
+
+/**
+ Lookup the EDK II Capsule Update Policy Protocol.
+**/
+BOOLEAN
+LookupCapsuleUpdatePolicyProtocol (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ if (mCapsuleUpdatePolicy != NULL) {
+ return TRUE;
+ }
+ Status = gBS->LocateProtocol (
+ &gEdkiiCapsuleUpdatePolicyProtocolGuid,
+ NULL,
+ (VOID **)&mCapsuleUpdatePolicy
+ );
+ if (EFI_ERROR (Status)) {
+ mCapsuleUpdatePolicy = NULL;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ Determine if the system power state supports a capsule update.
+
+ @param[out] Good Returns TRUE if system power state supports a capsule
+ update. Returns FALSE if system power state does not
+ support a capsule update. Return value is only valid if
+ return status is EFI_SUCCESS.
+
+ @retval EFI_SUCCESS Good parameter has been updated with result.
+ @retval EFI_INVALID_PARAMETER Good is NULL.
+ @retval EFI_DEVICE_ERROR System power state can not be determined.
+
+**/
+EFI_STATUS
+EFIAPI
+CheckSystemPower (
+ OUT BOOLEAN *Good
+ )
+{
+ if (LookupCapsuleUpdatePolicyProtocol ()) {
+ return mCapsuleUpdatePolicy->CheckSystemPower (mCapsuleUpdatePolicy, Good);
+ }
+ *Good = TRUE;
+ return EFI_SUCCESS;
+}
+
+/**
+ Determines if the system thermal state supports a capsule update.
+
+ @param[out] Good Returns TRUE if system thermal state supports a capsule
+ update. Returns FALSE if system thermal state does not
+ support a capsule update. Return value is only valid if
+ return status is EFI_SUCCESS.
+
+ @retval EFI_SUCCESS Good parameter has been updated with result.
+ @retval EFI_INVALID_PARAMETER Good is NULL.
+ @retval EFI_DEVICE_ERROR System thermal state can not be determined.
+
+**/
+EFI_STATUS
+EFIAPI
+CheckSystemThermal (
+ OUT BOOLEAN *Good
+ )
+{
+ if (LookupCapsuleUpdatePolicyProtocol ()) {
+ return mCapsuleUpdatePolicy->CheckSystemThermal (mCapsuleUpdatePolicy, Good);
+ }
+ *Good = TRUE;
+ return EFI_SUCCESS;
+}
+
+/**
+ Determines if the system environment state supports a capsule update.
+
+ @param[out] Good Returns TRUE if system environment state supports a capsule
+ update. Returns FALSE if system environment state does not
+ support a capsule update. Return value is only valid if
+ return status is EFI_SUCCESS.
+
+ @retval EFI_SUCCESS Good parameter has been updated with result.
+ @retval EFI_INVALID_PARAMETER Good is NULL.
+ @retval EFI_DEVICE_ERROR System environment state can not be determined.
+
+**/
+EFI_STATUS
+EFIAPI
+CheckSystemEnvironment (
+ OUT BOOLEAN *Good
+ )
+{
+ if (LookupCapsuleUpdatePolicyProtocol ()) {
+ return mCapsuleUpdatePolicy->CheckSystemEnvironment (mCapsuleUpdatePolicy, Good);
+ }
+ *Good = TRUE;
+ return EFI_SUCCESS;
+}
+
+/**
+ Determines if the Lowest Supported Version checks should be performed. The
+ expected result from this function is TRUE. A platform can choose to return
+ FALSE (e.g. during manufacturing or servicing) to allow a capsule update to a
+ version below the current Lowest Supported Version.
+
+ @retval TRUE The lowest supported version check is required.
+ @retval FALSE Do not perform lowest support version check.
+
+**/
+BOOLEAN
+EFIAPI
+IsLowestSupportedVersionCheckRequired (
+ VOID
+ )
+{
+ if (LookupCapsuleUpdatePolicyProtocol ()) {
+ return mCapsuleUpdatePolicy->IsLowestSupportedVersionCheckRequired (mCapsuleUpdatePolicy);
+ }
+ return TRUE;
+}
+
+/**
+ Determines if the FMP device should be locked when the event specified by
+ PcdFmpDeviceLockEventGuid is signaled. The expected result from this function
+ is TRUE so the FMP device is always locked. A platform can choose to return
+ FALSE (e.g. during manufacturing) to allow FMP devices to remain unlocked.
+
+ @retval TRUE The FMP device lock action is required at lock event guid.
+ @retval FALSE Do not perform FMP device lock at lock event guid.
+
+**/
+BOOLEAN
+EFIAPI
+IsLockFmpDeviceAtLockEventGuidRequired (
+ VOID
+ )
+{
+ if (LookupCapsuleUpdatePolicyProtocol ()) {
+ return mCapsuleUpdatePolicy->IsLockFmpDeviceAtLockEventGuidRequired (mCapsuleUpdatePolicy);
+ }
+ return TRUE;
+}
diff --git a/roms/edk2/FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolicyLibOnProtocol.inf b/roms/edk2/FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolicyLibOnProtocol.inf new file mode 100644 index 000000000..a56b836d2 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolicyLibOnProtocol.inf @@ -0,0 +1,40 @@ +## @file
+# Provides platform policy services used during a capsule update that uses the
+# services of the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL. If the
+# EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL is not available, then assume the
+# platform is in a state that supports a firmware update.
+#
+# Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
+# Copyright (c) 2018-2019, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = CapsuleUpdatePolicyLibOnProtocol
+ MODULE_UNI_FILE = CapsuleUpdatePolicyLibOnProtocol.uni
+ FILE_GUID = 0EA4C03F-D91B-4929-AAA5-B2FC8D69E2F4
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = CapsuleUpdatePolicyLib
+
+#
+# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
+#
+
+[Sources]
+ CapsuleUpdatePolicyLibOnProtocol.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ FmpDevicePkg/FmpDevicePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ UefiBootServicesTableLib
+
+[Protocols]
+ gEdkiiCapsuleUpdatePolicyProtocolGuid ## CONSUMES
diff --git a/roms/edk2/FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolicyLibOnProtocol.uni b/roms/edk2/FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolicyLibOnProtocol.uni new file mode 100644 index 000000000..58d078312 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Library/CapsuleUpdatePolicyLibOnProtocol/CapsuleUpdatePolicyLibOnProtocol.uni @@ -0,0 +1,15 @@ +// /** @file
+// Provides platform policy services used during a capsule update that uses the
+// services of the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL. If the
+// EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL is not available, then assume the
+// platform is in a state that supports a firmware update.
+//
+// Copyright (c) 2018-2019, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_MODULE_ABSTRACT #language en-US "Provides platform policy services used during a capsule update that uses the services of the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL."
+
+#string STR_MODULE_DESCRIPTION #language en-US "Provides platform policy services used during a capsule update that uses the services of the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL."
diff --git a/roms/edk2/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.c b/roms/edk2/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.c new file mode 100644 index 000000000..02ed600e0 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.c @@ -0,0 +1,198 @@ +/** @file
+ Provides FMP capsule dependency check services when updating the firmware
+ image of a FMP device.
+
+ Copyright (c) Microsoft Corporation.<BR>
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/FmpDependencyLib.h>
+#include <Library/FmpDependencyCheckLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+/**
+ Check dependency for firmware update.
+
+ @param[in] ImageTypeId Image Type Id.
+ @param[in] Version New version.
+ @param[in] Dependencies Fmp dependency.
+ @param[in] DependenciesSize Size, in bytes, of the Fmp dependency.
+
+ @retval TRUE Dependencies are satisfied.
+ @retval FALSE Dependencies are unsatisfied or dependency check fails.
+
+**/
+BOOLEAN
+EFIAPI
+CheckFmpDependency (
+ IN EFI_GUID ImageTypeId,
+ IN UINT32 Version,
+ IN EFI_FIRMWARE_IMAGE_DEP *Dependencies, OPTIONAL
+ IN UINT32 DependenciesSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer;
+ UINTN Index;
+ EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;
+ UINTN ImageInfoSize;
+ UINT32 *DescriptorVer;
+ UINT8 FmpImageInfoCount;
+ UINTN *DescriptorSize;
+ UINT32 PackageVersion;
+ CHAR16 *PackageVersionName;
+ UINTN NumberOfFmpInstance;
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR **FmpImageInfoBuf;
+ FMP_DEPEX_CHECK_VERSION_DATA *FmpVersions;
+ UINTN FmpVersionsCount;
+ BOOLEAN IsSatisfied;
+
+ FmpImageInfoBuf = NULL;
+ DescriptorVer = NULL;
+ DescriptorSize = NULL;
+ NumberOfFmpInstance = 0;
+ FmpVersions = NULL;
+ FmpVersionsCount = 0;
+ IsSatisfied = TRUE;
+ PackageVersionName = NULL;
+
+ //
+ // Get ImageDescriptors of all FMP instances, and archive them for dependency evaluation.
+ //
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareManagementProtocolGuid,
+ NULL,
+ &NumberOfFmpInstance,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "CheckFmpDependency: Get Firmware Management Protocol failed. (%r)", Status));
+ IsSatisfied = FALSE;
+ goto cleanup;
+ }
+
+ FmpImageInfoBuf = AllocateZeroPool (sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR *) * NumberOfFmpInstance);
+ if (FmpImageInfoBuf == NULL) {
+ IsSatisfied = FALSE;
+ goto cleanup;
+ }
+
+ DescriptorVer = AllocateZeroPool (sizeof(UINT32) * NumberOfFmpInstance);
+ if (DescriptorVer == NULL ) {
+ IsSatisfied = FALSE;
+ goto cleanup;
+ }
+
+ DescriptorSize = AllocateZeroPool (sizeof(UINTN) * NumberOfFmpInstance);
+ if (DescriptorSize == NULL ) {
+ IsSatisfied = FALSE;
+ goto cleanup;
+ }
+
+ FmpVersions = AllocateZeroPool (sizeof(FMP_DEPEX_CHECK_VERSION_DATA) * NumberOfFmpInstance);
+ if (FmpVersions == NULL) {
+ IsSatisfied = FALSE;
+ goto cleanup;
+ }
+
+ for (Index = 0; Index < NumberOfFmpInstance; Index ++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiFirmwareManagementProtocolGuid,
+ (VOID **) &Fmp
+ );
+ if (EFI_ERROR(Status)) {
+ continue;
+ }
+
+ ImageInfoSize = 0;
+ Status = Fmp->GetImageInfo (
+ Fmp,
+ &ImageInfoSize,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ );
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ continue;
+ }
+
+ FmpImageInfoBuf[Index] = AllocateZeroPool (ImageInfoSize);
+ if (FmpImageInfoBuf[Index] == NULL) {
+ continue;
+ }
+
+ Status = Fmp->GetImageInfo (
+ Fmp,
+ &ImageInfoSize, // ImageInfoSize
+ FmpImageInfoBuf[Index], // ImageInfo
+ &DescriptorVer[Index], // DescriptorVersion
+ &FmpImageInfoCount, // DescriptorCount
+ &DescriptorSize[Index], // DescriptorSize
+ &PackageVersion, // PackageVersion
+ &PackageVersionName // PackageVersionName
+ );
+ if (EFI_ERROR(Status)) {
+ FreePool (FmpImageInfoBuf[Index]);
+ FmpImageInfoBuf[Index] = NULL;
+ continue;
+ }
+
+ if (PackageVersionName != NULL) {
+ FreePool (PackageVersionName);
+ PackageVersionName = NULL;
+ }
+
+ CopyGuid (&FmpVersions[FmpVersionsCount].ImageTypeId, &FmpImageInfoBuf[Index]->ImageTypeId);
+ FmpVersions[FmpVersionsCount].Version = FmpImageInfoBuf[Index]->Version;
+ FmpVersionsCount ++;
+ }
+
+ //
+ // Evaluate firmware image's depex, against the version of other Fmp instances.
+ //
+ if (Dependencies != NULL) {
+ IsSatisfied = EvaluateDependency (Dependencies, DependenciesSize, FmpVersions, FmpVersionsCount);
+ }
+
+ if (!IsSatisfied) {
+ DEBUG ((DEBUG_ERROR, "CheckFmpDependency: %g\'s dependency is not satisfied!\n", ImageTypeId));
+ goto cleanup;
+ }
+
+cleanup:
+ if (FmpImageInfoBuf != NULL) {
+ for (Index = 0; Index < NumberOfFmpInstance; Index ++) {
+ if (FmpImageInfoBuf[Index] != NULL) {
+ FreePool (FmpImageInfoBuf[Index]);
+ }
+ }
+ FreePool (FmpImageInfoBuf);
+ }
+
+ if (DescriptorVer != NULL) {
+ FreePool (DescriptorVer);
+ }
+
+ if (DescriptorSize != NULL) {
+ FreePool (DescriptorSize);
+ }
+
+ if (FmpVersions != NULL) {
+ FreePool (FmpVersions);
+ }
+
+ return IsSatisfied;
+}
diff --git a/roms/edk2/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.inf b/roms/edk2/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.inf new file mode 100644 index 000000000..2050cc649 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.inf @@ -0,0 +1,43 @@ +## @file
+# Provides FMP capsule dependency check services when updating the firmware
+# image of a FMP device.
+#
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FmpDependencyCheckLib
+ MODULE_UNI_FILE = FmpDependencyCheckLib.uni
+ FILE_GUID = 8296D425-3095-4CFE-88D8-B0A44DB174A8
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = FmpDependencyCheckLib|DXE_DRIVER UEFI_DRIVER UEFI_APPLICATION
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
+#
+
+[Sources]
+ FmpDependencyCheckLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ FmpDevicePkg/FmpDevicePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ FmpDependencyLib
+ MemoryAllocationLib
+ UefiLib
+ UefiBootServicesTableLib
+
+[Protocols]
+ gEfiFirmwareManagementProtocolGuid ## CONSUMES
diff --git a/roms/edk2/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.uni b/roms/edk2/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.uni new file mode 100644 index 000000000..c6369e227 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.uni @@ -0,0 +1,13 @@ +// /** @file
+// Provides FMP capsule dependency check services when updating the firmware
+// image of a FMP device.
+//
+// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_MODULE_ABSTRACT #language en-US "FMP Dependency Check Lib"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Provides FMP capsule dependency check services when updating the firmware image of a FMP device."
diff --git a/roms/edk2/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.c b/roms/edk2/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.c new file mode 100644 index 000000000..55e9af229 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.c @@ -0,0 +1,34 @@ +/** @file
+ Null instance of FmpDependencyCheckLib.
+
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <PiDxe.h>
+#include <Library/FmpDependencyCheckLib.h>
+
+/**
+ Check dependency for firmware update.
+
+ @param[in] ImageTypeId Image Type Id.
+ @param[in] Version New version.
+ @param[in] Dependencies Fmp dependency.
+ @param[in] DependenciesSize Size, in bytes, of the Fmp dependency.
+
+ @retval TRUE Dependencies are satisfied.
+ @retval FALSE Dependencies are unsatisfied or dependency check fails.
+
+**/
+BOOLEAN
+EFIAPI
+CheckFmpDependency (
+ IN EFI_GUID ImageTypeId,
+ IN UINT32 Version,
+ IN EFI_FIRMWARE_IMAGE_DEP *Dependencies, OPTIONAL
+ IN UINT32 DependenciesSize
+ )
+{
+ return TRUE;
+}
diff --git a/roms/edk2/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.inf b/roms/edk2/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.inf new file mode 100644 index 000000000..5794d8919 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.inf @@ -0,0 +1,30 @@ +## @file
+# Null instance of FmpDependencyCheckLib as an option to skip the dependency
+# check when updating the firmware image of a FMP device.
+#
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FmpDependencyCheckLibNull
+ MODULE_UNI_FILE = FmpDependencyCheckLibNull.uni
+ FILE_GUID = D63F3166-9CBC-4AC2-8F23-8818E42EA2BD
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = FmpDependencyCheckLib|DXE_DRIVER UEFI_DRIVER UEFI_APPLICATION
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
+#
+
+[Sources]
+ FmpDependencyCheckLibNull.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ FmpDevicePkg/FmpDevicePkg.dec
diff --git a/roms/edk2/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.uni b/roms/edk2/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.uni new file mode 100644 index 000000000..7942d08f7 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.uni @@ -0,0 +1,13 @@ +// /** @file
+// Null instance of FmpDependencyCheckLib as an option to skip the dependency
+// check when updating the firmware image of a FMP device.
+//
+// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_MODULE_ABSTRACT #language en-US "FMP Dependency Check Library NULL instance"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Null instance of FmpDependencyCheckLib as an option to skip the dependency check when updating the firmware image of a FMP device."
diff --git a/roms/edk2/FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLib.c b/roms/edk2/FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLib.c new file mode 100644 index 000000000..083968143 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLib.c @@ -0,0 +1,50 @@ +/** @file
+ Null instance of FmpDependencyDeviceLib.
+
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <PiDxe.h>
+#include <Library/FmpDependencyDeviceLib.h>
+
+/**
+ Save dependency to Fmp device.
+
+ @param[in] Depex Fmp dependency.
+ @param[in] DepexSize Size, in bytes, of the Fmp dependency.
+
+ @retval EFI_SUCCESS Save Fmp dependency succeeds.
+ @retval EFI_UNSUPPORTED Save Fmp dependency is not supported.
+ @retval Others Save Fmp dependency fails.
+
+**/
+EFI_STATUS
+EFIAPI
+SaveFmpDependency (
+ IN EFI_FIRMWARE_IMAGE_DEP *Depex,
+ IN UINT32 DepexSize
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Get dependency from the Fmp device.
+ This caller is responsible for freeing the dependency buffer.
+
+ @param[out] DepexSize Size, in bytes, of the dependency.
+
+ @retval The pointer to dependency.
+ @retval NULL
+
+**/
+EFI_FIRMWARE_IMAGE_DEP*
+EFIAPI
+GetFmpDependency (
+ OUT UINT32 *DepexSize
+ )
+{
+ return NULL;
+}
diff --git a/roms/edk2/FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLibNull.inf b/roms/edk2/FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLibNull.inf new file mode 100644 index 000000000..d318cc9a6 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLibNull.inf @@ -0,0 +1,29 @@ +## @file
+# Fmp Dependency Device Library Null instance.
+#
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FmpDependencyDeviceLibNull
+ MODULE_UNI_FILE = FmpDependencyDeviceLibNull.uni
+ FILE_GUID = 05BE67B1-0748-4022-97E6-7C0D2F992AA6
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = FmpDependencyDeviceLib|DXE_DRIVER UEFI_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
+#
+
+[Sources]
+ FmpDependencyDeviceLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ FmpDevicePkg/FmpDevicePkg.dec
diff --git a/roms/edk2/FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLibNull.uni b/roms/edk2/FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLibNull.uni new file mode 100644 index 000000000..730ff65cb --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLibNull.uni @@ -0,0 +1,12 @@ +// /** @file
+// Fmp Dependency Device Library Null instance.
+//
+// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_MODULE_ABSTRACT #language en-US "Fmp Dependency Device Library Null instance."
+
+#string STR_MODULE_DESCRIPTION #language en-US "Null instance that does not support saving and getting dependency for Fmp device."
diff --git a/roms/edk2/FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.c b/roms/edk2/FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.c new file mode 100644 index 000000000..5ef25d241 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.c @@ -0,0 +1,548 @@ +/** @file
+ Supports Fmp Capsule Dependency Expression.
+
+ Copyright (c) Microsoft Corporation.<BR>
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <PiDxe.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/FmpDependencyLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+//
+// Define the initial size of the dependency expression evaluation stack
+//
+#define DEPEX_STACK_SIZE_INCREMENT 0x1000
+
+//
+// Type of stack element
+//
+typedef enum {
+ BooleanType,
+ VersionType
+} ELEMENT_TYPE;
+
+//
+// Value of stack element
+//
+typedef union {
+ BOOLEAN Boolean;
+ UINT32 Version;
+} ELEMENT_VALUE;
+
+//
+// Stack element used to evaluate dependency expressions
+//
+typedef struct {
+ ELEMENT_VALUE Value;
+ ELEMENT_TYPE Type;
+} DEPEX_ELEMENT;
+
+//
+// Global stack used to evaluate dependency expressions
+//
+DEPEX_ELEMENT *mDepexEvaluationStack = NULL;
+DEPEX_ELEMENT *mDepexEvaluationStackEnd = NULL;
+DEPEX_ELEMENT *mDepexEvaluationStackPointer = NULL;
+
+/**
+ Grow size of the Depex stack
+
+ @retval EFI_SUCCESS Stack successfully growed.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
+
+**/
+EFI_STATUS
+GrowDepexStack (
+ VOID
+ )
+{
+ DEPEX_ELEMENT *NewStack;
+ UINTN Size;
+
+ Size = DEPEX_STACK_SIZE_INCREMENT;
+ if (mDepexEvaluationStack != NULL) {
+ Size = Size + (mDepexEvaluationStackEnd - mDepexEvaluationStack);
+ }
+
+ NewStack = AllocatePool (Size * sizeof (DEPEX_ELEMENT));
+ if (NewStack == NULL) {
+ DEBUG ((DEBUG_ERROR, "GrowDepexStack: Cannot allocate memory for dependency evaluation stack!\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (mDepexEvaluationStack != NULL) {
+ //
+ // Copy to Old Stack to the New Stack
+ //
+ CopyMem (
+ NewStack,
+ mDepexEvaluationStack,
+ (mDepexEvaluationStackEnd - mDepexEvaluationStack) * sizeof (DEPEX_ELEMENT)
+ );
+
+ //
+ // Free The Old Stack
+ //
+ FreePool (mDepexEvaluationStack);
+ }
+
+ //
+ // Make the Stack pointer point to the old data in the new stack
+ //
+ mDepexEvaluationStackPointer = NewStack + (mDepexEvaluationStackPointer - mDepexEvaluationStack);
+ mDepexEvaluationStack = NewStack;
+ mDepexEvaluationStackEnd = NewStack + Size;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Push an element onto the Stack.
+
+ @param[in] Value Value to push.
+ @param[in] Type Element Type
+
+ @retval EFI_SUCCESS The value was pushed onto the stack.
+ @retval EFI_OUT_OF_RESOURCES There is not enough system memory to grow the stack.
+ @retval EFI_INVALID_PARAMETER Wrong stack element type.
+
+**/
+EFI_STATUS
+Push (
+ IN UINT32 Value,
+ IN UINTN Type
+ )
+{
+ EFI_STATUS Status;
+ DEPEX_ELEMENT Element;
+
+ //
+ // Check Type
+ //
+ if (Type != BooleanType && Type != VersionType) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check for a stack overflow condition
+ //
+ if (mDepexEvaluationStackPointer == mDepexEvaluationStackEnd) {
+ //
+ // Grow the stack
+ //
+ Status = GrowDepexStack ();
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ Element.Value.Version = Value;
+ Element.Type = Type;
+
+ //
+ // Push the item onto the stack
+ //
+ *mDepexEvaluationStackPointer = Element;
+ mDepexEvaluationStackPointer++;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Pop an element from the stack.
+
+ @param[out] Element Element to pop.
+ @param[in] Type Type of element.
+
+ @retval EFI_SUCCESS The value was popped onto the stack.
+ @retval EFI_ACCESS_DENIED The pop operation underflowed the stack.
+ @retval EFI_INVALID_PARAMETER Type is mismatched.
+
+**/
+EFI_STATUS
+Pop (
+ OUT DEPEX_ELEMENT *Element,
+ IN ELEMENT_TYPE Type
+ )
+{
+ //
+ // Check for a stack underflow condition
+ //
+ if (mDepexEvaluationStackPointer == mDepexEvaluationStack) {
+ DEBUG ((DEBUG_ERROR, "EvaluateDependency: Stack underflow!\n"));
+ return EFI_ACCESS_DENIED;
+ }
+
+ //
+ // Pop the item off the stack
+ //
+ mDepexEvaluationStackPointer--;
+ *Element = *mDepexEvaluationStackPointer;
+ if ((*Element).Type != Type) {
+ DEBUG ((DEBUG_ERROR, "EvaluateDependency: Popped element type is mismatched!\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Evaluate the dependencies. The caller must search all the Fmp instances and
+ gather their versions into FmpVersions parameter. If there is PUSH_GUID opcode
+ in dependency expression with no FmpVersions provided, the dependency will
+ evaluate to FALSE.
+
+ @param[in] Dependencies Dependency expressions.
+ @param[in] DependenciesSize Size of Dependency expressions.
+ @param[in] FmpVersions Array of Fmp ImageTypeId and version. This
+ parameter is optional and can be set to NULL.
+ @param[in] FmpVersionsCount Element count of the array. When FmpVersions
+ is NULL, FmpVersionsCount must be 0.
+
+ @retval TRUE Dependency expressions evaluate to TRUE.
+ @retval FALSE Dependency expressions evaluate to FALSE.
+
+**/
+BOOLEAN
+EFIAPI
+EvaluateDependency (
+ IN EFI_FIRMWARE_IMAGE_DEP *Dependencies,
+ IN UINTN DependenciesSize,
+ IN FMP_DEPEX_CHECK_VERSION_DATA *FmpVersions OPTIONAL,
+ IN UINTN FmpVersionsCount
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *Iterator;
+ UINT8 Index;
+ DEPEX_ELEMENT Element1;
+ DEPEX_ELEMENT Element2;
+ GUID ImageTypeId;
+ UINT32 Version;
+
+ //
+ // Check if parameter is valid.
+ //
+ if (Dependencies == NULL || DependenciesSize == 0) {
+ return FALSE;
+ }
+
+ if (FmpVersions == NULL && FmpVersionsCount > 0) {
+ return FALSE;
+ }
+
+ //
+ // Clean out memory leaks in Depex Boolean stack. Leaks are only caused by
+ // incorrectly formed DEPEX expressions
+ //
+ mDepexEvaluationStackPointer = mDepexEvaluationStack;
+
+ Iterator = (UINT8 *) Dependencies->Dependencies;
+ while (Iterator < (UINT8 *) Dependencies->Dependencies + DependenciesSize) {
+ switch (*Iterator)
+ {
+ case EFI_FMP_DEP_PUSH_GUID:
+ if (Iterator + sizeof (EFI_GUID) >= (UINT8 *) Dependencies->Dependencies + DependenciesSize) {
+ DEBUG ((DEBUG_ERROR, "EvaluateDependency: GUID extends beyond end of dependency expression!\n"));
+ goto Error;
+ }
+
+ CopyGuid (&ImageTypeId, (EFI_GUID *) (Iterator + 1));
+ Iterator = Iterator + sizeof (EFI_GUID);
+
+ for (Index = 0; Index < FmpVersionsCount; Index ++) {
+ if(CompareGuid (&FmpVersions[Index].ImageTypeId, &ImageTypeId)){
+ Status = Push (FmpVersions[Index].Version, VersionType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ break;
+ }
+ }
+ if (Index == FmpVersionsCount) {
+ DEBUG ((DEBUG_ERROR, "EvaluateDependency: %g is not found!\n", &ImageTypeId));
+ goto Error;
+ }
+ break;
+ case EFI_FMP_DEP_PUSH_VERSION:
+ if (Iterator + sizeof (UINT32) >= (UINT8 *) Dependencies->Dependencies + DependenciesSize ) {
+ DEBUG ((DEBUG_ERROR, "EvaluateDependency: VERSION extends beyond end of dependency expression!\n"));
+ goto Error;
+ }
+
+ Version = *(UINT32 *) (Iterator + 1);
+ Status = Push (Version, VersionType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ Iterator = Iterator + sizeof (UINT32);
+ break;
+ case EFI_FMP_DEP_VERSION_STR:
+ Iterator += AsciiStrnLenS ((CHAR8 *) Iterator, DependenciesSize - (Iterator - Dependencies->Dependencies));
+ if (Iterator == (UINT8 *) Dependencies->Dependencies + DependenciesSize) {
+ DEBUG ((DEBUG_ERROR, "EvaluateDependency: STRING extends beyond end of dependency expression!\n"));
+ goto Error;
+ }
+ break;
+ case EFI_FMP_DEP_AND:
+ Status = Pop (&Element1, BooleanType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ Status = Pop (&Element2, BooleanType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ Status = Push (Element1.Value.Boolean & Element2.Value.Boolean, BooleanType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ break;
+ case EFI_FMP_DEP_OR:
+ Status = Pop (&Element1, BooleanType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ Status = Pop(&Element2, BooleanType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ Status = Push (Element1.Value.Boolean | Element2.Value.Boolean, BooleanType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ break;
+ case EFI_FMP_DEP_NOT:
+ Status = Pop (&Element1, BooleanType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ Status = Push (!(Element1.Value.Boolean), BooleanType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ break;
+ case EFI_FMP_DEP_TRUE:
+ Status = Push (TRUE, BooleanType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ break;
+ case EFI_FMP_DEP_FALSE:
+ Status = Push (FALSE, BooleanType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ break;
+ case EFI_FMP_DEP_EQ:
+ Status = Pop (&Element1, VersionType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ Status = Pop (&Element2, VersionType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ Status = (Element1.Value.Version == Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ break;
+ case EFI_FMP_DEP_GT:
+ Status = Pop (&Element1, VersionType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ Status = Pop (&Element2, VersionType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ Status = (Element1.Value.Version > Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ break;
+ case EFI_FMP_DEP_GTE:
+ Status = Pop (&Element1, VersionType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ Status = Pop (&Element2, VersionType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ Status = (Element1.Value.Version >= Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ break;
+ case EFI_FMP_DEP_LT:
+ Status = Pop (&Element1, VersionType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ Status = Pop (&Element2, VersionType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ Status = (Element1.Value.Version < Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ break;
+ case EFI_FMP_DEP_LTE:
+ Status = Pop (&Element1, VersionType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ Status = Pop (&Element2, VersionType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ Status = (Element1.Value.Version <= Element2.Value.Version) ? Push (TRUE, BooleanType) : Push (FALSE, BooleanType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ break;
+ case EFI_FMP_DEP_END:
+ Status = Pop (&Element1, BooleanType);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+ return Element1.Value.Boolean;
+ default:
+ DEBUG ((DEBUG_ERROR, "EvaluateDependency: Unknown Opcode - %02x!\n", *Iterator));
+ goto Error;
+ }
+ Iterator++;
+ }
+
+ DEBUG ((DEBUG_ERROR, "EvaluateDependency: No EFI_FMP_DEP_END Opcode in expression!\n"));
+
+Error:
+ return FALSE;
+}
+
+/**
+ Validate the dependency expression and output its size.
+
+ @param[in] Dependencies Pointer to the EFI_FIRMWARE_IMAGE_DEP.
+ @param[in] MaxDepexSize Max size of the dependency.
+ @param[out] DepexSize Size of dependency.
+
+ @retval TRUE The dependency expression is valid.
+ @retval FALSE The dependency expression is invalid.
+
+**/
+BOOLEAN
+EFIAPI
+ValidateDependency (
+ IN EFI_FIRMWARE_IMAGE_DEP *Dependencies,
+ IN UINTN MaxDepexSize,
+ OUT UINT32 *DepexSize
+ )
+{
+ UINT8 *Depex;
+
+ if (DepexSize != NULL) {
+ *DepexSize = 0;
+ }
+
+ if (Dependencies == NULL) {
+ return FALSE;
+ }
+
+ Depex = Dependencies->Dependencies;
+ while (Depex < Dependencies->Dependencies + MaxDepexSize) {
+ switch (*Depex)
+ {
+ case EFI_FMP_DEP_PUSH_GUID:
+ Depex += sizeof (EFI_GUID) + 1;
+ break;
+ case EFI_FMP_DEP_PUSH_VERSION:
+ Depex += sizeof (UINT32) + 1;
+ break;
+ case EFI_FMP_DEP_VERSION_STR:
+ Depex += AsciiStrnLenS ((CHAR8 *) Depex, Dependencies->Dependencies + MaxDepexSize - Depex) + 1;
+ break;
+ case EFI_FMP_DEP_AND:
+ case EFI_FMP_DEP_OR:
+ case EFI_FMP_DEP_NOT:
+ case EFI_FMP_DEP_TRUE:
+ case EFI_FMP_DEP_FALSE:
+ case EFI_FMP_DEP_EQ:
+ case EFI_FMP_DEP_GT:
+ case EFI_FMP_DEP_GTE:
+ case EFI_FMP_DEP_LT:
+ case EFI_FMP_DEP_LTE:
+ Depex += 1;
+ break;
+ case EFI_FMP_DEP_END:
+ Depex += 1;
+ if (DepexSize != NULL) {
+ *DepexSize = (UINT32)(Depex - Dependencies->Dependencies);
+ }
+ return TRUE;
+ default:
+ return FALSE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ Get dependency from firmware image.
+
+ @param[in] Image Points to the firmware image.
+ @param[in] ImageSize Size, in bytes, of the firmware image.
+ @param[out] DepexSize Size, in bytes, of the dependency.
+
+ @retval The pointer to dependency.
+ @retval Null
+
+**/
+EFI_FIRMWARE_IMAGE_DEP*
+EFIAPI
+GetImageDependency (
+ IN EFI_FIRMWARE_IMAGE_AUTHENTICATION *Image,
+ IN UINTN ImageSize,
+ OUT UINT32 *DepexSize
+ )
+{
+ EFI_FIRMWARE_IMAGE_DEP *Depex;
+ UINTN MaxDepexSize;
+
+ if (Image == NULL) {
+ return NULL;
+ }
+
+ //
+ // Check to make sure that operation can be safely performed.
+ //
+ if (((UINTN)Image + sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr.dwLength) < (UINTN)Image || \
+ ((UINTN)Image + sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr.dwLength) >= (UINTN)Image + ImageSize) {
+ //
+ // Pointer overflow. Invalid image.
+ //
+ return NULL;
+ }
+
+ Depex = (EFI_FIRMWARE_IMAGE_DEP*)((UINT8 *)Image + sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr.dwLength);
+ MaxDepexSize = ImageSize - (sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr.dwLength);
+
+ //
+ // Validate the dependency and get the size of dependency
+ //
+ if (ValidateDependency (Depex, MaxDepexSize, DepexSize)) {
+ return Depex;
+ }
+
+ return NULL;
+}
+
diff --git a/roms/edk2/FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.inf b/roms/edk2/FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.inf new file mode 100644 index 000000000..b7e5c8d00 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.inf @@ -0,0 +1,34 @@ +## @file
+# Provides Fmp Capsule Dependency Expression support.
+#
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FmpDependencyLib
+ MODULE_UNI_FILE = FmpDependencyLib.uni
+ FILE_GUID = 67F55EA4-B4CF-4A08-931B-0BBCF1E0F7A3
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = FmpDependencyLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
+#
+
+[Sources]
+ FmpDependencyLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ FmpDevicePkg/FmpDevicePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ BaseMemoryLib
diff --git a/roms/edk2/FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.uni b/roms/edk2/FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.uni new file mode 100644 index 000000000..422a96b57 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.uni @@ -0,0 +1,12 @@ +// /** @file
+// Provides Fmp Capsule Dependency Expression support.
+//
+// Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_MODULE_ABSTRACT #language en-US "FMP Dependency Lib"
+
+#string STR_MODULE_DESCRIPTION #language en-US "Provides Fmp Capsule Dependency Expression support."
diff --git a/roms/edk2/FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLib.c b/roms/edk2/FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLib.c new file mode 100644 index 000000000..316de12e9 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLib.c @@ -0,0 +1,501 @@ +/** @file
+ 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.<BR>
+ Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+#include <Library/FmpDeviceLib.h>
+
+/**
+ Provide a function to install the Firmware Management Protocol instance onto a
+ device handle when the device is managed by a driver that follows the UEFI
+ Driver Model. If the device is not managed by a driver that follows the UEFI
+ Driver Model, then EFI_UNSUPPORTED is returned.
+
+ @param[in] FmpInstaller Function that installs the Firmware Management
+ Protocol.
+
+ @retval EFI_SUCCESS The device is managed by a driver that follows the
+ UEFI Driver Model. FmpInstaller must be called on
+ each Driver Binding Start().
+ @retval EFI_UNSUPPORTED The device is not managed by a driver that follows
+ the UEFI Driver Model.
+ @retval other The Firmware Management Protocol for this firmware
+ device is not installed. The firmware device is
+ still locked using FmpDeviceLock().
+
+**/
+EFI_STATUS
+EFIAPI
+RegisterFmpInstaller (
+ IN FMP_DEVICE_LIB_REGISTER_FMP_INSTALLER Function
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Provide a function to uninstall the Firmware Management Protocol instance from a
+ device handle when the device is managed by a driver that follows the UEFI
+ Driver Model. If the device is not managed by a driver that follows the UEFI
+ Driver Model, then EFI_UNSUPPORTED is returned.
+
+ @param[in] FmpUninstaller Function that installs the Firmware Management
+ Protocol.
+
+ @retval EFI_SUCCESS The device is managed by a driver that follows the
+ UEFI Driver Model. FmpUninstaller must be called on
+ each Driver Binding Stop().
+ @retval EFI_UNSUPPORTED The device is not managed by a driver that follows
+ the UEFI Driver Model.
+ @retval other The Firmware Management Protocol for this firmware
+ device is not installed. The firmware device is
+ still locked using FmpDeviceLock().
+
+**/
+EFI_STATUS
+EFIAPI
+RegisterFmpUninstaller (
+ IN FMP_DEVICE_LIB_REGISTER_FMP_UNINSTALLER Function
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Set the device context for the FmpDeviceLib services when the device is
+ managed by a driver that follows the UEFI Driver Model. If the device is not
+ managed by a driver that follows the UEFI Driver Model, then EFI_UNSUPPORTED
+ is returned. Once a device context is set, the FmpDeviceLib services
+ operate on the currently set device context.
+
+ @param[in] Handle Device handle for the FmpDeviceLib services.
+ If Handle is NULL, then Context is freed.
+ @param[in, out] Context Device context for the FmpDeviceLib services.
+ If Context is NULL, then a new context is allocated
+ for Handle and the current device context is set and
+ returned in Context. If Context is not NULL, then
+ the current device context is set.
+
+ @retval EFI_SUCCESS The device is managed by a driver that follows the
+ UEFI Driver Model.
+ @retval EFI_UNSUPPORTED The device is not managed by a driver that follows
+ the UEFI Driver Model.
+ @retval other The Firmware Management Protocol for this firmware
+ device is not installed. The firmware device is
+ still locked using FmpDeviceLock().
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceSetContext (
+ IN EFI_HANDLE Handle,
+ IN OUT VOID **Context
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Returns the size, in bytes, of the firmware image currently stored in the
+ firmware device. This function is used to by the GetImage() and
+ GetImageInfo() services of the Firmware Management Protocol. If the image
+ size can not be determined from the firmware device, then 0 must be returned.
+
+ @param[out] Size Pointer to the size, in bytes, of the firmware image
+ currently stored in the firmware device.
+
+ @retval EFI_SUCCESS The size of the firmware image currently
+ stored in the firmware device was returned.
+ @retval EFI_INVALID_PARAMETER Size is NULL.
+ @retval EFI_UNSUPPORTED The firmware device does not support reporting
+ the size of the currently stored firmware image.
+ @retval EFI_DEVICE_ERROR An error occurred attempting to determine the
+ size of the firmware image currently stored in
+ in the firmware device.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetSize (
+ OUT UINTN *Size
+ )
+{
+ if (Size == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ *Size = 0;
+ return EFI_SUCCESS;
+}
+
+/**
+ Returns the GUID value used to fill in the ImageTypeId field of the
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo()
+ service of the Firmware Management Protocol. If EFI_UNSUPPORTED is returned,
+ then the ImageTypeId field is set to gEfiCallerIdGuid. If EFI_SUCCESS is
+ returned, then ImageTypeId is set to the Guid returned from this function.
+
+ @param[out] Guid Double pointer to a GUID value that is updated to point to
+ to a GUID value. The GUID value is not allocated and must
+ not be modified or freed by the caller.
+
+ @retval EFI_SUCCESS EFI_FIRMWARE_IMAGE_DESCRIPTOR ImageTypeId GUID is set
+ to the returned Guid value.
+ @retval EFI_UNSUPPORTED EFI_FIRMWARE_IMAGE_DESCRIPTOR ImageTypeId GUID is set
+ to gEfiCallerIdGuid.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetImageTypeIdGuidPtr (
+ OUT EFI_GUID **Guid
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Returns values used to fill in the AttributesSupported and AttributesSettings
+ fields of the EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the
+ GetImageInfo() service of the Firmware Management Protocol. The following
+ bit values from the Firmware Management Protocol may be combined:
+ IMAGE_ATTRIBUTE_IMAGE_UPDATABLE
+ IMAGE_ATTRIBUTE_RESET_REQUIRED
+ IMAGE_ATTRIBUTE_AUTHENTICATION_REQUIRED
+ IMAGE_ATTRIBUTE_IN_USE
+ IMAGE_ATTRIBUTE_UEFI_IMAGE
+
+ @param[out] Supported Attributes supported by this firmware device.
+ @param[out] Setting Attributes settings for this firmware device.
+
+ @retval EFI_SUCCESS The attributes supported by the firmware
+ device were returned.
+ @retval EFI_INVALID_PARAMETER Supported is NULL.
+ @retval EFI_INVALID_PARAMETER Setting is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetAttributes (
+ OUT UINT64 *Supported,
+ OUT UINT64 *Setting
+ )
+{
+ if (Supported == NULL || Setting == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ *Supported = 0;
+ *Setting = 0;
+ return EFI_SUCCESS;
+}
+
+/**
+ Returns the value used to fill in the LowestSupportedVersion field of the
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo()
+ service of the Firmware Management Protocol. If EFI_SUCCESS is returned, then
+ the firmware device supports a method to report the LowestSupportedVersion
+ value from the currently stored firmware image. If the value can not be
+ reported for the firmware image currently stored in the firmware device, then
+ EFI_UNSUPPORTED must be returned. EFI_DEVICE_ERROR is returned if an error
+ occurs attempting to retrieve the LowestSupportedVersion value for the
+ currently stored firmware image.
+
+ @note It is recommended that all firmware devices support a method to report
+ the LowestSupportedVersion value from the currently stored firmware
+ image.
+
+ @param[out] LowestSupportedVersion LowestSupportedVersion value retrieved
+ from the currently stored firmware image.
+
+ @retval EFI_SUCCESS The lowest supported version of currently stored
+ firmware image was returned in LowestSupportedVersion.
+ @retval EFI_UNSUPPORTED The firmware device does not support a method to
+ report the lowest supported version of the currently
+ stored firmware image.
+ @retval EFI_DEVICE_ERROR An error occurred attempting to retrieve the lowest
+ supported version of the currently stored firmware
+ image.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetLowestSupportedVersion (
+ OUT UINT32 *LowestSupportedVersion
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Returns the Null-terminated Unicode string that is used to fill in the
+ VersionName field of the EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is
+ returned by the GetImageInfo() service of the Firmware Management Protocol.
+ The returned string must be allocated using EFI_BOOT_SERVICES.AllocatePool().
+
+ @note It is recommended that all firmware devices support a method to report
+ the VersionName string from the currently stored firmware image.
+
+ @param[out] VersionString The version string retrieved from the currently
+ stored firmware image.
+
+ @retval EFI_SUCCESS The version string of currently stored
+ firmware image was returned in Version.
+ @retval EFI_INVALID_PARAMETER VersionString is NULL.
+ @retval EFI_UNSUPPORTED The firmware device does not support a method
+ to report the version string of the currently
+ stored firmware image.
+ @retval EFI_DEVICE_ERROR An error occurred attempting to retrieve the
+ version string of the currently stored
+ firmware image.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources to allocate the
+ buffer for the version string of the currently
+ stored firmware image.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetVersionString (
+ OUT CHAR16 **VersionString
+ )
+{
+ if (VersionString == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ *VersionString = NULL;
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Returns the value used to fill in the Version field of the
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo()
+ service of the Firmware Management Protocol. If EFI_SUCCESS is returned, then
+ the firmware device supports a method to report the Version value from the
+ currently stored firmware image. If the value can not be reported for the
+ firmware image currently stored in the firmware device, then EFI_UNSUPPORTED
+ must be returned. EFI_DEVICE_ERROR is returned if an error occurs attempting
+ to retrieve the LowestSupportedVersion value for the currently stored firmware
+ image.
+
+ @note It is recommended that all firmware devices support a method to report
+ the Version value from the currently stored firmware image.
+
+ @param[out] Version The version value retrieved from the currently stored
+ firmware image.
+
+ @retval EFI_SUCCESS The version of currently stored firmware image was
+ returned in Version.
+ @retval EFI_UNSUPPORTED The firmware device does not support a method to
+ report the version of the currently stored firmware
+ image.
+ @retval EFI_DEVICE_ERROR An error occurred attempting to retrieve the version
+ of the currently stored firmware image.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetVersion (
+ OUT UINT32 *Version
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Returns the value used to fill in the HardwareInstance field of the
+ EFI_FIRMWARE_IMAGE_DESCRIPTOR structure that is returned by the GetImageInfo()
+ service of the Firmware Management Protocol. If EFI_SUCCESS is returned, then
+ the firmware device supports a method to report the HardwareInstance value.
+ If the value can not be reported for the firmware device, then EFI_UNSUPPORTED
+ must be returned. EFI_DEVICE_ERROR is returned if an error occurs attempting
+ to retrieve the HardwareInstance value for the firmware device.
+
+ @param[out] HardwareInstance The hardware instance value for the firmware
+ device.
+
+ @retval EFI_SUCCESS The hardware instance for the current firmware
+ device is returned in HardwareInstance.
+ @retval EFI_UNSUPPORTED The firmware device does not support a method to
+ report the hardware instance value.
+ @retval EFI_DEVICE_ERROR An error occurred attempting to retrieve the hardware
+ instance value.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetHardwareInstance (
+ OUT UINT64 *HardwareInstance
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Returns a copy of the firmware image currently stored in the firmware device.
+
+ @note It is recommended that all firmware devices support a method to retrieve
+ a copy currently stored firmware image. This can be used to support
+ features such as recovery and rollback.
+
+ @param[out] Image Pointer to a caller allocated buffer where the
+ currently stored firmware image is copied to.
+ @param[in, out] ImageSize Pointer the size, in bytes, of the Image buffer.
+ On return, points to the size, in bytes, of firmware
+ image currently stored in the firmware device.
+
+ @retval EFI_SUCCESS Image contains a copy of the firmware image
+ currently stored in the firmware device, and
+ ImageSize contains the size, in bytes, of the
+ firmware image currently stored in the
+ firmware device.
+ @retval EFI_BUFFER_TOO_SMALL The buffer specified by ImageSize is too small
+ to hold the firmware image currently stored in
+ the firmware device. The buffer size required
+ is returned in ImageSize.
+ @retval EFI_INVALID_PARAMETER The Image is NULL.
+ @retval EFI_INVALID_PARAMETER The ImageSize is NULL.
+ @retval EFI_UNSUPPORTED The operation is not supported.
+ @retval EFI_DEVICE_ERROR An error occurred attempting to retrieve the
+ firmware image currently stored in the firmware
+ device.
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceGetImage (
+ OUT VOID *Image,
+ IN OUT UINTN *ImageSize
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ 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
+
+ @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
+FmpDeviceCheckImage (
+ IN CONST VOID *Image,
+ IN UINTN ImageSize,
+ OUT UINT32 *ImageUpdatable
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ 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().
+
+ @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
+FmpDeviceSetImage (
+ 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
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ 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
+ firmware device must fail.
+
+ @note It is recommended that all firmware devices support a lock method to
+ prevent modifications to a stored firmware image.
+
+ @note A firmware device lock mechanism is typically only cleared by a full
+ system reset (not just sleep state/low power mode).
+
+ @retval EFI_SUCCESS The firmware device was locked.
+ @retval EFI_UNSUPPORTED The firmware device does not support locking
+
+**/
+EFI_STATUS
+EFIAPI
+FmpDeviceLock (
+ VOID
+ )
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/roms/edk2/FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLibNull.inf b/roms/edk2/FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLibNull.inf new file mode 100644 index 000000000..9c77e5bde --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLibNull.inf @@ -0,0 +1,31 @@ +## @file
+# 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.<BR>
+# Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FmpDeviceLibNull
+ MODULE_UNI_FILE = FmpDeviceLibNull.uni
+ FILE_GUID = 8507642B-AE92-4664-B713-807F7774A96D
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = FmpDeviceLib|DXE_DRIVER UEFI_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
+#
+
+[Sources]
+ FmpDeviceLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ FmpDevicePkg/FmpDevicePkg.dec
diff --git a/roms/edk2/FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLibNull.uni b/roms/edk2/FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLibNull.uni new file mode 100644 index 000000000..37efb8c9e --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Library/FmpDeviceLibNull/FmpDeviceLibNull.uni @@ -0,0 +1,13 @@ +// /** @file
+// Provides firmware device specific services to support updates of a firmware
+// image stored in a firmware device.
+//
+// Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_MODULE_ABSTRACT #language en-US "Provides firmware device specific services to support updates of a firmware image stored in a firmware device."
+
+#string STR_MODULE_DESCRIPTION #language en-US "Provides firmware device specific services to support updates of a firmware image stored in a firmware device."
diff --git a/roms/edk2/FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLib.c b/roms/edk2/FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLib.c new file mode 100644 index 000000000..119679cd9 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLib.c @@ -0,0 +1,171 @@ +/** @file
+ Provides services to retrieve values from Version 1 of a capsule's FMP Payload
+ Header. The FMP Payload Header structure is not defined in the library class.
+ Instead, services are provided to retrieve information from the FMP Payload
+ Header. If information is added to the FMP Payload Header, then new services
+ may be added to this library class to retrieve the new information.
+
+ Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
+ Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+#include <Library/FmpPayloadHeaderLib.h>
+
+///
+/// Define FMP Payload Header structure here so it is not public
+///
+
+#pragma pack(1)
+
+typedef struct {
+ UINT32 Signature;
+ UINT32 HeaderSize;
+ UINT32 FwVersion;
+ UINT32 LowestSupportedVersion;
+} FMP_PAYLOAD_HEADER;
+
+#pragma pack()
+
+///
+/// Identifier is used to make sure the data in the header is for this structure
+/// and version. If the structure changes update the last digit.
+///
+#define FMP_PAYLOAD_HEADER_SIGNATURE SIGNATURE_32 ('M', 'S', 'S', '1')
+
+/**
+ Returns the FMP Payload Header size in bytes.
+
+ @param[in] Header FMP Payload Header to evaluate
+ @param[in] FmpPayloadSize Size of FMP payload
+ @param[out] Size The size, in bytes, of the FMP Payload Header.
+
+ @retval EFI_SUCCESS The firmware version was returned.
+ @retval EFI_INVALID_PARAMETER Header is NULL.
+ @retval EFI_INVALID_PARAMETER Size is NULL.
+ @retval EFI_INVALID_PARAMETER Header is not a valid FMP Payload Header.
+
+**/
+EFI_STATUS
+EFIAPI
+GetFmpPayloadHeaderSize (
+ IN CONST VOID *Header,
+ IN CONST UINTN FmpPayloadSize,
+ OUT UINT32 *Size
+ )
+{
+ FMP_PAYLOAD_HEADER *FmpPayloadHeader;
+
+ FmpPayloadHeader = NULL;
+
+ if (Header == NULL || Size == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FmpPayloadHeader = (FMP_PAYLOAD_HEADER *)Header;
+ if ((UINTN)FmpPayloadHeader + sizeof (FMP_PAYLOAD_HEADER) < (UINTN)FmpPayloadHeader ||
+ (UINTN)FmpPayloadHeader + sizeof (FMP_PAYLOAD_HEADER) >= (UINTN)FmpPayloadHeader + FmpPayloadSize ||
+ FmpPayloadHeader->HeaderSize < sizeof (FMP_PAYLOAD_HEADER)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (FmpPayloadHeader->Signature != FMP_PAYLOAD_HEADER_SIGNATURE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Size = FmpPayloadHeader->HeaderSize;
+ return EFI_SUCCESS;
+}
+
+/**
+ Returns the version described in the FMP Payload Header.
+
+ @param[in] Header FMP Payload Header to evaluate
+ @param[in] FmpPayloadSize Size of FMP payload
+ @param[out] Version The firmware version described in the FMP Payload
+ Header.
+
+ @retval EFI_SUCCESS The firmware version was returned.
+ @retval EFI_INVALID_PARAMETER Header is NULL.
+ @retval EFI_INVALID_PARAMETER Version is NULL.
+ @retval EFI_INVALID_PARAMETER Header is not a valid FMP Payload Header.
+
+**/
+EFI_STATUS
+EFIAPI
+GetFmpPayloadHeaderVersion (
+ IN CONST VOID *Header,
+ IN CONST UINTN FmpPayloadSize,
+ OUT UINT32 *Version
+ )
+{
+ FMP_PAYLOAD_HEADER *FmpPayloadHeader;
+
+ FmpPayloadHeader = NULL;
+
+ if (Header == NULL || Version == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FmpPayloadHeader = (FMP_PAYLOAD_HEADER *)Header;
+ if ((UINTN)FmpPayloadHeader + sizeof (FMP_PAYLOAD_HEADER) < (UINTN)FmpPayloadHeader ||
+ (UINTN)FmpPayloadHeader + sizeof (FMP_PAYLOAD_HEADER) >= (UINTN)FmpPayloadHeader + FmpPayloadSize ||
+ FmpPayloadHeader->HeaderSize < sizeof (FMP_PAYLOAD_HEADER)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (FmpPayloadHeader->Signature != FMP_PAYLOAD_HEADER_SIGNATURE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Version = FmpPayloadHeader->FwVersion;
+ return EFI_SUCCESS;
+}
+
+/**
+ Returns the lowest supported version described in the FMP Payload Header.
+
+ @param[in] Header FMP Payload Header to evaluate
+ @param[in] FmpPayloadSize Size of FMP payload
+ @param[out] LowestSupportedVersion The lowest supported version described in
+ the FMP Payload Header.
+
+ @retval EFI_SUCCESS The lowest support version was returned.
+ @retval EFI_INVALID_PARAMETER Header is NULL.
+ @retval EFI_INVALID_PARAMETER LowestSupportedVersion is NULL.
+ @retval EFI_INVALID_PARAMETER Header is not a valid FMP Payload Header.
+
+**/
+EFI_STATUS
+EFIAPI
+GetFmpPayloadHeaderLowestSupportedVersion (
+ IN CONST VOID *Header,
+ IN CONST UINTN FmpPayloadSize,
+ OUT UINT32 *LowestSupportedVersion
+ )
+{
+ FMP_PAYLOAD_HEADER *FmpPayloadHeader;
+
+ FmpPayloadHeader = NULL;
+
+ if (Header == NULL || LowestSupportedVersion == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FmpPayloadHeader = (FMP_PAYLOAD_HEADER *)Header;
+ if ((UINTN)FmpPayloadHeader + sizeof (FMP_PAYLOAD_HEADER) < (UINTN)FmpPayloadHeader ||
+ (UINTN)FmpPayloadHeader + sizeof (FMP_PAYLOAD_HEADER) >= (UINTN)FmpPayloadHeader + FmpPayloadSize ||
+ FmpPayloadHeader->HeaderSize < sizeof (FMP_PAYLOAD_HEADER)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (FmpPayloadHeader->Signature != FMP_PAYLOAD_HEADER_SIGNATURE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *LowestSupportedVersion = FmpPayloadHeader->LowestSupportedVersion;
+ return EFI_SUCCESS;
+}
diff --git a/roms/edk2/FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLibV1.inf b/roms/edk2/FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLibV1.inf new file mode 100644 index 000000000..0d6692dce --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLibV1.inf @@ -0,0 +1,31 @@ +## @file
+# Provides services to retrieve values from Version 1 of a capsule's FMP Payload
+# Header. The FMP Payload Header structure is not defined in the library class.
+# Instead, services are provided to retrieve information from the FMP Payload
+# Header. If information is added to the FMP Payload Header, then new services
+# may be added to this library class to retrieve the new information.
+#
+# Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
+# Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = FmpPayloadHeaderLibV1
+ FILE_GUID = 98A79A6C-513C-4E72-8375-39C0A7244C4B
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = FmpPayloadHeaderLib|DXE_DRIVER UEFI_DRIVER UEFI_APPLICATION
+
+#
+# VALID_ARCHITECTURES = IA32 X64 ARM AARCH64
+#
+
+[Sources]
+ FmpPayloadHeaderLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ FmpDevicePkg/FmpDevicePkg.dec
diff --git a/roms/edk2/FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLibV1.uni b/roms/edk2/FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLibV1.uni new file mode 100644 index 000000000..52481b779 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Library/FmpPayloadHeaderLibV1/FmpPayloadHeaderLibV1.uni @@ -0,0 +1,16 @@ +// /** @file
+// Provides services to retrieve values from Version 1 of a capsule's FMP Payload
+// Header. The FMP Payload Header structure is not defined in the library class.
+// Instead, services are provided to retrieve information from the FMP Payload
+// Header. If information is added to the FMP Payload Header, then new services
+// may be added to this library class to retrieve the new information.
+//
+// Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+#string STR_MODULE_ABSTRACT #language en-US "Provides services to retrieve values from Version 1 of a capsule's FMP Payload Header."
+
+#string STR_MODULE_DESCRIPTION #language en-US "Provides services to retrieve values from Version 1 of a capsule's FMP Payload Header."
diff --git a/roms/edk2/FmpDevicePkg/PrivateInclude/Library/FmpPayloadHeaderLib.h b/roms/edk2/FmpDevicePkg/PrivateInclude/Library/FmpPayloadHeaderLib.h new file mode 100644 index 000000000..24afd5e29 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/PrivateInclude/Library/FmpPayloadHeaderLib.h @@ -0,0 +1,83 @@ +/** @file
+ Provides services to retrieve values from a capsule's FMP Payload Header.
+ The structure is not included in the library class. Instead, services are
+ provided to retrieve information from the FMP Payload Header. If information
+ is added to the FMP Payload Header, then new services may be added to this
+ library class to retrieve the new information.
+
+ Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
+ Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _FMP_PAYLOAD_HEADER_LIB_H__
+#define _FMP_PAYLOAD_HEADER_LIB_H__
+
+/**
+ Returns the FMP Payload Header size in bytes.
+
+ @param[in] Header FMP Payload Header to evaluate
+ @param[in] FmpPayloadSize Size of FMP payload
+ @param[out] Size The size, in bytes, of the FMP Payload Header.
+
+ @retval EFI_SUCCESS The firmware version was returned.
+ @retval EFI_INVALID_PARAMETER Header is NULL.
+ @retval EFI_INVALID_PARAMETER Size is NULL.
+ @retval EFI_INVALID_PARAMETER Header is not a valid FMP Payload Header.
+
+**/
+EFI_STATUS
+EFIAPI
+GetFmpPayloadHeaderSize (
+ IN CONST VOID *Header,
+ IN CONST UINTN FmpPayloadSize,
+ OUT UINT32 *Size
+ );
+
+/**
+ Returns the version described in the FMP Payload Header.
+
+ @param[in] Header FMP Payload Header to evaluate
+ @param[in] FmpPayloadSize Size of FMP payload
+ @param[out] Version The firmware version described in the FMP Payload
+ Header.
+
+ @retval EFI_SUCCESS The firmware version was returned.
+ @retval EFI_INVALID_PARAMETER Header is NULL.
+ @retval EFI_INVALID_PARAMETER Version is NULL.
+ @retval EFI_INVALID_PARAMETER Header is not a valid FMP Payload Header.
+
+**/
+EFI_STATUS
+EFIAPI
+GetFmpPayloadHeaderVersion (
+ IN CONST VOID *Header,
+ IN CONST UINTN FmpPayloadSize,
+ OUT UINT32 *Version
+ );
+
+/**
+ Returns the lowest supported version described in the FMP Payload Header.
+
+ @param[in] Header FMP Payload Header to evaluate
+ @param[in] FmpPayloadSize Size of FMP payload
+ @param[out] LowestSupportedVersion The lowest supported version described in
+ the FMP Payload Header.
+
+ @retval EFI_SUCCESS The lowest support version was returned.
+ @retval EFI_INVALID_PARAMETER Header is NULL.
+ @retval EFI_INVALID_PARAMETER LowestSupportedVersion is NULL.
+ @retval EFI_INVALID_PARAMETER Header is not a valid FMP Payload Header.
+
+**/
+EFI_STATUS
+EFIAPI
+GetFmpPayloadHeaderLowestSupportedVersion (
+ IN CONST VOID *Header,
+ IN CONST UINTN FmpPayloadSize,
+ OUT UINT32 *LowestSupportedVersion
+ );
+
+#endif
diff --git a/roms/edk2/FmpDevicePkg/PrivateInclude/Protocol/CapsuleUpdatePolicy.h b/roms/edk2/FmpDevicePkg/PrivateInclude/Protocol/CapsuleUpdatePolicy.h new file mode 100644 index 000000000..4f7d91729 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/PrivateInclude/Protocol/CapsuleUpdatePolicy.h @@ -0,0 +1,132 @@ +/** @file
+ Provides platform policy services used during a capsule update.
+
+ Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __CAPSULE_UPDATE_POLICY_H__
+#define __CAPSULE_UPDATE_POLICY_H__
+
+#define EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL_GUID \
+ { \
+ 0x487784c5, 0x6299, 0x4ba6, { 0xb0, 0x96, 0x5c, 0xc5, 0x27, 0x7c, 0xf7, 0x57 } \
+ }
+
+typedef struct _EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL;
+
+/**
+ Determine if the system power state supports a capsule update.
+
+ @param[in] This A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL instance.
+ @param[out] Good Returns TRUE if system power state supports a capsule
+ update. Returns FALSE if system power state does not
+ support a capsule update. Return value is only valid if
+ return status is EFI_SUCCESS.
+
+ @retval EFI_SUCCESS Good parameter has been updated with result.
+ @retval EFI_INVALID_PARAMETER Good is NULL.
+ @retval EFI_DEVICE_ERROR System power state can not be determined.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EDKII_CAPSULE_UPDATE_POLICY_CHECK_SYSTEM_POWER) (
+ IN EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL *This,
+ OUT BOOLEAN *Good
+ );
+
+/**
+ Determines if the system thermal state supports a capsule update.
+
+ @param[in] This A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL instance.
+ @param[out] Good Returns TRUE if system thermal state supports a capsule
+ update. Returns FALSE if system thermal state does not
+ support a capsule update. Return value is only valid if
+ return status is EFI_SUCCESS.
+
+ @retval EFI_SUCCESS Good parameter has been updated with result.
+ @retval EFI_INVALID_PARAMETER Good is NULL.
+ @retval EFI_DEVICE_ERROR System thermal state can not be determined.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EDKII_CAPSULE_UPDATE_POLICY_CHECK_SYSTEM_THERMAL) (
+ IN EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL *This,
+ OUT BOOLEAN *Good
+ );
+
+/**
+ Determines if the system environment state supports a capsule update.
+
+ @param[in] This A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL instance.
+ @param[out] Good Returns TRUE if system environment state supports a capsule
+ update. Returns FALSE if system environment state does not
+ support a capsule update. Return value is only valid if
+ return status is EFI_SUCCESS.
+
+ @retval EFI_SUCCESS Good parameter has been updated with result.
+ @retval EFI_INVALID_PARAMETER Good is NULL.
+ @retval EFI_DEVICE_ERROR System environment state can not be determined.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI * EDKII_CAPSULE_UPDATE_POLICY_CHECK_SYSTEM_ENVIRONMENT) (
+ IN EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL *This,
+ OUT BOOLEAN *Good
+ );
+
+/**
+ Determines if the Lowest Supported Version checks should be performed. The
+ expected result from this function is TRUE. A platform can choose to return
+ FALSE (e.g. during manufacturing or servicing) to allow a capsule update to a
+ version below the current Lowest Supported Version.
+
+ @param[in] This A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL instance.
+
+ @retval TRUE The lowest supported version check is required.
+ @retval FALSE Do not perform lowest support version check.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI * EDKII_CAPSULE_UPDATE_POLICY_IS_LOWEST_SUPPORTED_VERSION_CHECK_REQUIRED) (
+ IN EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL *This
+ );
+
+/**
+ Determines if the FMP device should be locked when the event specified by
+ PcdFmpDeviceLockEventGuid is signaled. The expected result from this function
+ is TRUE so the FMP device is always locked. A platform can choose to return
+ FALSE (e.g. during manufacturing) to allow FMP devices to remain unlocked.
+
+ @param[in] This A pointer to the EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL instance.
+
+ @retval TRUE The FMP device lock action is required at lock event guid.
+ @retval FALSE Do not perform FMP device lock at lock event guid.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI * EDKII_CAPSULE_UPDATE_POLICY_IS_FMP_DEVICE_AT_LOCK_EVENT_REQUIRED) (
+ IN EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL *This
+ );
+
+///
+/// This protocol provides platform policy services used during a capsule update.
+///
+struct _EDKII_CAPSULE_UPDATE_POLICY_PROTOCOL {
+ EDKII_CAPSULE_UPDATE_POLICY_CHECK_SYSTEM_POWER CheckSystemPower;
+ EDKII_CAPSULE_UPDATE_POLICY_CHECK_SYSTEM_THERMAL CheckSystemThermal;
+ EDKII_CAPSULE_UPDATE_POLICY_CHECK_SYSTEM_ENVIRONMENT CheckSystemEnvironment;
+ EDKII_CAPSULE_UPDATE_POLICY_IS_LOWEST_SUPPORTED_VERSION_CHECK_REQUIRED IsLowestSupportedVersionCheckRequired;
+ EDKII_CAPSULE_UPDATE_POLICY_IS_FMP_DEVICE_AT_LOCK_EVENT_REQUIRED IsLockFmpDeviceAtLockEventGuidRequired;
+};
+
+extern EFI_GUID gEdkiiCapsuleUpdatePolicyProtocolGuid;
+
+#endif
diff --git a/roms/edk2/FmpDevicePkg/Test/FmpDeviceHostPkgTest.dsc b/roms/edk2/FmpDevicePkg/Test/FmpDeviceHostPkgTest.dsc new file mode 100644 index 000000000..83574399b --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Test/FmpDeviceHostPkgTest.dsc @@ -0,0 +1,28 @@ +## @file
+# FmpDevicePkg DSC file used to build host-based unit tests.
+#
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ PLATFORM_NAME = FmpDevicePkgHostTest
+ PLATFORM_GUID = 80B12646-9A30-4516-AABF-DE1919B573E3
+ PLATFORM_VERSION = 0.1
+ DSC_SPECIFICATION = 0x00010005
+ OUTPUT_DIRECTORY = Build/FmpDevicePkg/HostTest
+ SUPPORTED_ARCHITECTURES = IA32|X64
+ BUILD_TARGETS = NOOPT
+ SKUID_IDENTIFIER = DEFAULT
+
+!include UnitTestFrameworkPkg/UnitTestFrameworkPkgHost.dsc.inc
+
+[LibraryClasses]
+ FmpDependencyLib|FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.inf
+
+[Components]
+ #
+ # Build HOST_APPLICATION that tests the FmpDependencyLib
+ #
+ FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/FmpDependencyLibUnitTestsHost.inf
diff --git a/roms/edk2/FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/EvaluateDependencyUnitTest.c b/roms/edk2/FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/EvaluateDependencyUnitTest.c new file mode 100644 index 000000000..f8ccdd906 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/EvaluateDependencyUnitTest.c @@ -0,0 +1,270 @@ +/** @file
+ Unit tests of EvaluateDependency API in FmpDependencyLib.
+
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/FmpDependencyLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UnitTestLib.h>
+
+#define UNIT_TEST_APP_NAME "FmpDependencyLib Unit Test Application"
+#define UNIT_TEST_APP_VERSION "1.0"
+
+typedef struct {
+ UINT8 *Dependencies;
+ UINTN DependenciesSize;
+ BOOLEAN ExpectedResult;
+} BASIC_TEST_CONTEXT;
+
+//
+// Image Type ID of FMP device A
+//
+#define IMAGE_TYPE_ID_1 { 0x97144DFA, 0xEB8E, 0xD14D, {0x8B, 0x4D, 0x39, 0x88, 0x24, 0x96, 0x56, 0x42}}
+
+//
+// Image Type ID of FMP device B
+//
+#define IMAGE_TYPE_ID_2 { 0xA42A7370, 0x433A, 0x684D, {0x9A, 0xA1, 0xDE, 0x62, 0x23, 0x30, 0x6C, 0xF3}}
+
+//
+// Device A's version is 0x00000002
+// Device B's version is 0x00000003
+//
+static FMP_DEPEX_CHECK_VERSION_DATA mFmpVersions[] = {
+ {IMAGE_TYPE_ID_1, 0x00000002},
+ {IMAGE_TYPE_ID_2, 0x00000003}
+};
+
+// Valid Dependency Expression 1: (Version(A) > 0x00000001) && (Version(B) >= 0x00000003)
+static UINT8 mExpression1[] = {
+ EFI_FMP_DEP_PUSH_VERSION, 0x01, 0x00, 0x00, 0x00,
+ EFI_FMP_DEP_PUSH_GUID, 0xFA, 0x4D, 0x14, 0x97, 0x8E, 0xEB, 0x4D, 0xD1, 0x8B, 0x4D, 0x39, 0x88, 0x24, 0x96, 0x56, 0x42,
+ EFI_FMP_DEP_GT,
+ EFI_FMP_DEP_PUSH_VERSION, 0x03, 0x00, 0x00, 0x00,
+ EFI_FMP_DEP_PUSH_GUID, 0x70, 0x73, 0x2A, 0xA4, 0x3A, 0x43, 0x4D, 0x68, 0x9A, 0xA1, 0xDE, 0x62, 0x23, 0x30, 0x6C, 0xF3,
+ EFI_FMP_DEP_GTE,
+ EFI_FMP_DEP_AND,
+ EFI_FMP_DEP_END
+};
+
+// Valid Dependency Expression 2: (Version(A) < 0x00000002) || (Version(B) <= 0x00000003)
+static UINT8 mExpression2[] = {
+ EFI_FMP_DEP_PUSH_VERSION, 0x02, 0x00, 0x00, 0x00,
+ EFI_FMP_DEP_PUSH_GUID, 0xFA, 0x4D, 0x14, 0x97, 0x8E, 0xEB, 0x4D, 0xD1, 0x8B, 0x4D, 0x39, 0x88, 0x24, 0x96, 0x56, 0x42,
+ EFI_FMP_DEP_LT,
+ EFI_FMP_DEP_PUSH_VERSION, 0x03, 0x00, 0x00, 0x00,
+ EFI_FMP_DEP_PUSH_GUID, 0x70, 0x73, 0x2A, 0xA4, 0x3A, 0x43, 0x4D, 0x68, 0x9A, 0xA1, 0xDE, 0x62, 0x23, 0x30, 0x6C, 0xF3,
+ EFI_FMP_DEP_LTE,
+ EFI_FMP_DEP_OR,
+ EFI_FMP_DEP_END
+};
+
+// Valid Dependency Expression 3: !(Version(A) == 0x0000002)
+static UINT8 mExpression3[] = {
+ EFI_FMP_DEP_PUSH_VERSION, 0x02, 0x00, 0x00, 0x00,
+ EFI_FMP_DEP_PUSH_GUID, 0xFA, 0x4D, 0x14, 0x97, 0x8E, 0xEB, 0x4D, 0xD1, 0x8B, 0x4D, 0x39, 0x88, 0x24, 0x96, 0x56, 0x42,
+ EFI_FMP_DEP_EQ,
+ EFI_FMP_DEP_NOT,
+ EFI_FMP_DEP_END
+};
+
+// Valid Dependency Expression 4: "Test" TRUE && FALSE
+static UINT8 mExpression4[] = {
+ EFI_FMP_DEP_VERSION_STR, 'T', 'e', 's', 't', '\0',
+ EFI_FMP_DEP_TRUE,
+ EFI_FMP_DEP_FALSE,
+ EFI_FMP_DEP_AND,
+ EFI_FMP_DEP_END
+};
+
+// Invalid Dependency Expression 1: Invalid Op-code
+static UINT8 mExpression5[] = {EFI_FMP_DEP_TRUE, 0xAA, EFI_FMP_DEP_END};
+
+// Invalid Dependency Expression 2: String doesn't end with '\0'
+static UINT8 mExpression6[] = {EFI_FMP_DEP_VERSION_STR, 'T', 'e', 's', 't', EFI_FMP_DEP_TRUE, EFI_FMP_DEP_END};
+
+// Invalid Dependency Expression 3: GUID is in invalid size
+static UINT8 mExpression7[] = {
+ EFI_FMP_DEP_PUSH_VERSION, 0x02, 0x00, 0x00, 0x00,
+ EFI_FMP_DEP_PUSH_GUID, 0xAA, 0xBB, 0xCC, 0xDD,
+ EFI_FMP_DEP_GTE,
+ EFI_FMP_DEP_END
+};
+
+// Invalid Dependency Expression 4: Version is in invalid size
+static UINT8 mExpression8[] = {
+ EFI_FMP_DEP_PUSH_VERSION, 0x02, 0x00,
+ EFI_FMP_DEP_PUSH_GUID, 0xDA, 0xCB, 0x25, 0xAC, 0x9E, 0xCD, 0x5E, 0xE2, 0x9C, 0x5E, 0x4A, 0x99, 0x35, 0xA7, 0x67, 0x53,
+ EFI_FMP_DEP_GTE,
+ EFI_FMP_DEP_END
+};
+
+// Invalid Dependency Expression 5: Operand and operator mismatch
+static UINT8 mExpression9[] = {EFI_FMP_DEP_TRUE, EFI_FMP_DEP_FALSE, EFI_FMP_DEP_GTE, EFI_FMP_DEP_END};
+
+// Invalid Dependency Expression 6: GUID is NOT FOUND
+static UINT8 mExpression10[] = {
+ EFI_FMP_DEP_PUSH_VERSION, 0x02, 0x00, 0x00, 0x00,
+ EFI_FMP_DEP_PUSH_GUID, 0xDA, 0xCB, 0x25, 0xAC, 0x9E, 0xCD, 0x5E, 0xE2, 0x9C, 0x5E, 0x4A, 0x99, 0x35, 0xA7, 0x67, 0x53,
+ EFI_FMP_DEP_GT,
+ EFI_FMP_DEP_END
+};
+
+// Invalid Dependency Expression 7: Stack underflow
+static UINT8 mExpression11[] = {
+ EFI_FMP_DEP_PUSH_VERSION, 0x02, 0x00, 0x00, 0x00,
+ EFI_FMP_DEP_GT,
+ EFI_FMP_DEP_END
+};
+
+// ------------------------------------------------Test Depex------Depex Size----------------Expected Result
+static BASIC_TEST_CONTEXT mBasicTestTrue1 = {mExpression1, sizeof(mExpression1), TRUE};
+static BASIC_TEST_CONTEXT mBasicTestTrue2 = {mExpression2, sizeof(mExpression2), TRUE};
+static BASIC_TEST_CONTEXT mBasicTestFalse1 = {mExpression3, sizeof(mExpression3), FALSE};
+static BASIC_TEST_CONTEXT mBasicTestFalse2 = {mExpression4, sizeof(mExpression4), FALSE};
+static BASIC_TEST_CONTEXT mBasicTestInvalid1 = {mExpression1, sizeof(mExpression1) - 1, FALSE};
+static BASIC_TEST_CONTEXT mBasicTestInvalid2 = {mExpression5, sizeof(mExpression5), FALSE};
+static BASIC_TEST_CONTEXT mBasicTestInvalid3 = {mExpression6, sizeof(mExpression6), FALSE};
+static BASIC_TEST_CONTEXT mBasicTestInvalid4 = {mExpression7, sizeof(mExpression7), FALSE};
+static BASIC_TEST_CONTEXT mBasicTestInvalid5 = {mExpression8, sizeof(mExpression8), FALSE};
+static BASIC_TEST_CONTEXT mBasicTestInvalid6 = {mExpression9, sizeof(mExpression9), FALSE};
+static BASIC_TEST_CONTEXT mBasicTestInvalid7 = {mExpression10, sizeof(mExpression10), FALSE};
+static BASIC_TEST_CONTEXT mBasicTestInvalid8 = {mExpression11, sizeof(mExpression11), FALSE};
+
+/**
+ Unit test for EvaluateDependency() API of the FmpDependencyLib.
+
+ @param[in] Context [Optional] An optional parameter that enables:
+ 1) test-case reuse with varied parameters and
+ 2) test-case re-entry for Target tests that need a
+ reboot. This parameter is a VOID* and it is the
+ responsibility of the test author to ensure that the
+ contents are well understood by all test cases that may
+ consume it.
+
+ @retval UNIT_TEST_PASSED The Unit test has completed and the test
+ case was successful.
+ @retval UNIT_TEST_ERROR_TEST_FAILED A test case assertion has failed.
+**/
+STATIC
+UNIT_TEST_STATUS
+EFIAPI
+EvaluateDependencyTest (
+ IN UNIT_TEST_CONTEXT Context
+ )
+{
+ BASIC_TEST_CONTEXT *TestContext;
+ BOOLEAN EvaluationResult;
+
+ TestContext = (BASIC_TEST_CONTEXT *)Context;
+
+ EvaluationResult = EvaluateDependency (
+ (EFI_FIRMWARE_IMAGE_DEP *)TestContext->Dependencies,
+ TestContext->DependenciesSize,
+ mFmpVersions,
+ sizeof(mFmpVersions)/sizeof(FMP_DEPEX_CHECK_VERSION_DATA)
+ );
+
+ UT_ASSERT_EQUAL (EvaluationResult, TestContext->ExpectedResult);
+
+ return UNIT_TEST_PASSED;
+}
+
+/**
+ Initialize the unit test framework, suite, and unit tests for the
+ EvaluateDependency API in FmpDependencyLib and run the unit tests.
+
+ @retval EFI_SUCCESS All test cases were dispatched.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available to
+ initialize the unit tests.
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+UnitTestingEntry (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UNIT_TEST_FRAMEWORK_HANDLE Fw;
+ UNIT_TEST_SUITE_HANDLE DepexEvalTests;
+
+ Fw = NULL;
+
+ DEBUG ((DEBUG_INFO, "%a v%a\n", UNIT_TEST_APP_NAME, UNIT_TEST_APP_VERSION));
+
+ //
+ // Start setting up the test framework for running the tests.
+ //
+ Status = InitUnitTestFramework (&Fw, UNIT_TEST_APP_NAME, gEfiCallerBaseName, UNIT_TEST_APP_VERSION);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed in InitUnitTestFramework. Status = %r\n", Status));
+ goto EXIT;
+ }
+
+ //
+ // Populate the Unit Test Suite.
+ //
+ Status = CreateUnitTestSuite (&DepexEvalTests, Fw, "Evaluate Dependency Test", "FmpDependencyLib.EvaluateDependency", NULL, NULL);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed in CreateUnitTestSuite for DepexEvalTests\n"));
+ goto EXIT;
+ }
+
+ AddTestCase (DepexEvalTests, "Evaluate to True - 1", "Test1", EvaluateDependencyTest, NULL, NULL, &mBasicTestTrue1);
+ AddTestCase (DepexEvalTests, "Evaluate to True - 2", "Test2", EvaluateDependencyTest, NULL, NULL, &mBasicTestTrue2);
+ AddTestCase (DepexEvalTests, "Evaluate to False - 1", "Test3", EvaluateDependencyTest, NULL, NULL, &mBasicTestFalse1);
+ AddTestCase (DepexEvalTests, "Evaluate to False - 2", "Test4", EvaluateDependencyTest, NULL, NULL, &mBasicTestFalse2);
+ AddTestCase (DepexEvalTests, "Error: Non-END-terminated expression", "Test5", EvaluateDependencyTest, NULL, NULL, &mBasicTestInvalid1);
+ AddTestCase (DepexEvalTests, "Error: UNKNOWN Op-Code", "Test6", EvaluateDependencyTest, NULL, NULL, &mBasicTestInvalid2);
+ AddTestCase (DepexEvalTests, "Error: Non-Null-terminated string", "Test7", EvaluateDependencyTest, NULL, NULL, &mBasicTestInvalid3);
+ AddTestCase (DepexEvalTests, "Error: GUID size is not 16", "Test8", EvaluateDependencyTest, NULL, NULL, &mBasicTestInvalid4);
+ AddTestCase (DepexEvalTests, "Error: Version size is not 4", "Test9", EvaluateDependencyTest, NULL, NULL, &mBasicTestInvalid5);
+ AddTestCase (DepexEvalTests, "Error: Operand and operator mismatch", "Test10", EvaluateDependencyTest, NULL, NULL, &mBasicTestInvalid6);
+ AddTestCase (DepexEvalTests, "Error: GUID is NOT FOUND", "Test11", EvaluateDependencyTest, NULL, NULL, &mBasicTestInvalid7);
+ AddTestCase (DepexEvalTests, "Error: Stack Underflow", "Test12", EvaluateDependencyTest, NULL, NULL, &mBasicTestInvalid8);
+
+ //
+ // Execute the tests.
+ //
+ Status = RunAllTestSuites (Fw);
+
+EXIT:
+ if (Fw) {
+ FreeUnitTestFramework (Fw);
+ }
+
+ return Status;
+}
+
+/**
+ Standard UEFI entry point for target based unit test execution from UEFI Shell.
+**/
+EFI_STATUS
+EFIAPI
+FmpDependencyLibUnitTestAppEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ return UnitTestingEntry ();
+}
+
+/**
+ Standard POSIX C entry point for host based unit test execution.
+**/
+int
+main (
+ int argc,
+ char *argv[]
+ )
+{
+ return UnitTestingEntry ();
+}
diff --git a/roms/edk2/FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/FmpDependencyLibUnitTestsHost.inf b/roms/edk2/FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/FmpDependencyLibUnitTestsHost.inf new file mode 100644 index 000000000..93ae635da --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/FmpDependencyLibUnitTestsHost.inf @@ -0,0 +1,34 @@ +## @file
+# Unit tests of EvaluateDependency API in FmpDependencyLib that are run from host
+# environment.
+#
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = FmpDependencyLibUnitTestsHost
+ FILE_GUID = CE32C647-CAD7-4099-9463-653B932C1691
+ MODULE_TYPE = HOST_APPLICATION
+ VERSION_STRING = 1.0
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ EvaluateDependencyUnitTest.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ FmpDevicePkg/FmpDevicePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ UnitTestLib
+ FmpDependencyLib
diff --git a/roms/edk2/FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/FmpDependencyLibUnitTestsUefi.inf b/roms/edk2/FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/FmpDependencyLibUnitTestsUefi.inf new file mode 100644 index 000000000..a2ca36917 --- /dev/null +++ b/roms/edk2/FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/FmpDependencyLibUnitTestsUefi.inf @@ -0,0 +1,35 @@ +## @file
+# Unit tests of EvaluateDependency API in FmpDependencyLib that are run from UEFI Shell.
+#
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+##
+
+[Defines]
+ INF_VERSION = 0x00010006
+ BASE_NAME = FmpDependencyLibUnitTestsUefi
+ FILE_GUID = 8FF4C129-C2EF-445D-8658-9A342A1FCC4D
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ ENTRY_POINT = FmpDependencyLibUnitTestAppEntry
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ EvaluateDependencyUnitTest.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ FmpDevicePkg/FmpDevicePkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ UefiApplicationEntryPoint
+ DebugLib
+ UnitTestLib
+ FmpDependencyLib
|