]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/Pei/Memory/MemoryServices.c
Merge branch of PI tree to main trunk
[mirror_edk2.git] / MdeModulePkg / Core / Pei / Memory / MemoryServices.c
CommitLineData
192f6d4c 1/*++\r
2\r
3Copyright (c) 2006, Intel Corporation \r
4All rights reserved. This program and the accompanying materials \r
5are licensed and made available under the terms and conditions of the BSD License \r
6which accompanies this distribution. The full text of the license may be found at \r
7http://opensource.org/licenses/bsd-license.php \r
8 \r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
11\r
12Module Name:\r
13\r
14 MemoryServices.c\r
15\r
16Abstract:\r
17\r
18 EFI PEI Core memory services\r
19\r
20--*/\r
21\r
192f6d4c 22#include <PeiMain.h>\r
23\r
24VOID\r
25InitializeMemoryServices (\r
b0d803fe 26 IN PEI_CORE_INSTANCE *PrivateData,\r
5aae0aa7 27 IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,\r
192f6d4c 28 IN PEI_CORE_INSTANCE *OldCoreData\r
29 )\r
30/*++\r
31\r
32Routine Description:\r
33\r
34 Initialize the memory services.\r
35\r
36Arguments:\r
37\r
38 PeiServices - The PEI core services table.\r
5aae0aa7 39 SecCoreData - Points to a data structure containing information about the PEI core's operating\r
40 environment, such as the size and location of temporary RAM, the stack location and\r
41 the BFV location.\r
42\r
192f6d4c 43 OldCoreData - Pointer to the PEI Core data.\r
44 NULL if being run in non-permament memory mode.\r
45\r
46Returns:\r
47\r
48 None\r
49\r
50--*/\r
51{\r
192f6d4c 52 PrivateData->SwitchStackSignal = FALSE;\r
53\r
54 if (OldCoreData == NULL) {\r
55\r
56 PrivateData->PeiMemoryInstalled = FALSE;\r
57\r
5aae0aa7 58 PrivateData->BottomOfCarHeap = SecCoreData->PeiTemporaryRamBase; \r
59 PrivateData->TopOfCarHeap = (VOID *)((UINTN)(PrivateData->BottomOfCarHeap) + SecCoreData->PeiTemporaryRamSize);\r
192f6d4c 60 \r
61 DEBUG_CODE_BEGIN ();\r
5aae0aa7 62 PrivateData->SizeOfCacheAsRam = SecCoreData->PeiTemporaryRamSize + SecCoreData->StackSize;\r
63 PrivateData->MaxTopOfCarHeap = (VOID *) ((UINTN) PrivateData->BottomOfCarHeap + (UINTN) PrivateData->SizeOfCacheAsRam);\r
b0d803fe 64 PrivateData->StackBase = (EFI_PHYSICAL_ADDRESS) (UINTN) SecCoreData->StackBase;\r
65 PrivateData->StackSize = (UINT64) SecCoreData->StackSize;\r
192f6d4c 66 DEBUG_CODE_END ();\r
67\r
68 PrivateData->HobList.Raw = PrivateData->BottomOfCarHeap;\r
69 \r
70 PeiCoreBuildHobHandoffInfoTable (\r
71 BOOT_WITH_FULL_CONFIGURATION,\r
72 (EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData->BottomOfCarHeap,\r
5aae0aa7 73 (UINTN) SecCoreData->PeiTemporaryRamSize\r
192f6d4c 74 );\r
192f6d4c 75\r
76 //\r
77 // Set PS to point to ServiceTableShadow in Cache\r
78 //\r
79 PrivateData->PS = &(PrivateData->ServiceTableShadow);\r
b0d803fe 80 }\r
81 \r
192f6d4c 82 return;\r
83}\r
84\r
85EFI_STATUS\r
86EFIAPI\r
87PeiInstallPeiMemory (\r
0c2b5da8 88 IN CONST EFI_PEI_SERVICES **PeiServices,\r
192f6d4c 89 IN EFI_PHYSICAL_ADDRESS MemoryBegin,\r
90 IN UINT64 MemoryLength\r
91 )\r
92/*++\r
93\r
94Routine Description:\r
95\r
96 Install the permanent memory is now available.\r
97 Creates HOB (PHIT and Stack).\r
98\r
99Arguments:\r
100\r
101 PeiServices - The PEI core services table.\r
102 MemoryBegin - Start of memory address.\r
103 MemoryLength - Length of memory.\r
104\r
105Returns:\r
106\r
107 Status - EFI_SUCCESS\r
108 \r
109--*/\r
110{\r
111 PEI_CORE_INSTANCE *PrivateData;\r
112 EFI_HOB_HANDOFF_INFO_TABLE *OldHandOffHob;\r
113 EFI_HOB_HANDOFF_INFO_TABLE *NewHandOffHob;\r
114 UINT64 PeiStackSize;\r
115 UINT64 EfiFreeMemorySize;\r
116 EFI_PHYSICAL_ADDRESS PhysicalAddressOfOldHob;\r
117 \r
118 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
119\r
120 PrivateData->SwitchStackSignal = TRUE;\r
121 PrivateData->PeiMemoryInstalled = TRUE;\r
122\r
123 PrivateData->StackBase = MemoryBegin;\r
124 \r
125 PeiStackSize = RShiftU64 (MemoryLength, 1);\r
126 if (PEI_STACK_SIZE > PeiStackSize) {\r
127 PrivateData->StackSize = PeiStackSize;\r
128 } else {\r
129 PrivateData->StackSize = PEI_STACK_SIZE;\r
130 }\r
131\r
132 OldHandOffHob = PrivateData->HobList.HandoffInformationTable;\r
133\r
134 PrivateData->HobList.Raw = (VOID *)((UINTN)(MemoryBegin + PrivateData->StackSize));\r
135 NewHandOffHob = PrivateData->HobList.HandoffInformationTable;\r
136 PhysicalAddressOfOldHob = (EFI_PHYSICAL_ADDRESS) (UINTN) OldHandOffHob;\r
137\r
138 EfiFreeMemorySize = OldHandOffHob->EfiFreeMemoryBottom - PhysicalAddressOfOldHob;\r
139 \r
140 DEBUG ((EFI_D_INFO, "HOBLIST address before memory init = 0x%08x\n", OldHandOffHob));\r
141 DEBUG ((EFI_D_INFO, "HOBLIST address after memory init = 0x%08x\n", NewHandOffHob));\r
142\r
143 CopyMem (\r
144 NewHandOffHob,\r
145 OldHandOffHob,\r
146 (UINTN)EfiFreeMemorySize\r
147 );\r
148\r
149 NewHandOffHob->EfiMemoryTop = MemoryBegin + MemoryLength;\r
150 NewHandOffHob->EfiFreeMemoryTop = NewHandOffHob->EfiMemoryTop;\r
151 NewHandOffHob->EfiMemoryBottom = MemoryBegin;\r
152 \r
153 NewHandOffHob->EfiFreeMemoryBottom = (UINTN)NewHandOffHob + EfiFreeMemorySize; \r
154 \r
155 NewHandOffHob->EfiEndOfHobList = (UINTN)NewHandOffHob +\r
156 (OldHandOffHob->EfiEndOfHobList -\r
157 PhysicalAddressOfOldHob);\r
158\r
159 ConvertPpiPointers (PeiServices, OldHandOffHob, NewHandOffHob);\r
160\r
161 BuildStackHob (PrivateData->StackBase, PrivateData->StackSize);\r
162 \r
163\r
164 return EFI_SUCCESS; \r
165}\r
166\r
167EFI_STATUS\r
168EFIAPI\r
169PeiAllocatePages (\r
0c2b5da8 170 IN CONST EFI_PEI_SERVICES **PeiServices,\r
192f6d4c 171 IN EFI_MEMORY_TYPE MemoryType,\r
172 IN UINTN Pages,\r
173 OUT EFI_PHYSICAL_ADDRESS *Memory\r
174 )\r
175/*++\r
176\r
177Routine Description:\r
178\r
179 Memory allocation service on permanent memory, \r
180 not usable prior to the memory installation.\r
181\r
182Arguments:\r
183\r
184 PeiServices - The PEI core services table.\r
185 MemoryType - Type of memory to allocate.\r
186 Pages - Number of pages to allocate.\r
187 Memory - Pointer of memory allocated.\r
188\r
189Returns:\r
190\r
191 Status - EFI_SUCCESS The allocation was successful\r
192 EFI_INVALID_PARAMETER Only AllocateAnyAddress is supported.\r
193 EFI_NOT_AVAILABLE_YET Called with permanent memory not available\r
194 EFI_OUT_OF_RESOURCES There is not enough HOB heap to satisfy the requirement\r
195 to allocate the number of pages.\r
196\r
197--*/\r
198{\r
199 PEI_CORE_INSTANCE *PrivateData;\r
200 EFI_PEI_HOB_POINTERS Hob;\r
201 EFI_PHYSICAL_ADDRESS Offset;\r
202\r
203 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
204\r
205 //\r
206 // Check if Hob already available\r
207 //\r
208 if (!PrivateData->PeiMemoryInstalled) {\r
209 return EFI_NOT_AVAILABLE_YET;\r
210 }\r
211\r
212 Hob.Raw = PrivateData->HobList.Raw;\r
213\r
214 //\r
215 // Check to see if on 4k boundary\r
216 //\r
217 Offset = Hob.HandoffInformationTable->EfiFreeMemoryTop & 0xFFF;\r
218\r
219 //\r
220 // If not aligned, make the allocation aligned.\r
221 //\r
222 if (Offset != 0) {\r
223 Hob.HandoffInformationTable->EfiFreeMemoryTop -= Offset;\r
224 }\r
225\r
226 //\r
227 // Verify that there is sufficient memory to satisfy the allocation\r
228 //\r
229 if (Hob.HandoffInformationTable->EfiFreeMemoryTop - ((Pages * EFI_PAGE_SIZE) + sizeof (EFI_HOB_MEMORY_ALLOCATION)) < \r
230 Hob.HandoffInformationTable->EfiFreeMemoryBottom) {\r
231 DEBUG ((EFI_D_ERROR, "AllocatePages failed: No 0x%x Pages is available.\n", Pages));\r
232 DEBUG ((EFI_D_ERROR, "There is only left 0x%x pages memory resource to be allocated.\n", \\r
233 EFI_SIZE_TO_PAGES ((UINTN) (Hob.HandoffInformationTable->EfiFreeMemoryTop - Hob.HandoffInformationTable->EfiFreeMemoryBottom))));\r
234 return EFI_OUT_OF_RESOURCES;\r
235 } else {\r
236 //\r
237 // Update the PHIT to reflect the memory usage\r
238 //\r
239 Hob.HandoffInformationTable->EfiFreeMemoryTop -= Pages * EFI_PAGE_SIZE;\r
240\r
241 //\r
242 // Update the value for the caller\r
243 //\r
244 *Memory = Hob.HandoffInformationTable->EfiFreeMemoryTop;\r
245\r
246 //\r
247 // Create a memory allocation HOB.\r
248 //\r
249 BuildMemoryAllocationHob (\r
250 Hob.HandoffInformationTable->EfiFreeMemoryTop,\r
251 Pages * EFI_PAGE_SIZE + Offset,\r
252 MemoryType\r
253 );\r
254\r
255 return EFI_SUCCESS;\r
256 }\r
257}\r
258\r
259\r
260EFI_STATUS\r
261EFIAPI\r
262PeiAllocatePool (\r
0c2b5da8 263 IN CONST EFI_PEI_SERVICES **PeiServices,\r
192f6d4c 264 IN UINTN Size,\r
265 OUT VOID **Buffer\r
266 )\r
267/*++\r
268\r
269Routine Description:\r
270\r
271 Memory allocation service on the CAR. \r
272\r
273Arguments:\r
274\r
275 PeiServices - The PEI core services table.\r
276\r
277 Size - Amount of memory required\r
278\r
279 Buffer - Address of pointer to the buffer\r
280\r
281Returns:\r
282\r
283 Status - EFI_SUCCESS The allocation was successful\r
284 EFI_OUT_OF_RESOURCES There is not enough heap to satisfy the requirement\r
285 to allocate the requested size.\r
286 \r
287--*/\r
288{\r
289 EFI_STATUS Status;\r
290 EFI_HOB_MEMORY_POOL *Hob;\r
291\r
292 //\r
293 // If some "post-memory" PEIM wishes to allocate larger pool,\r
294 // it should use AllocatePages service instead.\r
295 //\r
296 ASSERT (Size < 0x10000 - sizeof (EFI_HOB_MEMORY_POOL));\r
297 Status = PeiServicesCreateHob (\r
298 EFI_HOB_TYPE_MEMORY_POOL,\r
299 (UINT16)(sizeof (EFI_HOB_MEMORY_POOL) + Size),\r
300 (VOID **)&Hob\r
301 );\r
302 *Buffer = Hob+1; \r
303\r
304\r
305 return Status;\r
306}\r