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