\r
**/\r
\r
-#include <PeiMain.h>\r
+#include "PeiMain.h"\r
\r
/**\r
\r
Initialize the memory services.\r
\r
-\r
- @param PrivateData Add parameter description\r
+ @param PrivateData Points to PeiCore's private instance data.\r
@param SecCoreData Points to a data structure containing information about the PEI core's operating\r
environment, such as the size and location of temporary RAM, the stack location and\r
the BFV location.\r
)\r
{\r
\r
- PrivateData->SwitchStackSignal = FALSE;\r
+ PrivateData->SwitchStackSignal = FALSE;\r
\r
//\r
// First entering PeiCore, following code will initialized some field\r
if (OldCoreData == NULL) {\r
\r
PrivateData->PeiMemoryInstalled = FALSE;\r
-\r
- PrivateData->BottomOfCarHeap = SecCoreData->PeiTemporaryRamBase; \r
- PrivateData->TopOfCarHeap = (VOID *)((UINTN)(PrivateData->BottomOfCarHeap) + SecCoreData->PeiTemporaryRamSize);\r
- PrivateData->SizeOfTemporaryMemory = SecCoreData->TemporaryRamSize;\r
- PrivateData->StackSize = (UINT64) SecCoreData->StackSize;\r
- \r
- DEBUG_CODE_BEGIN ();\r
- PrivateData->SizeOfCacheAsRam = SecCoreData->PeiTemporaryRamSize + SecCoreData->StackSize;\r
- PrivateData->MaxTopOfCarHeap = (VOID *) ((UINTN) PrivateData->BottomOfCarHeap + (UINTN) PrivateData->SizeOfCacheAsRam);\r
- PrivateData->StackBase = (EFI_PHYSICAL_ADDRESS) (UINTN) SecCoreData->StackBase;\r
- PrivateData->StackSize = (UINT64) SecCoreData->StackSize;\r
- DEBUG_CODE_END ();\r
-\r
- PrivateData->HobList.Raw = PrivateData->BottomOfCarHeap;\r
+ PrivateData->HobList.Raw = SecCoreData->PeiTemporaryRamBase;\r
\r
PeiCoreBuildHobHandoffInfoTable (\r
BOOT_WITH_FULL_CONFIGURATION,\r
- (EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData->BottomOfCarHeap,\r
+ (EFI_PHYSICAL_ADDRESS) (UINTN) SecCoreData->PeiTemporaryRamBase,\r
(UINTN) SecCoreData->PeiTemporaryRamSize\r
);\r
\r
\r
/**\r
\r
- Install the permanent memory is now available.\r
- Creates HOB (PHIT and Stack).\r
+ This function registers the found memory configuration with the PEI Foundation.\r
\r
+ The usage model is that the PEIM that discovers the permanent memory shall invoke this service.\r
+ This routine will hold discoveried memory information into PeiCore's private data,\r
+ and set SwitchStackSignal flag. After PEIM who discovery memory is dispatched,\r
+ PeiDispatcher will migrate temporary memory to permenement memory.\r
+ \r
@param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
@param MemoryBegin Start of memory address.\r
@param MemoryLength Length of memory.\r
DEBUG ((EFI_D_INFO, "PeiInstallPeiMemory MemoryBegin 0x%LX, MemoryLength 0x%LX\n", MemoryBegin, MemoryLength));\r
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
\r
+ //\r
+ // PEI_SERVICE.InstallPeiMemory should only be called one time during whole PEI phase.\r
+ // If it is invoked more than one time, ASSERT information is given for developer debugging in debug tip and\r
+ // simply return EFI_SUCESS in release tip to ignore it.\r
+ // \r
+ if (PrivateData->PeiMemoryInstalled) {\r
+ DEBUG ((EFI_D_ERROR, "ERROR: PeiInstallPeiMemory is called more than once!\n"));\r
+ ASSERT (PrivateData->PeiMemoryInstalled);\r
+ return EFI_SUCCESS;\r
+ }\r
+ \r
PrivateData->PhysicalMemoryBegin = MemoryBegin;\r
PrivateData->PhysicalMemoryLength = MemoryLength;\r
PrivateData->FreePhysicalMemoryTop = MemoryBegin + MemoryLength;\r
@param Memory Pointer of memory allocated.\r
\r
@retval EFI_SUCCESS The allocation was successful\r
- @retval EFI_INVALID_PARAMETER Only AllocateAnyAddress is supported.\r
@retval EFI_NOT_AVAILABLE_YET Called with permanent memory not available\r
@retval EFI_OUT_OF_RESOURCES There is not enough HOB heap to satisfy the requirement\r
to allocate the number of pages.\r
EFI_STATUS\r
EFIAPI\r
PeiAllocatePages (\r
- IN CONST EFI_PEI_SERVICES **PeiServices,\r
- IN EFI_MEMORY_TYPE MemoryType,\r
- IN UINTN Pages,\r
- OUT EFI_PHYSICAL_ADDRESS *Memory\r
+ IN CONST EFI_PEI_SERVICES **PeiServices,\r
+ IN EFI_MEMORY_TYPE MemoryType,\r
+ IN UINTN Pages,\r
+ OUT EFI_PHYSICAL_ADDRESS *Memory\r
)\r
{\r
PEI_CORE_INSTANCE *PrivateData;\r
EFI_PEI_HOB_POINTERS Hob;\r
- EFI_PHYSICAL_ADDRESS Offset;\r
EFI_PHYSICAL_ADDRESS *FreeMemoryTop;\r
EFI_PHYSICAL_ADDRESS *FreeMemoryBottom;\r
+ UINTN RemainingPages;\r
\r
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
Hob.Raw = PrivateData->HobList.Raw;\r
if (!PrivateData->PeiMemoryInstalled) {\r
//\r
// When PeiInstallMemory is called but CAR has *not* been moved to temporary memory,\r
- // the AllocatePage will dependent the field of PEI_CORE_INSTANCE structure.\r
+ // the AllocatePage will depend on the field of PEI_CORE_INSTANCE structure.\r
//\r
if (!PrivateData->SwitchStackSignal) {\r
return EFI_NOT_AVAILABLE_YET;\r
}\r
\r
//\r
- // Check to see if on 4k boundary\r
+ // Check to see if on 4k boundary, If not aligned, make the allocation aligned.\r
//\r
- Offset = *(FreeMemoryTop) & 0xFFF;\r
+ *(FreeMemoryTop) -= *(FreeMemoryTop) & 0xFFF;\r
\r
//\r
- // If not aligned, make the allocation aligned.\r
+ // Verify that there is sufficient memory to satisfy the allocation\r
//\r
- if (Offset != 0) {\r
- *(FreeMemoryTop) -= Offset;\r
- }\r
- \r
+ RemainingPages = EFI_SIZE_TO_PAGES ((UINTN) (*FreeMemoryTop - *FreeMemoryBottom));\r
//\r
- // Verify that there is sufficient memory to satisfy the allocation\r
+ // For page allocation, the overhead sizeof (EFI_HOB_MEMORY_ALLOCATION) needs one extra page.\r
+ // So the number of remaining pages needs to be greater than that of the request pages.\r
//\r
- if (*(FreeMemoryTop) - ((Pages * EFI_PAGE_SIZE) + sizeof (EFI_HOB_MEMORY_ALLOCATION)) < \r
- *(FreeMemoryBottom)) {\r
- DEBUG ((EFI_D_ERROR, "AllocatePages failed: No 0x%x Pages is available.\n", Pages));\r
- DEBUG ((EFI_D_ERROR, "There is only left 0x%x pages memory resource to be allocated.\n", \\r
- EFI_SIZE_TO_PAGES ((UINTN) (*(FreeMemoryTop) - *(FreeMemoryBottom)))));\r
+ if (RemainingPages <= Pages) {\r
+ DEBUG ((EFI_D_ERROR, "AllocatePages failed: No 0x%lx Pages is available.\n", (UINT64) Pages));\r
+ DEBUG ((EFI_D_ERROR, "There is only left 0x%lx pages memory resource to be allocated.\n", (UINT64) RemainingPages));\r
return EFI_OUT_OF_RESOURCES;\r
} else {\r
//\r
\r
/**\r
\r
- Memory allocation service on the CAR.\r
+ Pool allocation service. Before permenent memory is discoveried, the pool will \r
+ be allocated the heap in the CAR. Genenrally, the size of heap in temporary \r
+ memory does not exceed to 64K, so the biggest pool size could be allocated is \r
+ 64K.\r
\r
-\r
- @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
- @param Size Amount of memory required\r
- @param Buffer Address of pointer to the buffer\r
+ @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
+ @param Size Amount of memory required\r
+ @param Buffer Address of pointer to the buffer\r
\r
@retval EFI_SUCCESS The allocation was successful\r
@retval EFI_OUT_OF_RESOURCES There is not enough heap to satisfy the requirement\r
EFI_STATUS\r
EFIAPI\r
PeiAllocatePool (\r
- IN CONST EFI_PEI_SERVICES **PeiServices,\r
- IN UINTN Size,\r
- OUT VOID **Buffer\r
+ IN CONST EFI_PEI_SERVICES **PeiServices,\r
+ IN UINTN Size,\r
+ OUT VOID **Buffer\r
)\r
{\r
EFI_STATUS Status;\r
EFI_HOB_MEMORY_POOL *Hob;\r
\r
- //\r
- // If some "post-memory" PEIM wishes to allocate larger pool,\r
- // it should use AllocatePages service instead.\r
- //\r
- ASSERT (Size < 0x10000 - sizeof (EFI_HOB_MEMORY_POOL));\r
- Status = PeiServicesCreateHob (\r
+ //\r
+ // If some "post-memory" PEIM wishes to allocate larger pool,\r
+ // it should use AllocatePages service instead.\r
+ //\r
+ \r
+ //\r
+ // Generally, the size of heap in temporary memory does not exceed to 64K,\r
+ // so the maxmium size of pool is 0x10000 - sizeof (EFI_HOB_MEMORY_POOL)\r
+ //\r
+ ASSERT (Size < 0x10000 - sizeof (EFI_HOB_MEMORY_POOL));\r
+ Status = PeiServicesCreateHob (\r
EFI_HOB_TYPE_MEMORY_POOL,\r
(UINT16)(sizeof (EFI_HOB_MEMORY_POOL) + Size),\r
(VOID **)&Hob\r
);\r
*Buffer = Hob+1; \r
\r
-\r
return Status;\r
}\r