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
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
**/\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
// * 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
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
// 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
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
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
// 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
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
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
//\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