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