+**/\r
+VOID\r
+FreeMemoryAllocationHob (\r
+ IN PEI_CORE_INSTANCE *PrivateData,\r
+ IN OUT EFI_HOB_MEMORY_ALLOCATION *MemoryAllocationHobToFree\r
+ )\r
+{\r
+ EFI_PEI_HOB_POINTERS Hob;\r
+ EFI_PHYSICAL_ADDRESS *FreeMemoryTop;\r
+ EFI_HOB_MEMORY_ALLOCATION *MemoryAllocationHob;\r
+\r
+ Hob.Raw = PrivateData->HobList.Raw;\r
+\r
+ if (!PrivateData->PeiMemoryInstalled && PrivateData->SwitchStackSignal) {\r
+ //\r
+ // When PeiInstallMemory is called but temporary memory has *not* been moved to permanent memory,\r
+ // use the FreePhysicalMemoryTop field of PEI_CORE_INSTANCE structure.\r
+ //\r
+ FreeMemoryTop = &(PrivateData->FreePhysicalMemoryTop);\r
+ } else {\r
+ FreeMemoryTop = &(Hob.HandoffInformationTable->EfiFreeMemoryTop);\r
+ }\r
+\r
+ if (MemoryAllocationHobToFree->AllocDescriptor.MemoryBaseAddress == *FreeMemoryTop) {\r
+ //\r
+ // Update *FreeMemoryTop.\r
+ //\r
+ *FreeMemoryTop += MemoryAllocationHobToFree->AllocDescriptor.MemoryLength;\r
+ //\r
+ // Mark the memory allocation HOB to be unused(freed).\r
+ //\r
+ MemoryAllocationHobToFree->Header.HobType = EFI_HOB_TYPE_UNUSED;\r
+\r
+ MemoryAllocationHob = NULL;\r
+ Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION);\r
+ while (Hob.Raw != NULL) {\r
+ if ((Hob.MemoryAllocation->AllocDescriptor.MemoryType == EfiConventionalMemory) &&\r
+ (Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress == *FreeMemoryTop)) {\r
+ //\r
+ // Found memory allocation HOB that has EfiConventionalMemory MemoryType and\r
+ // MemoryBaseAddress == new *FreeMemoryTop.\r
+ //\r
+ MemoryAllocationHob = (EFI_HOB_MEMORY_ALLOCATION *) Hob.Raw;\r
+ break;\r
+ }\r
+ Hob.Raw = GET_NEXT_HOB (Hob);\r
+ Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw);\r
+ }\r
+ //\r
+ // Free memory allocation HOB iteratively.\r
+ //\r
+ if (MemoryAllocationHob != NULL) {\r
+ FreeMemoryAllocationHob (PrivateData, MemoryAllocationHob);\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ Frees memory pages.\r
+\r
+ @param[in] PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
+ @param[in] Memory The base physical address of the pages to be freed.\r
+ @param[in] Pages The number of contiguous 4 KB pages to free.\r
+\r
+ @retval EFI_SUCCESS The requested pages were freed.\r
+ @retval EFI_INVALID_PARAMETER Memory is not a page-aligned address or Pages is invalid.\r
+ @retval EFI_NOT_FOUND The requested memory pages were not allocated with\r
+ AllocatePages().\r
+\r
+**/\r