+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation \r
-All rights reserved. This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
-\r
- MemoryServices.c\r
-\r
-Abstract:\r
-\r
- EFI PEI Core memory services\r
-\r
---*/\r
-\r
-#include <PeiMain.h>\r
-\r
-VOID\r
-InitializeMemoryServices (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,\r
- IN PEI_CORE_INSTANCE *OldCoreData\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Initialize the memory services.\r
-\r
-Arguments:\r
-\r
- PeiServices - The PEI core services table.\r
- PeiStartupDescriptor - Information and services provided by SEC phase.\r
- OldCoreData - Pointer to the PEI Core data.\r
- NULL if being run in non-permament memory mode.\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
-{\r
- PEI_CORE_INSTANCE *PrivateData;\r
- UINT64 SizeOfCarHeap;\r
-\r
- PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
- PrivateData->SwitchStackSignal = FALSE;\r
-\r
- if (OldCoreData == NULL) {\r
-\r
- PrivateData->PeiMemoryInstalled = FALSE;\r
-\r
- PrivateData->BottomOfCarHeap = (VOID *) (((UINTN)(VOID *)(&PrivateData))\r
- & (~((PeiStartupDescriptor->SizeOfCacheAsRam) - 1))); \r
- PrivateData->TopOfCarHeap = (VOID *)((UINTN)(PrivateData->BottomOfCarHeap) + PeiStartupDescriptor->SizeOfCacheAsRam);\r
- //\r
- // SizeOfCarHeap is 1/2 (arbitrary) of CacheAsRam Size.\r
- //\r
- SizeOfCarHeap = (UINT64) PeiStartupDescriptor->SizeOfCacheAsRam;\r
- SizeOfCarHeap = RShiftU64 (SizeOfCarHeap, 1);\r
- \r
- DEBUG_CODE_BEGIN ();\r
- PrivateData->SizeOfCacheAsRam = PeiStartupDescriptor->SizeOfCacheAsRam;\r
- PrivateData->MaxTopOfCarHeap = (VOID *) ((UINTN) PrivateData->BottomOfCarHeap + (UINTN) SizeOfCarHeap);\r
- DEBUG_CODE_END ();\r
-\r
- PrivateData->HobList.Raw = PrivateData->BottomOfCarHeap;\r
- \r
- PeiCoreBuildHobHandoffInfoTable (\r
- BOOT_WITH_FULL_CONFIGURATION,\r
- (EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData->BottomOfCarHeap,\r
- (UINTN) SizeOfCarHeap\r
- );\r
- //\r
- // Copy PeiServices from ROM to Cache in PrivateData\r
- //\r
- CopyMem (&(PrivateData->ServiceTableShadow), *PeiServices, sizeof (EFI_PEI_SERVICES));\r
-\r
- //\r
- // Set PS to point to ServiceTableShadow in Cache\r
- //\r
- PrivateData->PS = &(PrivateData->ServiceTableShadow);\r
- } else {\r
- // \r
- // Set PS to point to ServiceTableShadow in Cache one time after the \r
- // stack switched to main memory \r
- // \r
- PrivateData->PS = &(PrivateData->ServiceTableShadow); \r
-} \r
-\r
- return;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PeiInstallPeiMemory (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- IN EFI_PHYSICAL_ADDRESS MemoryBegin,\r
- IN UINT64 MemoryLength\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Install the permanent memory is now available.\r
- Creates HOB (PHIT and Stack).\r
-\r
-Arguments:\r
-\r
- PeiServices - The PEI core services table.\r
- MemoryBegin - Start of memory address.\r
- MemoryLength - Length of memory.\r
-\r
-Returns:\r
-\r
- Status - EFI_SUCCESS\r
- \r
---*/\r
-{\r
- PEI_CORE_INSTANCE *PrivateData;\r
- EFI_HOB_HANDOFF_INFO_TABLE *OldHandOffHob;\r
- EFI_HOB_HANDOFF_INFO_TABLE *NewHandOffHob;\r
- UINT64 PeiStackSize;\r
- UINT64 EfiFreeMemorySize;\r
- EFI_PHYSICAL_ADDRESS PhysicalAddressOfOldHob;\r
- \r
- PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
-\r
- PrivateData->SwitchStackSignal = TRUE;\r
- PrivateData->PeiMemoryInstalled = TRUE;\r
-\r
- PrivateData->StackBase = MemoryBegin;\r
- \r
- PeiStackSize = RShiftU64 (MemoryLength, 1);\r
- if (PEI_STACK_SIZE > PeiStackSize) {\r
- PrivateData->StackSize = PeiStackSize;\r
- } else {\r
- PrivateData->StackSize = PEI_STACK_SIZE;\r
- }\r
-\r
- OldHandOffHob = PrivateData->HobList.HandoffInformationTable;\r
-\r
- PrivateData->HobList.Raw = (VOID *)((UINTN)(MemoryBegin + PrivateData->StackSize));\r
- NewHandOffHob = PrivateData->HobList.HandoffInformationTable;\r
- PhysicalAddressOfOldHob = (EFI_PHYSICAL_ADDRESS) (UINTN) OldHandOffHob;\r
-\r
- EfiFreeMemorySize = OldHandOffHob->EfiFreeMemoryBottom - PhysicalAddressOfOldHob;\r
- \r
- DEBUG ((EFI_D_INFO, "HOBLIST address before memory init = 0x%08x\n", OldHandOffHob));\r
- DEBUG ((EFI_D_INFO, "HOBLIST address after memory init = 0x%08x\n", NewHandOffHob));\r
-\r
- CopyMem (\r
- NewHandOffHob,\r
- OldHandOffHob,\r
- (UINTN)EfiFreeMemorySize\r
- );\r
-\r
- NewHandOffHob->EfiMemoryTop = MemoryBegin + MemoryLength;\r
- NewHandOffHob->EfiFreeMemoryTop = NewHandOffHob->EfiMemoryTop;\r
- NewHandOffHob->EfiMemoryBottom = MemoryBegin;\r
- \r
- NewHandOffHob->EfiFreeMemoryBottom = (UINTN)NewHandOffHob + EfiFreeMemorySize; \r
- \r
- NewHandOffHob->EfiEndOfHobList = (UINTN)NewHandOffHob +\r
- (OldHandOffHob->EfiEndOfHobList -\r
- PhysicalAddressOfOldHob);\r
-\r
- ConvertPpiPointers (PeiServices, OldHandOffHob, NewHandOffHob);\r
-\r
- BuildStackHob (PrivateData->StackBase, PrivateData->StackSize);\r
- \r
-\r
- return EFI_SUCCESS; \r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PeiAllocatePages (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- IN EFI_MEMORY_TYPE MemoryType,\r
- IN UINTN Pages,\r
- OUT EFI_PHYSICAL_ADDRESS *Memory\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Memory allocation service on permanent memory, \r
- not usable prior to the memory installation.\r
-\r
-Arguments:\r
-\r
- PeiServices - The PEI core services table.\r
- MemoryType - Type of memory to allocate.\r
- Pages - Number of pages to allocate.\r
- Memory - Pointer of memory allocated.\r
-\r
-Returns:\r
-\r
- Status - EFI_SUCCESS The allocation was successful\r
- EFI_INVALID_PARAMETER Only AllocateAnyAddress is supported.\r
- EFI_NOT_AVAILABLE_YET Called with permanent memory not available\r
- EFI_OUT_OF_RESOURCES There is not enough HOB heap to satisfy the requirement\r
- to allocate the number of pages.\r
-\r
---*/\r
-{\r
- PEI_CORE_INSTANCE *PrivateData;\r
- EFI_PEI_HOB_POINTERS Hob;\r
- EFI_PHYSICAL_ADDRESS Offset;\r
-\r
- PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
-\r
- //\r
- // Check if Hob already available\r
- //\r
- if (!PrivateData->PeiMemoryInstalled) {\r
- return EFI_NOT_AVAILABLE_YET;\r
- }\r
-\r
- Hob.Raw = PrivateData->HobList.Raw;\r
-\r
- //\r
- // Check to see if on 4k boundary\r
- //\r
- Offset = Hob.HandoffInformationTable->EfiFreeMemoryTop & 0xFFF;\r
-\r
- //\r
- // If not aligned, make the allocation aligned.\r
- //\r
- if (Offset != 0) {\r
- Hob.HandoffInformationTable->EfiFreeMemoryTop -= Offset;\r
- }\r
-\r
- //\r
- // Verify that there is sufficient memory to satisfy the allocation\r
- //\r
- if (Hob.HandoffInformationTable->EfiFreeMemoryTop - ((Pages * EFI_PAGE_SIZE) + sizeof (EFI_HOB_MEMORY_ALLOCATION)) < \r
- Hob.HandoffInformationTable->EfiFreeMemoryBottom) {\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) (Hob.HandoffInformationTable->EfiFreeMemoryTop - Hob.HandoffInformationTable->EfiFreeMemoryBottom))));\r
- return EFI_OUT_OF_RESOURCES;\r
- } else {\r
- //\r
- // Update the PHIT to reflect the memory usage\r
- //\r
- Hob.HandoffInformationTable->EfiFreeMemoryTop -= Pages * EFI_PAGE_SIZE;\r
-\r
- //\r
- // Update the value for the caller\r
- //\r
- *Memory = Hob.HandoffInformationTable->EfiFreeMemoryTop;\r
-\r
- //\r
- // Create a memory allocation HOB.\r
- //\r
- BuildMemoryAllocationHob (\r
- Hob.HandoffInformationTable->EfiFreeMemoryTop,\r
- Pages * EFI_PAGE_SIZE + Offset,\r
- MemoryType\r
- );\r
-\r
- return EFI_SUCCESS;\r
- }\r
-}\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PeiAllocatePool (\r
- IN EFI_PEI_SERVICES **PeiServices,\r
- IN UINTN Size,\r
- OUT VOID **Buffer\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Memory allocation service on the CAR. \r
-\r
-Arguments:\r
-\r
- PeiServices - The PEI core services table.\r
-\r
- Size - Amount of memory required\r
-\r
- Buffer - Address of pointer to the buffer\r
-\r
-Returns:\r
-\r
- Status - EFI_SUCCESS The allocation was successful\r
- EFI_OUT_OF_RESOURCES There is not enough heap to satisfy the requirement\r
- to allocate the requested size.\r
- \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
- EFI_HOB_TYPE_PEI_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