]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Core/Pei/Memory/MemoryServices.c
Update PeiReportStatusCodeLib instance, which will support report data prior to...
[mirror_edk2.git] / MdeModulePkg / Core / Pei / Memory / MemoryServices.c
... / ...
CommitLineData
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
22#include <PeiMain.h>\r
23\r
24VOID\r
25InitializeMemoryServices (\r
26 IN PEI_CORE_INSTANCE *PrivateData,\r
27 IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,\r
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
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
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
52 PrivateData->SwitchStackSignal = FALSE;\r
53\r
54 if (OldCoreData == NULL) {\r
55\r
56 PrivateData->PeiMemoryInstalled = FALSE;\r
57\r
58 PrivateData->BottomOfCarHeap = SecCoreData->PeiTemporaryRamBase; \r
59 PrivateData->TopOfCarHeap = (VOID *)((UINTN)(PrivateData->BottomOfCarHeap) + SecCoreData->PeiTemporaryRamSize);\r
60 \r
61 DEBUG_CODE_BEGIN ();\r
62 PrivateData->SizeOfCacheAsRam = SecCoreData->PeiTemporaryRamSize + SecCoreData->StackSize;\r
63 PrivateData->MaxTopOfCarHeap = (VOID *) ((UINTN) PrivateData->BottomOfCarHeap + (UINTN) PrivateData->SizeOfCacheAsRam);\r
64 PrivateData->StackBase = (EFI_PHYSICAL_ADDRESS) (UINTN) SecCoreData->StackBase;\r
65 PrivateData->StackSize = (UINT64) SecCoreData->StackSize;\r
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
73 (UINTN) SecCoreData->PeiTemporaryRamSize\r
74 );\r
75\r
76 //\r
77 // Set PS to point to ServiceTableShadow in Cache\r
78 //\r
79 PrivateData->PS = &(PrivateData->ServiceTableShadow);\r
80 }\r
81 \r
82 return;\r
83}\r
84\r
85EFI_STATUS\r
86EFIAPI\r
87PeiInstallPeiMemory (\r
88 IN CONST EFI_PEI_SERVICES **PeiServices,\r
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 DEBUG ((EFI_D_INFO, "PeiInstallPeiMemory MemoryBegin 0x%LX, MemoryLength 0x%LX\n", MemoryBegin, MemoryLength));\r
119 \r
120 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
121\r
122 PrivateData->SwitchStackSignal = TRUE;\r
123 PrivateData->PeiMemoryInstalled = TRUE;\r
124\r
125 PrivateData->StackBase = MemoryBegin;\r
126 \r
127 PeiStackSize = RShiftU64 (MemoryLength, 1);\r
128 if (PEI_STACK_SIZE > PeiStackSize) {\r
129 PrivateData->StackSize = PeiStackSize;\r
130 } else {\r
131 PrivateData->StackSize = PEI_STACK_SIZE;\r
132 }\r
133\r
134 OldHandOffHob = PrivateData->HobList.HandoffInformationTable;\r
135\r
136 PrivateData->HobList.Raw = (VOID *)((UINTN)(MemoryBegin + PrivateData->StackSize));\r
137 NewHandOffHob = PrivateData->HobList.HandoffInformationTable;\r
138 PhysicalAddressOfOldHob = (EFI_PHYSICAL_ADDRESS) (UINTN) OldHandOffHob;\r
139\r
140 EfiFreeMemorySize = OldHandOffHob->EfiFreeMemoryBottom - PhysicalAddressOfOldHob;\r
141 \r
142 DEBUG ((EFI_D_INFO, "HOBLIST address before memory init = 0x%p\n", OldHandOffHob));\r
143 DEBUG ((EFI_D_INFO, "HOBLIST address after memory init = 0x%p\n", NewHandOffHob));\r
144\r
145 CopyMem (\r
146 NewHandOffHob,\r
147 OldHandOffHob,\r
148 (UINTN)EfiFreeMemorySize\r
149 );\r
150\r
151 NewHandOffHob->EfiMemoryTop = MemoryBegin + MemoryLength;\r
152 NewHandOffHob->EfiFreeMemoryTop = NewHandOffHob->EfiMemoryTop;\r
153 NewHandOffHob->EfiMemoryBottom = MemoryBegin;\r
154 \r
155 NewHandOffHob->EfiFreeMemoryBottom = (UINTN)NewHandOffHob + EfiFreeMemorySize; \r
156 \r
157 NewHandOffHob->EfiEndOfHobList = (UINTN)NewHandOffHob +\r
158 (OldHandOffHob->EfiEndOfHobList -\r
159 PhysicalAddressOfOldHob);\r
160 \r
161 //\r
162 // For IPF in CAR mode the real memory access is uncached,in InstallPeiMemory()\r
163 // the 63-bit of address is set to 1.\r
164 //\r
165 SWITCH_TO_CACHE_MODE (PrivateData);\r
166 \r
167 ConvertPpiPointers (PeiServices, OldHandOffHob, NewHandOffHob);\r
168\r
169 BuildStackHob (PrivateData->StackBase, PrivateData->StackSize);\r
170 \r
171\r
172 return EFI_SUCCESS; \r
173}\r
174\r
175EFI_STATUS\r
176EFIAPI\r
177PeiAllocatePages (\r
178 IN CONST EFI_PEI_SERVICES **PeiServices,\r
179 IN EFI_MEMORY_TYPE MemoryType,\r
180 IN UINTN Pages,\r
181 OUT EFI_PHYSICAL_ADDRESS *Memory\r
182 )\r
183/*++\r
184\r
185Routine Description:\r
186\r
187 Memory allocation service on permanent memory, \r
188 not usable prior to the memory installation.\r
189\r
190Arguments:\r
191\r
192 PeiServices - The PEI core services table.\r
193 MemoryType - Type of memory to allocate.\r
194 Pages - Number of pages to allocate.\r
195 Memory - Pointer of memory allocated.\r
196\r
197Returns:\r
198\r
199 Status - EFI_SUCCESS The allocation was successful\r
200 EFI_INVALID_PARAMETER Only AllocateAnyAddress is supported.\r
201 EFI_NOT_AVAILABLE_YET Called with permanent memory not available\r
202 EFI_OUT_OF_RESOURCES There is not enough HOB heap to satisfy the requirement\r
203 to allocate the number of pages.\r
204\r
205--*/\r
206{\r
207 PEI_CORE_INSTANCE *PrivateData;\r
208 EFI_PEI_HOB_POINTERS Hob;\r
209 EFI_PHYSICAL_ADDRESS Offset;\r
210\r
211 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
212\r
213 //\r
214 // Check if Hob already available\r
215 //\r
216 if (!PrivateData->PeiMemoryInstalled) {\r
217 return EFI_NOT_AVAILABLE_YET;\r
218 }\r
219\r
220 Hob.Raw = PrivateData->HobList.Raw;\r
221\r
222 //\r
223 // Check to see if on 4k boundary\r
224 //\r
225 Offset = Hob.HandoffInformationTable->EfiFreeMemoryTop & 0xFFF;\r
226\r
227 //\r
228 // If not aligned, make the allocation aligned.\r
229 //\r
230 if (Offset != 0) {\r
231 Hob.HandoffInformationTable->EfiFreeMemoryTop -= Offset;\r
232 }\r
233\r
234 ASSERT (Hob.HandoffInformationTable->EfiFreeMemoryTop >= Hob.HandoffInformationTable->EfiFreeMemoryBottom);\r
235 //\r
236 // Verify that there is sufficient memory to satisfy the allocation\r
237 //\r
238 if (Hob.HandoffInformationTable->EfiFreeMemoryTop - ((Pages * EFI_PAGE_SIZE) + sizeof (EFI_HOB_MEMORY_ALLOCATION)) < \r
239 Hob.HandoffInformationTable->EfiFreeMemoryBottom) {\r
240 DEBUG ((EFI_D_ERROR, "AllocatePages failed: No 0x%x Pages is available.\n", Pages));\r
241 DEBUG ((EFI_D_ERROR, "There is only left 0x%x pages memory resource to be allocated.\n", \\r
242 EFI_SIZE_TO_PAGES ((UINTN) (Hob.HandoffInformationTable->EfiFreeMemoryTop - Hob.HandoffInformationTable->EfiFreeMemoryBottom))));\r
243 return EFI_OUT_OF_RESOURCES;\r
244 } else {\r
245 //\r
246 // Update the PHIT to reflect the memory usage\r
247 //\r
248 Hob.HandoffInformationTable->EfiFreeMemoryTop -= Pages * EFI_PAGE_SIZE;\r
249\r
250 //\r
251 // Update the value for the caller\r
252 //\r
253 *Memory = Hob.HandoffInformationTable->EfiFreeMemoryTop;\r
254\r
255 //\r
256 // Create a memory allocation HOB.\r
257 //\r
258 BuildMemoryAllocationHob (\r
259 Hob.HandoffInformationTable->EfiFreeMemoryTop,\r
260 Pages * EFI_PAGE_SIZE,\r
261 MemoryType\r
262 );\r
263\r
264 return EFI_SUCCESS;\r
265 }\r
266}\r
267\r
268\r
269EFI_STATUS\r
270EFIAPI\r
271PeiAllocatePool (\r
272 IN CONST EFI_PEI_SERVICES **PeiServices,\r
273 IN UINTN Size,\r
274 OUT VOID **Buffer\r
275 )\r
276/*++\r
277\r
278Routine Description:\r
279\r
280 Memory allocation service on the CAR. \r
281\r
282Arguments:\r
283\r
284 PeiServices - The PEI core services table.\r
285\r
286 Size - Amount of memory required\r
287\r
288 Buffer - Address of pointer to the buffer\r
289\r
290Returns:\r
291\r
292 Status - EFI_SUCCESS The allocation was successful\r
293 EFI_OUT_OF_RESOURCES There is not enough heap to satisfy the requirement\r
294 to allocate the requested size.\r
295 \r
296--*/\r
297{\r
298 EFI_STATUS Status;\r
299 EFI_HOB_MEMORY_POOL *Hob;\r
300\r
301 //\r
302 // If some "post-memory" PEIM wishes to allocate larger pool,\r
303 // it should use AllocatePages service instead.\r
304 //\r
305 ASSERT (Size < 0x10000 - sizeof (EFI_HOB_MEMORY_POOL));\r
306 Status = PeiServicesCreateHob (\r
307 EFI_HOB_TYPE_MEMORY_POOL,\r
308 (UINT16)(sizeof (EFI_HOB_MEMORY_POOL) + Size),\r
309 (VOID **)&Hob\r
310 );\r
311 *Buffer = Hob+1; \r
312\r
313\r
314 return Status;\r
315}\r