mirror of https://github.com/acidanthera/audk.git
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>
This commit is contained in:
parent
ed3ff1acb4
commit
359cb1a3b9
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -59,20 +59,6 @@ FindFreeMem (
|
|||
UINTN DataSize
|
||||
);
|
||||
|
||||
/**
|
||||
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
|
||||
|
@ -247,10 +233,69 @@ FindFreeMem (
|
|||
return MemBase;
|
||||
}
|
||||
|
||||
/**
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue