+ Private->MemoryPages.Size = (UINTN) (Private->HobList.HandoffInformationTable->EfiMemoryTop -\r
+ Private->HobList.HandoffInformationTable->EfiFreeMemoryTop);\r
+ if (Private->MemoryPages.Size == 0) {\r
+ //\r
+ // No any memory page allocated in pre-memory phase.\r
+ //\r
+ return;\r
+ }\r
+ Private->MemoryPages.Base = Private->HobList.HandoffInformationTable->EfiFreeMemoryTop;\r
+\r
+ ASSERT (Private->MemoryPages.Size <= Private->FreePhysicalMemoryTop);\r
+ NewMemPagesBase = Private->FreePhysicalMemoryTop - Private->MemoryPages.Size;\r
+ NewMemPagesBase &= ~(UINT64)EFI_PAGE_MASK;\r
+ ASSERT (NewMemPagesBase >= Private->PhysicalMemoryBegin);\r
+ //\r
+ // Copy memory pages at temporary heap top to permanent heap top.\r
+ //\r
+ if (TemporaryRamMigrated) {\r
+ //\r
+ // Memory pages at temporary heap top has been migrated to permanent heap,\r
+ // Here still needs to copy them from permanent heap to permanent heap top.\r
+ //\r
+ MemPagesBase = Private->MemoryPages.Base;\r
+ if (Private->HeapOffsetPositive) {\r
+ MemPagesBase += Private->HeapOffset;\r
+ } else {\r
+ MemPagesBase -= Private->HeapOffset;\r
+ }\r
+ CopyMem ((VOID *)(UINTN)NewMemPagesBase, (VOID *)(UINTN)MemPagesBase, Private->MemoryPages.Size);\r
+ } else {\r
+ CopyMem ((VOID *)(UINTN)NewMemPagesBase, (VOID *)(UINTN)Private->MemoryPages.Base, Private->MemoryPages.Size);\r
+ }\r
+\r
+ if (NewMemPagesBase >= Private->MemoryPages.Base) {\r
+ Private->MemoryPages.OffsetPositive = TRUE;\r
+ Private->MemoryPages.Offset = (UINTN)(NewMemPagesBase - Private->MemoryPages.Base);\r
+ } else {\r
+ Private->MemoryPages.OffsetPositive = FALSE;\r
+ Private->MemoryPages.Offset = (UINTN)(Private->MemoryPages.Base - NewMemPagesBase);\r
+ }\r
+\r
+ DEBUG ((DEBUG_INFO, "Pages Offset = 0x%lX\n", (UINT64) Private->MemoryPages.Offset));\r
+\r
+ Private->FreePhysicalMemoryTop = NewMemPagesBase;\r
+}\r
+\r
+/**\r
+ Migrate MemoryBaseAddress in memory allocation HOBs\r
+ from the temporary memory to PEI installed memory.\r
+\r
+ @param[in] PrivateData Pointer to PeiCore's private data structure.\r
+\r
+**/\r
+VOID\r
+ConvertMemoryAllocationHobs (\r
+ IN PEI_CORE_INSTANCE *PrivateData\r
+ )\r
+{\r
+ EFI_PEI_HOB_POINTERS Hob;\r
+ EFI_HOB_MEMORY_ALLOCATION *MemoryAllocationHob;\r
+ EFI_PHYSICAL_ADDRESS OldMemPagesBase;\r
+ UINTN OldMemPagesSize;\r
+\r
+ if (PrivateData->MemoryPages.Size == 0) {\r
+ //\r
+ // No any memory page allocated in pre-memory phase.\r
+ //\r
+ return;\r
+ }\r
+\r
+ OldMemPagesBase = PrivateData->MemoryPages.Base;\r
+ OldMemPagesSize = PrivateData->MemoryPages.Size;\r
+\r
+ MemoryAllocationHob = NULL;\r
+ Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION);\r
+ while (Hob.Raw != NULL) {\r
+ MemoryAllocationHob = (EFI_HOB_MEMORY_ALLOCATION *) Hob.Raw;\r
+ if ((MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress >= OldMemPagesBase) &&\r
+ (MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress < (OldMemPagesBase + OldMemPagesSize))\r
+ ) {\r
+ if (PrivateData->MemoryPages.OffsetPositive) {\r
+ MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress += PrivateData->MemoryPages.Offset;\r
+ } else {\r
+ MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress -= PrivateData->MemoryPages.Offset;\r
+ }\r
+ }\r
+\r
+ Hob.Raw = GET_NEXT_HOB (Hob);\r
+ Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw);\r
+ }\r
+}\r
+\r
+/**\r
+ Internal function to build a HOB for the memory allocation.\r
+ It will search and reuse the unused(freed) memory allocation HOB,\r
+ or build memory allocation HOB normally if no unused(freed) memory allocation HOB found.\r
+\r
+ @param[in] BaseAddress The 64 bit physical address of the memory.\r
+ @param[in] Length The length of the memory allocation in bytes.\r
+ @param[in] MemoryType The type of memory allocated by this HOB.\r
+\r
+**/\r
+VOID\r
+InternalBuildMemoryAllocationHob (\r
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,\r
+ IN UINT64 Length,\r
+ IN EFI_MEMORY_TYPE MemoryType\r
+ )\r
+{\r
+ EFI_PEI_HOB_POINTERS Hob;\r
+ EFI_HOB_MEMORY_ALLOCATION *MemoryAllocationHob;\r