* [edk2-devel] [PATCH V4 1/5] FmpDevicePkg: Add FmpDependency library class and BASE instance
2020-05-15 1:51 [edk2-devel] [PATCH V4 0/5] FmpDevicePkg: Move capsule dependency implement to library Xu, Wei6
@ 2020-05-15 1:51 ` Xu, Wei6
2020-05-15 1:51 ` [edk2-devel] [PATCH V4 2/5] FmpDevicePkg/Test: Add FmpDependencyLib unit test Xu, Wei6
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Xu, Wei6 @ 2020-05-15 1:51 UTC (permalink / raw)
To: devel; +Cc: Michael D Kinney, Liming Gao, Sean Brogan
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2696
This library provides services to evaluate Fmp capsule dependency
expression, validate dependency expression and get dependency
from firmware image.
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>
Signed-off-by: Wei6 Xu <wei6.xu@intel.com>
Reviewed-by: Sean Brogan <sean.brogan@microsoft.com>
---
FmpDevicePkg/FmpDevicePkg.dec | 6 +-
FmpDevicePkg/FmpDevicePkg.dsc | 4 +-
FmpDevicePkg/Include/Library/FmpDependencyLib.h | 89 ++++
.../Library/FmpDependencyLib/FmpDependencyLib.c | 546 +++++++++++++++++++++
.../Library/FmpDependencyLib/FmpDependencyLib.inf | 34 ++
.../Library/FmpDependencyLib/FmpDependencyLib.uni | 12 +
6 files changed, 689 insertions(+), 2 deletions(-)
create mode 100644 FmpDevicePkg/Include/Library/FmpDependencyLib.h
create mode 100644 FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.c
create mode 100644 FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.inf
create mode 100644 FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.uni
diff --git a/FmpDevicePkg/FmpDevicePkg.dec b/FmpDevicePkg/FmpDevicePkg.dec
index 55671878dd..4947008346 100644
--- a/FmpDevicePkg/FmpDevicePkg.dec
+++ b/FmpDevicePkg/FmpDevicePkg.dec
@@ -5,11 +5,11 @@
# 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 - 2019, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##
@@ -33,10 +33,14 @@
## @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
+
[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
diff --git a/FmpDevicePkg/FmpDevicePkg.dsc b/FmpDevicePkg/FmpDevicePkg.dsc
index b8fb9d7c19..dfb3c1a141 100644
--- a/FmpDevicePkg/FmpDevicePkg.dsc
+++ b/FmpDevicePkg/FmpDevicePkg.dsc
@@ -5,11 +5,11 @@
# 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 - 2019, Intel 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
#
##
@@ -58,10 +58,11 @@
!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
TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
[LibraryClasses.ARM, LibraryClasses.AARCH64]
#
# It is not possible to prevent the ARM compiler for generic intrinsic functions.
@@ -86,10 +87,11 @@
#
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/FmpDxe/FmpDxeLib.inf
#
# Modules
#
diff --git a/FmpDevicePkg/Include/Library/FmpDependencyLib.h b/FmpDevicePkg/Include/Library/FmpDependencyLib.h
new file mode 100644
index 0000000000..1110eefa9a
--- /dev/null
+++ b/FmpDevicePkg/Include/Library/FmpDependencyLib.h
@@ -0,0 +1,89 @@
+/** @file
+ Fmp Capsule Dependency support 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_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 capsule is valid.
+ @retval FALSE The capsule 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/FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.c b/FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.c
new file mode 100644
index 0000000000..91dc0b9abd
--- /dev/null
+++ b/FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.c
@@ -0,0 +1,546 @@
+/** @file
+ Supports Fmp Capsule Dependency Expression.
+
+ 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"));
+ }
+ 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 exression!\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 capsule is valid.
+ @retval FALSE The capsule 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/FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.inf b/FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.inf
new file mode 100644
index 0000000000..b7e5c8d002
--- /dev/null
+++ b/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/FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.uni b/FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.uni
new file mode 100644
index 0000000000..422a96b570
--- /dev/null
+++ b/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."
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [edk2-devel] [PATCH V4 2/5] FmpDevicePkg/Test: Add FmpDependencyLib unit test
2020-05-15 1:51 [edk2-devel] [PATCH V4 0/5] FmpDevicePkg: Move capsule dependency implement to library Xu, Wei6
2020-05-15 1:51 ` [edk2-devel] [PATCH V4 1/5] FmpDevicePkg: Add FmpDependency library class and BASE instance Xu, Wei6
@ 2020-05-15 1:51 ` Xu, Wei6
2020-05-15 1:51 ` [edk2-devel] [PATCH V4 3/5] FmpDevicePkg: Add FmpDependencyCheck library class and instances Xu, Wei6
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Xu, Wei6 @ 2020-05-15 1:51 UTC (permalink / raw)
To: devel; +Cc: Michael D Kinney, Liming Gao, Sean Brogan
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2696
* Add unit tests for EvaluateDependency API in FmpDependencyLib.
* Add Test/FmpDeviceHostPkgTest.dsc to build host based unit test.
* Update FmpDevicePkg.dsc to build target based unit test.
* Update FmpDevicePkg.ci.yaml to build and run host based test.
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>
Signed-off-by: Wei6 Xu <wei6.xu@intel.com>
Reviewed-by: Sean Brogan <sean.brogan@microsoft.com>
---
FmpDevicePkg/FmpDevicePkg.ci.yaml | 10 +
FmpDevicePkg/FmpDevicePkg.dsc | 7 +
FmpDevicePkg/Test/FmpDeviceHostPkgTest.dsc | 28 +++
.../FmpDependencyLib/EvaluateDependencyUnitTest.c | 270 +++++++++++++++++++++
.../FmpDependencyLibUnitTestsHost.inf | 34 +++
.../FmpDependencyLibUnitTestsUefi.inf | 35 +++
6 files changed, 384 insertions(+)
create mode 100644 FmpDevicePkg/Test/FmpDeviceHostPkgTest.dsc
create mode 100644 FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/EvaluateDependencyUnitTest.c
create mode 100644 FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/FmpDependencyLibUnitTestsHost.inf
create mode 100644 FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/FmpDependencyLibUnitTestsUefi.inf
diff --git a/FmpDevicePkg/FmpDevicePkg.ci.yaml b/FmpDevicePkg/FmpDevicePkg.ci.yaml
index c17b355d42..74a0aefe8e 100644
--- a/FmpDevicePkg/FmpDevicePkg.ci.yaml
+++ b/FmpDevicePkg/FmpDevicePkg.ci.yaml
@@ -6,26 +6,36 @@
##
{
"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": []
},
diff --git a/FmpDevicePkg/FmpDevicePkg.dsc b/FmpDevicePkg/FmpDevicePkg.dsc
index dfb3c1a141..49c6ff3a30 100644
--- a/FmpDevicePkg/FmpDevicePkg.dsc
+++ b/FmpDevicePkg/FmpDevicePkg.dsc
@@ -34,10 +34,12 @@
# 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
@@ -161,7 +163,12 @@
# 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/FmpDevicePkg/Test/FmpDeviceHostPkgTest.dsc b/FmpDevicePkg/Test/FmpDeviceHostPkgTest.dsc
new file mode 100644
index 0000000000..83574399be
--- /dev/null
+++ b/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/FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/EvaluateDependencyUnitTest.c b/FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/EvaluateDependencyUnitTest.c
new file mode 100644
index 0000000000..f8ccdd906f
--- /dev/null
+++ b/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/FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/FmpDependencyLibUnitTestsHost.inf b/FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/FmpDependencyLibUnitTestsHost.inf
new file mode 100644
index 0000000000..93ae635da5
--- /dev/null
+++ b/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/FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/FmpDependencyLibUnitTestsUefi.inf b/FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/FmpDependencyLibUnitTestsUefi.inf
new file mode 100644
index 0000000000..a2ca369171
--- /dev/null
+++ b/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
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [edk2-devel] [PATCH V4 3/5] FmpDevicePkg: Add FmpDependencyCheck library class and instances
2020-05-15 1:51 [edk2-devel] [PATCH V4 0/5] FmpDevicePkg: Move capsule dependency implement to library Xu, Wei6
2020-05-15 1:51 ` [edk2-devel] [PATCH V4 1/5] FmpDevicePkg: Add FmpDependency library class and BASE instance Xu, Wei6
2020-05-15 1:51 ` [edk2-devel] [PATCH V4 2/5] FmpDevicePkg/Test: Add FmpDependencyLib unit test Xu, Wei6
@ 2020-05-15 1:51 ` Xu, Wei6
2020-05-15 1:51 ` [edk2-devel] [PATCH V4 4/5] FmpDevicePkg: Add FmpDependencyDevice library class and NULL instance Xu, Wei6
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Xu, Wei6 @ 2020-05-15 1:51 UTC (permalink / raw)
To: devel; +Cc: Michael D Kinney, Liming Gao, Sean Brogan
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2696
* This library class provides platform specific services to support
dependency check during updating firmware image. Platform can perform
dependency check in platform specific manner by implementing its own
FmpDependencyCheckLib.
* Add FmpDependencyCheck instance to provide a sample of dependency
check. The sample instance only checks the dependency from capsule
image. The dependency from other FMP instances isn't checked here.
* Add NULL instance as an option to skip the dependency check.
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>
Signed-off-by: Wei6 Xu <wei6.xu@intel.com>
Reviewed-by: Sean Brogan <sean.brogan@microsoft.com>
---
FmpDevicePkg/FmpDevicePkg.dec | 4 +
FmpDevicePkg/FmpDevicePkg.dsc | 3 +
.../Include/Library/FmpDependencyCheckLib.h | 38 ++++
.../FmpDependencyCheckLib/FmpDependencyCheckLib.c | 196 +++++++++++++++++++++
.../FmpDependencyCheckLib.inf | 43 +++++
.../FmpDependencyCheckLib.uni | 13 ++
.../FmpDependencyCheckLibNull.c | 34 ++++
.../FmpDependencyCheckLibNull.inf | 30 ++++
.../FmpDependencyCheckLibNull.uni | 13 ++
9 files changed, 374 insertions(+)
create mode 100644 FmpDevicePkg/Include/Library/FmpDependencyCheckLib.h
create mode 100644 FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.c
create mode 100644 FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.inf
create mode 100644 FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.uni
create mode 100644 FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.c
create mode 100644 FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.inf
create mode 100644 FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.uni
diff --git a/FmpDevicePkg/FmpDevicePkg.dec b/FmpDevicePkg/FmpDevicePkg.dec
index 4947008346..871d5ce890 100644
--- a/FmpDevicePkg/FmpDevicePkg.dec
+++ b/FmpDevicePkg/FmpDevicePkg.dec
@@ -37,10 +37,14 @@
## @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
+
[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
diff --git a/FmpDevicePkg/FmpDevicePkg.dsc b/FmpDevicePkg/FmpDevicePkg.dsc
index 49c6ff3a30..7e80806171 100644
--- a/FmpDevicePkg/FmpDevicePkg.dsc
+++ b/FmpDevicePkg/FmpDevicePkg.dsc
@@ -61,10 +61,11 @@
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
TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
[LibraryClasses.ARM, LibraryClasses.AARCH64]
#
# It is not possible to prevent the ARM compiler for generic intrinsic functions.
@@ -90,10 +91,12 @@
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/FmpDxe/FmpDxeLib.inf
#
# Modules
#
diff --git a/FmpDevicePkg/Include/Library/FmpDependencyCheckLib.h b/FmpDevicePkg/Include/Library/FmpDependencyCheckLib.h
new file mode 100644
index 0000000000..ec380c4947
--- /dev/null
+++ b/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/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.c b/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.c
new file mode 100644
index 0000000000..5e0241b259
--- /dev/null
+++ b/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.c
@@ -0,0 +1,196 @@
+/** @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
+
+**/
+#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));
+ 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/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.inf b/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.inf
new file mode 100644
index 0000000000..2050cc6490
--- /dev/null
+++ b/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/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.uni b/FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.uni
new file mode 100644
index 0000000000..c6369e2277
--- /dev/null
+++ b/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/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.c b/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.c
new file mode 100644
index 0000000000..55e9af2290
--- /dev/null
+++ b/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/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.inf b/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.inf
new file mode 100644
index 0000000000..5794d89191
--- /dev/null
+++ b/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/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.uni b/FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.uni
new file mode 100644
index 0000000000..7942d08f76
--- /dev/null
+++ b/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."
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [edk2-devel] [PATCH V4 4/5] FmpDevicePkg: Add FmpDependencyDevice library class and NULL instance
2020-05-15 1:51 [edk2-devel] [PATCH V4 0/5] FmpDevicePkg: Move capsule dependency implement to library Xu, Wei6
` (2 preceding siblings ...)
2020-05-15 1:51 ` [edk2-devel] [PATCH V4 3/5] FmpDevicePkg: Add FmpDependencyCheck library class and instances Xu, Wei6
@ 2020-05-15 1:51 ` Xu, Wei6
2020-05-15 1:51 ` [edk2-devel] [PATCH V4 5/5] FmpDevicePkg/FmpDxe: Use new Fmp dependency libraries Xu, Wei6
2020-05-15 3:01 ` [edk2-devel] [PATCH V4 0/5] FmpDevicePkg: Move capsule dependency implement to library Liming Gao
5 siblings, 0 replies; 7+ messages in thread
From: Xu, Wei6 @ 2020-05-15 1:51 UTC (permalink / raw)
To: devel; +Cc: Michael D Kinney, Liming Gao, Sean Brogan
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2696
This library provides firmware device specific services to support
saving dependency to firmware device and getting dependency from
firmware device.
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>
Signed-off-by: Wei6 Xu <wei6.xu@intel.com>
Reviewed-by: Sean Brogan <sean.brogan@microsoft.com>
---
FmpDevicePkg/FmpDevicePkg.dec | 5 +++
FmpDevicePkg/FmpDevicePkg.dsc | 2 +
.../Include/Library/FmpDependencyDeviceLib.h | 51 ++++++++++++++++++++++
.../FmpDependencyDeviceLib.c | 50 +++++++++++++++++++++
.../FmpDependencyDeviceLibNull.inf | 29 ++++++++++++
.../FmpDependencyDeviceLibNull.uni | 12 +++++
6 files changed, 149 insertions(+)
create mode 100644 FmpDevicePkg/Include/Library/FmpDependencyDeviceLib.h
create mode 100644 FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLib.c
create mode 100644 FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLibNull.inf
create mode 100644 FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLibNull.uni
diff --git a/FmpDevicePkg/FmpDevicePkg.dec b/FmpDevicePkg/FmpDevicePkg.dec
index 871d5ce890..cab63f5a47 100644
--- a/FmpDevicePkg/FmpDevicePkg.dec
+++ b/FmpDevicePkg/FmpDevicePkg.dec
@@ -41,10 +41,15 @@
## @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
diff --git a/FmpDevicePkg/FmpDevicePkg.dsc b/FmpDevicePkg/FmpDevicePkg.dsc
index 7e80806171..bdb73f2828 100644
--- a/FmpDevicePkg/FmpDevicePkg.dsc
+++ b/FmpDevicePkg/FmpDevicePkg.dsc
@@ -62,10 +62,11 @@
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.
@@ -93,10 +94,11 @@
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
#
diff --git a/FmpDevicePkg/Include/Library/FmpDependencyDeviceLib.h b/FmpDevicePkg/Include/Library/FmpDependencyDeviceLib.h
new file mode 100644
index 0000000000..4351173b7e
--- /dev/null
+++ b/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/FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLib.c b/FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLib.c
new file mode 100644
index 0000000000..0839681430
--- /dev/null
+++ b/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/FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLibNull.inf b/FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLibNull.inf
new file mode 100644
index 0000000000..d318cc9a67
--- /dev/null
+++ b/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/FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLibNull.uni b/FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLibNull.uni
new file mode 100644
index 0000000000..730ff65cbd
--- /dev/null
+++ b/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."
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [edk2-devel] [PATCH V4 5/5] FmpDevicePkg/FmpDxe: Use new Fmp dependency libraries
2020-05-15 1:51 [edk2-devel] [PATCH V4 0/5] FmpDevicePkg: Move capsule dependency implement to library Xu, Wei6
` (3 preceding siblings ...)
2020-05-15 1:51 ` [edk2-devel] [PATCH V4 4/5] FmpDevicePkg: Add FmpDependencyDevice library class and NULL instance Xu, Wei6
@ 2020-05-15 1:51 ` Xu, Wei6
2020-05-15 3:01 ` [edk2-devel] [PATCH V4 0/5] FmpDevicePkg: Move capsule dependency implement to library Liming Gao
5 siblings, 0 replies; 7+ messages in thread
From: Xu, Wei6 @ 2020-05-15 1:51 UTC (permalink / raw)
To: devel; +Cc: Michael D Kinney, Liming Gao, Sean Brogan
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2696
Remove the orginal Fmp Capsule Dependency implement, and use new
FmpDependencyLib, FmpDependencyCheckLib and FmpDependencyDeviceLib
APIs instead.
A platform can perform the dependency check in a platform specific
manner by implementing its own FmpDependencyCheckLib.
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>
Signed-off-by: Wei6 Xu <wei6.xu@intel.com>
Reviewed-by: Sean Brogan <sean.brogan@microsoft.com>
---
FmpDevicePkg/FmpDxe/Dependency.c | 679 --------------------------------------
FmpDevicePkg/FmpDxe/Dependency.h | 63 ----
FmpDevicePkg/FmpDxe/FmpDxe.c | 256 +++-----------
FmpDevicePkg/FmpDxe/FmpDxe.h | 4 +
FmpDevicePkg/FmpDxe/FmpDxe.inf | 5 +-
FmpDevicePkg/FmpDxe/FmpDxeLib.inf | 5 +-
6 files changed, 64 insertions(+), 948 deletions(-)
delete mode 100644 FmpDevicePkg/FmpDxe/Dependency.c
delete mode 100644 FmpDevicePkg/FmpDxe/Dependency.h
diff --git a/FmpDevicePkg/FmpDxe/Dependency.c b/FmpDevicePkg/FmpDxe/Dependency.c
deleted file mode 100644
index 65c23989c6..0000000000
--- a/FmpDevicePkg/FmpDxe/Dependency.c
+++ /dev/null
@@ -1,679 +0,0 @@
-/** @file
- Supports Capsule Dependency Expression.
-
- Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
-
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-#include "FmpDxe.h"
-#include "Dependency.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 variable used to support dependency evaluation
-//
-UINTN mNumberOfFmpInstance = 0;
-EFI_FIRMWARE_IMAGE_DESCRIPTOR **mFmpImageInfoBuf = NULL;
-
-//
-// Indicates the status of dependency check, default value is DEPENDENCIES_SATISFIED.
-//
-UINT8 mDependenciesCheckStatus = DEPENDENCIES_SATISFIED;
-
-//
-// 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) {
- 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) {
- return EFI_ACCESS_DENIED;
- }
-
- //
- // Pop the item off the stack
- //
- mDepexEvaluationStackPointer--;
- *Element = *mDepexEvaluationStackPointer;
- if ((*Element).Type != Type) {
- return EFI_INVALID_PARAMETER;
- }
- return EFI_SUCCESS;
-}
-
-/**
- Evaluate the dependencies.
-
- @param[in] Dependencies Dependency expressions.
- @param[in] DependenciesSize Size of Dependency expressions.
-
- @retval TRUE Dependency expressions evaluate to TRUE.
- @retval FALSE Dependency expressions evaluate to FALSE.
-
-**/
-BOOLEAN
-EvaluateDependencies (
- IN CONST EFI_FIRMWARE_IMAGE_DEP * Dependencies,
- IN CONST UINTN DependenciesSize
- )
-{
- EFI_STATUS Status;
- UINT8 *Iterator;
- UINT8 Index;
- DEPEX_ELEMENT Element1;
- DEPEX_ELEMENT Element2;
- GUID ImageTypeId;
- UINT32 Version;
-
- if (Dependencies == NULL || DependenciesSize == 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) {
- Status = EFI_INVALID_PARAMETER;
- goto Error;
- }
-
- CopyGuid (&ImageTypeId, (EFI_GUID *) (Iterator + 1));
- Iterator = Iterator + sizeof (EFI_GUID);
-
- for (Index = 0; Index < mNumberOfFmpInstance; Index ++){
- if (mFmpImageInfoBuf[Index] == NULL) {
- continue;
- }
- if(CompareGuid (&mFmpImageInfoBuf[Index]->ImageTypeId, &ImageTypeId)){
- Status = Push (mFmpImageInfoBuf[Index]->Version, VersionType);
- if (EFI_ERROR (Status)) {
- goto Error;
- }
- break;
- }
- }
- if (Index == mNumberOfFmpInstance) {
- Status = EFI_NOT_FOUND;
- goto Error;
- }
- break;
- case EFI_FMP_DEP_PUSH_VERSION:
- if (Iterator + sizeof (UINT32) >= (UINT8 *) Dependencies->Dependencies + DependenciesSize ) {
- Status = EFI_INVALID_PARAMETER;
- 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));
- 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:
- Status = EFI_INVALID_PARAMETER;
- goto Error;
- }
- Iterator++;
- }
-
-Error:
-
- DEBUG ((DEBUG_ERROR, "FmpDxe(%s): EvaluateDependencies() - RESULT = FALSE (Status = %r)\n", mImageIdName, Status));
- return FALSE;
-}
-
-/**
- Validate the dependency expression and output its size.
-
- @param[in] ImageDepex Pointer to the EFI_FIRMWARE_IMAGE_DEP.
- @param[in] MaxDepexSize Max size of the dependency.
- @param[out] DepexSize Size of dependency.
-
- @retval TRUE The capsule is valid.
- @retval FALSE The capsule is invalid.
-
-**/
-BOOLEAN
-ValidateImageDepex (
- IN EFI_FIRMWARE_IMAGE_DEP *ImageDepex,
- IN CONST UINTN MaxDepexSize,
- OUT UINT32 *DepexSize
- )
-{
- UINT8 *Depex;
-
- *DepexSize = 0;
- Depex = ImageDepex->Dependencies;
- while (Depex < ImageDepex->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, ImageDepex->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;
- *DepexSize = (UINT32)(Depex - ImageDepex->Dependencies);
- return TRUE;
- default:
- return FALSE;
- }
- }
-
- return FALSE;
-}
-
-
-/**
- Get the size of dependencies. Assume the dependencies is validated before
- calling this function.
-
- @param[in] Dependencies Pointer to the EFI_FIRMWARE_IMAGE_DEP.
-
- @retval The size of dependencies.
-
-**/
-UINTN
-GetDepexSize (
- IN CONST EFI_FIRMWARE_IMAGE_DEP *Dependencies
- )
-{
- UINTN Index;
-
- if (Dependencies == NULL) {
- return 0;
- }
-
- Index = 0;
- while (Dependencies->Dependencies[Index] != EFI_FMP_DEP_END) {
- Index ++;
- }
-
- return Index + 1;
-}
-
-/**
- Check dependency for firmware update.
-
- @param[in] ImageTypeId Image Type Id.
- @param[in] Version New version.
- @param[in] Dependencies The dependencies.
- @param[in] DependenciesSize Size of the dependencies
- @param[out] IsSatisfied Indicate the dependencies is satisfied or not.
-
- @retval EFI_SUCCESS Dependency Evaluation is successful.
- @retval Others Dependency Evaluation fails with unexpected error.
-
-**/
-EFI_STATUS
-EvaluateImageDependencies (
- IN CONST EFI_GUID ImageTypeId,
- IN CONST UINT32 Version,
- IN CONST EFI_FIRMWARE_IMAGE_DEP *Dependencies,
- IN CONST UINT32 DependenciesSize,
- OUT BOOLEAN *IsSatisfied
- )
-{
- EFI_STATUS Status;
- EFI_HANDLE *HandleBuffer;
- UINTN Index;
- EFI_FIRMWARE_MANAGEMENT_PROTOCOL *Fmp;
- UINTN ImageInfoSize;
- UINT32 FmpImageInfoDescriptorVer;
- UINT8 FmpImageInfoCount;
- UINTN DescriptorSize;
- UINT32 PackageVersion;
- CHAR16 *PackageVersionName;
- UINTN DepexSize;
-
- *IsSatisfied = TRUE;
- PackageVersionName = NULL;
-
- //
- // Get ImageDescriptors of all FMP instances, and archive them for depex evaluation.
- //
- Status = gBS->LocateHandleBuffer (
- ByProtocol,
- &gEfiFirmwareManagementProtocolGuid,
- NULL,
- &mNumberOfFmpInstance,
- &HandleBuffer
- );
- if (EFI_ERROR (Status)) {
- return EFI_ABORTED;
- }
-
- mFmpImageInfoBuf = AllocateZeroPool (sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR *) * mNumberOfFmpInstance);
- if (mFmpImageInfoBuf == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- for (Index = 0; Index < mNumberOfFmpInstance; 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;
- }
-
- mFmpImageInfoBuf[Index] = AllocateZeroPool (ImageInfoSize);
- if (mFmpImageInfoBuf[Index] == NULL) {
- continue;
- }
-
- Status = Fmp->GetImageInfo (
- Fmp,
- &ImageInfoSize, // ImageInfoSize
- mFmpImageInfoBuf[Index], // ImageInfo
- &FmpImageInfoDescriptorVer, // DescriptorVersion
- &FmpImageInfoCount, // DescriptorCount
- &DescriptorSize, // DescriptorSize
- &PackageVersion, // PackageVersion
- &PackageVersionName // PackageVersionName
- );
- if (EFI_ERROR(Status)) {
- FreePool (mFmpImageInfoBuf[Index]);
- mFmpImageInfoBuf[Index] = NULL;
- continue;
- }
-
- if (PackageVersionName != NULL) {
- FreePool (PackageVersionName);
- PackageVersionName = NULL;
- }
- }
-
- //
- // Step 1 - Evaluate firmware image's depex, against the version of other Fmp instances.
- //
- if (Dependencies != NULL) {
- *IsSatisfied = EvaluateDependencies (Dependencies, DependenciesSize);
- }
-
- if (!*IsSatisfied) {
- goto cleanup;
- }
-
- //
- // Step 2 - Evaluate the depex of all other Fmp instances, against the new version in
- // the firmware image.
- //
-
- //
- // Update the new version to mFmpImageInfoBuf.
- //
- for (Index = 0; Index < mNumberOfFmpInstance; Index ++) {
- if (mFmpImageInfoBuf[Index] != NULL) {
- if (CompareGuid (&ImageTypeId, &mFmpImageInfoBuf[Index]->ImageTypeId)) {
- mFmpImageInfoBuf[Index]->Version = Version;
- break;
- }
- }
- }
-
- //
- // Evaluate the Dependencies one by one.
- //
- for (Index = 0; Index < mNumberOfFmpInstance; Index ++) {
- if (mFmpImageInfoBuf[Index] != NULL) {
- //
- // Skip the Fmp instance to be "SetImage".
- //
- if (CompareGuid (&ImageTypeId, &mFmpImageInfoBuf[Index]->ImageTypeId)) {
- continue;
- }
- if ((mFmpImageInfoBuf[Index]->AttributesSupported & IMAGE_ATTRIBUTE_DEPENDENCY) &&
- mFmpImageInfoBuf[Index]->Dependencies != NULL) {
- //
- // Get the size of depex.
- // Assume that the dependencies in EFI_FIRMWARE_IMAGE_DESCRIPTOR is validated when PopulateDescriptor().
- //
- DepexSize = GetDepexSize (mFmpImageInfoBuf[Index]->Dependencies);
- if (DepexSize > 0) {
- *IsSatisfied = EvaluateDependencies (mFmpImageInfoBuf[Index]->Dependencies, DepexSize);
- if (!*IsSatisfied) {
- break;
- }
- }
- }
- }
- }
-
-cleanup:
- if (mFmpImageInfoBuf != NULL) {
- for (Index = 0; Index < mNumberOfFmpInstance; Index ++) {
- if (mFmpImageInfoBuf[Index] != NULL) {
- FreePool (mFmpImageInfoBuf[Index]);
- }
- }
- FreePool (mFmpImageInfoBuf);
- }
-
- return EFI_SUCCESS;
-}
diff --git a/FmpDevicePkg/FmpDxe/Dependency.h b/FmpDevicePkg/FmpDxe/Dependency.h
deleted file mode 100644
index badd2542d6..0000000000
--- a/FmpDevicePkg/FmpDxe/Dependency.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/** @file
- Fmp Capsule Dependency support 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 __DEPENDENCY_H__
-#define __DEPENDENCY_H__
-
-#include <Library/UefiLib.h>
-#include <Protocol/FirmwareManagement.h>
-
-#define DEPENDENCIES_SATISFIED 0
-#define DEPENDENCIES_UNSATISFIED 1
-#define DEPENDENCIES_INVALID 2
-
-extern UINT8 mDependenciesCheckStatus;
-
-/**
- Validate the dependency expression and output its size.
-
- @param[in] ImageDepex Pointer to the EFI_FIRMWARE_IMAGE_DEP.
- @param[in] MaxDepexSize Max size of the dependency.
- @param[out] DepexSize Size of dependency.
-
- @retval TRUE The capsule is valid.
- @retval FALSE The capsule is invalid.
-
-**/
-BOOLEAN
-ValidateImageDepex (
- IN EFI_FIRMWARE_IMAGE_DEP *ImageDepex,
- IN CONST UINTN MaxDepexSize,
- OUT UINT32 *DepexSize
- );
-
-/**
- Check dependency for firmware update.
-
- @param[in] ImageTypeId Image Type Id.
- @param[in] Version New version.
- @param[in] Dependencies The dependencies.
- @param[in] DepexSize Size of the dependencies
- @param[out] IsSatisfied Indicate the dependencies is satisfied or not.
-
- @retval EFI_SUCCESS Dependency Evaluation is successful.
- @retval Others Dependency Evaluation fails with unexpected error.
-
-**/
-EFI_STATUS
-EvaluateImageDependencies (
- IN CONST EFI_GUID ImageTypeId,
- IN CONST UINT32 Version,
- IN CONST EFI_FIRMWARE_IMAGE_DEP *Dependencies,
- IN CONST UINT32 DepexSize,
- OUT BOOLEAN *IsSatisfied
- );
-
-#endif
diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.c b/FmpDevicePkg/FmpDxe/FmpDxe.c
index 5b523291e4..58841774fe 100644
--- a/FmpDevicePkg/FmpDxe/FmpDxe.c
+++ b/FmpDevicePkg/FmpDxe/FmpDxe.c
@@ -10,11 +10,10 @@
**/
#include "FmpDxe.h"
#include "VariableSupport.h"
-#include "Dependency.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
@@ -79,11 +78,12 @@ const FIRMWARE_MANAGEMENT_PRIVATE_DATA mFirmwareManagementPrivateDataTemplate =
NULL, // FmpDeviceContext
NULL, // VersionVariableName
NULL, // LsvVariableName
NULL, // LastAttemptStatusVariableName
NULL, // LastAttemptVersionVariableName
- NULL // FmpStateVariableName
+ NULL, // FmpStateVariableName
+ TRUE // DependenciesSatisfied
};
///
/// GUID that is used to create event used to lock the firmware storage device.
///
@@ -274,17 +274,11 @@ VOID
PopulateDescriptor (
FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private
)
{
EFI_STATUS Status;
- VOID *Image;
- UINTN ImageSize;
- BOOLEAN IsDepexValid;
- UINT32 DepexSize;
-
- Image = NULL;
- ImageSize = 0;
+ UINT32 DependenciesSize;
if (Private->DescriptorPopulated) {
return;
}
@@ -385,50 +379,22 @@ PopulateDescriptor (
Private->Descriptor.LastAttemptVersion = GetLastAttemptVersionFromVariable (Private);
Private->Descriptor.LastAttemptStatus = GetLastAttemptStatusFromVariable (Private);
//
- // Get the dependency from the FmpDeviceLib and populate it to the descriptor.
+ // Get the dependency from the FmpDependencyDeviceLib.
//
Private->Descriptor.Dependencies = NULL;
//
// Check the attribute IMAGE_ATTRIBUTE_DEPENDENCY
//
- if (Private->Descriptor.AttributesSupported & IMAGE_ATTRIBUTE_DEPENDENCY) {
- //
- // The parameter "Image" of FmpDeviceGetImage() is extended to contain the dependency.
- // Get the dependency from the Image.
- //
- ImageSize = Private->Descriptor.Size;
- Image = AllocatePool (ImageSize);
- if (Image != NULL) {
- Status = FmpDeviceGetImage (Image, &ImageSize);
- if (Status == EFI_BUFFER_TOO_SMALL) {
- FreePool (Image);
- Image = AllocatePool (ImageSize);
- if (Image != NULL) {
- Status = FmpDeviceGetImage (Image, &ImageSize);
- }
- }
- }
- if (!EFI_ERROR (Status) && Image != NULL) {
- IsDepexValid = ValidateImageDepex ((EFI_FIRMWARE_IMAGE_DEP *) Image, ImageSize, &DepexSize);
- if (IsDepexValid) {
- Private->Descriptor.Dependencies = AllocatePool (DepexSize);
- if (Private->Descriptor.Dependencies != NULL) {
- CopyMem (Private->Descriptor.Dependencies->Dependencies, Image, DepexSize);
- }
- }
- }
+ if (Private->Descriptor.AttributesSetting & IMAGE_ATTRIBUTE_DEPENDENCY) {
+ Private->Descriptor.Dependencies = GetFmpDependency (&DependenciesSize);
}
Private->DescriptorPopulated = TRUE;
-
- if (Image != NULL) {
- FreePool (Image);
- }
}
/**
Returns information about the current firmware image(s) of the device.
@@ -586,21 +552,16 @@ GetTheImage (
)
{
EFI_STATUS Status;
FIRMWARE_MANAGEMENT_PRIVATE_DATA *Private;
UINTN Size;
- UINT8 *ImageBuffer;
- UINTN ImageBufferSize;
- UINT32 DepexSize;
if (!FeaturePcdGet (PcdFmpDeviceStorageAccessEnable)) {
return EFI_UNSUPPORTED;
}
- Status = EFI_SUCCESS;
- ImageBuffer = NULL;
- DepexSize = 0;
+ Status = EFI_SUCCESS;
//
// Retrieve the private context structure
//
Private = FIRMWARE_MANAGEMENT_PRIVATE_DATA_FROM_THIS (This);
@@ -626,49 +587,12 @@ GetTheImage (
//
Status = FmpDeviceGetSize (&Size);
if (EFI_ERROR (Status)) {
Size = 0;
}
-
- //
- // The parameter "Image" of FmpDeviceGetImage() is extended to contain the dependency.
- // Get the Fmp Payload from the Image.
- //
- ImageBufferSize = Size;
- ImageBuffer = AllocatePool (ImageBufferSize);
- if (ImageBuffer == NULL) {
- DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetImage() - AllocatePool fails.\n", mImageIdName));
- Status = EFI_NOT_FOUND;
- goto cleanup;
- }
- Status = FmpDeviceGetImage (ImageBuffer, &ImageBufferSize);
- if (Status == EFI_BUFFER_TOO_SMALL) {
- FreePool (ImageBuffer);
- ImageBuffer = AllocatePool (ImageBufferSize);
- if (ImageBuffer == NULL) {
- DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetImage() - AllocatePool fails.\n", mImageIdName));
- Status = EFI_NOT_FOUND;
- goto cleanup;
- }
- Status = FmpDeviceGetImage (ImageBuffer, &ImageBufferSize);
- }
- if (EFI_ERROR (Status)) {
- goto cleanup;
- }
-
- //
- // Check the attribute IMAGE_ATTRIBUTE_DEPENDENCY
- //
- if (Private->Descriptor.AttributesSetting & IMAGE_ATTRIBUTE_DEPENDENCY) {
- //
- // Validate the dependency to get its size.
- //
- ValidateImageDepex ((EFI_FIRMWARE_IMAGE_DEP *) ImageBuffer, ImageBufferSize, &DepexSize);
- }
-
- if (*ImageSize < ImageBufferSize - DepexSize) {
- *ImageSize = ImageBufferSize - DepexSize;
+ if (*ImageSize < Size) {
+ *ImageSize = Size;
DEBUG ((DEBUG_VERBOSE, "FmpDxe(%s): GetImage() - ImageSize is to small.\n", mImageIdName));
Status = EFI_BUFFER_TOO_SMALL;
goto cleanup;
}
@@ -676,57 +600,50 @@ GetTheImage (
DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetImage() - Image Pointer Parameter is NULL.\n", mImageIdName));
Status = EFI_INVALID_PARAMETER;
goto cleanup;
}
- //
- // Image is after the dependency expression.
- //
- *ImageSize = ImageBufferSize - DepexSize;
- CopyMem (Image, ImageBuffer + DepexSize, *ImageSize);
- Status = EFI_SUCCESS;
-
+ Status = FmpDeviceGetImage (Image, ImageSize);
cleanup:
- if (ImageBuffer != NULL) {
- FreePool (ImageBuffer);
- }
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] 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
@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
)
{
//
// 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) {
+ 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;
}
- *PayloadSize = ImageSize - (sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr.dwLength);
- return (VOID *)((UINT8 *)Image + sizeof (Image->MonotonicCount) + Image->AuthInfo.Hdr.dwLength);
+ *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.
@@ -809,12 +726,10 @@ CheckTheImage (
UINTN PublicKeyDataLength;
UINT8 *PublicKeyDataXdr;
UINT8 *PublicKeyDataXdrEnd;
EFI_FIRMWARE_IMAGE_DEP *Dependencies;
UINT32 DependenciesSize;
- BOOLEAN IsDepexValid;
- BOOLEAN IsDepexSatisfied;
Status = EFI_SUCCESS;
RawSize = 0;
FmpPayloadHeader = NULL;
FmpPayloadSize = 0;
@@ -848,10 +763,15 @@ CheckTheImage (
//
//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
//
@@ -933,49 +853,30 @@ CheckTheImage (
*ImageUpdatable = IMAGE_UPDATABLE_INVALID_TYPE;
Status = EFI_SUCCESS;
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, &FmpPayloadSize );
+ 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)) {
- //
- // Check if there is dependency expression
- //
- IsDepexValid = ValidateImageDepex ((EFI_FIRMWARE_IMAGE_DEP*) FmpPayloadHeader, FmpPayloadSize, &DependenciesSize);
- if (IsDepexValid && (DependenciesSize < FmpPayloadSize)) {
- //
- // Fmp payload is after dependency expression
- //
- Dependencies = (EFI_FIRMWARE_IMAGE_DEP*) FmpPayloadHeader;
- FmpPayloadHeader = (UINT8 *) Dependencies + DependenciesSize;
- FmpPayloadSize = FmpPayloadSize - DependenciesSize;
- 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;
- }
- } else {
- DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - Dependency is invalid.\n", mImageIdName));
- mDependenciesCheckStatus = DEPENDENCIES_INVALID;
- *ImageUpdatable = IMAGE_UPDATABLE_INVALID;
- Status = EFI_SUCCESS;
- goto cleanup;
- }
- } else {
- DEBUG ((DEBUG_WARN, "FmpDxe(%s): CheckTheImage() - No dependency associated in image.\n", mImageIdName));
+ 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
//
@@ -991,18 +892,13 @@ CheckTheImage (
}
//
// Evaluate dependency expression
//
- Status = EvaluateImageDependencies (Private->Descriptor.ImageTypeId, Version, Dependencies, DependenciesSize, &IsDepexSatisfied);
- if (!IsDepexSatisfied || EFI_ERROR (Status)) {
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - Dependency check failed %r.\n", mImageIdName, Status));
- } else {
- DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - Dependency is not satisfied.\n", mImageIdName));
- }
- mDependenciesCheckStatus = DEPENDENCIES_UNSATISFIED;
+ 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;
}
@@ -1111,13 +1007,10 @@ SetTheImage (
UINT32 LastAttemptStatus;
UINT32 Version;
UINT32 LowestSupportedVersion;
EFI_FIRMWARE_IMAGE_DEP *Dependencies;
UINT32 DependenciesSize;
- BOOLEAN IsDepexValid;
- UINT8 *ImageBuffer;
- UINTN ImageBufferSize;
Status = EFI_SUCCESS;
Updateable = 0;
BooleanValue = FALSE;
FmpHeaderSize = 0;
@@ -1126,12 +1019,10 @@ SetTheImage (
AllHeaderSize = 0;
IncomingFwVersion = 0;
LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL;
Dependencies = NULL;
DependenciesSize = 0;
- ImageBuffer = NULL;
- ImageBufferSize = 0;
if (!FeaturePcdGet (PcdFmpDeviceStorageAccessEnable)) {
return EFI_UNSUPPORTED;
}
@@ -1159,15 +1050,10 @@ SetTheImage (
DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - Device is already locked. Can't update.\n", mImageIdName));
Status = EFI_UNSUPPORTED;
goto cleanup;
}
- //
- // Set check status to satisfied before CheckTheImage()
- //
- mDependenciesCheckStatus = DEPENDENCIES_SATISFIED;
-
//
// Call check image to verify the image
//
Status = CheckTheImage (This, ImageIndex, Image, ImageSize, &Updateable);
if (EFI_ERROR (Status)) {
@@ -1176,36 +1062,26 @@ SetTheImage (
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, &FmpPayloadSize );
+ 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)) {
- //
- // Check if there is dependency expression
- //
- IsDepexValid = ValidateImageDepex ((EFI_FIRMWARE_IMAGE_DEP*) FmpHeader, FmpPayloadSize, &DependenciesSize);
- if (IsDepexValid && (DependenciesSize < FmpPayloadSize)) {
- //
- // Fmp payload is after dependency expression
- //
- Dependencies = (EFI_FIRMWARE_IMAGE_DEP*) FmpHeader;
- FmpHeader = (UINT8 *) FmpHeader + DependenciesSize;
- FmpPayloadSize = FmpPayloadSize - DependenciesSize;
- Status = GetFmpPayloadHeaderVersion (FmpHeader, FmpPayloadSize, &IncomingFwVersion);
- }
- }
if (!EFI_ERROR (Status)) {
//
// Set to actual value
//
SetLastAttemptVersionInVariable (Private, IncomingFwVersion);
@@ -1216,14 +1092,12 @@ SetTheImage (
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 (mDependenciesCheckStatus == DEPENDENCIES_UNSATISFIED) {
+ if (Private->DependenciesSatisfied == FALSE) {
LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_UNSATISFIED_DEPENDENCIES;
- } else if (mDependenciesCheckStatus == DEPENDENCIES_INVALID) {
- LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT;
}
Status = EFI_ABORTED;
goto cleanup;
}
@@ -1321,59 +1195,41 @@ SetTheImage (
DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - GetAllHeaderSize failed.\n", mImageIdName));
Status = EFI_ABORTED;
goto cleanup;
}
- //
- // Check the attribute IMAGE_ATTRIBUTE_DEPENDENCY
- //
- if (Private->Descriptor.AttributesSetting & IMAGE_ATTRIBUTE_DEPENDENCY) {
- //
- // To support saving dependency, extend param "Image" of FmpDeviceSetImage() to
- // contain the dependency inside. FmpDeviceSetImage() is responsible for saving
- // the dependency which can be used for future dependency check.
- //
- ImageBufferSize = DependenciesSize + ImageSize - AllHeaderSize;
- ImageBuffer = AllocatePool (ImageBufferSize);
- if (ImageBuffer == NULL) {
- DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - AllocatePool failed.\n", mImageIdName));
- Status = EFI_ABORTED;
- goto cleanup;
- }
- CopyMem (ImageBuffer, Dependencies->Dependencies, DependenciesSize);
- CopyMem (ImageBuffer + DependenciesSize, (UINT8 *)Image + AllHeaderSize, ImageBufferSize - DependenciesSize);
- } else {
- ImageBufferSize = ImageSize - AllHeaderSize;
- ImageBuffer = AllocateCopyPool(ImageBufferSize, (UINT8 *)Image + AllHeaderSize);
- if (ImageBuffer == NULL) {
- DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - AllocatePool 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 (
- ImageBuffer,
- ImageBufferSize,
+ (((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
//
@@ -1396,14 +1252,10 @@ SetTheImage (
SetLowestSupportedVersionInVariable (Private, LowestSupportedVersion);
LastAttemptStatus = LAST_ATTEMPT_STATUS_SUCCESS;
cleanup:
- if (ImageBuffer != NULL) {
- FreePool (ImageBuffer);
- }
-
mProgressFunc = NULL;
SetLastAttemptStatusInVariable (Private, LastAttemptStatus);
if (Progress != NULL) {
//
diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.h b/FmpDevicePkg/FmpDxe/FmpDxe.h
index 150f18b656..30754dea49 100644
--- a/FmpDevicePkg/FmpDxe/FmpDxe.h
+++ b/FmpDevicePkg/FmpDxe/FmpDxe.h
@@ -26,10 +26,13 @@
#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>
@@ -64,10 +67,11 @@ typedef struct {
CHAR16 *VersionVariableName;
CHAR16 *LsvVariableName;
CHAR16 *LastAttemptStatusVariableName;
CHAR16 *LastAttemptVersionVariableName;
CHAR16 *FmpStateVariableName;
+ BOOLEAN DependenciesSatisfied;
} FIRMWARE_MANAGEMENT_PRIVATE_DATA;
///
///
///
diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.inf b/FmpDevicePkg/FmpDxe/FmpDxe.inf
index 97b6518fa1..eeb904a091 100644
--- a/FmpDevicePkg/FmpDxe/FmpDxe.inf
+++ b/FmpDevicePkg/FmpDxe/FmpDxe.inf
@@ -26,12 +26,10 @@
#
[Sources]
FmpDxe.c
FmpDxe.h
- Dependency.c
- Dependency.h
DetectTestKey.c
VariableSupport.h
VariableSupport.c
[Packages]
@@ -52,10 +50,13 @@
BaseCryptLib
FmpAuthenticationLib
FmpDeviceLib
FmpPayloadHeaderLib
CapsuleUpdatePolicyLib
+ FmpDependencyLib
+ FmpDependencyCheckLib
+ FmpDependencyDeviceLib
[Guids]
gEfiEndOfDxeEventGroupGuid
[Protocols]
diff --git a/FmpDevicePkg/FmpDxe/FmpDxeLib.inf b/FmpDevicePkg/FmpDxe/FmpDxeLib.inf
index de005b6892..9a93b5e6ac 100644
--- a/FmpDevicePkg/FmpDxe/FmpDxeLib.inf
+++ b/FmpDevicePkg/FmpDxe/FmpDxeLib.inf
@@ -27,12 +27,10 @@
#
[Sources]
FmpDxe.c
FmpDxe.h
- Dependency.c
- Dependency.h
DetectTestKey.c
VariableSupport.h
VariableSupport.c
[Packages]
@@ -52,10 +50,13 @@
BaseCryptLib
FmpAuthenticationLib
FmpDeviceLib
FmpPayloadHeaderLib
CapsuleUpdatePolicyLib
+ FmpDependencyLib
+ FmpDependencyCheckLib
+ FmpDependencyDeviceLib
[Guids]
gEfiEndOfDxeEventGroupGuid
[Protocols]
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [edk2-devel] [PATCH V4 0/5] FmpDevicePkg: Move capsule dependency implement to library
2020-05-15 1:51 [edk2-devel] [PATCH V4 0/5] FmpDevicePkg: Move capsule dependency implement to library Xu, Wei6
` (4 preceding siblings ...)
2020-05-15 1:51 ` [edk2-devel] [PATCH V4 5/5] FmpDevicePkg/FmpDxe: Use new Fmp dependency libraries Xu, Wei6
@ 2020-05-15 3:01 ` Liming Gao
5 siblings, 0 replies; 7+ messages in thread
From: Liming Gao @ 2020-05-15 3:01 UTC (permalink / raw)
To: devel@edk2.groups.io, Xu, Wei6; +Cc: Kinney, Michael D, Sean Brogan
Reviewed-by: Liming Gao <liming.gao@intel.com>
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Xu, Wei6
> Sent: Friday, May 15, 2020 9:51 AM
> To: devel@edk2.groups.io
> Cc: Kinney, Michael D <michael.d.kinney@intel.com>; Gao, Liming <liming.gao@intel.com>; Sean Brogan
> <sean.brogan@microsoft.com>
> Subject: [edk2-devel] [PATCH V4 0/5] FmpDevicePkg: Move capsule dependency implement to library
>
> v4:
> - Remove the CONST in ValidateDependency API to keep APIs common.
>
> v3:
> - Refine description and comments of API: EvaluateDependency(),
> GetFmpDependency(), CheckFmpDependency().
> - Remove the check on the dependencies coming from other FMP instances.
>
> v2:
> - Remove API GetDependencySize in FmpDependencyLib.
> - Correct comments in FmpDependencyLib unit test; Correct the error status
> when CreateUnitTestSuite fails.
> - Update comments for null instance of FmpDependencyCheckLib; Remove
> SaveFmpDependency and GetFmpDependency from FmpDependencyCheckLib
> - Add new FmpDependencyDevice library class to provide firmware device
> specific SaveFmpDependency and GetFmpDependency services.
> - Update FmpDxe to use new FmpDependencyDeviceLib
>
> v1:
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2696
>
> This patch series move the implementation of Fmp Capsule Dependency from
> FmpDxe driver into two library classes. FmpDependencyLib is a base lib
> to provide generic dependency evaluation services. FmpDependencyCheckLib
> is a platform lib to provide dependency check services during firmware
> update. Platform can perform the dependency check in platform specific
> manner by implementing its own FmpDependencyCheckLib.
> This patch series also add unit test for EvaluateDependency API in
> FmpDependencyLib.
>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Sean Brogan <sean.brogan@microsoft.com>
> Signed-off-by: Wei6 Xu <wei6.xu@intel.com>
>
>
> Wei6 Xu (5):
> FmpDevicePkg: Add FmpDependency library class and BASE instance
> FmpDevicePkg/Test: Add FmpDependencyLib unit test
> FmpDevicePkg: Add FmpDependencyCheck library class and instances
> FmpDevicePkg: Add FmpDependencyDevice library class and NULL instance
> FmpDevicePkg/FmpDxe: Use new Fmp dependency libraries
>
> FmpDevicePkg/FmpDevicePkg.ci.yaml | 10 +
> FmpDevicePkg/FmpDevicePkg.dec | 15 +-
> FmpDevicePkg/FmpDevicePkg.dsc | 16 +-
> FmpDevicePkg/FmpDxe/Dependency.h | 63 ----
> FmpDevicePkg/FmpDxe/FmpDxe.c | 256 ++++------------
> FmpDevicePkg/FmpDxe/FmpDxe.h | 4 +
> FmpDevicePkg/FmpDxe/FmpDxe.inf | 5 +-
> FmpDevicePkg/FmpDxe/FmpDxeLib.inf | 5 +-
> .../Include/Library/FmpDependencyCheckLib.h | 38 +++
> .../Include/Library/FmpDependencyDeviceLib.h | 51 ++++
> FmpDevicePkg/Include/Library/FmpDependencyLib.h | 89 ++++++
> .../FmpDependencyCheckLib/FmpDependencyCheckLib.c | 196 ++++++++++++
> .../FmpDependencyCheckLib.inf | 43 +++
> .../FmpDependencyCheckLib.uni | 13 +
> .../FmpDependencyCheckLibNull.c | 34 +++
> .../FmpDependencyCheckLibNull.inf | 30 ++
> .../FmpDependencyCheckLibNull.uni | 13 +
> .../FmpDependencyDeviceLib.c | 50 +++
> .../FmpDependencyDeviceLibNull.inf | 29 ++
> .../FmpDependencyDeviceLibNull.uni | 12 +
> .../FmpDependencyLib/FmpDependencyLib.c} | 337 +++++++--------------
> .../Library/FmpDependencyLib/FmpDependencyLib.inf | 34 +++
> .../Library/FmpDependencyLib/FmpDependencyLib.uni | 12 +
> FmpDevicePkg/Test/FmpDeviceHostPkgTest.dsc | 28 ++
> .../FmpDependencyLib/EvaluateDependencyUnitTest.c | 270 +++++++++++++++++
> .../FmpDependencyLibUnitTestsHost.inf | 34 +++
> .../FmpDependencyLibUnitTestsUefi.inf | 35 +++
> 27 files changed, 1216 insertions(+), 506 deletions(-)
> delete mode 100644 FmpDevicePkg/FmpDxe/Dependency.h
> create mode 100644 FmpDevicePkg/Include/Library/FmpDependencyCheckLib.h
> create mode 100644 FmpDevicePkg/Include/Library/FmpDependencyDeviceLib.h
> create mode 100644 FmpDevicePkg/Include/Library/FmpDependencyLib.h
> create mode 100644 FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.c
> create mode 100644 FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.inf
> create mode 100644 FmpDevicePkg/Library/FmpDependencyCheckLib/FmpDependencyCheckLib.uni
> create mode 100644 FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.c
> create mode 100644 FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.inf
> create mode 100644 FmpDevicePkg/Library/FmpDependencyCheckLibNull/FmpDependencyCheckLibNull.uni
> create mode 100644 FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLib.c
> create mode 100644 FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLibNull.inf
> create mode 100644 FmpDevicePkg/Library/FmpDependencyDeviceLibNull/FmpDependencyDeviceLibNull.uni
> rename FmpDevicePkg/{FmpDxe/Dependency.c => Library/FmpDependencyLib/FmpDependencyLib.c} (53%)
> create mode 100644 FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.inf
> create mode 100644 FmpDevicePkg/Library/FmpDependencyLib/FmpDependencyLib.uni
> create mode 100644 FmpDevicePkg/Test/FmpDeviceHostPkgTest.dsc
> create mode 100644 FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/EvaluateDependencyUnitTest.c
> create mode 100644 FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/FmpDependencyLibUnitTestsHost.inf
> create mode 100644 FmpDevicePkg/Test/UnitTest/Library/FmpDependencyLib/FmpDependencyLibUnitTestsUefi.inf
>
> --
> 2.16.2.windows.1
>
>
>
^ permalink raw reply [flat|nested] 7+ messages in thread