]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/Pei/Memory/MemoryServices.c
Merge Temporary Ram support patch.
[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
58dcdada 24static EFI_PEI_PPI_DESCRIPTOR mMemoryDiscoveredPpi = {\r
25 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
26 &gEfiPeiMemoryDiscoveredPpiGuid,\r
27 NULL\r
28};\r
29\r
192f6d4c 30VOID\r
31InitializeMemoryServices (\r
b0d803fe 32 IN PEI_CORE_INSTANCE *PrivateData,\r
5aae0aa7 33 IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,\r
192f6d4c 34 IN PEI_CORE_INSTANCE *OldCoreData\r
35 )\r
36/*++\r
37\r
38Routine Description:\r
39\r
40 Initialize the memory services.\r
41\r
42Arguments:\r
43\r
44 PeiServices - The PEI core services table.\r
5aae0aa7 45 SecCoreData - Points to a data structure containing information about the PEI core's operating\r
46 environment, such as the size and location of temporary RAM, the stack location and\r
47 the BFV location.\r
48\r
192f6d4c 49 OldCoreData - Pointer to the PEI Core data.\r
50 NULL if being run in non-permament memory mode.\r
51\r
52Returns:\r
53\r
54 None\r
55\r
56--*/\r
57{\r
58dcdada 58 \r
59 PrivateData->SwitchStackSignal = FALSE;\r
192f6d4c 60\r
61 if (OldCoreData == NULL) {\r
62\r
63 PrivateData->PeiMemoryInstalled = FALSE;\r
64\r
58dcdada 65 PrivateData->BottomOfCarHeap = SecCoreData->PeiTemporaryRamBase; \r
66 PrivateData->TopOfCarHeap = (VOID *)((UINTN)(PrivateData->BottomOfCarHeap) + SecCoreData->PeiTemporaryRamSize);\r
67 PrivateData->SizeOfTemporaryMemory = SecCoreData->TemporaryRamSize;\r
68 PrivateData->StackSize = (UINT64) SecCoreData->StackSize;\r
69 \r
192f6d4c 70 DEBUG_CODE_BEGIN ();\r
5aae0aa7 71 PrivateData->SizeOfCacheAsRam = SecCoreData->PeiTemporaryRamSize + SecCoreData->StackSize;\r
72 PrivateData->MaxTopOfCarHeap = (VOID *) ((UINTN) PrivateData->BottomOfCarHeap + (UINTN) PrivateData->SizeOfCacheAsRam);\r
b0d803fe 73 PrivateData->StackBase = (EFI_PHYSICAL_ADDRESS) (UINTN) SecCoreData->StackBase;\r
74 PrivateData->StackSize = (UINT64) SecCoreData->StackSize;\r
192f6d4c 75 DEBUG_CODE_END ();\r
76\r
77 PrivateData->HobList.Raw = PrivateData->BottomOfCarHeap;\r
78 \r
79 PeiCoreBuildHobHandoffInfoTable (\r
80 BOOT_WITH_FULL_CONFIGURATION,\r
81 (EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData->BottomOfCarHeap,\r
5aae0aa7 82 (UINTN) SecCoreData->PeiTemporaryRamSize\r
192f6d4c 83 );\r
192f6d4c 84\r
85 //\r
86 // Set PS to point to ServiceTableShadow in Cache\r
87 //\r
88 PrivateData->PS = &(PrivateData->ServiceTableShadow);\r
b0d803fe 89 }\r
90 \r
192f6d4c 91 return;\r
92}\r
93\r
94EFI_STATUS\r
95EFIAPI\r
96PeiInstallPeiMemory (\r
58dcdada 97 IN CONST EFI_PEI_SERVICES **PeiServices,\r
98 IN EFI_PHYSICAL_ADDRESS MemoryBegin,\r
99 IN UINT64 MemoryLength\r
192f6d4c 100 )\r
101/*++\r
102\r
103Routine Description:\r
104\r
105 Install the permanent memory is now available.\r
106 Creates HOB (PHIT and Stack).\r
107\r
108Arguments:\r
109\r
110 PeiServices - The PEI core services table.\r
111 MemoryBegin - Start of memory address.\r
112 MemoryLength - Length of memory.\r
113\r
114Returns:\r
115\r
116 Status - EFI_SUCCESS\r
117 \r
118--*/\r
119{\r
120 PEI_CORE_INSTANCE *PrivateData;\r
58dcdada 121\r
a3a15d21 122 DEBUG ((EFI_D_INFO, "PeiInstallPeiMemory MemoryBegin 0x%LX, MemoryLength 0x%LX\n", MemoryBegin, MemoryLength));\r
192f6d4c 123 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
124\r
58dcdada 125 PrivateData->PhysicalMemoryBegin = MemoryBegin;\r
126 PrivateData->PhysicalMemoryLength = MemoryLength;\r
127 PrivateData->FreePhysicalMemoryTop = MemoryBegin + MemoryLength;\r
128 \r
129 PrivateData->SwitchStackSignal = TRUE;\r
192f6d4c 130\r
131 return EFI_SUCCESS; \r
132}\r
133\r
134EFI_STATUS\r
135EFIAPI\r
136PeiAllocatePages (\r
0c2b5da8 137 IN CONST EFI_PEI_SERVICES **PeiServices,\r
192f6d4c 138 IN EFI_MEMORY_TYPE MemoryType,\r
139 IN UINTN Pages,\r
140 OUT EFI_PHYSICAL_ADDRESS *Memory\r
141 )\r
142/*++\r
143\r
144Routine Description:\r
145\r
146 Memory allocation service on permanent memory, \r
147 not usable prior to the memory installation.\r
148\r
149Arguments:\r
150\r
151 PeiServices - The PEI core services table.\r
152 MemoryType - Type of memory to allocate.\r
153 Pages - Number of pages to allocate.\r
154 Memory - Pointer of memory allocated.\r
155\r
156Returns:\r
157\r
158 Status - EFI_SUCCESS The allocation was successful\r
159 EFI_INVALID_PARAMETER Only AllocateAnyAddress is supported.\r
160 EFI_NOT_AVAILABLE_YET Called with permanent memory not available\r
161 EFI_OUT_OF_RESOURCES There is not enough HOB heap to satisfy the requirement\r
162 to allocate the number of pages.\r
163\r
164--*/\r
165{\r
166 PEI_CORE_INSTANCE *PrivateData;\r
167 EFI_PEI_HOB_POINTERS Hob;\r
168 EFI_PHYSICAL_ADDRESS Offset;\r
58dcdada 169 EFI_PHYSICAL_ADDRESS *FreeMemoryTop;\r
170 EFI_PHYSICAL_ADDRESS *FreeMemoryBottom;\r
192f6d4c 171\r
172 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
58dcdada 173 Hob.Raw = PrivateData->HobList.Raw;\r
174 \r
192f6d4c 175 //\r
176 // Check if Hob already available\r
177 //\r
178 if (!PrivateData->PeiMemoryInstalled) {\r
58dcdada 179 //\r
180 // When PeiInstallMemory is called but CAR has *not* been moved to temporary memory,\r
181 // the AllocatePage will dependent the field of PEI_CORE_INSTANCE structure.\r
182 //\r
183 if (!PrivateData->SwitchStackSignal) {\r
184 return EFI_NOT_AVAILABLE_YET;\r
185 } else {\r
186 FreeMemoryTop = &(PrivateData->FreePhysicalMemoryTop);\r
187 FreeMemoryBottom = &(PrivateData->PhysicalMemoryBegin);\r
188 }\r
189 } else {\r
190 FreeMemoryTop = &(Hob.HandoffInformationTable->EfiFreeMemoryTop);\r
191 FreeMemoryBottom = &(Hob.HandoffInformationTable->EfiFreeMemoryBottom);\r
192f6d4c 192 }\r
193\r
58dcdada 194 \r
192f6d4c 195\r
196 //\r
197 // Check to see if on 4k boundary\r
198 //\r
58dcdada 199 Offset = *(FreeMemoryTop) & 0xFFF;\r
200 \r
192f6d4c 201 //\r
202 // If not aligned, make the allocation aligned.\r
203 //\r
204 if (Offset != 0) {\r
58dcdada 205 *(FreeMemoryTop) -= Offset;\r
192f6d4c 206 }\r
58dcdada 207 \r
192f6d4c 208 //\r
209 // Verify that there is sufficient memory to satisfy the allocation\r
210 //\r
58dcdada 211 if (*(FreeMemoryTop) - ((Pages * EFI_PAGE_SIZE) + sizeof (EFI_HOB_MEMORY_ALLOCATION)) < \r
212 *(FreeMemoryBottom)) {\r
192f6d4c 213 DEBUG ((EFI_D_ERROR, "AllocatePages failed: No 0x%x Pages is available.\n", Pages));\r
214 DEBUG ((EFI_D_ERROR, "There is only left 0x%x pages memory resource to be allocated.\n", \\r
58dcdada 215 EFI_SIZE_TO_PAGES ((UINTN) (*(FreeMemoryTop) - *(FreeMemoryBottom)))));\r
192f6d4c 216 return EFI_OUT_OF_RESOURCES;\r
217 } else {\r
218 //\r
219 // Update the PHIT to reflect the memory usage\r
220 //\r
58dcdada 221 *(FreeMemoryTop) -= Pages * EFI_PAGE_SIZE;\r
192f6d4c 222\r
223 //\r
224 // Update the value for the caller\r
225 //\r
58dcdada 226 *Memory = *(FreeMemoryTop);\r
192f6d4c 227\r
228 //\r
229 // Create a memory allocation HOB.\r
230 //\r
231 BuildMemoryAllocationHob (\r
58dcdada 232 *(FreeMemoryTop),\r
0a7d0741 233 Pages * EFI_PAGE_SIZE,\r
192f6d4c 234 MemoryType\r
235 );\r
236\r
237 return EFI_SUCCESS;\r
238 }\r
239}\r
240\r
241\r
242EFI_STATUS\r
243EFIAPI\r
244PeiAllocatePool (\r
0c2b5da8 245 IN CONST EFI_PEI_SERVICES **PeiServices,\r
192f6d4c 246 IN UINTN Size,\r
247 OUT VOID **Buffer\r
248 )\r
249/*++\r
250\r
251Routine Description:\r
252\r
253 Memory allocation service on the CAR. \r
254\r
255Arguments:\r
256\r
257 PeiServices - The PEI core services table.\r
258\r
259 Size - Amount of memory required\r
260\r
261 Buffer - Address of pointer to the buffer\r
262\r
263Returns:\r
264\r
265 Status - EFI_SUCCESS The allocation was successful\r
266 EFI_OUT_OF_RESOURCES There is not enough heap to satisfy the requirement\r
267 to allocate the requested size.\r
268 \r
269--*/\r
270{\r
271 EFI_STATUS Status;\r
272 EFI_HOB_MEMORY_POOL *Hob;\r
273\r
274 //\r
275 // If some "post-memory" PEIM wishes to allocate larger pool,\r
276 // it should use AllocatePages service instead.\r
277 //\r
278 ASSERT (Size < 0x10000 - sizeof (EFI_HOB_MEMORY_POOL));\r
279 Status = PeiServicesCreateHob (\r
280 EFI_HOB_TYPE_MEMORY_POOL,\r
281 (UINT16)(sizeof (EFI_HOB_MEMORY_POOL) + Size),\r
282 (VOID **)&Hob\r
283 );\r
284 *Buffer = Hob+1; \r
285\r
286\r
287 return Status;\r
288}\r