//\r
// Go ahead to scan this Fv, and cache FileHandles within it.\r
//\r
- for (PeimCount = 0; PeimCount < PcdGet32 (PcdPeiCoreMaxPeimPerFv); PeimCount++) {\r
+ for (PeimCount = 0; PeimCount < FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv); PeimCount++) {\r
Status = FvPpi->FindFileByType (FvPpi, PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE, CoreFileHandle->FvHandle, &FileHandle);\r
if (Status != EFI_SUCCESS) {\r
break;\r
// Check whether the count of Peims exceeds the max support PEIMs in a FV image\r
// If more Peims are required in a FV image, PcdPeiCoreMaxPeimPerFv can be set to a larger value in DSC file.\r
//\r
- ASSERT (PeimCount < PcdGet32 (PcdPeiCoreMaxPeimPerFv));\r
+ ASSERT (PeimCount < FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv));\r
\r
//\r
// Get Apriori File handle\r
//\r
return (VOID*) ((UINTN) EntryPoint + (UINTN) PeiCore - (UINTN) _ModuleEntryPoint);\r
}\r
+//\r
+// This is the minimum memory required by DxeCore initialization. When LMFA feature enabled,\r
+// This part of memory still need reserved on the very top of memory so that the DXE Core could \r
+// use these memory for data initialization. This macro should be sync with the same marco\r
+// defined in DXE Core.\r
+//\r
+#define MINIMUM_INITIAL_MEMORY_SIZE 0x10000\r
+/**\r
+ Hook function for Loading Module at Fixed Address feature\r
+ \r
+ This function should only be invoked when Loading Module at Fixed Address(LMFA) feature is enabled. When feature is\r
+ configured as Load Modules at Fix Absolute Address, this function is to validate the top address assigned by user. When \r
+ feature is configured as Load Modules at Fixed Offset, the functino is to find the top address which is TOLM-TSEG in general. \r
+ And also the function will re-install PEI memory. \r
+\r
+ @param PrivateData Pointer to the private data passed in from caller\r
+\r
+**/\r
+VOID\r
+PeiLoadFixAddressHook(\r
+ IN PEI_CORE_INSTANCE *PrivateData\r
+ )\r
+{\r
+ EFI_PHYSICAL_ADDRESS TopLoadingAddress;\r
+ UINT64 PeiMemorySize;\r
+ UINT64 TotalReservedMemorySize;\r
+ UINT64 MemoryRangeEnd;\r
+ EFI_PHYSICAL_ADDRESS HighAddress; \r
+ EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;\r
+ EFI_HOB_RESOURCE_DESCRIPTOR *NextResourceHob;\r
+ EFI_HOB_RESOURCE_DESCRIPTOR *CurrentResourceHob;\r
+ EFI_PEI_HOB_POINTERS CurrentHob;\r
+ EFI_PEI_HOB_POINTERS Hob;\r
+ EFI_PEI_HOB_POINTERS NextHob;\r
+ EFI_PHYSICAL_ADDRESS MaxMemoryBaseAddress;\r
+ UINT64 MaxMemoryLength;\r
+ //\r
+ // Initialize Local Variables\r
+ //\r
+ CurrentResourceHob = NULL;\r
+ ResourceHob = NULL;\r
+ NextResourceHob = NULL;\r
+ MaxMemoryBaseAddress = 0;\r
+ MaxMemoryLength = 0;\r
+ HighAddress = 0;\r
+ TopLoadingAddress = 0;\r
+ MemoryRangeEnd = 0;\r
+ CurrentHob.Raw = PrivateData->HobList.Raw;\r
+ PeiMemorySize = PrivateData->PhysicalMemoryLength;\r
+ //\r
+ // The top reserved memory include 3 parts: the topest range is for DXE core initialization with the size MINIMUM_INITIAL_MEMORY_SIZE\r
+ // then RuntimeCodePage range and Boot time code range.\r
+ // \r
+ TotalReservedMemorySize = MINIMUM_INITIAL_MEMORY_SIZE + EFI_PAGES_TO_SIZE(PcdGet32(PcdLoadFixAddressRuntimeCodePageNumber));\r
+ TotalReservedMemorySize+= EFI_PAGES_TO_SIZE(PcdGet32(PcdLoadFixAddressBootTimeCodePageNumber)) ; \r
+ //\r
+ // PEI memory range lies below the top reserved memory\r
+ // \r
+ TotalReservedMemorySize += PeiMemorySize;\r
+ \r
+ DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO: PcdLoadFixAddressRuntimeCodePageNumber= 0x%x.\n", PcdGet32(PcdLoadFixAddressRuntimeCodePageNumber)));\r
+ DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO: PcdLoadFixAddressBootTimeCodePageNumber= 0x%x.\n", PcdGet32(PcdLoadFixAddressBootTimeCodePageNumber)));\r
+ DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO: PcdLoadFixAddressPeiCodePageNumber= 0x%x.\n", PcdGet32(PcdLoadFixAddressPeiCodePageNumber))); \r
+ DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO: Total Reserved Memory Size = 0x%lx.\n", TotalReservedMemorySize));\r
+ //\r
+ // Loop through the system memory typed hob to merge the adjacent memory range \r
+ //\r
+ for (Hob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {\r
+ // \r
+ // See if this is a resource descriptor HOB \r
+ //\r
+ if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {\r
+ \r
+ ResourceHob = Hob.ResourceDescriptor; \r
+ //\r
+ // If range described in this hob is not system memory or heigher than MAX_ADDRESS, ignored.\r
+ //\r
+ if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY &&\r
+ ResourceHob->PhysicalStart + ResourceHob->ResourceLength > MAX_ADDRESS) {\r
+ continue;\r
+ } \r
+ \r
+ for (NextHob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST(NextHob); NextHob.Raw = GET_NEXT_HOB(NextHob)) { \r
+ if (NextHob.Raw == Hob.Raw){\r
+ continue;\r
+ } \r
+ //\r
+ // See if this is a resource descriptor HOB\r
+ //\r
+ if (GET_HOB_TYPE (NextHob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {\r
+ \r
+ NextResourceHob = NextHob.ResourceDescriptor;\r
+ //\r
+ // test if range described in this NextResourceHob is system memory and have the same attribute.\r
+ // Note: Here is a assumption that system memory should always be healthy even without test.\r
+ // \r
+ if (NextResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY &&\r
+ (((NextResourceHob->ResourceAttribute^ResourceHob->ResourceAttribute)&(~EFI_RESOURCE_ATTRIBUTE_TESTED)) == 0)){\r
+ \r
+ //\r
+ // See if the memory range described in ResourceHob and NextResourceHob is adjacent\r
+ //\r
+ if ((ResourceHob->PhysicalStart <= NextResourceHob->PhysicalStart && \r
+ ResourceHob->PhysicalStart + ResourceHob->ResourceLength >= NextResourceHob->PhysicalStart)|| \r
+ (ResourceHob->PhysicalStart >= NextResourceHob->PhysicalStart&&\r
+ ResourceHob->PhysicalStart <= NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength)) {\r
+ \r
+ MemoryRangeEnd = ((ResourceHob->PhysicalStart + ResourceHob->ResourceLength)>(NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength)) ?\r
+ (ResourceHob->PhysicalStart + ResourceHob->ResourceLength):(NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength);\r
+ \r
+ ResourceHob->PhysicalStart = (ResourceHob->PhysicalStart < NextResourceHob->PhysicalStart) ? \r
+ ResourceHob->PhysicalStart : NextResourceHob->PhysicalStart;\r
+ \r
+ \r
+ ResourceHob->ResourceLength = (MemoryRangeEnd - ResourceHob->PhysicalStart);\r
+ \r
+ ResourceHob->ResourceAttribute = ResourceHob->ResourceAttribute & (~EFI_RESOURCE_ATTRIBUTE_TESTED);\r
+ //\r
+ // Delete the NextResourceHob by marking it as unused.\r
+ //\r
+ GET_HOB_TYPE (NextHob) = EFI_HOB_TYPE_UNUSED;\r
+ \r
+ }\r
+ }\r
+ } \r
+ }\r
+ } \r
+ }\r
+ //\r
+ // Try to find and validate the TOP address.\r
+ // \r
+ if ((INT64)PcdGet64(PcdLoadModuleAtFixAddressEnable) > 0 ) {\r
+ //\r
+ // The LMFA feature is enabled as load module at fixed absolute address.\r
+ //\r
+ TopLoadingAddress = (EFI_PHYSICAL_ADDRESS)PcdGet64(PcdLoadModuleAtFixAddressEnable);\r
+ DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO: Loading module at fixed absolute address.\n"));\r
+ //\r
+ // validate the Address. Loop the resource descriptor HOB to make sure the address is in valid memory range\r
+ //\r
+ if ((TopLoadingAddress & EFI_PAGE_MASK) != 0) {\r
+ DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED ERROR:Top Address 0x%lx is invalid since top address should be page align. \n", TopLoadingAddress)); \r
+ ASSERT (FALSE); \r
+ }\r
+ //\r
+ // Search for a memory region that is below MAX_ADDRESS and in which TopLoadingAddress lies \r
+ //\r
+ for (Hob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {\r
+ //\r
+ // See if this is a resource descriptor HOB\r
+ //\r
+ if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {\r
+\r
+ ResourceHob = Hob.ResourceDescriptor;\r
+ //\r
+ // See if this resource descrior HOB describes tested system memory below MAX_ADDRESS\r
+ // \r
+ if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY &&\r
+ ResourceHob->PhysicalStart + ResourceHob->ResourceLength <= MAX_ADDRESS) {\r
+ //\r
+ // See if Top address specified by user is valid.\r
+ //\r
+ if (ResourceHob->PhysicalStart + TotalReservedMemorySize < TopLoadingAddress && \r
+ (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - MINIMUM_INITIAL_MEMORY_SIZE) >= TopLoadingAddress) {\r
+ CurrentResourceHob = ResourceHob; \r
+ CurrentHob = Hob;\r
+ break;\r
+ }\r
+ }\r
+ } \r
+ } \r
+ if (CurrentResourceHob != NULL) {\r
+ DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO:Top Address 0x%lx is valid \n", TopLoadingAddress));\r
+ TopLoadingAddress += MINIMUM_INITIAL_MEMORY_SIZE; \r
+ } else {\r
+ DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED ERROR:Top Address 0x%lx is invalid \n", TopLoadingAddress)); \r
+ DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED ERROR:The recommended Top Address for the platform is: \n")); \r
+ //\r
+ // Print the recomended Top address range.\r
+ // \r
+ for (Hob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {\r
+ //\r
+ // See if this is a resource descriptor HOB\r
+ //\r
+ if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {\r
+ \r
+ ResourceHob = Hob.ResourceDescriptor;\r
+ //\r
+ // See if this resource descrior HOB describes tested system memory below MAX_ADDRESS\r
+ // \r
+ if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY &&\r
+ ResourceHob->PhysicalStart + ResourceHob->ResourceLength <= MAX_ADDRESS) {\r
+ //\r
+ // See if Top address specified by user is valid.\r
+ //\r
+ if (ResourceHob->ResourceLength > TotalReservedMemorySize) {\r
+ DEBUG ((EFI_D_INFO, "(0x%lx, 0x%lx)\n", \r
+ (ResourceHob->PhysicalStart + TotalReservedMemorySize -MINIMUM_INITIAL_MEMORY_SIZE), \r
+ (ResourceHob->PhysicalStart + ResourceHob->ResourceLength -MINIMUM_INITIAL_MEMORY_SIZE) \r
+ )); \r
+ }\r
+ }\r
+ }\r
+ } \r
+ //\r
+ // Assert here \r
+ //\r
+ ASSERT (FALSE); \r
+ } \r
+ } else {\r
+ //\r
+ // The LMFA feature is enabled as load module at fixed offset relative to TOLM\r
+ // Parse the Hob list to find the topest available memory. Generally it is (TOLM - TSEG)\r
+ //\r
+ //\r
+ // Search for a tested memory region that is below MAX_ADDRESS\r
+ //\r
+ for (Hob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {\r
+ //\r
+ // See if this is a resource descriptor HOB \r
+ //\r
+ if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {\r
+ \r
+ ResourceHob = Hob.ResourceDescriptor; \r
+ //\r
+ // See if this resource descrior HOB describes tested system memory below MAX_ADDRESS\r
+ //\r
+ if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY && \r
+ ResourceHob->PhysicalStart + ResourceHob->ResourceLength <= MAX_ADDRESS &&\r
+ ResourceHob->ResourceLength > TotalReservedMemorySize) {\r
+ //\r
+ // See if this is the highest largest system memory region below MaxAddress\r
+ //\r
+ if (ResourceHob->PhysicalStart > HighAddress) {\r
+ CurrentResourceHob = ResourceHob;\r
+ CurrentHob = Hob;\r
+ HighAddress = CurrentResourceHob->PhysicalStart;\r
+ }\r
+ }\r
+ } \r
+ }\r
+ if (CurrentResourceHob == NULL) {\r
+ DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED ERROR:The System Memory is too small\n")); \r
+ //\r
+ // Assert here \r
+ //\r
+ ASSERT (FALSE); \r
+ } else {\r
+ TopLoadingAddress = CurrentResourceHob->PhysicalStart + CurrentResourceHob->ResourceLength ; \r
+ } \r
+ }\r
+ \r
+ if (CurrentResourceHob != NULL) {\r
+ //\r
+ // rebuild hob for PEI memmory and reserved memory\r
+ //\r
+ BuildResourceDescriptorHob (\r
+ EFI_RESOURCE_SYSTEM_MEMORY, // MemoryType,\r
+ (\r
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
+ EFI_RESOURCE_ATTRIBUTE_TESTED |\r
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
+ EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
+ EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
+ EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE\r
+ ),\r
+ (TopLoadingAddress - TotalReservedMemorySize), // MemoryBegin\r
+ TotalReservedMemorySize // MemoryLength\r
+ );\r
+ //\r
+ // rebuild hob for the remain memory if necessary\r
+ //\r
+ if (CurrentResourceHob->PhysicalStart < TopLoadingAddress - TotalReservedMemorySize) {\r
+ BuildResourceDescriptorHob (\r
+ EFI_RESOURCE_SYSTEM_MEMORY, // MemoryType,\r
+ (\r
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
+ EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
+ EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
+ EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE\r
+ ),\r
+ CurrentResourceHob->PhysicalStart, // MemoryBegin\r
+ (TopLoadingAddress - TotalReservedMemorySize - CurrentResourceHob->PhysicalStart) // MemoryLength\r
+ );\r
+ }\r
+ if (CurrentResourceHob->PhysicalStart + CurrentResourceHob->ResourceLength > TopLoadingAddress ) {\r
+ BuildResourceDescriptorHob (\r
+ EFI_RESOURCE_SYSTEM_MEMORY, \r
+ (\r
+ EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
+ EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
+ EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
+ EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
+ EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE\r
+ ),\r
+ TopLoadingAddress, \r
+ (CurrentResourceHob->PhysicalStart + CurrentResourceHob->ResourceLength - TopLoadingAddress) \r
+ );\r
+ }\r
+ //\r
+ // Delete CurrentHob by marking it as unused since the the memory range described by is rebuilt.\r
+ //\r
+ GET_HOB_TYPE (CurrentHob) = EFI_HOB_TYPE_UNUSED; \r
+ }\r
\r
+ //\r
+ // Cache the top address for Loading Module at Fixed Address feature\r
+ //\r
+ PrivateData->LoadModuleAtFixAddressTopAddress = TopLoadingAddress - MINIMUM_INITIAL_MEMORY_SIZE;\r
+ DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO: Top address = 0x%lx\n", PrivateData->LoadModuleAtFixAddressTopAddress)); \r
+ //\r
+ // reinstall the PEI memory relative to TopLoadingAddress\r
+ //\r
+ PrivateData->PhysicalMemoryBegin = TopLoadingAddress - TotalReservedMemorySize;\r
+ PrivateData->FreePhysicalMemoryTop = PrivateData->PhysicalMemoryBegin + PeiMemorySize;\r
+}\r
/**\r
Conduct PEIM dispatch.\r
\r
UINTN OldCheckingTop;\r
UINTN OldCheckingBottom;\r
PEI_CORE_FV_HANDLE *CoreFvHandle;\r
+ VOID *LoadFixPeiCodeBegin;\r
\r
- PeiServices = (CONST EFI_PEI_SERVICES **) &Private->PS;\r
+ PeiServices = (CONST EFI_PEI_SERVICES **) &Private->Ps;\r
PeimEntryPoint = NULL;\r
PeimFileHandle = NULL;\r
EntryPoint = 0;\r
SaveCurrentFileHandle = Private->CurrentFileHandle;\r
\r
for (Index1 = 0; Index1 <= SaveCurrentFvCount; Index1++) {\r
- for (Index2 = 0; (Index2 < PcdGet32 (PcdPeiCoreMaxPeimPerFv)) && (Private->Fv[Index1].FvFileHandles[Index2] != NULL); Index2++) {\r
+ for (Index2 = 0; (Index2 < FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv)) && (Private->Fv[Index1].FvFileHandles[Index2] != NULL); Index2++) {\r
if (Private->Fv[Index1].PeimState[Index2] == PEIM_STATE_REGISITER_FOR_SHADOW) {\r
PeimFileHandle = Private->Fv[Index1].FvFileHandles[Index2];\r
Status = PeiLoadImage (\r
- (CONST EFI_PEI_SERVICES **) &Private->PS,\r
+ (CONST EFI_PEI_SERVICES **) &Private->Ps,\r
PeimFileHandle,\r
PEIM_STATE_REGISITER_FOR_SHADOW,\r
&EntryPoint,\r
PeimEntryPoint = (EFI_PEIM_ENTRY_POINT2)(UINTN)EntryPoint;\r
\r
PERF_START (PeimFileHandle, "PEIM", NULL, 0);\r
- PeimEntryPoint(PeimFileHandle, (const EFI_PEI_SERVICES **) &Private->PS);\r
+ PeimEntryPoint(PeimFileHandle, (const EFI_PEI_SERVICES **) &Private->Ps);\r
PERF_END (PeimFileHandle, "PEIM", NULL, 0);\r
}\r
\r
// Start to dispatch all modules within the current Fv.\r
//\r
for (PeimCount = Private->CurrentPeimCount;\r
- (PeimCount < PcdGet32 (PcdPeiCoreMaxPeimPerFv)) && (Private->CurrentFvFileHandles[PeimCount] != NULL);\r
+ (PeimCount < FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv)) && (Private->CurrentFvFileHandles[PeimCount] != NULL);\r
PeimCount++) {\r
Private->CurrentPeimCount = PeimCount;\r
PeimFileHandle = Private->CurrentFileHandle = Private->CurrentFvFileHandles[PeimCount];\r
));\r
DEBUG_CODE_END ();\r
\r
+ if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) {\r
+ //\r
+ // Loading Module at Fixed Address is enabled\r
+ //\r
+ PeiLoadFixAddressHook(Private);\r
+ //\r
+ // if Loading Module at Fixed Address is enabled, This is the first invoke to page\r
+ // allocation for Pei Code range. This memory range should be reserved for loading PEIMs\r
+ //\r
+ LoadFixPeiCodeBegin = AllocatePages((UINTN)PcdGet32(PcdLoadFixAddressPeiCodePageNumber));\r
+ DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO: PeiCodeBegin = 0x%lX, PeiCodeTop= 0x%lX\n", (UINT64)(UINTN)LoadFixPeiCodeBegin, (UINT64)((UINTN)LoadFixPeiCodeBegin + PcdGet32(PcdLoadFixAddressPeiCodePageNumber) * EFI_PAGE_SIZE)));\r
+ }\r
+ \r
//\r
// Reserve the size of new stack at bottom of physical memory\r
//\r
//\r
// Fixup the PeiCore's private data\r
//\r
- PrivateInMem->PS = &PrivateInMem->ServiceTableShadow;\r
+ PrivateInMem->Ps = &PrivateInMem->ServiceTableShadow;\r
PrivateInMem->CpuIo = &PrivateInMem->ServiceTableShadow.CpuIo;\r
PrivateInMem->HobList.Raw = (VOID*) ((UINTN) PrivateInMem->HobList.Raw + HeapOffset);\r
PrivateInMem->StackBase = (EFI_PHYSICAL_ADDRESS)(((UINTN)PrivateInMem->PhysicalMemoryBegin + EFI_PAGE_MASK) & ~EFI_PAGE_MASK);\r
\r
- PeiServices = (CONST EFI_PEI_SERVICES **) &PrivateInMem->PS;\r
+ PeiServices = (CONST EFI_PEI_SERVICES **) &PrivateInMem->Ps;\r
\r
//\r
// Fixup for PeiService's address\r
//\r
PrivateInMem->PeimDispatcherReenter = TRUE;\r
\r
+ if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) {\r
+ //\r
+ // if Loading Module at Fixed Address is enabled, allocate the PEI code memory range usage bit map array.\r
+ // Every bit in the array indicate the status of the corresponding memory page available or not\r
+ //\r
+ PrivateInMem->PeiCodeMemoryRangeUsageBitMap = AllocateZeroPool (((PcdGet32(PcdLoadFixAddressPeiCodePageNumber)>>6) + 1)*sizeof(UINT64));\r
+ }\r
//\r
// Shadow PEI Core. When permanent memory is avaiable, shadow\r
// PEI Core and PEIMs to get high performance.\r
//\r
// Evaluate a given DEPEX\r
//\r
- return PeimDispatchReadiness (&Private->PS, DepexData);\r
+ return PeimDispatchReadiness (&Private->Ps, DepexData);\r
}\r
\r
/**\r