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