public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation.
@ 2020-01-10  5:34 Xu, Wei6
  2020-01-10  5:34 ` [edk2-devel][PATCH 1/3] MdePkg: Add definition for Fmp Capsule Dependency Xu, Wei6
                   ` (3 more replies)
  0 siblings, 4 replies; 9+ messages in thread
From: Xu, Wei6 @ 2020-01-10  5:34 UTC (permalink / raw)
  To: devel

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2421

This series implements Fmp Capsule Dependency.
Fmp Capsule Dependency is an incremental change of Fmp Capsule Update.
The capsule format is extended to include a set of binary encoded dependency expression.
The dependency expression is evaluated before update is applied.
This feature is defined in UEFI Spec 2.8.

Wei6 Xu (3):
  MdePkg: Add definition for Fmp Capsule Dependency.
  MdeModulePkg/CapsuleApp: Enhance CapsuleApp for Fmp Capsule Dependency
  FmdDevicePkg/FmpDxe: Support Fmp Capsule Dependency.

 FmpDevicePkg/FmpDxe/Dependency.c                  | 679 ++++++++++++++++++++++
 FmpDevicePkg/FmpDxe/Dependency.h                  |  63 ++
 FmpDevicePkg/FmpDxe/FmpDxe.c                      | 238 +++++++-
 FmpDevicePkg/FmpDxe/FmpDxe.inf                    |   4 +-
 FmpDevicePkg/FmpDxe/FmpDxeLib.inf                 |   4 +-
 MdeModulePkg/Application/CapsuleApp/CapsuleDump.c |  16 +-
 MdePkg/Include/Guid/SystemResourceTable.h         |  19 +-
 MdePkg/Include/Protocol/FirmwareManagement.h      |  35 +-
 8 files changed, 1030 insertions(+), 28 deletions(-)
 create mode 100644 FmpDevicePkg/FmpDxe/Dependency.c
 create mode 100644 FmpDevicePkg/FmpDxe/Dependency.h

-- 
2.16.2.windows.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [edk2-devel][PATCH 1/3] MdePkg: Add definition for Fmp Capsule Dependency.
  2020-01-10  5:34 [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation Xu, Wei6
@ 2020-01-10  5:34 ` Xu, Wei6
  2020-01-10  5:34 ` [edk2-devel][PATCH 2/3] MdeModulePkg/CapsuleApp: Enhance CapsuleApp " Xu, Wei6
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 9+ messages in thread
From: Xu, Wei6 @ 2020-01-10  5:34 UTC (permalink / raw)
  To: devel; +Cc: Michael D Kinney, Liming Gao

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2421

Add new definitions for Fmp Capsule dependency in UEFI Spec 2.8.
1. Extend the Last Attempt Status with a value to indicate the firmware
update fails with unsatisfied dependencies.
2. Add the definition of dependency expression op-codes.
3. Add the definition of EFI_FIRMWARE_IMAGE_DEP which is an array of FMP
dependency expression op-codes.
4. Extend the EFI_FIRMWARE_IMAGE_DESCRIPTOR with a pointer to the array of
FMP dependency expression op-codes.
5. Extend the Image Attribute Definitions with IMAGE_ATTRIBUTE_DEPENDENCY
to indicate that there is and EFI_FIRMWARE_IMAGE_DEP section associated
with the image.
6. Update EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION to 4.

Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Signed-off-by: Wei6 Xu <wei6.xu@intel.com>
---
 MdePkg/Include/Guid/SystemResourceTable.h    | 19 ++++++++-------
 MdePkg/Include/Protocol/FirmwareManagement.h | 35 ++++++++++++++++++++++++++--
 2 files changed, 43 insertions(+), 11 deletions(-)

diff --git a/MdePkg/Include/Guid/SystemResourceTable.h b/MdePkg/Include/Guid/SystemResourceTable.h
index 57c42bf9f3..418b8c8d05 100644
--- a/MdePkg/Include/Guid/SystemResourceTable.h
+++ b/MdePkg/Include/Guid/SystemResourceTable.h
@@ -1,9 +1,9 @@
 /** @file
   Guid & data structure used for EFI System Resource Table (ESRT)
 
-  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.<BR>
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
   @par Revision Reference:
   GUIDs defined in UEFI 2.5 spec.
 
@@ -32,18 +32,19 @@
 #define ESRT_FW_TYPE_UEFIDRIVER      0x00000003
 
 ///
 /// Last Attempt Status Values
 ///
-#define LAST_ATTEMPT_STATUS_SUCCESS                       0x00000000
-#define LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL            0x00000001
-#define LAST_ATTEMPT_STATUS_ERROR_INSUFFICIENT_RESOURCES  0x00000002
-#define LAST_ATTEMPT_STATUS_ERROR_INCORRECT_VERSION       0x00000003
-#define LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT          0x00000004
-#define LAST_ATTEMPT_STATUS_ERROR_AUTH_ERROR              0x00000005
-#define LAST_ATTEMPT_STATUS_ERROR_PWR_EVT_AC              0x00000006
-#define LAST_ATTEMPT_STATUS_ERROR_PWR_EVT_BATT            0x00000007
+#define LAST_ATTEMPT_STATUS_SUCCESS                         0x00000000
+#define LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL              0x00000001
+#define LAST_ATTEMPT_STATUS_ERROR_INSUFFICIENT_RESOURCES    0x00000002
+#define LAST_ATTEMPT_STATUS_ERROR_INCORRECT_VERSION         0x00000003
+#define LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT            0x00000004
+#define LAST_ATTEMPT_STATUS_ERROR_AUTH_ERROR                0x00000005
+#define LAST_ATTEMPT_STATUS_ERROR_PWR_EVT_AC                0x00000006
+#define LAST_ATTEMPT_STATUS_ERROR_PWR_EVT_BATT              0x00000007
+#define LAST_ATTEMPT_STATUS_ERROR_UNSATISFIED_DEPENDENCIES  0x00000008
 
 typedef struct {
   ///
   /// The firmware class field contains a GUID that identifies a firmware component
   /// that can be updated via UpdateCapsule(). This GUID must be unique within all
diff --git a/MdePkg/Include/Protocol/FirmwareManagement.h b/MdePkg/Include/Protocol/FirmwareManagement.h
index 0a0bf4c84a..297bb5ff03 100644
--- a/MdePkg/Include/Protocol/FirmwareManagement.h
+++ b/MdePkg/Include/Protocol/FirmwareManagement.h
@@ -6,11 +6,11 @@
 
   GetImageInfo() is the only required function. GetImage(), SetImage(),
   CheckImage(), GetPackageInfo(), and SetPackageInfo() shall return
   EFI_UNSUPPORTED if not supported by the driver.
 
-  Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2009 - 2020, Intel Corporation. All rights reserved.<BR>
   Copyright (c) 2013 - 2014, Hewlett-Packard Development Company, L.P.<BR>
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
   @par Revision Reference:
   This Protocol is introduced in UEFI Specification 2.3
@@ -26,10 +26,35 @@
     0x86c77a67, 0xb97, 0x4633, {0xa1, 0x87, 0x49, 0x10, 0x4d, 0x6, 0x85, 0xc7 } \
   }
 
 typedef struct _EFI_FIRMWARE_MANAGEMENT_PROTOCOL EFI_FIRMWARE_MANAGEMENT_PROTOCOL;
 
+///
+/// Dependency Expression Opcode
+///
+#define EFI_FMP_DEP_PUSH_GUID        0x00
+#define EFI_FMP_DEP_PUSH_VERSION     0x01
+#define EFI_FMP_DEP_VERSION_STR      0x02
+#define EFI_FMP_DEP_AND              0x03
+#define EFI_FMP_DEP_OR               0x04
+#define EFI_FMP_DEP_NOT              0x05
+#define EFI_FMP_DEP_TRUE             0x06
+#define EFI_FMP_DEP_FALSE            0x07
+#define EFI_FMP_DEP_EQ               0x08
+#define EFI_FMP_DEP_GT               0x09
+#define EFI_FMP_DEP_GTE              0x0A
+#define EFI_FMP_DEP_LT               0x0B
+#define EFI_FMP_DEP_LTE              0x0C
+#define EFI_FMP_DEP_END              0x0D
+
+///
+/// Image Attribute - Dependency
+///
+typedef struct {
+  UINT8 Dependencies[1];
+} EFI_FIRMWARE_IMAGE_DEP;
+
 ///
 /// EFI_FIRMWARE_IMAGE_DESCRIPTOR
 ///
 typedef struct {
   ///
@@ -109,10 +134,11 @@ typedef struct {
   /// instance a zero can be used. A zero means the FMP provider is not able to determine a
   /// unique hardware instance number or a hardware instance number is not needed. Only
   /// present in version 3 or higher.
   ///
   UINT64                           HardwareInstance;
+  EFI_FIRMWARE_IMAGE_DEP           *Dependencies;
 } EFI_FIRMWARE_IMAGE_DESCRIPTOR;
 
 
 //
 // Image Attribute Definitions
@@ -141,10 +167,15 @@ typedef struct {
 #define    IMAGE_ATTRIBUTE_IN_USE                  0x0000000000000008
 ///
 /// The attribute IMAGE_ATTRIBUTE_UEFI_IMAGE indicates that this image is an EFI compatible image.
 ///
 #define    IMAGE_ATTRIBUTE_UEFI_IMAGE              0x0000000000000010
+///
+/// The attribute IMAGE_ATTRIBUTE_DEPENDENCY indicates that there is an EFI_FIRMWARE_IMAGE_DEP
+/// section associated with the image.
+///
+#define    IMAGE_ATTRIBUTE_DEPENDENCY              0x0000000000000020
 
 
 //
 // Image Compatibility Definitions
 //
@@ -156,11 +187,11 @@ typedef struct {
 #define   IMAGE_COMPATIBILITY_CHECK_SUPPORTED      0x0000000000000001
 
 ///
 /// Descriptor Version exposed by GetImageInfo() function
 ///
-#define   EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION   3
+#define   EFI_FIRMWARE_IMAGE_DESCRIPTOR_VERSION   4
 
 
 ///
 /// Image Attribute - Authentication Required
 ///
-- 
2.16.2.windows.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [edk2-devel][PATCH 2/3] MdeModulePkg/CapsuleApp: Enhance CapsuleApp for Fmp Capsule Dependency
  2020-01-10  5:34 [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation Xu, Wei6
  2020-01-10  5:34 ` [edk2-devel][PATCH 1/3] MdePkg: Add definition for Fmp Capsule Dependency Xu, Wei6
@ 2020-01-10  5:34 ` Xu, Wei6
  2020-01-10  5:34 ` [edk2-devel][PATCH 3/3] FmdDevicePkg/FmpDxe: Support " Xu, Wei6
  2020-01-16 12:25 ` [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation Liming Gao
  3 siblings, 0 replies; 9+ messages in thread
From: Xu, Wei6 @ 2020-01-10  5:34 UTC (permalink / raw)
  To: devel; +Cc: Michael D Kinney, Liming Gao

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2421

1. Enhance "CapsuleApp -P" to output the depex expression op-codes in
the EFI_FIRMWARE_IMAGE_DESCRIPTOR.
2. Enhance Last Attempt Status String with a new string to describe the
error LAST_ATTEMPT_STATUS_ERROR_UNSATISFIED_DEPENDENCIES.

Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Signed-off-by: Wei6 Xu <wei6.xu@intel.com>
---
 MdeModulePkg/Application/CapsuleApp/CapsuleDump.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/MdeModulePkg/Application/CapsuleApp/CapsuleDump.c b/MdeModulePkg/Application/CapsuleApp/CapsuleDump.c
index 58a93568d0..d65197b256 100644
--- a/MdeModulePkg/Application/CapsuleApp/CapsuleDump.c
+++ b/MdeModulePkg/Application/CapsuleApp/CapsuleDump.c
@@ -1,9 +1,9 @@
 /** @file
   Dump Capsule image information.
 
-  Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2016 - 2020, Intel Corporation. All rights reserved.<BR>
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
 
 #include "CapsuleApp.h"
@@ -336,10 +336,11 @@ CHAR8 *mLastAttemptStatusString[] = {
   "Error: Incorrect Version",
   "Error: Invalid Format",
   "Error: Auth Error",
   "Error: Power Event AC",
   "Error: Power Event Battery",
+  "Error: Unsatisfied Dependencies",
 };
 
 /**
   Convert FwType to a string.
 
@@ -1005,10 +1006,11 @@ DumpFmpImageInfo (
   IN CHAR16                          *PackageVersionName
   )
 {
   EFI_FIRMWARE_IMAGE_DESCRIPTOR                 *CurrentImageInfo;
   UINTN                                         Index;
+  UINTN                                         Index2;
 
   Print(L"  DescriptorVersion  - 0x%x\n", DescriptorVersion);
   Print(L"  DescriptorCount    - 0x%x\n", DescriptorCount);
   Print(L"  DescriptorSize     - 0x%x\n", DescriptorSize);
   Print(L"  PackageVersion     - 0x%x\n", PackageVersion);
@@ -1041,10 +1043,22 @@ DumpFmpImageInfo (
       Print(L"    LowestSupportedImageVersion - 0x%x\n", CurrentImageInfo->LowestSupportedImageVersion);
       if (DescriptorVersion > 2) {
         Print(L"    LastAttemptVersion          - 0x%x\n", CurrentImageInfo->LastAttemptVersion);
         Print(L"    LastAttemptStatus           - 0x%x (%a)\n", CurrentImageInfo->LastAttemptStatus, LastAttemptStatusToString(CurrentImageInfo->LastAttemptStatus));
         Print(L"    HardwareInstance            - 0x%lx\n", CurrentImageInfo->HardwareInstance);
+        if (DescriptorVersion > 3) {
+          Print(L"    Dependencies                - ");
+          if (CurrentImageInfo->Dependencies == NULL) {
+            Print(L"NULL\n");
+          } else {
+            Index2 = 0;
+            do {
+              Print(L"%02x ", CurrentImageInfo->Dependencies->Dependencies[Index2]);
+            } while (CurrentImageInfo->Dependencies->Dependencies[Index2 ++] != EFI_FMP_DEP_END);
+            Print(L"\n");
+          }
+        }
       }
     }
     //
     // Use DescriptorSize to move ImageInfo Pointer to stay compatible with different ImageInfo version
     //
-- 
2.16.2.windows.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [edk2-devel][PATCH 3/3] FmdDevicePkg/FmpDxe: Support Fmp Capsule Dependency.
  2020-01-10  5:34 [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation Xu, Wei6
  2020-01-10  5:34 ` [edk2-devel][PATCH 1/3] MdePkg: Add definition for Fmp Capsule Dependency Xu, Wei6
  2020-01-10  5:34 ` [edk2-devel][PATCH 2/3] MdeModulePkg/CapsuleApp: Enhance CapsuleApp " Xu, Wei6
@ 2020-01-10  5:34 ` Xu, Wei6
  2020-01-16 12:25 ` [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation Liming Gao
  3 siblings, 0 replies; 9+ messages in thread
From: Xu, Wei6 @ 2020-01-10  5:34 UTC (permalink / raw)
  To: devel; +Cc: Michael D Kinney, Liming Gao

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2421

Capsule Dependency is an incremental change of Fmp Capsule Update. The
capsule format is extended to include a set of binary encoded dependency
expression. The dependency expression is signed together with the Fmp
payload and evaluated before update is applied.
This feature is defined in UEFI Spec 2.8.

The dependency evaluation has two steps:
1. Validate platform existing Fmp images' version satisfy the dependency
expression in capsule image.
2. Validate the capsule image version satisfy all the platform existing
Fmp image's dependency expression.
If the dependency expression evaluates to FALSE, then the capsule update
fails and last attempt status is set to
LAST_ATTEMPT_STATUS_ERROR_UNSATISFIED_DEPENDENCIES.

The dependency saving and getting is FmpDeviceLib implementation scope.
The parameter "Image" of FmpDeviceSetImage and FmpDeviceGetImage function
is extended to contain the dependency. The layout:
  +--------------------------+
  |   Dependency Op-codes    |
  +--------------------------+
  |    Fmp Payload Image     |
  +--------------------------+
1. FmpDeviceSetImage is responsible for retrieving the dependency from the
parameter "Image" and saving it to a protected storage.
2. FmpDeviceGetImage is responsible for retrieving the dependency from the
storage where FmpDeviceSetImage saves dependency and combining it with the
Fmp Payload Image into one buffer which is returned to the caller. This
dependency will be populated into EFI_FIRMWARE_IMAGE_DESCRIPTOR and used
for dependency evaluation.
3. FmpDeviceGetAttributes must set the bit IMAGE_ATTRIBUTE_DEPENDENCY to
indicate the Fmp device supports Fmp Capsule Dependency feature.

Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Signed-off-by: Wei6 Xu <wei6.xu@intel.com>
---
 FmpDevicePkg/FmpDxe/Dependency.c  | 679 ++++++++++++++++++++++++++++++++++++++
 FmpDevicePkg/FmpDxe/Dependency.h  |  63 ++++
 FmpDevicePkg/FmpDxe/FmpDxe.c      | 238 ++++++++++++-
 FmpDevicePkg/FmpDxe/FmpDxe.inf    |   4 +-
 FmpDevicePkg/FmpDxe/FmpDxeLib.inf |   4 +-
 5 files changed, 972 insertions(+), 16 deletions(-)
 create mode 100644 FmpDevicePkg/FmpDxe/Dependency.c
 create mode 100644 FmpDevicePkg/FmpDxe/Dependency.h

diff --git a/FmpDevicePkg/FmpDxe/Dependency.c b/FmpDevicePkg/FmpDxe/Dependency.c
new file mode 100644
index 0000000000..b63a36b989
--- /dev/null
+++ b/FmpDevicePkg/FmpDxe/Dependency.c
@@ -0,0 +1,679 @@
+/** @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[in]  Value                  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 = AllocatePool (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
new file mode 100644
index 0000000000..a2aaaceeae
--- /dev/null
+++ b/FmpDevicePkg/FmpDxe/Dependency.h
@@ -0,0 +1,63 @@
+/** @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                  DependenciesSize,
+  OUT BOOLEAN                      *IsSatisfied
+  );
+
+#endif
diff --git a/FmpDevicePkg/FmpDxe/FmpDxe.c b/FmpDevicePkg/FmpDxe/FmpDxe.c
index fe465af11e..aa92331966 100644
--- a/FmpDevicePkg/FmpDxe/FmpDxe.c
+++ b/FmpDevicePkg/FmpDxe/FmpDxe.c
@@ -2,18 +2,19 @@
   Produces a Firmware Management Protocol that supports updates to a firmware
   image stored in a firmware device with platform and firmware device specific
   information provided through PCDs and libraries.
 
   Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
-  Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.<BR>
 
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
 
 #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
@@ -273,10 +274,17 @@ VOID
 PopulateDescriptor (
   FIRMWARE_MANAGEMENT_PRIVATE_DATA  *Private
   )
 {
   EFI_STATUS  Status;
+  VOID        *Image;
+  UINTN       ImageSize;
+  BOOLEAN     IsDepexValid;
+  UINT32      DepexSize;
+
+  Image     = NULL;
+  ImageSize = 0;
 
   if (Private->DescriptorPopulated) {
     return;
   }
 
@@ -376,11 +384,51 @@ PopulateDescriptor (
   }
 
   Private->Descriptor.LastAttemptVersion = GetLastAttemptVersionFromVariable (Private);
   Private->Descriptor.LastAttemptStatus  = GetLastAttemptStatusFromVariable (Private);
 
+  //
+  // Get the dependency from the FmpDeviceLib and populate it to the descriptor.
+  //
+  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 == TRUE) {
+        Private->Descriptor.Dependencies = AllocatePool (DepexSize);
+        if (Private->Descriptor.Dependencies != NULL) {
+          CopyMem (Private->Descriptor.Dependencies->Dependencies, Image, DepexSize);
+        }
+      }
+    }
+  }
+
   Private->DescriptorPopulated = TRUE;
+
+  if (Image != NULL) {
+    FreePool (Image);
+  }
 }
 
 /**
   Returns information about the current firmware image(s) of the device.
 
@@ -538,16 +586,21 @@ 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;
+  Status          = EFI_SUCCESS;
+  ImageBuffer     = NULL;
+  DepexSize       = 0;
 
   //
   // Retrieve the private context structure
   //
   Private = FIRMWARE_MANAGEMENT_PRIVATE_DATA_FROM_THIS (This);
@@ -573,12 +626,49 @@ GetTheImage (
   //
   Status = FmpDeviceGetSize (&Size);
   if (EFI_ERROR (Status)) {
     Size = 0;
   }
-  if (*ImageSize < Size) {
-    *ImageSize = Size;
+
+  //
+  // 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;
     DEBUG ((DEBUG_VERBOSE, "FmpDxe(%s): GetImage() - ImageSize is to small.\n", mImageIdName));
     Status = EFI_BUFFER_TOO_SMALL;
     goto cleanup;
   }
 
@@ -586,12 +676,21 @@ GetTheImage (
     DEBUG ((DEBUG_ERROR, "FmpDxe(%s): GetImage() - Image Pointer Parameter is NULL.\n", mImageIdName));
     Status = EFI_INVALID_PARAMETER;
     goto cleanup;
   }
 
-  Status = FmpDeviceGetImage (Image, ImageSize);
+  //
+  // Image is after the dependency expression.
+  //
+  *ImageSize = ImageBufferSize - DepexSize;
+  CopyMem (Image, ImageBuffer + DepexSize, *ImageSize);
+  Status = EFI_SUCCESS;
+
 cleanup:
+  if (ImageBuffer != NULL) {
+    FreePool (ImageBuffer);
+  }
 
   return Status;
 }
 
 /**
@@ -708,18 +807,24 @@ CheckTheImage (
   UINT32                            Index;
   VOID                              *PublicKeyData;
   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;
   Version          = 0;
   FmpHeaderSize    = 0;
   AllHeaderSize    = 0;
+  Dependencies     = NULL;
+  DependenciesSize = 0;
 
   if (!FeaturePcdGet (PcdFmpDeviceStorageAccessEnable)) {
     return EFI_UNSUPPORTED;
   }
 
@@ -840,14 +945,37 @@ CheckTheImage (
     Status = EFI_ABORTED;
     goto cleanup;
   }
   Status = GetFmpPayloadHeaderVersion (FmpPayloadHeader, FmpPayloadSize, &Version);
   if (EFI_ERROR (Status)) {
-    DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - GetFmpPayloadHeaderVersion failed %r.\n", mImageIdName, Status));
-    *ImageUpdatable = IMAGE_UPDATABLE_INVALID;
-    Status = EFI_SUCCESS;
-    goto cleanup;
+    //
+    // Check 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));
   }
 
   //
   // Check the lowest supported version
   //
@@ -860,10 +988,26 @@ CheckTheImage (
     *ImageUpdatable = IMAGE_UPDATABLE_INVALID_OLD;
     Status = EFI_SUCCESS;
     goto cleanup;
   }
 
+  //
+  // 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;
+    *ImageUpdatable = IMAGE_UPDATABLE_INVALID;
+    Status = EFI_SUCCESS;
+    goto cleanup;
+  }
+
   //
   // Get the FmpHeaderSize so we can determine the real payload size
   //
   Status = GetFmpPayloadHeaderSize (FmpPayloadHeader, FmpPayloadSize, &FmpHeaderSize);
   if (EFI_ERROR (Status)) {
@@ -875,11 +1019,11 @@ CheckTheImage (
 
   //
   // Call FmpDevice Lib Check Image on the
   // Raw payload.  So all headers need stripped off
   //
-  AllHeaderSize = GetAllHeaderSize ( (EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, FmpHeaderSize );
+  AllHeaderSize = GetAllHeaderSize ( (EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, FmpHeaderSize + DependenciesSize);
   if (AllHeaderSize == 0) {
     DEBUG ((DEBUG_ERROR, "FmpDxe(%s): CheckTheImage() - GetAllHeaderSize failed.\n", mImageIdName));
     Status = EFI_ABORTED;
     goto cleanup;
   }
@@ -965,20 +1109,29 @@ SetTheImage (
   UINT32                            AllHeaderSize;
   UINT32                            IncomingFwVersion;
   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;
   FmpHeader          = NULL;
   FmpPayloadSize     = 0;
   AllHeaderSize      = 0;
-  IncomingFwVersion = 0;
+  IncomingFwVersion  = 0;
   LastAttemptStatus  = LAST_ATTEMPT_STATUS_ERROR_UNSUCCESSFUL;
+  Dependencies       = NULL;
+  DependenciesSize   = 0;
+  ImageBuffer        = NULL;
+  ImageBufferSize    = 0;
 
   if (!FeaturePcdGet (PcdFmpDeviceStorageAccessEnable)) {
     return EFI_UNSUPPORTED;
   }
 
@@ -1006,10 +1159,15 @@ 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)) {
@@ -1029,10 +1187,25 @@ SetTheImage (
     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);
@@ -1043,10 +1216,15 @@ 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) {
+      LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_UNSATISFIED_DEPENDENCIES;
+    } else if (mDependenciesCheckStatus == DEPENDENCIES_INVALID) {
+      LastAttemptStatus = LAST_ATTEMPT_STATUS_ERROR_INVALID_FORMAT;
+    }
     Status = EFI_ABORTED;
     goto cleanup;
   }
 
   if (Progress == NULL) {
@@ -1136,28 +1314,56 @@ SetTheImage (
   if (EFI_ERROR (Status)) {
     DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - GetFmpPayloadHeaderSize failed %r.\n", mImageIdName, Status));
     goto cleanup;
   }
 
-  AllHeaderSize = GetAllHeaderSize ( (EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, FmpHeaderSize );
+  AllHeaderSize = GetAllHeaderSize ((EFI_FIRMWARE_IMAGE_AUTHENTICATION *)Image, FmpHeaderSize + DependenciesSize);
   if (AllHeaderSize == 0) {
     DEBUG ((DEBUG_ERROR, "FmpDxe(%s): SetTheImage() - GetAllHeaderSize failed.\n", mImageIdName));
     Status = EFI_ABORTED;
     goto cleanup;
   }
 
+  //
+  // 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 (
-             (((UINT8 *)Image) + AllHeaderSize),
-             ImageSize - AllHeaderSize,
+             ImageBuffer,
+             ImageBufferSize,
              VendorCode,
              FmpDxeProgress,
              IncomingFwVersion,
              AbortReason
              );
@@ -1190,10 +1396,14 @@ 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.inf b/FmpDevicePkg/FmpDxe/FmpDxe.inf
index bec73aa8fb..97b6518fa1 100644
--- a/FmpDevicePkg/FmpDxe/FmpDxe.inf
+++ b/FmpDevicePkg/FmpDxe/FmpDxe.inf
@@ -2,11 +2,11 @@
 #  Produces a Firmware Management Protocol that supports updates to a firmware
 #  image stored in a firmware device with platform and firmware device specific
 #  information provided through PCDs and libraries.
 #
 #  Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
-#  Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.<BR>
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 ##
 
 [Defines]
@@ -26,10 +26,12 @@
 #
 
 [Sources]
   FmpDxe.c
   FmpDxe.h
+  Dependency.c
+  Dependency.h
   DetectTestKey.c
   VariableSupport.h
   VariableSupport.c
 
 [Packages]
diff --git a/FmpDevicePkg/FmpDxe/FmpDxeLib.inf b/FmpDevicePkg/FmpDxe/FmpDxeLib.inf
index edc0cd66c1..de005b6892 100644
--- a/FmpDevicePkg/FmpDxe/FmpDxeLib.inf
+++ b/FmpDevicePkg/FmpDxe/FmpDxeLib.inf
@@ -2,11 +2,11 @@
 #  Produces a Firmware Management Protocol that supports updates to a firmware
 #  image stored in a firmware device with platform and firmware device specific
 #  information provided through PCDs and libraries.
 #
 #  Copyright (c) 2016, Microsoft Corporation. All rights reserved.<BR>
-#  Copyright (c) 2018 - 2019, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2018 - 2020, Intel Corporation. All rights reserved.<BR>
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 ##
 
 [Defines]
@@ -27,10 +27,12 @@
 #
 
 [Sources]
   FmpDxe.c
   FmpDxe.h
+  Dependency.c
+  Dependency.h
   DetectTestKey.c
   VariableSupport.h
   VariableSupport.c
 
 [Packages]
-- 
2.16.2.windows.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation.
  2020-01-10  5:34 [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation Xu, Wei6
                   ` (2 preceding siblings ...)
  2020-01-10  5:34 ` [edk2-devel][PATCH 3/3] FmdDevicePkg/FmpDxe: Support " Xu, Wei6
@ 2020-01-16 12:25 ` Liming Gao
  2020-01-16 13:31   ` Xu, Wei6
  3 siblings, 1 reply; 9+ messages in thread
From: Liming Gao @ 2020-01-16 12:25 UTC (permalink / raw)
  To: devel@edk2.groups.io, Xu, Wei6

Wei:
  The code change looks good. Reviewed-by: Liming Gao <liming.gao@intel.com>
  
  Please share which test have been done. 

Thanks
Liming
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Xu, Wei6
> Sent: Friday, January 10, 2020 1:35 PM
> To: devel@edk2.groups.io
> Subject: [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation.
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2421
> 
> This series implements Fmp Capsule Dependency.
> Fmp Capsule Dependency is an incremental change of Fmp Capsule Update.
> The capsule format is extended to include a set of binary encoded dependency expression.
> The dependency expression is evaluated before update is applied.
> This feature is defined in UEFI Spec 2.8.
> 
> Wei6 Xu (3):
>   MdePkg: Add definition for Fmp Capsule Dependency.
>   MdeModulePkg/CapsuleApp: Enhance CapsuleApp for Fmp Capsule Dependency
>   FmdDevicePkg/FmpDxe: Support Fmp Capsule Dependency.
> 
>  FmpDevicePkg/FmpDxe/Dependency.c                  | 679 ++++++++++++++++++++++
>  FmpDevicePkg/FmpDxe/Dependency.h                  |  63 ++
>  FmpDevicePkg/FmpDxe/FmpDxe.c                      | 238 +++++++-
>  FmpDevicePkg/FmpDxe/FmpDxe.inf                    |   4 +-
>  FmpDevicePkg/FmpDxe/FmpDxeLib.inf                 |   4 +-
>  MdeModulePkg/Application/CapsuleApp/CapsuleDump.c |  16 +-
>  MdePkg/Include/Guid/SystemResourceTable.h         |  19 +-
>  MdePkg/Include/Protocol/FirmwareManagement.h      |  35 +-
>  8 files changed, 1030 insertions(+), 28 deletions(-)
>  create mode 100644 FmpDevicePkg/FmpDxe/Dependency.c
>  create mode 100644 FmpDevicePkg/FmpDxe/Dependency.h
> 
> --
> 2.16.2.windows.1
> 
> 
> 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation.
  2020-01-16 12:25 ` [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation Liming Gao
@ 2020-01-16 13:31   ` Xu, Wei6
  2020-01-16 13:54     ` Liming Gao
       [not found]     ` <15EA627A19795932.4264@groups.io>
  0 siblings, 2 replies; 9+ messages in thread
From: Xu, Wei6 @ 2020-01-16 13:31 UTC (permalink / raw)
  To: Gao, Liming, devel@edk2.groups.io

Hi Liming,

Thanks a lot for review.

We did following test:
On OVMF: 
1. Unit test to verify the handling of all op-codes.
2. Unit test for updated APIs
3. Verify capsule update process with satisfied/unsatisfied/invalid dependency. 

On real dev machine: 
1. Update Fmp Device which supports dependency, with capsule which has dependency inside.
2. Update Fmp Device which supports dependency, with capsule which has no dependency inside.
3. Update Fmp Device which doesn't support dependency, with capsule which has dependency inside.
4. Update Fmp Device which doesn't support dependency, with capsule which has no dependency inside.

BR,
Wei

> -----Original Message-----
> From: Gao, Liming <liming.gao@intel.com>
> Sent: Thursday, January 16, 2020 8:25 PM
> To: devel@edk2.groups.io; Xu, Wei6 <wei6.xu@intel.com>
> Subject: RE: [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation.
> 
> Wei:
>   The code change looks good. Reviewed-by: Liming Gao <liming.gao@intel.com>
> 
>   Please share which test have been done.
> 
> Thanks
> Liming
> > -----Original Message-----
> > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Xu,
> > Wei6
> > Sent: Friday, January 10, 2020 1:35 PM
> > To: devel@edk2.groups.io
> > Subject: [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation.
> >
> > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2421
> >
> > This series implements Fmp Capsule Dependency.
> > Fmp Capsule Dependency is an incremental change of Fmp Capsule Update.
> > The capsule format is extended to include a set of binary encoded dependency
> expression.
> > The dependency expression is evaluated before update is applied.
> > This feature is defined in UEFI Spec 2.8.
> >
> > Wei6 Xu (3):
> >   MdePkg: Add definition for Fmp Capsule Dependency.
> >   MdeModulePkg/CapsuleApp: Enhance CapsuleApp for Fmp Capsule
> Dependency
> >   FmdDevicePkg/FmpDxe: Support Fmp Capsule Dependency.
> >
> >  FmpDevicePkg/FmpDxe/Dependency.c                  | 679
> ++++++++++++++++++++++
> >  FmpDevicePkg/FmpDxe/Dependency.h                  |  63 ++
> >  FmpDevicePkg/FmpDxe/FmpDxe.c                      | 238 +++++++-
> >  FmpDevicePkg/FmpDxe/FmpDxe.inf                    |   4 +-
> >  FmpDevicePkg/FmpDxe/FmpDxeLib.inf                 |   4 +-
> >  MdeModulePkg/Application/CapsuleApp/CapsuleDump.c |  16 +-
> >  MdePkg/Include/Guid/SystemResourceTable.h         |  19 +-
> >  MdePkg/Include/Protocol/FirmwareManagement.h      |  35 +-
> >  8 files changed, 1030 insertions(+), 28 deletions(-)  create mode
> > 100644 FmpDevicePkg/FmpDxe/Dependency.c  create mode 100644
> > FmpDevicePkg/FmpDxe/Dependency.h
> >
> > --
> > 2.16.2.windows.1
> >
> >
> > 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation.
  2020-01-16 13:31   ` Xu, Wei6
@ 2020-01-16 13:54     ` Liming Gao
       [not found]     ` <15EA627A19795932.4264@groups.io>
  1 sibling, 0 replies; 9+ messages in thread
From: Liming Gao @ 2020-01-16 13:54 UTC (permalink / raw)
  To: Xu, Wei6, devel@edk2.groups.io

Wei:
  Thanks for your update. I think those unit tests are enough. 

Liming
> -----Original Message-----
> From: Xu, Wei6 <wei6.xu@intel.com>
> Sent: Thursday, January 16, 2020 9:31 PM
> To: Gao, Liming <liming.gao@intel.com>; devel@edk2.groups.io
> Subject: RE: [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation.
> 
> Hi Liming,
> 
> Thanks a lot for review.
> 
> We did following test:
> On OVMF:
> 1. Unit test to verify the handling of all op-codes.
> 2. Unit test for updated APIs
> 3. Verify capsule update process with satisfied/unsatisfied/invalid dependency.
> 
> On real dev machine:
> 1. Update Fmp Device which supports dependency, with capsule which has dependency inside.
> 2. Update Fmp Device which supports dependency, with capsule which has no dependency inside.
> 3. Update Fmp Device which doesn't support dependency, with capsule which has dependency inside.
> 4. Update Fmp Device which doesn't support dependency, with capsule which has no dependency inside.
> 
> BR,
> Wei
> 
> > -----Original Message-----
> > From: Gao, Liming <liming.gao@intel.com>
> > Sent: Thursday, January 16, 2020 8:25 PM
> > To: devel@edk2.groups.io; Xu, Wei6 <wei6.xu@intel.com>
> > Subject: RE: [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation.
> >
> > Wei:
> >   The code change looks good. Reviewed-by: Liming Gao <liming.gao@intel.com>
> >
> >   Please share which test have been done.
> >
> > Thanks
> > Liming
> > > -----Original Message-----
> > > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Xu,
> > > Wei6
> > > Sent: Friday, January 10, 2020 1:35 PM
> > > To: devel@edk2.groups.io
> > > Subject: [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation.
> > >
> > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2421
> > >
> > > This series implements Fmp Capsule Dependency.
> > > Fmp Capsule Dependency is an incremental change of Fmp Capsule Update.
> > > The capsule format is extended to include a set of binary encoded dependency
> > expression.
> > > The dependency expression is evaluated before update is applied.
> > > This feature is defined in UEFI Spec 2.8.
> > >
> > > Wei6 Xu (3):
> > >   MdePkg: Add definition for Fmp Capsule Dependency.
> > >   MdeModulePkg/CapsuleApp: Enhance CapsuleApp for Fmp Capsule
> > Dependency
> > >   FmdDevicePkg/FmpDxe: Support Fmp Capsule Dependency.
> > >
> > >  FmpDevicePkg/FmpDxe/Dependency.c                  | 679
> > ++++++++++++++++++++++
> > >  FmpDevicePkg/FmpDxe/Dependency.h                  |  63 ++
> > >  FmpDevicePkg/FmpDxe/FmpDxe.c                      | 238 +++++++-
> > >  FmpDevicePkg/FmpDxe/FmpDxe.inf                    |   4 +-
> > >  FmpDevicePkg/FmpDxe/FmpDxeLib.inf                 |   4 +-
> > >  MdeModulePkg/Application/CapsuleApp/CapsuleDump.c |  16 +-
> > >  MdePkg/Include/Guid/SystemResourceTable.h         |  19 +-
> > >  MdePkg/Include/Protocol/FirmwareManagement.h      |  35 +-
> > >  8 files changed, 1030 insertions(+), 28 deletions(-)  create mode
> > > 100644 FmpDevicePkg/FmpDxe/Dependency.c  create mode 100644
> > > FmpDevicePkg/FmpDxe/Dependency.h
> > >
> > > --
> > > 2.16.2.windows.1
> > >
> > >
> > > 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation.
       [not found]     ` <15EA627A19795932.4264@groups.io>
@ 2020-01-17  0:32       ` Liming Gao
  2020-01-17  0:49         ` Xu, Wei6
  0 siblings, 1 reply; 9+ messages in thread
From: Liming Gao @ 2020-01-17  0:32 UTC (permalink / raw)
  To: devel@edk2.groups.io, Gao, Liming, Xu, Wei6

Wei:
  Is there Wiki page to introduce how to enable Capsule Dependency and how to verify Capsule with Dependency?

Thanks
Liming
-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Liming Gao
Sent: 2020年1月16日 21:55
To: Xu, Wei6 <wei6.xu@intel.com>; devel@edk2.groups.io
Subject: Re: [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation.

Wei:
  Thanks for your update. I think those unit tests are enough. 

Liming
> -----Original Message-----
> From: Xu, Wei6 <wei6.xu@intel.com>
> Sent: Thursday, January 16, 2020 9:31 PM
> To: Gao, Liming <liming.gao@intel.com>; devel@edk2.groups.io
> Subject: RE: [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation.
> 
> Hi Liming,
> 
> Thanks a lot for review.
> 
> We did following test:
> On OVMF:
> 1. Unit test to verify the handling of all op-codes.
> 2. Unit test for updated APIs
> 3. Verify capsule update process with satisfied/unsatisfied/invalid dependency.
> 
> On real dev machine:
> 1. Update Fmp Device which supports dependency, with capsule which has dependency inside.
> 2. Update Fmp Device which supports dependency, with capsule which has no dependency inside.
> 3. Update Fmp Device which doesn't support dependency, with capsule which has dependency inside.
> 4. Update Fmp Device which doesn't support dependency, with capsule which has no dependency inside.
> 
> BR,
> Wei
> 
> > -----Original Message-----
> > From: Gao, Liming <liming.gao@intel.com>
> > Sent: Thursday, January 16, 2020 8:25 PM
> > To: devel@edk2.groups.io; Xu, Wei6 <wei6.xu@intel.com>
> > Subject: RE: [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation.
> >
> > Wei:
> >   The code change looks good. Reviewed-by: Liming Gao 
> > <liming.gao@intel.com>
> >
> >   Please share which test have been done.
> >
> > Thanks
> > Liming
> > > -----Original Message-----
> > > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Xu,
> > > Wei6
> > > Sent: Friday, January 10, 2020 1:35 PM
> > > To: devel@edk2.groups.io
> > > Subject: [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation.
> > >
> > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2421
> > >
> > > This series implements Fmp Capsule Dependency.
> > > Fmp Capsule Dependency is an incremental change of Fmp Capsule Update.
> > > The capsule format is extended to include a set of binary encoded 
> > > dependency
> > expression.
> > > The dependency expression is evaluated before update is applied.
> > > This feature is defined in UEFI Spec 2.8.
> > >
> > > Wei6 Xu (3):
> > >   MdePkg: Add definition for Fmp Capsule Dependency.
> > >   MdeModulePkg/CapsuleApp: Enhance CapsuleApp for Fmp Capsule
> > Dependency
> > >   FmdDevicePkg/FmpDxe: Support Fmp Capsule Dependency.
> > >
> > >  FmpDevicePkg/FmpDxe/Dependency.c                  | 679
> > ++++++++++++++++++++++
> > >  FmpDevicePkg/FmpDxe/Dependency.h                  |  63 ++
> > >  FmpDevicePkg/FmpDxe/FmpDxe.c                      | 238 +++++++-
> > >  FmpDevicePkg/FmpDxe/FmpDxe.inf                    |   4 +-
> > >  FmpDevicePkg/FmpDxe/FmpDxeLib.inf                 |   4 +-
> > >  MdeModulePkg/Application/CapsuleApp/CapsuleDump.c |  16 +-
> > >  MdePkg/Include/Guid/SystemResourceTable.h         |  19 +-
> > >  MdePkg/Include/Protocol/FirmwareManagement.h      |  35 +-
> > >  8 files changed, 1030 insertions(+), 28 deletions(-)  create mode
> > > 100644 FmpDevicePkg/FmpDxe/Dependency.c  create mode 100644 
> > > FmpDevicePkg/FmpDxe/Dependency.h
> > >
> > > --
> > > 2.16.2.windows.1
> > >
> > >
> > > 





^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation.
  2020-01-17  0:32       ` Liming Gao
@ 2020-01-17  0:49         ` Xu, Wei6
  0 siblings, 0 replies; 9+ messages in thread
From: Xu, Wei6 @ 2020-01-17  0:49 UTC (permalink / raw)
  To: Gao, Liming, devel@edk2.groups.io

Sorry. I haven't prepared a Wiki for it.
But I can make one as soon as possible.

BR,
Wei

-----Original Message-----
From: Gao, Liming 
Sent: Friday, January 17, 2020 8:32 AM
To: devel@edk2.groups.io; Gao, Liming <liming.gao@intel.com>; Xu, Wei6 <wei6.xu@intel.com>
Subject: RE: [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation.

Wei:
  Is there Wiki page to introduce how to enable Capsule Dependency and how to verify Capsule with Dependency?

Thanks
Liming
-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Liming Gao
Sent: 2020年1月16日 21:55
To: Xu, Wei6 <wei6.xu@intel.com>; devel@edk2.groups.io
Subject: Re: [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation.

Wei:
  Thanks for your update. I think those unit tests are enough. 

Liming
> -----Original Message-----
> From: Xu, Wei6 <wei6.xu@intel.com>
> Sent: Thursday, January 16, 2020 9:31 PM
> To: Gao, Liming <liming.gao@intel.com>; devel@edk2.groups.io
> Subject: RE: [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation.
> 
> Hi Liming,
> 
> Thanks a lot for review.
> 
> We did following test:
> On OVMF:
> 1. Unit test to verify the handling of all op-codes.
> 2. Unit test for updated APIs
> 3. Verify capsule update process with satisfied/unsatisfied/invalid dependency.
> 
> On real dev machine:
> 1. Update Fmp Device which supports dependency, with capsule which has dependency inside.
> 2. Update Fmp Device which supports dependency, with capsule which has no dependency inside.
> 3. Update Fmp Device which doesn't support dependency, with capsule which has dependency inside.
> 4. Update Fmp Device which doesn't support dependency, with capsule which has no dependency inside.
> 
> BR,
> Wei
> 
> > -----Original Message-----
> > From: Gao, Liming <liming.gao@intel.com>
> > Sent: Thursday, January 16, 2020 8:25 PM
> > To: devel@edk2.groups.io; Xu, Wei6 <wei6.xu@intel.com>
> > Subject: RE: [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation.
> >
> > Wei:
> >   The code change looks good. Reviewed-by: Liming Gao 
> > <liming.gao@intel.com>
> >
> >   Please share which test have been done.
> >
> > Thanks
> > Liming
> > > -----Original Message-----
> > > From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Xu,
> > > Wei6
> > > Sent: Friday, January 10, 2020 1:35 PM
> > > To: devel@edk2.groups.io
> > > Subject: [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation.
> > >
> > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2421
> > >
> > > This series implements Fmp Capsule Dependency.
> > > Fmp Capsule Dependency is an incremental change of Fmp Capsule Update.
> > > The capsule format is extended to include a set of binary encoded 
> > > dependency
> > expression.
> > > The dependency expression is evaluated before update is applied.
> > > This feature is defined in UEFI Spec 2.8.
> > >
> > > Wei6 Xu (3):
> > >   MdePkg: Add definition for Fmp Capsule Dependency.
> > >   MdeModulePkg/CapsuleApp: Enhance CapsuleApp for Fmp Capsule
> > Dependency
> > >   FmdDevicePkg/FmpDxe: Support Fmp Capsule Dependency.
> > >
> > >  FmpDevicePkg/FmpDxe/Dependency.c                  | 679
> > ++++++++++++++++++++++
> > >  FmpDevicePkg/FmpDxe/Dependency.h                  |  63 ++
> > >  FmpDevicePkg/FmpDxe/FmpDxe.c                      | 238 +++++++-
> > >  FmpDevicePkg/FmpDxe/FmpDxe.inf                    |   4 +-
> > >  FmpDevicePkg/FmpDxe/FmpDxeLib.inf                 |   4 +-
> > >  MdeModulePkg/Application/CapsuleApp/CapsuleDump.c |  16 +-
> > >  MdePkg/Include/Guid/SystemResourceTable.h         |  19 +-
> > >  MdePkg/Include/Protocol/FirmwareManagement.h      |  35 +-
> > >  8 files changed, 1030 insertions(+), 28 deletions(-)  create mode
> > > 100644 FmpDevicePkg/FmpDxe/Dependency.c  create mode 100644 
> > > FmpDevicePkg/FmpDxe/Dependency.h
> > >
> > > --
> > > 2.16.2.windows.1
> > >
> > >
> > > 





^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2020-01-17  0:49 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-01-10  5:34 [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation Xu, Wei6
2020-01-10  5:34 ` [edk2-devel][PATCH 1/3] MdePkg: Add definition for Fmp Capsule Dependency Xu, Wei6
2020-01-10  5:34 ` [edk2-devel][PATCH 2/3] MdeModulePkg/CapsuleApp: Enhance CapsuleApp " Xu, Wei6
2020-01-10  5:34 ` [edk2-devel][PATCH 3/3] FmdDevicePkg/FmpDxe: Support " Xu, Wei6
2020-01-16 12:25 ` [edk2-devel][PATCH 0/3] Fmp Capsule Dependency implementation Liming Gao
2020-01-16 13:31   ` Xu, Wei6
2020-01-16 13:54     ` Liming Gao
     [not found]     ` <15EA627A19795932.4264@groups.io>
2020-01-17  0:32       ` Liming Gao
2020-01-17  0:49         ` Xu, Wei6

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox