]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg CapsulePei: Validate capsule integrity by memory resource hob
authorStar Zeng <star.zeng@intel.com>
Tue, 26 Apr 2016 04:52:42 +0000 (12:52 +0800)
committerStar Zeng <star.zeng@intel.com>
Tue, 21 Jun 2016 10:50:05 +0000 (18:50 +0800)
Cc: Jiewen Yao <jiewen.yao@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
MdeModulePkg/Universal/CapsulePei/Capsule.h
MdeModulePkg/Universal/CapsulePei/CapsulePei.inf
MdeModulePkg/Universal/CapsulePei/Common/CapsuleCoalesce.c
MdeModulePkg/Universal/CapsulePei/Common/CommonHeader.h
MdeModulePkg/Universal/CapsulePei/UefiCapsule.c
MdeModulePkg/Universal/CapsulePei/X64/X64Entry.c

index 411dffa682a1387a7477b8cedf617e5c1b1ed0a5..3614c21f878072a7771590195f309a3482af0c4b 100644 (file)
@@ -24,6 +24,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 #include <Ppi/ReadOnlyVariable2.h>\r
 #include <Guid/CapsuleVendor.h>\r
 \r
+#include <Library/BaseLib.h>\r
 #include <Library/DebugLib.h>\r
 #include <Library/PeimEntryPoint.h>\r
 #include <Library/PeiServicesLib.h>\r
index d7aa37186f667af8dbd3ceba7fc5153765c23b88..d2ca0d06912c35103c5586d76f60153023a64a82 100644 (file)
@@ -6,7 +6,7 @@
 #  This external input must be validated carefully to avoid security issue like\r
 #  buffer overflow, integer overflow.\r
 #\r
-# Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
 #\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions\r
@@ -46,6 +46,7 @@
 \r
 \r
 [LibraryClasses]\r
+  BaseLib\r
   HobLib\r
   BaseMemoryLib\r
   PeiServicesLib\r
index 006d9006369c280182a7e56c461d0ae944466351..9e8315eb97c62c7d87aca443424f8eb097c9855f 100644 (file)
@@ -59,20 +59,6 @@ FindFreeMem (
   UINTN                             DataSize\r
   );\r
 \r
-/**\r
-  Check the integrity of the capsule descriptors.\r
-\r
-  @param BlockList    Pointer to the capsule descriptors\r
-\r
-  @retval NULL           BlockList is not valid.\r
-  @retval LastBlockDesc  Last one Block in BlockList\r
-\r
-**/\r
-EFI_CAPSULE_BLOCK_DESCRIPTOR *\r
-ValidateCapsuleIntegrity (\r
-  IN EFI_CAPSULE_BLOCK_DESCRIPTOR    *BlockList\r
-  );\r
-\r
 /**\r
   The capsule block descriptors may be fragmented and spread all over memory.\r
   To simplify the coalescing of capsule blocks, first coalesce all the\r
@@ -247,10 +233,69 @@ FindFreeMem (
   return MemBase;\r
 }\r
 \r
+/**\r
+  Validate capsule by MemoryResource.\r
+\r
+  @param MemoryResource  Pointer to the buffer of memory resource descriptor.\r
+  @param Address         Address to be validated.\r
+  @param Size            Size to be validated.\r
+\r
+  @retval TRUE  No memory resource descriptor reported in HOB list before capsule Coalesce,\r
+                or it is valid in one MemoryResource.\r
+          FALSE It is not in any MemoryResource.\r
+\r
+**/\r
+BOOLEAN\r
+ValidateCapsuleByMemoryResource (\r
+  IN MEMORY_RESOURCE_DESCRIPTOR     *MemoryResource,\r
+  IN EFI_PHYSICAL_ADDRESS           Address,\r
+  IN UINT64                         Size\r
+  )\r
+{\r
+  UINTN             Index;\r
+\r
+  //\r
+  // Sanity Check\r
+  //\r
+  if (Size > MAX_ADDRESS) {\r
+    DEBUG ((EFI_D_ERROR, "ERROR: Size(0x%lx) > MAX_ADDRESS\n", Size));\r
+    return FALSE;\r
+  }\r
+\r
+  //\r
+  // Sanity Check\r
+  //\r
+  if (Address > (MAX_ADDRESS - Size)) {\r
+    DEBUG ((EFI_D_ERROR, "ERROR: Address(0x%lx) > (MAX_ADDRESS - Size(0x%lx))\n", Address, Size));\r
+    return FALSE;\r
+  }\r
+\r
+  if (MemoryResource == NULL) {\r
+    //\r
+    // No memory resource descriptor reported in HOB list before capsule Coalesce.\r
+    //\r
+    return TRUE;\r
+  }\r
+\r
+  for (Index = 0; MemoryResource[Index].ResourceLength != 0; Index++) {\r
+    if ((Address >= MemoryResource[Index].PhysicalStart) &&\r
+        ((Address + Size) <= (MemoryResource[Index].PhysicalStart + MemoryResource[Index].ResourceLength))) {\r
+      DEBUG ((EFI_D_INFO, "Address(0x%lx) Size(0x%lx) in MemoryResource[0x%x] - Start(0x%lx) Length(0x%lx)\n",\r
+                          Address, Size,\r
+                          Index, MemoryResource[Index].PhysicalStart, MemoryResource[Index].ResourceLength));\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  DEBUG ((EFI_D_ERROR, "ERROR: Address(0x%lx) Size(0x%lx) not in any MemoryResource\n", Address, Size));\r
+  return FALSE;\r
+}\r
+\r
 /**\r
   Check the integrity of the capsule descriptors.\r
 \r
-  @param BlockList    Pointer to the capsule descriptors\r
+  @param BlockList       Pointer to the capsule descriptors\r
+  @param MemoryResource  Pointer to the buffer of memory resource descriptor.\r
 \r
   @retval NULL           BlockList is not valid.\r
   @retval LastBlockDesc  Last one Block in BlockList\r
@@ -258,7 +303,8 @@ FindFreeMem (
 **/\r
 EFI_CAPSULE_BLOCK_DESCRIPTOR *\r
 ValidateCapsuleIntegrity (\r
-  IN EFI_CAPSULE_BLOCK_DESCRIPTOR    *BlockList\r
+  IN EFI_CAPSULE_BLOCK_DESCRIPTOR    *BlockList,\r
+  IN MEMORY_RESOURCE_DESCRIPTOR      *MemoryResource\r
   )\r
 {\r
   EFI_CAPSULE_HEADER             *CapsuleHeader;\r
@@ -274,14 +320,19 @@ ValidateCapsuleIntegrity (
   //   * The first capsule header guid\r
   //   * The first capsule header flag\r
   //   * The first capsule header HeaderSize\r
-  //   * Length > MAX_ADDRESS\r
-  //   * ContinuationPointer > MAX_ADDRESS\r
-  //   * DataBlock + Length > MAX_ADDRESS\r
+  //   * Below check will be done in ValidateCapsuleByMemoryResource()\r
+  //     Length > MAX_ADDRESS \r
+  //     Ptr + sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR) > MAX_ADDRESS\r
+  //     DataBlock + Length > MAX_ADDRESS\r
   //\r
   CapsuleSize  = 0;\r
   CapsuleCount = 0;\r
   Ptr = BlockList;\r
 \r
+  if (!ValidateCapsuleByMemoryResource (MemoryResource, (EFI_PHYSICAL_ADDRESS) (UINTN) Ptr, sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR))) {\r
+    return NULL;\r
+  }\r
+\r
   DEBUG ((EFI_D_INFO, "Ptr - 0x%x\n", Ptr));\r
   DEBUG ((EFI_D_INFO, "Ptr->Length - 0x%x\n", Ptr->Length));\r
   DEBUG ((EFI_D_INFO, "Ptr->Union - 0x%x\n", Ptr->Union.ContinuationPointer));\r
@@ -293,36 +344,21 @@ ValidateCapsuleIntegrity (
       DEBUG ((EFI_D_ERROR, "ERROR: BlockList address failed alignment check\n"));\r
       return NULL;\r
     }\r
-    //\r
-    // Sanity Check\r
-    //\r
-    if (Ptr->Length > MAX_ADDRESS) {\r
-      DEBUG ((EFI_D_ERROR, "ERROR: Ptr->Length(0x%lx) > MAX_ADDRESS\n", Ptr->Length));\r
-      return NULL;\r
-    }\r
 \r
     if (Ptr->Length == 0) {\r
-      //\r
-      // Sanity Check\r
-      //\r
-      if (Ptr->Union.ContinuationPointer > MAX_ADDRESS) {\r
-        DEBUG ((EFI_D_ERROR, "ERROR: Ptr->Union.ContinuationPointer(0x%lx) > MAX_ADDRESS\n", Ptr->Union.ContinuationPointer));\r
-        return NULL;\r
-      }\r
       //\r
       // Descriptor points to another list of block descriptors somewhere\r
       // else.\r
       //\r
       Ptr = (EFI_CAPSULE_BLOCK_DESCRIPTOR  *) (UINTN) Ptr->Union.ContinuationPointer;\r
+      if (!ValidateCapsuleByMemoryResource (MemoryResource, (EFI_PHYSICAL_ADDRESS) (UINTN) Ptr, sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR))) {\r
+        return NULL;\r
+      }\r
       DEBUG ((EFI_D_INFO, "Ptr(C) - 0x%x\n", Ptr));\r
       DEBUG ((EFI_D_INFO, "Ptr->Length - 0x%x\n", Ptr->Length));\r
       DEBUG ((EFI_D_INFO, "Ptr->Union - 0x%x\n", Ptr->Union.ContinuationPointer));\r
     } else {\r
-      //\r
-      // Sanity Check\r
-      //\r
-      if (Ptr->Union.DataBlock > (MAX_ADDRESS - (UINTN)Ptr->Length)) {\r
-        DEBUG ((EFI_D_ERROR, "ERROR: Ptr->Union.DataBlock(0x%lx) > (MAX_ADDRESS - (UINTN)Ptr->Length(0x%lx))\n", Ptr->Union.DataBlock, Ptr->Length));\r
+      if (!ValidateCapsuleByMemoryResource (MemoryResource, Ptr->Union.DataBlock, Ptr->Length)) {\r
         return NULL;\r
       }\r
 \r
@@ -370,6 +406,9 @@ ValidateCapsuleIntegrity (
       // Move to next BLOCK descriptor\r
       //\r
       Ptr++;\r
+      if (!ValidateCapsuleByMemoryResource (MemoryResource, (EFI_PHYSICAL_ADDRESS) (UINTN) Ptr, sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR))) {\r
+        return NULL;\r
+      }\r
       DEBUG ((EFI_D_INFO, "Ptr(B) - 0x%x\n", Ptr));\r
       DEBUG ((EFI_D_INFO, "Ptr->Length - 0x%x\n", Ptr->Length));\r
       DEBUG ((EFI_D_INFO, "Ptr->Union - 0x%x\n", Ptr->Union.ContinuationPointer));\r
@@ -816,6 +855,7 @@ CapsuleTestPatternPreCoalesce (
   Get capsule descriptors from variable CapsuleUpdateData, CapsuleUpdateData1, CapsuleUpdateData2...\r
 \r
   @param BlockListBuffer            Pointer to the buffer of capsule descriptors variables\r
+  @param MemoryResource             Pointer to the buffer of memory resource descriptor.\r
   @param BlockDescriptorList        Pointer to the capsule descriptors list\r
 \r
   @retval EFI_SUCCESS               a valid capsule is present\r
@@ -824,6 +864,7 @@ CapsuleTestPatternPreCoalesce (
 EFI_STATUS\r
 BuildCapsuleDescriptors (\r
   IN  EFI_PHYSICAL_ADDRESS            *BlockListBuffer,\r
+  IN  MEMORY_RESOURCE_DESCRIPTOR      *MemoryResource,\r
   OUT EFI_CAPSULE_BLOCK_DESCRIPTOR    **BlockDescriptorList \r
   )\r
 {\r
@@ -844,7 +885,7 @@ BuildCapsuleDescriptors (
     // Test integrity of descriptors.\r
     //\r
     if (BlockListBuffer[Index] < MAX_ADDRESS) {\r
-      TempBlock = ValidateCapsuleIntegrity ((EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)BlockListBuffer[Index]);\r
+      TempBlock = ValidateCapsuleIntegrity ((EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)BlockListBuffer[Index], MemoryResource);\r
       if (TempBlock != NULL) {\r
         if (LastBlock == NULL) {\r
           LastBlock = TempBlock;\r
@@ -928,7 +969,8 @@ CapsuleImageBase-->+---------------------------+
   coalesce capsule data into memory.\r
 \r
   @param PeiServices        General purpose services available to every PEIM.\r
-  @param BlockListBuffer    Point to the buffer of Capsule Descriptor Variables.\r
+  @param BlockListBuffer    Pointer to the buffer of Capsule Descriptor Variables.\r
+  @param MemoryResource     Pointer to the buffer of memory resource descriptor.\r
   @param MemoryBase         Pointer to the base of a block of memory that we can walk\r
                             all over while trying to coalesce our buffers.\r
                             On output, this variable will hold the base address of\r
@@ -950,6 +992,7 @@ EFIAPI
 CapsuleDataCoalesce (\r
   IN EFI_PEI_SERVICES                **PeiServices,\r
   IN EFI_PHYSICAL_ADDRESS            *BlockListBuffer,\r
+  IN MEMORY_RESOURCE_DESCRIPTOR      *MemoryResource,\r
   IN OUT VOID                        **MemoryBase,\r
   IN OUT UINTN                       *MemorySize\r
   )\r
@@ -994,7 +1037,7 @@ CapsuleDataCoalesce (
   //\r
   // Build capsule descriptors list\r
   //\r
-  Status = BuildCapsuleDescriptors (BlockListBuffer, &BlockList);\r
+  Status = BuildCapsuleDescriptors (BlockListBuffer, MemoryResource, &BlockList);\r
   if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
index 6210d2133ebc3baa25fdb9d3a7fc76e4c1ee86c5..7298874f9e629e92d89aca56d3d4d45ed4f847a5 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Common header file.\r
 \r
-Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -35,6 +35,17 @@ typedef struct {
 } EFI_CAPSULE_PEIM_PRIVATE_DATA;\r
 #pragma pack()\r
 \r
+typedef struct {\r
+  ///\r
+  /// The physical start address of the resource region.\r
+  ///\r
+  EFI_PHYSICAL_ADDRESS        PhysicalStart;\r
+  ///\r
+  /// The number of bytes of the resource region.\r
+  ///\r
+  UINT64                      ResourceLength;\r
+} MEMORY_RESOURCE_DESCRIPTOR;\r
+\r
 #define CAPSULE_TEST_SIGNATURE SIGNATURE_32('T', 'E', 'S', 'T')\r
 \r
 #if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)\r
@@ -45,6 +56,7 @@ typedef struct {
   UINT64                StackBufferLength;\r
   EFI_PHYSICAL_ADDRESS  JumpBuffer;\r
   EFI_PHYSICAL_ADDRESS  BlockListAddr;\r
+  EFI_PHYSICAL_ADDRESS  MemoryResource;\r
   EFI_PHYSICAL_ADDRESS  MemoryBase64Ptr;\r
   EFI_PHYSICAL_ADDRESS  MemorySize64Ptr;\r
   BOOLEAN               Page1GSupport;\r
@@ -71,6 +83,7 @@ typedef struct {
 \r
   @param PeiServices        General purpose services available to every PEIM.\r
   @param BlockListBuffer    Point to the buffer of Capsule Descriptor Variables.\r
+  @param MemoryResource     Pointer to the buffer of memory resource descriptor.\r
   @param MemoryBase         Pointer to the base of a block of memory that we can walk\r
                             all over while trying to coalesce our buffers.\r
                             On output, this variable will hold the base address of\r
@@ -94,7 +107,8 @@ EFI_STATUS
 EFIAPI\r
 CapsuleDataCoalesce (\r
   IN EFI_PEI_SERVICES                **PeiServices,\r
-  IN IN EFI_PHYSICAL_ADDRESS         *BlockListBuffer,\r
+  IN EFI_PHYSICAL_ADDRESS            *BlockListBuffer,\r
+  IN MEMORY_RESOURCE_DESCRIPTOR      *MemoryResource,\r
   IN OUT VOID                        **MemoryBase,\r
   IN OUT UINTN                       *MemorySize\r
   );\r
index befd803af17b82f4261b778f4c0d6c50ed79ba6b..e60105b31caa69d719565fa3f0a89f3093059a83 100644 (file)
@@ -354,6 +354,7 @@ Thunk32To64 (
   @param  LongModeBuffer            The context of long mode.\r
   @param  CoalesceEntry             Entry of coalesce image.\r
   @param  BlockListAddr             Address of block list.\r
+  @param  MemoryResource            Pointer to the buffer of memory resource descriptor.\r
   @param  MemoryBase                Base of memory range.\r
   @param  MemorySize                Size of memory range.\r
 \r
@@ -366,6 +367,7 @@ ModeSwitch (
   IN EFI_CAPSULE_LONG_MODE_BUFFER   *LongModeBuffer,\r
   IN COALESCE_ENTRY                 CoalesceEntry,\r
   IN EFI_PHYSICAL_ADDRESS           BlockListAddr,\r
+  IN MEMORY_RESOURCE_DESCRIPTOR     *MemoryResource,\r
   IN OUT VOID                       **MemoryBase,\r
   IN OUT UINTN                      *MemorySize\r
   )\r
@@ -429,6 +431,7 @@ ModeSwitch (
   Context.StackBufferLength     = LongModeBuffer->StackSize;\r
   Context.EntryPoint            = (EFI_PHYSICAL_ADDRESS)(UINTN)CoalesceEntry;\r
   Context.BlockListAddr         = BlockListAddr;\r
+  Context.MemoryResource        = (EFI_PHYSICAL_ADDRESS)(UINTN)MemoryResource;\r
   Context.MemoryBase64Ptr       = (EFI_PHYSICAL_ADDRESS)(UINTN)&MemoryBase64;\r
   Context.MemorySize64Ptr       = (EFI_PHYSICAL_ADDRESS)(UINTN)&MemorySize64;\r
   Context.Page1GSupport         = Page1GSupport;\r
@@ -560,6 +563,133 @@ GetLongModeContext (
 }\r
 #endif\r
 \r
+#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)\r
+/**\r
+  Get physical address bits.\r
+\r
+  @return Physical address bits.\r
+\r
+**/\r
+UINT8\r
+GetPhysicalAddressBits (\r
+  VOID\r
+  )\r
+{\r
+  UINT32                        RegEax;\r
+  UINT8                         PhysicalAddressBits;\r
+  VOID                          *Hob;\r
+\r
+  //\r
+  // Get physical address bits supported.\r
+  //\r
+  Hob = GetFirstHob (EFI_HOB_TYPE_CPU);\r
+  if (Hob != NULL) {\r
+    PhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace;\r
+  } else {\r
+    AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);\r
+    if (RegEax >= 0x80000008) {\r
+      AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);\r
+      PhysicalAddressBits = (UINT8) RegEax;\r
+    } else {\r
+      PhysicalAddressBits = 36;\r
+    }\r
+  }\r
+\r
+  //\r
+  // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses.\r
+  //\r
+  ASSERT (PhysicalAddressBits <= 52);\r
+  if (PhysicalAddressBits > 48) {\r
+    PhysicalAddressBits = 48;\r
+  }\r
+\r
+  return PhysicalAddressBits;\r
+}\r
+#endif\r
+\r
+/**\r
+  Build memory resource descriptor from resource descriptor in HOB list.\r
+\r
+  @return Pointer to the buffer of memory resource descriptor.\r
+          NULL if no memory resource descriptor reported in HOB list\r
+          before capsule Coalesce.\r
+\r
+**/\r
+MEMORY_RESOURCE_DESCRIPTOR *\r
+BuildMemoryResourceDescriptor (\r
+  VOID\r
+  )\r
+{\r
+  EFI_PEI_HOB_POINTERS          Hob;\r
+  UINTN                         Index;\r
+  EFI_HOB_RESOURCE_DESCRIPTOR   *ResourceDescriptor;\r
+  MEMORY_RESOURCE_DESCRIPTOR    *MemoryResource;\r
+  EFI_STATUS                    Status;\r
+\r
+  //\r
+  // Get the count of memory resource descriptor.\r
+  //\r
+  Index = 0;\r
+  Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);\r
+  while (Hob.Raw != NULL) {\r
+    ResourceDescriptor = (EFI_HOB_RESOURCE_DESCRIPTOR *) Hob.Raw;\r
+    if (ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {\r
+      Index++;\r
+    }\r
+    Hob.Raw = GET_NEXT_HOB (Hob);\r
+    Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);\r
+  }\r
+\r
+  if (Index == 0) {\r
+    DEBUG ((EFI_D_INFO | EFI_D_WARN, "No memory resource descriptor reported in HOB list before capsule Coalesce\n"));\r
+#if defined (MDE_CPU_IA32) || defined (MDE_CPU_X64)\r
+    //\r
+    // Allocate memory to hold memory resource descriptor,\r
+    // include extra one NULL terminate memory resource descriptor.\r
+    //\r
+    Status = PeiServicesAllocatePool ((1 + 1) * sizeof (MEMORY_RESOURCE_DESCRIPTOR), (VOID **) &MemoryResource);\r
+    ASSERT_EFI_ERROR (Status);\r
+    ZeroMem (MemoryResource, (1 + 1) * sizeof (MEMORY_RESOURCE_DESCRIPTOR));\r
+  \r
+    MemoryResource[0].PhysicalStart = 0;\r
+    MemoryResource[0].ResourceLength = LShiftU64 (1, GetPhysicalAddressBits ());\r
+    DEBUG ((EFI_D_INFO, "MemoryResource[0x0] - Start(0x%0lx) Length(0x%0lx)\n",\r
+                        MemoryResource[0x0].PhysicalStart, MemoryResource[0x0].ResourceLength));\r
+    return MemoryResource;\r
+#else\r
+    return NULL;\r
+#endif\r
+  }\r
+\r
+  //\r
+  // Allocate memory to hold memory resource descriptor,\r
+  // include extra one NULL terminate memory resource descriptor.\r
+  //\r
+  Status = PeiServicesAllocatePool ((Index + 1) * sizeof (MEMORY_RESOURCE_DESCRIPTOR), (VOID **) &MemoryResource);\r
+  ASSERT_EFI_ERROR (Status);\r
+  ZeroMem (MemoryResource, (Index + 1) * sizeof (MEMORY_RESOURCE_DESCRIPTOR));\r
+\r
+  //\r
+  // Get the content of memory resource descriptor.\r
+  //\r
+  Index = 0;\r
+  Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);\r
+  while (Hob.Raw != NULL) {\r
+    ResourceDescriptor = (EFI_HOB_RESOURCE_DESCRIPTOR *) Hob.Raw;\r
+    if (ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {\r
+      DEBUG ((EFI_D_INFO, "MemoryResource[0x%x] - Start(0x%0lx) Length(0x%0lx)\n",\r
+                          Index, ResourceDescriptor->PhysicalStart, ResourceDescriptor->ResourceLength));\r
+      MemoryResource[Index].PhysicalStart = ResourceDescriptor->PhysicalStart;\r
+      MemoryResource[Index].ResourceLength = ResourceDescriptor->ResourceLength;\r
+      Index++;\r
+    }\r
+    Hob.Raw = GET_NEXT_HOB (Hob);\r
+    Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);\r
+  }\r
+\r
+  return MemoryResource;\r
+}\r
+\r
 /**\r
   Checks for the presence of capsule descriptors.\r
   Get capsule descriptors from variable CapsuleUpdateData, CapsuleUpdateData1, CapsuleUpdateData2...\r
@@ -711,6 +841,7 @@ CapsuleCoalesce (
   EFI_BOOT_MODE                        BootMode;\r
   EFI_PEI_READ_ONLY_VARIABLE2_PPI      *PPIVariableServices;\r
   EFI_PHYSICAL_ADDRESS                 *VariableArrayAddress;\r
+  MEMORY_RESOURCE_DESCRIPTOR           *MemoryResource;\r
 #ifdef MDE_CPU_IA32\r
   UINT16                               CoalesceImageMachineType;\r
   EFI_PHYSICAL_ADDRESS                 CoalesceImageEntryPoint;\r
@@ -800,6 +931,8 @@ CapsuleCoalesce (
     goto Done;\r
   }\r
 \r
+  MemoryResource = BuildMemoryResourceDescriptor ();\r
+\r
 #ifdef MDE_CPU_IA32\r
   if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {\r
     //\r
@@ -825,18 +958,18 @@ CapsuleCoalesce (
     }\r
     ASSERT (CoalesceImageEntryPoint != 0);\r
     CoalesceEntry = (COALESCE_ENTRY) (UINTN) CoalesceImageEntryPoint;\r
-    Status = ModeSwitch (&LongModeBuffer, CoalesceEntry, (EFI_PHYSICAL_ADDRESS)(UINTN)VariableArrayAddress, MemoryBase, MemorySize);\r
+    Status = ModeSwitch (&LongModeBuffer, CoalesceEntry, (EFI_PHYSICAL_ADDRESS)(UINTN)VariableArrayAddress, MemoryResource, MemoryBase, MemorySize);\r
   } else {\r
     //\r
     // Capsule is processed in IA32 mode.\r
     //\r
-    Status = CapsuleDataCoalesce (PeiServices, (EFI_PHYSICAL_ADDRESS *)(UINTN)VariableArrayAddress, MemoryBase, MemorySize);\r
+    Status = CapsuleDataCoalesce (PeiServices, (EFI_PHYSICAL_ADDRESS *)(UINTN)VariableArrayAddress, MemoryResource, MemoryBase, MemorySize);\r
   }\r
 #else\r
   //\r
   // Process capsule directly.\r
   //\r
-  Status = CapsuleDataCoalesce (PeiServices, (EFI_PHYSICAL_ADDRESS *)(UINTN)VariableArrayAddress, MemoryBase, MemorySize);\r
+  Status = CapsuleDataCoalesce (PeiServices, (EFI_PHYSICAL_ADDRESS *)(UINTN)VariableArrayAddress, MemoryResource, MemoryBase, MemorySize);\r
 #endif\r
   \r
   DEBUG ((EFI_D_INFO, "Capsule Coalesce Status = %r!\n", Status));\r
index 670e2c7d5ff85c5a657aef248be5c00c8e0f6875..d1042e30efb11c1585edab88c763af487ef66a8a 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   The X64 entrypoint is used to process capsule in long mode.\r
 \r
-Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials\r
 are licensed and made available under the terms and conditions of the BSD License\r
 which accompanies this distribution.  The full text of the license may be found at\r
@@ -258,6 +258,7 @@ _ModuleEntryPoint (
   Status = CapsuleDataCoalesce (\r
              NULL,\r
              (EFI_PHYSICAL_ADDRESS *) (UINTN) EntrypointContext->BlockListAddr,\r
+             (MEMORY_RESOURCE_DESCRIPTOR *) (UINTN) EntrypointContext->MemoryResource,\r
              (VOID **) (UINTN) EntrypointContext->MemoryBase64Ptr,\r
              (UINTN *) (UINTN) EntrypointContext->MemorySize64Ptr\r
              );\r