summaryrefslogtreecommitdiff
path: root/EdkModulePkg/Core/Pei/Memory
diff options
context:
space:
mode:
authorbbahnsen <bbahnsen@6f19259b-4bc3-4df7-8a09-765794883524>2006-04-21 22:54:32 +0000
committerbbahnsen <bbahnsen@6f19259b-4bc3-4df7-8a09-765794883524>2006-04-21 22:54:32 +0000
commit878ddf1fc3540a715f63594ed22b6929e881afb4 (patch)
treec56c44dac138137b510e1fba7c3efe5e4d84bea2 /EdkModulePkg/Core/Pei/Memory
downloadedk2-platforms-878ddf1fc3540a715f63594ed22b6929e881afb4.tar.xz
Initial import.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'EdkModulePkg/Core/Pei/Memory')
-rw-r--r--EdkModulePkg/Core/Pei/Memory/MemoryServices.c314
1 files changed, 314 insertions, 0 deletions
diff --git a/EdkModulePkg/Core/Pei/Memory/MemoryServices.c b/EdkModulePkg/Core/Pei/Memory/MemoryServices.c
new file mode 100644
index 0000000000..48b2b3818c
--- /dev/null
+++ b/EdkModulePkg/Core/Pei/Memory/MemoryServices.c
@@ -0,0 +1,314 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ MemoryServices.c
+
+Abstract:
+
+ EFI PEI Core memory services
+
+--*/
+
+#include <PeiMain.h>
+
+VOID
+InitializeMemoryServices (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize the memory services.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ PeiStartupDescriptor - Information and services provided by SEC phase.
+ OldCoreData - Pointer to the PEI Core data.
+ NULL if being run in non-permament memory mode.
+
+Returns:
+
+ None
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ UINT64 SizeOfCarHeap;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+ PrivateData->SwitchStackSignal = FALSE;
+
+ if (OldCoreData == NULL) {
+
+ PrivateData->PeiMemoryInstalled = FALSE;
+
+ PrivateData->BottomOfCarHeap = (VOID *) (((UINTN)(VOID *)(&PrivateData))
+ & (~((PeiStartupDescriptor->SizeOfCacheAsRam) - 1)));
+ PrivateData->TopOfCarHeap = (VOID *)((UINTN)(PrivateData->BottomOfCarHeap) + PeiStartupDescriptor->SizeOfCacheAsRam);
+ //
+ // SizeOfCarHeap is 1/2 (arbitrary) of CacheAsRam Size.
+ //
+ SizeOfCarHeap = (UINT64) PeiStartupDescriptor->SizeOfCacheAsRam;
+ SizeOfCarHeap = RShiftU64 (SizeOfCarHeap, 1);
+
+ DEBUG_CODE (
+ PrivateData->SizeOfCacheAsRam = PeiStartupDescriptor->SizeOfCacheAsRam;
+ PrivateData->MaxTopOfCarHeap = (VOID *) ((UINTN) PrivateData->BottomOfCarHeap + (UINTN) SizeOfCarHeap);
+ );
+
+ PrivateData->HobList.Raw = PrivateData->BottomOfCarHeap;
+
+ PeiCoreBuildHobHandoffInfoTable (
+ BOOT_WITH_FULL_CONFIGURATION,
+ (EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData->BottomOfCarHeap,
+ (UINTN) SizeOfCarHeap
+ );
+ //
+ // Copy PeiServices from ROM to Cache in PrivateData
+ //
+ CopyMem (&(PrivateData->ServiceTableShadow), *PeiServices, sizeof (EFI_PEI_SERVICES));
+
+ //
+ // Set PS to point to ServiceTableShadow in Cache
+ //
+ PrivateData->PS = &(PrivateData->ServiceTableShadow);
+ } else {
+ //
+ // Set PS to point to ServiceTableShadow in Cache one time after the
+ // stack switched to main memory
+ //
+ PrivateData->PS = &(PrivateData->ServiceTableShadow);
+}
+
+ return;
+}
+
+EFI_STATUS
+EFIAPI
+PeiInstallPeiMemory (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS MemoryBegin,
+ IN UINT64 MemoryLength
+ )
+/*++
+
+Routine Description:
+
+ Install the permanent memory is now available.
+ Creates HOB (PHIT and Stack).
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ MemoryBegin - Start of memory address.
+ MemoryLength - Length of memory.
+
+Returns:
+
+ Status - EFI_SUCCESS
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ EFI_HOB_HANDOFF_INFO_TABLE *OldHandOffHob;
+ EFI_HOB_HANDOFF_INFO_TABLE *NewHandOffHob;
+ UINT64 PeiStackSize;
+ UINT64 EfiFreeMemorySize;
+ EFI_PHYSICAL_ADDRESS PhysicalAddressOfOldHob;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+ PrivateData->SwitchStackSignal = TRUE;
+ PrivateData->PeiMemoryInstalled = TRUE;
+
+ PrivateData->StackBase = MemoryBegin;
+
+ PeiStackSize = RShiftU64 (MemoryLength, 1);
+ if (PEI_STACK_SIZE > PeiStackSize) {
+ PrivateData->StackSize = PeiStackSize;
+ } else {
+ PrivateData->StackSize = PEI_STACK_SIZE;
+ }
+
+ OldHandOffHob = PrivateData->HobList.HandoffInformationTable;
+
+ PrivateData->HobList.Raw = (VOID *)((UINTN)(MemoryBegin + PrivateData->StackSize));
+ NewHandOffHob = PrivateData->HobList.HandoffInformationTable;
+ PhysicalAddressOfOldHob = (EFI_PHYSICAL_ADDRESS) (UINTN) OldHandOffHob;
+
+ EfiFreeMemorySize = OldHandOffHob->EfiFreeMemoryBottom - PhysicalAddressOfOldHob;
+
+ DEBUG ((EFI_D_INFO, "HOBLIST address before memory init = 0x%08x\n", OldHandOffHob));
+ DEBUG ((EFI_D_INFO, "HOBLIST address after memory init = 0x%08x\n", NewHandOffHob));
+
+ CopyMem (
+ NewHandOffHob,
+ OldHandOffHob,
+ (UINTN)EfiFreeMemorySize
+ );
+
+ NewHandOffHob->EfiMemoryTop = MemoryBegin + MemoryLength;
+ NewHandOffHob->EfiFreeMemoryTop = NewHandOffHob->EfiMemoryTop;
+ NewHandOffHob->EfiMemoryBottom = MemoryBegin;
+
+ NewHandOffHob->EfiFreeMemoryBottom = (UINTN)NewHandOffHob + EfiFreeMemorySize;
+
+ NewHandOffHob->EfiEndOfHobList = (UINTN)NewHandOffHob +
+ (OldHandOffHob->EfiEndOfHobList -
+ PhysicalAddressOfOldHob);
+
+ ConvertPpiPointers (PeiServices, OldHandOffHob, NewHandOffHob);
+
+ BuildStackHob (PrivateData->StackBase, PrivateData->StackSize);
+
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+PeiAllocatePages (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ OUT EFI_PHYSICAL_ADDRESS *Memory
+ )
+/*++
+
+Routine Description:
+
+ Memory allocation service on permanent memory,
+ not usable prior to the memory installation.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ MemoryType - Type of memory to allocate.
+ Pages - Number of pages to allocate.
+ Memory - Pointer of memory allocated.
+
+Returns:
+
+ Status - EFI_SUCCESS The allocation was successful
+ EFI_INVALID_PARAMETER Only AllocateAnyAddress is supported.
+ EFI_NOT_AVAILABLE_YET Called with permanent memory not available
+ EFI_OUT_OF_RESOURCES There is not enough HOB heap to satisfy the requirement
+ to allocate the number of pages.
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_PHYSICAL_ADDRESS Offset;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+ //
+ // Check if Hob already available
+ //
+ if (!PrivateData->PeiMemoryInstalled) {
+ return EFI_NOT_AVAILABLE_YET;
+ }
+
+ Hob.Raw = PrivateData->HobList.Raw;
+
+ //
+ // Check to see if on 4k boundary
+ //
+ Offset = Hob.HandoffInformationTable->EfiFreeMemoryTop & 0xFFF;
+
+ //
+ // If not aligned, make the allocation aligned.
+ //
+ if (Offset != 0) {
+ Hob.HandoffInformationTable->EfiFreeMemoryTop -= Offset;
+ }
+
+ //
+ // Verify that there is sufficient memory to satisfy the allocation
+ //
+ if (Hob.HandoffInformationTable->EfiFreeMemoryTop - ((Pages * EFI_PAGE_SIZE) + sizeof (EFI_HOB_MEMORY_ALLOCATION)) <
+ Hob.HandoffInformationTable->EfiFreeMemoryBottom) {
+ return EFI_OUT_OF_RESOURCES;
+ } else {
+ //
+ // Update the PHIT to reflect the memory usage
+ //
+ Hob.HandoffInformationTable->EfiFreeMemoryTop -= Pages * EFI_PAGE_SIZE;
+
+ //
+ // Update the value for the caller
+ //
+ *Memory = Hob.HandoffInformationTable->EfiFreeMemoryTop;
+
+ //
+ // Create a memory allocation HOB.
+ //
+ BuildMemoryAllocationHob (
+ Hob.HandoffInformationTable->EfiFreeMemoryTop,
+ Pages * EFI_PAGE_SIZE + Offset,
+ MemoryType
+ );
+
+ return EFI_SUCCESS;
+ }
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiAllocatePool (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINTN Size,
+ OUT VOID **Buffer
+ )
+/*++
+
+Routine Description:
+
+ Memory allocation service on the CAR.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ Size - Amount of memory required
+
+ Buffer - Address of pointer to the buffer
+
+Returns:
+
+ Status - EFI_SUCCESS The allocation was successful
+ EFI_OUT_OF_RESOURCES There is not enough heap to satisfy the requirement
+ to allocate the requested size.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_HOB_MEMORY_POOL *Hob;
+
+
+ Status = PeiCoreCreateHob (
+ EFI_HOB_TYPE_PEI_MEMORY_POOL,
+ (UINT16)(sizeof (EFI_HOB_MEMORY_POOL) + Size),
+ (VOID **)&Hob
+ );
+ *Buffer = Hob+1;
+
+
+ return Status;
+}