3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 EFI PEI Core memory services
24 static EFI_PEI_PPI_DESCRIPTOR mMemoryDiscoveredPpi
= {
25 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
26 &gEfiPeiMemoryDiscoveredPpiGuid
,
31 InitializeMemoryServices (
32 IN PEI_CORE_INSTANCE
*PrivateData
,
33 IN CONST EFI_SEC_PEI_HAND_OFF
*SecCoreData
,
34 IN PEI_CORE_INSTANCE
*OldCoreData
40 Initialize the memory services.
44 PeiServices - The PEI core services table.
45 SecCoreData - Points to a data structure containing information about the PEI core's operating
46 environment, such as the size and location of temporary RAM, the stack location and
49 OldCoreData - Pointer to the PEI Core data.
50 NULL if being run in non-permament memory mode.
59 PrivateData
->SwitchStackSignal
= FALSE
;
61 if (OldCoreData
== NULL
) {
63 PrivateData
->PeiMemoryInstalled
= FALSE
;
65 PrivateData
->BottomOfCarHeap
= SecCoreData
->PeiTemporaryRamBase
;
66 PrivateData
->TopOfCarHeap
= (VOID
*)((UINTN
)(PrivateData
->BottomOfCarHeap
) + SecCoreData
->PeiTemporaryRamSize
);
67 PrivateData
->SizeOfTemporaryMemory
= SecCoreData
->TemporaryRamSize
;
68 PrivateData
->StackSize
= (UINT64
) SecCoreData
->StackSize
;
71 PrivateData
->SizeOfCacheAsRam
= SecCoreData
->PeiTemporaryRamSize
+ SecCoreData
->StackSize
;
72 PrivateData
->MaxTopOfCarHeap
= (VOID
*) ((UINTN
) PrivateData
->BottomOfCarHeap
+ (UINTN
) PrivateData
->SizeOfCacheAsRam
);
73 PrivateData
->StackBase
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) SecCoreData
->StackBase
;
74 PrivateData
->StackSize
= (UINT64
) SecCoreData
->StackSize
;
77 PrivateData
->HobList
.Raw
= PrivateData
->BottomOfCarHeap
;
79 PeiCoreBuildHobHandoffInfoTable (
80 BOOT_WITH_FULL_CONFIGURATION
,
81 (EFI_PHYSICAL_ADDRESS
) (UINTN
) PrivateData
->BottomOfCarHeap
,
82 (UINTN
) SecCoreData
->PeiTemporaryRamSize
86 // Set PS to point to ServiceTableShadow in Cache
88 PrivateData
->PS
= &(PrivateData
->ServiceTableShadow
);
97 IN CONST EFI_PEI_SERVICES
**PeiServices
,
98 IN EFI_PHYSICAL_ADDRESS MemoryBegin
,
99 IN UINT64 MemoryLength
105 Install the permanent memory is now available.
106 Creates HOB (PHIT and Stack).
110 PeiServices - The PEI core services table.
111 MemoryBegin - Start of memory address.
112 MemoryLength - Length of memory.
120 PEI_CORE_INSTANCE
*PrivateData
;
122 DEBUG ((EFI_D_INFO
, "PeiInstallPeiMemory MemoryBegin 0x%LX, MemoryLength 0x%LX\n", MemoryBegin
, MemoryLength
));
123 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
125 PrivateData
->PhysicalMemoryBegin
= MemoryBegin
;
126 PrivateData
->PhysicalMemoryLength
= MemoryLength
;
127 PrivateData
->FreePhysicalMemoryTop
= MemoryBegin
+ MemoryLength
;
129 PrivateData
->SwitchStackSignal
= TRUE
;
137 IN CONST EFI_PEI_SERVICES
**PeiServices
,
138 IN EFI_MEMORY_TYPE MemoryType
,
140 OUT EFI_PHYSICAL_ADDRESS
*Memory
146 Memory allocation service on permanent memory,
147 not usable prior to the memory installation.
151 PeiServices - The PEI core services table.
152 MemoryType - Type of memory to allocate.
153 Pages - Number of pages to allocate.
154 Memory - Pointer of memory allocated.
158 Status - EFI_SUCCESS The allocation was successful
159 EFI_INVALID_PARAMETER Only AllocateAnyAddress is supported.
160 EFI_NOT_AVAILABLE_YET Called with permanent memory not available
161 EFI_OUT_OF_RESOURCES There is not enough HOB heap to satisfy the requirement
162 to allocate the number of pages.
166 PEI_CORE_INSTANCE
*PrivateData
;
167 EFI_PEI_HOB_POINTERS Hob
;
168 EFI_PHYSICAL_ADDRESS Offset
;
169 EFI_PHYSICAL_ADDRESS
*FreeMemoryTop
;
170 EFI_PHYSICAL_ADDRESS
*FreeMemoryBottom
;
172 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
173 Hob
.Raw
= PrivateData
->HobList
.Raw
;
176 // Check if Hob already available
178 if (!PrivateData
->PeiMemoryInstalled
) {
180 // When PeiInstallMemory is called but CAR has *not* been moved to temporary memory,
181 // the AllocatePage will dependent the field of PEI_CORE_INSTANCE structure.
183 if (!PrivateData
->SwitchStackSignal
) {
184 return EFI_NOT_AVAILABLE_YET
;
186 FreeMemoryTop
= &(PrivateData
->FreePhysicalMemoryTop
);
187 FreeMemoryBottom
= &(PrivateData
->PhysicalMemoryBegin
);
190 FreeMemoryTop
= &(Hob
.HandoffInformationTable
->EfiFreeMemoryTop
);
191 FreeMemoryBottom
= &(Hob
.HandoffInformationTable
->EfiFreeMemoryBottom
);
197 // Check to see if on 4k boundary
199 Offset
= *(FreeMemoryTop
) & 0xFFF;
202 // If not aligned, make the allocation aligned.
205 *(FreeMemoryTop
) -= Offset
;
209 // Verify that there is sufficient memory to satisfy the allocation
211 if (*(FreeMemoryTop
) - ((Pages
* EFI_PAGE_SIZE
) + sizeof (EFI_HOB_MEMORY_ALLOCATION
)) <
212 *(FreeMemoryBottom
)) {
213 DEBUG ((EFI_D_ERROR
, "AllocatePages failed: No 0x%x Pages is available.\n", Pages
));
214 DEBUG ((EFI_D_ERROR
, "There is only left 0x%x pages memory resource to be allocated.\n", \
215 EFI_SIZE_TO_PAGES ((UINTN
) (*(FreeMemoryTop
) - *(FreeMemoryBottom
)))));
216 return EFI_OUT_OF_RESOURCES
;
219 // Update the PHIT to reflect the memory usage
221 *(FreeMemoryTop
) -= Pages
* EFI_PAGE_SIZE
;
224 // Update the value for the caller
226 *Memory
= *(FreeMemoryTop
);
229 // Create a memory allocation HOB.
231 BuildMemoryAllocationHob (
233 Pages
* EFI_PAGE_SIZE
,
245 IN CONST EFI_PEI_SERVICES
**PeiServices
,
253 Memory allocation service on the CAR.
257 PeiServices - The PEI core services table.
259 Size - Amount of memory required
261 Buffer - Address of pointer to the buffer
265 Status - EFI_SUCCESS The allocation was successful
266 EFI_OUT_OF_RESOURCES There is not enough heap to satisfy the requirement
267 to allocate the requested size.
272 EFI_HOB_MEMORY_POOL
*Hob
;
275 // If some "post-memory" PEIM wishes to allocate larger pool,
276 // it should use AllocatePages service instead.
278 ASSERT (Size
< 0x10000 - sizeof (EFI_HOB_MEMORY_POOL
));
279 Status
= PeiServicesCreateHob (
280 EFI_HOB_TYPE_MEMORY_POOL
,
281 (UINT16
)(sizeof (EFI_HOB_MEMORY_POOL
) + Size
),