Add TRUE to the depex.
[mirror_edk2.git] / MdeModulePkg / Core / Pei / Memory / MemoryServices.c
CommitLineData
615c6dd0 1/** @file\r
b1f6a7c6 2 EFI PEI Core memory services\r
3 \r
192f6d4c 4Copyright (c) 2006, Intel Corporation \r
5All rights reserved. This program and the accompanying materials \r
6are licensed and made available under the terms and conditions of the BSD License \r
7which accompanies this distribution. The full text of the license may be found at \r
8http://opensource.org/licenses/bsd-license.php \r
9 \r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
12\r
615c6dd0 13**/\r
192f6d4c 14\r
192f6d4c 15#include <PeiMain.h>\r
16\r
b1f6a7c6 17/**\r
192f6d4c 18\r
19 Initialize the memory services.\r
20\r
14941e68 21\r
22 @param PrivateData Add parameter description\r
b1f6a7c6 23 @param SecCoreData Points to a data structure containing information about the PEI core's operating\r
5aae0aa7 24 environment, such as the size and location of temporary RAM, the stack location and\r
25 the BFV location.\r
b1f6a7c6 26 @param OldCoreData Pointer to the PEI Core data.\r
192f6d4c 27 NULL if being run in non-permament memory mode.\r
28\r
b1f6a7c6 29**/\r
30VOID\r
31InitializeMemoryServices (\r
32 IN PEI_CORE_INSTANCE *PrivateData,\r
33 IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,\r
34 IN PEI_CORE_INSTANCE *OldCoreData\r
35 )\r
192f6d4c 36{\r
58dcdada 37 \r
38 PrivateData->SwitchStackSignal = FALSE;\r
192f6d4c 39\r
40f26b8f 40 //\r
41 // First entering PeiCore, following code will initialized some field\r
42 // in PeiCore's private data according to hand off data from sec core.\r
43 //\r
192f6d4c 44 if (OldCoreData == NULL) {\r
45\r
46 PrivateData->PeiMemoryInstalled = FALSE;\r
47\r
58dcdada 48 PrivateData->BottomOfCarHeap = SecCoreData->PeiTemporaryRamBase; \r
49 PrivateData->TopOfCarHeap = (VOID *)((UINTN)(PrivateData->BottomOfCarHeap) + SecCoreData->PeiTemporaryRamSize);\r
50 PrivateData->SizeOfTemporaryMemory = SecCoreData->TemporaryRamSize;\r
51 PrivateData->StackSize = (UINT64) SecCoreData->StackSize;\r
52 \r
192f6d4c 53 DEBUG_CODE_BEGIN ();\r
5aae0aa7 54 PrivateData->SizeOfCacheAsRam = SecCoreData->PeiTemporaryRamSize + SecCoreData->StackSize;\r
55 PrivateData->MaxTopOfCarHeap = (VOID *) ((UINTN) PrivateData->BottomOfCarHeap + (UINTN) PrivateData->SizeOfCacheAsRam);\r
b0d803fe 56 PrivateData->StackBase = (EFI_PHYSICAL_ADDRESS) (UINTN) SecCoreData->StackBase;\r
57 PrivateData->StackSize = (UINT64) SecCoreData->StackSize;\r
192f6d4c 58 DEBUG_CODE_END ();\r
59\r
60 PrivateData->HobList.Raw = PrivateData->BottomOfCarHeap;\r
61 \r
62 PeiCoreBuildHobHandoffInfoTable (\r
63 BOOT_WITH_FULL_CONFIGURATION,\r
64 (EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData->BottomOfCarHeap,\r
5aae0aa7 65 (UINTN) SecCoreData->PeiTemporaryRamSize\r
192f6d4c 66 );\r
192f6d4c 67\r
68 //\r
69 // Set PS to point to ServiceTableShadow in Cache\r
70 //\r
71 PrivateData->PS = &(PrivateData->ServiceTableShadow);\r
b0d803fe 72 }\r
73 \r
192f6d4c 74 return;\r
75}\r
76\r
b1f6a7c6 77/**\r
78\r
14941e68 79 Install the permanent memory is now available.\r
80 Creates HOB (PHIT and Stack).\r
b1f6a7c6 81\r
d73d93c3 82 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
83 @param MemoryBegin Start of memory address.\r
84 @param MemoryLength Length of memory.\r
b1f6a7c6 85\r
86 @return EFI_SUCCESS Always success.\r
87\r
88**/\r
192f6d4c 89EFI_STATUS\r
90EFIAPI\r
91PeiInstallPeiMemory (\r
58dcdada 92 IN CONST EFI_PEI_SERVICES **PeiServices,\r
93 IN EFI_PHYSICAL_ADDRESS MemoryBegin,\r
94 IN UINT64 MemoryLength\r
192f6d4c 95 )\r
192f6d4c 96{\r
97 PEI_CORE_INSTANCE *PrivateData;\r
58dcdada 98\r
a3a15d21 99 DEBUG ((EFI_D_INFO, "PeiInstallPeiMemory MemoryBegin 0x%LX, MemoryLength 0x%LX\n", MemoryBegin, MemoryLength));\r
192f6d4c 100 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
101\r
58dcdada 102 PrivateData->PhysicalMemoryBegin = MemoryBegin;\r
103 PrivateData->PhysicalMemoryLength = MemoryLength;\r
104 PrivateData->FreePhysicalMemoryTop = MemoryBegin + MemoryLength;\r
105 \r
106 PrivateData->SwitchStackSignal = TRUE;\r
192f6d4c 107\r
108 return EFI_SUCCESS; \r
109}\r
110\r
b1f6a7c6 111/**\r
112\r
113 Memory allocation service on permanent memory,\r
114 not usable prior to the memory installation.\r
115\r
116\r
d73d93c3 117 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
118 @param MemoryType Type of memory to allocate.\r
119 @param Pages Number of pages to allocate.\r
120 @param Memory Pointer of memory allocated.\r
b1f6a7c6 121\r
122 @retval EFI_SUCCESS The allocation was successful\r
14941e68 123 @retval EFI_INVALID_PARAMETER Only AllocateAnyAddress is supported.\r
b1f6a7c6 124 @retval EFI_NOT_AVAILABLE_YET Called with permanent memory not available\r
125 @retval EFI_OUT_OF_RESOURCES There is not enough HOB heap to satisfy the requirement\r
126 to allocate the number of pages.\r
127\r
128**/\r
192f6d4c 129EFI_STATUS\r
130EFIAPI\r
131PeiAllocatePages (\r
14941e68 132 IN CONST EFI_PEI_SERVICES **PeiServices,\r
133 IN EFI_MEMORY_TYPE MemoryType,\r
134 IN UINTN Pages,\r
135 OUT EFI_PHYSICAL_ADDRESS *Memory\r
192f6d4c 136 )\r
192f6d4c 137{\r
138 PEI_CORE_INSTANCE *PrivateData;\r
139 EFI_PEI_HOB_POINTERS Hob;\r
14941e68 140 EFI_PHYSICAL_ADDRESS Offset;\r
58dcdada 141 EFI_PHYSICAL_ADDRESS *FreeMemoryTop;\r
142 EFI_PHYSICAL_ADDRESS *FreeMemoryBottom;\r
192f6d4c 143\r
144 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);\r
58dcdada 145 Hob.Raw = PrivateData->HobList.Raw;\r
146 \r
192f6d4c 147 //\r
148 // Check if Hob already available\r
149 //\r
150 if (!PrivateData->PeiMemoryInstalled) {\r
58dcdada 151 //\r
152 // When PeiInstallMemory is called but CAR has *not* been moved to temporary memory,\r
14941e68 153 // the AllocatePage will dependent the field of PEI_CORE_INSTANCE structure.\r
58dcdada 154 //\r
155 if (!PrivateData->SwitchStackSignal) {\r
156 return EFI_NOT_AVAILABLE_YET;\r
157 } else {\r
158 FreeMemoryTop = &(PrivateData->FreePhysicalMemoryTop);\r
159 FreeMemoryBottom = &(PrivateData->PhysicalMemoryBegin);\r
160 }\r
161 } else {\r
162 FreeMemoryTop = &(Hob.HandoffInformationTable->EfiFreeMemoryTop);\r
163 FreeMemoryBottom = &(Hob.HandoffInformationTable->EfiFreeMemoryBottom);\r
192f6d4c 164 }\r
165\r
192f6d4c 166 //\r
14941e68 167 // Check to see if on 4k boundary\r
192f6d4c 168 //\r
14941e68 169 Offset = *(FreeMemoryTop) & 0xFFF;\r
170 \r
171 //\r
172 // If not aligned, make the allocation aligned.\r
173 //\r
174 if (Offset != 0) {\r
175 *(FreeMemoryTop) -= Offset;\r
176 }\r
58dcdada 177 \r
192f6d4c 178 //\r
179 // Verify that there is sufficient memory to satisfy the allocation\r
180 //\r
58dcdada 181 if (*(FreeMemoryTop) - ((Pages * EFI_PAGE_SIZE) + sizeof (EFI_HOB_MEMORY_ALLOCATION)) < \r
182 *(FreeMemoryBottom)) {\r
192f6d4c 183 DEBUG ((EFI_D_ERROR, "AllocatePages failed: No 0x%x Pages is available.\n", Pages));\r
184 DEBUG ((EFI_D_ERROR, "There is only left 0x%x pages memory resource to be allocated.\n", \\r
58dcdada 185 EFI_SIZE_TO_PAGES ((UINTN) (*(FreeMemoryTop) - *(FreeMemoryBottom)))));\r
192f6d4c 186 return EFI_OUT_OF_RESOURCES;\r
187 } else {\r
188 //\r
189 // Update the PHIT to reflect the memory usage\r
190 //\r
58dcdada 191 *(FreeMemoryTop) -= Pages * EFI_PAGE_SIZE;\r
192f6d4c 192\r
193 //\r
194 // Update the value for the caller\r
195 //\r
58dcdada 196 *Memory = *(FreeMemoryTop);\r
192f6d4c 197\r
198 //\r
199 // Create a memory allocation HOB.\r
200 //\r
201 BuildMemoryAllocationHob (\r
58dcdada 202 *(FreeMemoryTop),\r
0a7d0741 203 Pages * EFI_PAGE_SIZE,\r
192f6d4c 204 MemoryType\r
205 );\r
206\r
207 return EFI_SUCCESS;\r
208 }\r
209}\r
210\r
b1f6a7c6 211/**\r
212\r
14941e68 213 Memory allocation service on the CAR.\r
214\r
b1f6a7c6 215\r
14941e68 216 @param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.\r
217 @param Size Amount of memory required\r
218 @param Buffer Address of pointer to the buffer\r
b1f6a7c6 219\r
220 @retval EFI_SUCCESS The allocation was successful\r
221 @retval EFI_OUT_OF_RESOURCES There is not enough heap to satisfy the requirement\r
222 to allocate the requested size.\r
223\r
224**/\r
192f6d4c 225EFI_STATUS\r
226EFIAPI\r
227PeiAllocatePool (\r
14941e68 228 IN CONST EFI_PEI_SERVICES **PeiServices,\r
229 IN UINTN Size,\r
230 OUT VOID **Buffer\r
192f6d4c 231 )\r
192f6d4c 232{\r
233 EFI_STATUS Status;\r
234 EFI_HOB_MEMORY_POOL *Hob;\r
235\r
14941e68 236 //\r
237 // If some "post-memory" PEIM wishes to allocate larger pool,\r
238 // it should use AllocatePages service instead.\r
239 //\r
240 ASSERT (Size < 0x10000 - sizeof (EFI_HOB_MEMORY_POOL));\r
241 Status = PeiServicesCreateHob (\r
192f6d4c 242 EFI_HOB_TYPE_MEMORY_POOL,\r
243 (UINT16)(sizeof (EFI_HOB_MEMORY_POOL) + Size),\r
244 (VOID **)&Hob\r
245 );\r
246 *Buffer = Hob+1; \r
247\r
14941e68 248\r
192f6d4c 249 return Status;\r
250}\r