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
25 InitializeMemoryServices (
26 IN EFI_PEI_SERVICES
**PeiServices
,
27 IN EFI_PEI_STARTUP_DESCRIPTOR
*PeiStartupDescriptor
,
28 IN PEI_CORE_INSTANCE
*OldCoreData
34 Initialize the memory services.
38 PeiServices - The PEI core services table.
39 PeiStartupDescriptor - Information and services provided by SEC phase.
40 OldCoreData - Pointer to the PEI Core data.
41 NULL if being run in non-permament memory mode.
49 PEI_CORE_INSTANCE
*PrivateData
;
52 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
53 PrivateData
->SwitchStackSignal
= FALSE
;
55 if (OldCoreData
== NULL
) {
57 PrivateData
->PeiMemoryInstalled
= FALSE
;
59 PrivateData
->BottomOfCarHeap
= (VOID
*) (((UINTN
)(VOID
*)(&PrivateData
))
60 & (~((PeiStartupDescriptor
->SizeOfCacheAsRam
) - 1)));
61 PrivateData
->TopOfCarHeap
= (VOID
*)((UINTN
)(PrivateData
->BottomOfCarHeap
) + PeiStartupDescriptor
->SizeOfCacheAsRam
);
63 // SizeOfCarHeap is 1/2 (arbitrary) of CacheAsRam Size.
65 SizeOfCarHeap
= (UINT64
) PeiStartupDescriptor
->SizeOfCacheAsRam
;
66 SizeOfCarHeap
= RShiftU64 (SizeOfCarHeap
, 1);
69 PrivateData
->SizeOfCacheAsRam
= PeiStartupDescriptor
->SizeOfCacheAsRam
;
70 PrivateData
->MaxTopOfCarHeap
= (VOID
*) ((UINTN
) PrivateData
->BottomOfCarHeap
+ (UINTN
) SizeOfCarHeap
);
73 PrivateData
->HobList
.Raw
= PrivateData
->BottomOfCarHeap
;
75 PeiCoreBuildHobHandoffInfoTable (
76 BOOT_WITH_FULL_CONFIGURATION
,
77 (EFI_PHYSICAL_ADDRESS
) (UINTN
) PrivateData
->BottomOfCarHeap
,
81 // Copy PeiServices from ROM to Cache in PrivateData
83 CopyMem (&(PrivateData
->ServiceTableShadow
), *PeiServices
, sizeof (EFI_PEI_SERVICES
));
86 // Set PS to point to ServiceTableShadow in Cache
88 PrivateData
->PS
= &(PrivateData
->ServiceTableShadow
);
91 // Set PS to point to ServiceTableShadow in Cache one time after the
92 // stack switched to main memory
94 PrivateData
->PS
= &(PrivateData
->ServiceTableShadow
);
102 PeiInstallPeiMemory (
103 IN EFI_PEI_SERVICES
**PeiServices
,
104 IN EFI_PHYSICAL_ADDRESS MemoryBegin
,
105 IN UINT64 MemoryLength
111 Install the permanent memory is now available.
112 Creates HOB (PHIT and Stack).
116 PeiServices - The PEI core services table.
117 MemoryBegin - Start of memory address.
118 MemoryLength - Length of memory.
126 PEI_CORE_INSTANCE
*PrivateData
;
127 EFI_HOB_HANDOFF_INFO_TABLE
*OldHandOffHob
;
128 EFI_HOB_HANDOFF_INFO_TABLE
*NewHandOffHob
;
130 UINT64 EfiFreeMemorySize
;
131 EFI_PHYSICAL_ADDRESS PhysicalAddressOfOldHob
;
133 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
135 PrivateData
->SwitchStackSignal
= TRUE
;
136 PrivateData
->PeiMemoryInstalled
= TRUE
;
138 PrivateData
->StackBase
= MemoryBegin
;
140 PeiStackSize
= RShiftU64 (MemoryLength
, 1);
141 if (PEI_STACK_SIZE
> PeiStackSize
) {
142 PrivateData
->StackSize
= PeiStackSize
;
144 PrivateData
->StackSize
= PEI_STACK_SIZE
;
147 OldHandOffHob
= PrivateData
->HobList
.HandoffInformationTable
;
149 PrivateData
->HobList
.Raw
= (VOID
*)((UINTN
)(MemoryBegin
+ PrivateData
->StackSize
));
150 NewHandOffHob
= PrivateData
->HobList
.HandoffInformationTable
;
151 PhysicalAddressOfOldHob
= (EFI_PHYSICAL_ADDRESS
) (UINTN
) OldHandOffHob
;
153 EfiFreeMemorySize
= OldHandOffHob
->EfiFreeMemoryBottom
- PhysicalAddressOfOldHob
;
155 DEBUG ((EFI_D_INFO
, "HOBLIST address before memory init = 0x%08x\n", OldHandOffHob
));
156 DEBUG ((EFI_D_INFO
, "HOBLIST address after memory init = 0x%08x\n", NewHandOffHob
));
161 (UINTN
)EfiFreeMemorySize
164 NewHandOffHob
->EfiMemoryTop
= MemoryBegin
+ MemoryLength
;
165 NewHandOffHob
->EfiFreeMemoryTop
= NewHandOffHob
->EfiMemoryTop
;
166 NewHandOffHob
->EfiMemoryBottom
= MemoryBegin
;
168 NewHandOffHob
->EfiFreeMemoryBottom
= (UINTN
)NewHandOffHob
+ EfiFreeMemorySize
;
170 NewHandOffHob
->EfiEndOfHobList
= (UINTN
)NewHandOffHob
+
171 (OldHandOffHob
->EfiEndOfHobList
-
172 PhysicalAddressOfOldHob
);
174 ConvertPpiPointers (PeiServices
, OldHandOffHob
, NewHandOffHob
);
176 BuildStackHob (PrivateData
->StackBase
, PrivateData
->StackSize
);
185 IN EFI_PEI_SERVICES
**PeiServices
,
186 IN EFI_MEMORY_TYPE MemoryType
,
188 OUT EFI_PHYSICAL_ADDRESS
*Memory
194 Memory allocation service on permanent memory,
195 not usable prior to the memory installation.
199 PeiServices - The PEI core services table.
200 MemoryType - Type of memory to allocate.
201 Pages - Number of pages to allocate.
202 Memory - Pointer of memory allocated.
206 Status - EFI_SUCCESS The allocation was successful
207 EFI_INVALID_PARAMETER Only AllocateAnyAddress is supported.
208 EFI_NOT_AVAILABLE_YET Called with permanent memory not available
209 EFI_OUT_OF_RESOURCES There is not enough HOB heap to satisfy the requirement
210 to allocate the number of pages.
214 PEI_CORE_INSTANCE
*PrivateData
;
215 EFI_PEI_HOB_POINTERS Hob
;
216 EFI_PHYSICAL_ADDRESS Offset
;
218 PrivateData
= PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices
);
221 // Check if Hob already available
223 if (!PrivateData
->PeiMemoryInstalled
) {
224 return EFI_NOT_AVAILABLE_YET
;
227 Hob
.Raw
= PrivateData
->HobList
.Raw
;
230 // Check to see if on 4k boundary
232 Offset
= Hob
.HandoffInformationTable
->EfiFreeMemoryTop
& 0xFFF;
235 // If not aligned, make the allocation aligned.
238 Hob
.HandoffInformationTable
->EfiFreeMemoryTop
-= Offset
;
242 // Verify that there is sufficient memory to satisfy the allocation
244 if (Hob
.HandoffInformationTable
->EfiFreeMemoryTop
- ((Pages
* EFI_PAGE_SIZE
) + sizeof (EFI_HOB_MEMORY_ALLOCATION
)) <
245 Hob
.HandoffInformationTable
->EfiFreeMemoryBottom
) {
246 DEBUG ((EFI_D_ERROR
, "AllocatePages failed: No 0x%x Pages is available.\n", Pages
));
247 DEBUG ((EFI_D_ERROR
, "There is only left 0x%x pages memory resource to be allocated.\n", \
248 (Hob
.HandoffInformationTable
->EfiFreeMemoryTop
- Hob
.HandoffInformationTable
->EfiFreeMemoryBottom
)/EFI_PAGE_SIZE
));
249 return EFI_OUT_OF_RESOURCES
;
252 // Update the PHIT to reflect the memory usage
254 Hob
.HandoffInformationTable
->EfiFreeMemoryTop
-= Pages
* EFI_PAGE_SIZE
;
257 // Update the value for the caller
259 *Memory
= Hob
.HandoffInformationTable
->EfiFreeMemoryTop
;
262 // Create a memory allocation HOB.
264 BuildMemoryAllocationHob (
265 Hob
.HandoffInformationTable
->EfiFreeMemoryTop
,
266 Pages
* EFI_PAGE_SIZE
+ Offset
,
278 IN EFI_PEI_SERVICES
**PeiServices
,
286 Memory allocation service on the CAR.
290 PeiServices - The PEI core services table.
292 Size - Amount of memory required
294 Buffer - Address of pointer to the buffer
298 Status - EFI_SUCCESS The allocation was successful
299 EFI_OUT_OF_RESOURCES There is not enough heap to satisfy the requirement
300 to allocate the requested size.
305 EFI_HOB_MEMORY_POOL
*Hob
;
308 // If some "post-memory" PEIM wishes to allocate larger pool,
309 // it should use AllocatePages service instead.
311 ASSERT (Size
< 0x10000 - sizeof (EFI_HOB_MEMORY_POOL
));
312 Status
= PeiServicesCreateHob (
313 EFI_HOB_TYPE_PEI_MEMORY_POOL
,
314 (UINT16
)(sizeof (EFI_HOB_MEMORY_POOL
) + Size
),