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