]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFspWrapperPkg/Library/PeiFspHobProcessLibSample/FspHobProcessLibSample.c
a96c151df4cd810f884f9d1941d22db09c324b5b
[mirror_edk2.git] / IntelFspWrapperPkg / Library / PeiFspHobProcessLibSample / FspHobProcessLibSample.c
1 /** @file
2 Sample to provide FSP hob process related function.
3
4 Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
5 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 <PiPei.h>
16
17 #include <Library/PeiServicesLib.h>
18 #include <Library/PeiServicesTablePointerLib.h>
19 #include <Library/BaseLib.h>
20 #include <Library/DebugLib.h>
21 #include <Library/BaseMemoryLib.h>
22 #include <Library/HobLib.h>
23 #include <Library/PcdLib.h>
24 #include <Library/FspPlatformInfoLib.h>
25
26 #include <Guid/GuidHobFspEas.h>
27 #include <Guid/MemoryTypeInformation.h>
28 #include <Guid/PcdDataBaseHobGuid.h>
29 #include <Ppi/Capsule.h>
30
31 //
32 // Additional pages are used by DXE memory manager.
33 // It should be consistent between RetrieveRequiredMemorySize() and GetPeiMemSize()
34 //
35 #define PEI_ADDITIONAL_MEMORY_SIZE (16 * EFI_PAGE_SIZE)
36
37 /**
38 Get the mem size in memory type infromation table.
39
40 @param[in] PeiServices PEI Services table.
41
42 @return the mem size in memory type infromation table.
43 **/
44 UINT64
45 GetMemorySizeInMemoryTypeInformation (
46 IN EFI_PEI_SERVICES **PeiServices
47 )
48 {
49 EFI_STATUS Status;
50 EFI_PEI_HOB_POINTERS Hob;
51 EFI_MEMORY_TYPE_INFORMATION *MemoryData;
52 UINT8 Index;
53 UINTN TempPageNum;
54
55 MemoryData = NULL;
56 Status = (*PeiServices)->GetHobList ((CONST EFI_PEI_SERVICES**)PeiServices, (VOID **) &Hob.Raw);
57 while (!END_OF_HOB_LIST (Hob)) {
58 if (Hob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION &&
59 CompareGuid (&Hob.Guid->Name, &gEfiMemoryTypeInformationGuid)) {
60 MemoryData = (EFI_MEMORY_TYPE_INFORMATION *) (Hob.Raw + sizeof (EFI_HOB_GENERIC_HEADER) + sizeof (EFI_GUID));
61 break;
62 }
63
64 Hob.Raw = GET_NEXT_HOB (Hob);
65 }
66
67 if (MemoryData == NULL) {
68 return 0;
69 }
70
71 TempPageNum = 0;
72 for (Index = 0; MemoryData[Index].Type != EfiMaxMemoryType; Index++) {
73 //
74 // Accumulate default memory size requirements
75 //
76 TempPageNum += MemoryData[Index].NumberOfPages;
77 }
78
79 return TempPageNum * EFI_PAGE_SIZE;
80 }
81
82 /**
83 Get the mem size need to be reserved in PEI phase.
84
85 @param[in] PeiServices PEI Services table.
86
87 @return the mem size need to be reserved in PEI phase.
88 **/
89 UINT64
90 RetrieveRequiredMemorySize (
91 IN EFI_PEI_SERVICES **PeiServices
92 )
93 {
94 UINT64 Size;
95
96 Size = GetMemorySizeInMemoryTypeInformation (PeiServices);
97 return Size + PEI_ADDITIONAL_MEMORY_SIZE;
98 }
99
100 /**
101 Get the mem size need to be consumed and reserved in PEI phase.
102
103 @param[in] PeiServices PEI Services table.
104 @param[in] BootMode Current boot mode.
105
106 @return the mem size need to be consumed and reserved in PEI phase.
107 **/
108 UINT64
109 GetPeiMemSize (
110 IN EFI_PEI_SERVICES **PeiServices,
111 IN UINT32 BootMode
112 )
113 {
114 UINT64 Size;
115 UINT64 MinSize;
116
117 if (BootMode == BOOT_IN_RECOVERY_MODE) {
118 return PcdGet32 (PcdPeiRecoveryMinMemSize);
119 }
120
121 Size = GetMemorySizeInMemoryTypeInformation (PeiServices);
122
123 if (BootMode == BOOT_ON_FLASH_UPDATE) {
124 //
125 // Maybe more size when in CapsuleUpdate phase ?
126 //
127 MinSize = PcdGet32 (PcdPeiMinMemSize);
128 } else {
129 MinSize = PcdGet32 (PcdPeiMinMemSize);
130 }
131
132 return MinSize + Size + PEI_ADDITIONAL_MEMORY_SIZE;
133 }
134
135 /**
136 BIOS process FspBobList for Memory Resource Descriptor.
137
138 @param[in] FspHobList Pointer to the HOB data structure produced by FSP.
139
140 @return If platform process the FSP hob list successfully.
141 **/
142 EFI_STATUS
143 EFIAPI
144 FspHobProcessForMemoryResource (
145 IN VOID *FspHobList
146 )
147 {
148 EFI_PEI_HOB_POINTERS Hob;
149 UINT64 LowMemorySize;
150 UINT64 FspMemorySize;
151 EFI_PHYSICAL_ADDRESS FspMemoryBase;
152 UINT64 PeiMemSize;
153 EFI_PHYSICAL_ADDRESS PeiMemBase;
154 UINT64 S3PeiMemSize;
155 EFI_PHYSICAL_ADDRESS S3PeiMemBase;
156 BOOLEAN FoundFspMemHob;
157 EFI_STATUS Status;
158 EFI_BOOT_MODE BootMode;
159 EFI_PEI_CAPSULE_PPI *Capsule;
160 VOID *CapsuleBuffer;
161 UINTN CapsuleBufferLength;
162 UINT64 RequiredMemSize;
163 EFI_PEI_SERVICES **PeiServices;
164
165 PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer ();
166
167 PeiServicesGetBootMode (&BootMode);
168
169 PeiMemBase = 0;
170 LowMemorySize = 0;
171 FspMemorySize = 0;
172 FspMemoryBase = 0;
173 FoundFspMemHob = FALSE;
174
175 //
176 // Parse the hob list from fsp
177 // Report all the resource hob except the memory between 1M and 4G
178 //
179 Hob.Raw = (UINT8 *)(UINTN)FspHobList;
180 DEBUG((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList));
181
182 while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw)) != NULL) {
183 DEBUG((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType));
184 if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) ||
185 (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED)) {
186 DEBUG((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));
187 DEBUG((DEBUG_INFO, "PhysicalStart: 0x%x\n", Hob.ResourceDescriptor->PhysicalStart));
188 DEBUG((DEBUG_INFO, "ResourceLength: 0x%x\n", Hob.ResourceDescriptor->ResourceLength));
189 DEBUG((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));
190 }
191
192 if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) // Found the low memory length below 4G
193 && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB)
194 && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB)) {
195 LowMemorySize += Hob.ResourceDescriptor->ResourceLength;
196 Hob.Raw = GET_NEXT_HOB (Hob);
197 continue;
198 }
199
200 if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED) // Found the low memory length below 4G
201 && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB)
202 && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB)
203 && (CompareGuid (&Hob.ResourceDescriptor->Owner, &gFspReservedMemoryResourceHobGuid))) {
204 FoundFspMemHob = TRUE;
205 FspMemoryBase = Hob.ResourceDescriptor->PhysicalStart;
206 FspMemorySize = Hob.ResourceDescriptor->ResourceLength;
207 DEBUG((DEBUG_INFO, "Find fsp mem hob, base 0x%x, len 0x%x\n", FspMemoryBase, FspMemorySize));
208 }
209
210 //
211 // Report the resource hob
212 //
213 BuildResourceDescriptorHob (
214 Hob.ResourceDescriptor->ResourceType,
215 Hob.ResourceDescriptor->ResourceAttribute,
216 Hob.ResourceDescriptor->PhysicalStart,
217 Hob.ResourceDescriptor->ResourceLength
218 );
219
220 Hob.Raw = GET_NEXT_HOB (Hob);
221 }
222
223 if (!FoundFspMemHob) {
224 DEBUG((DEBUG_INFO, "Didn't find the fsp used memory information.\n"));
225 //ASSERT(FALSE);
226 }
227
228 DEBUG((DEBUG_INFO, "LowMemorySize: 0x%x.\n", LowMemorySize));
229 DEBUG((DEBUG_INFO, "FspMemoryBase: 0x%x.\n", FspMemoryBase));
230 DEBUG((DEBUG_INFO, "FspMemorySize: 0x%x.\n", FspMemorySize));
231
232 if (BootMode == BOOT_ON_S3_RESUME) {
233 BuildResourceDescriptorHob (
234 EFI_RESOURCE_SYSTEM_MEMORY,
235 (
236 EFI_RESOURCE_ATTRIBUTE_PRESENT |
237 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
238 // EFI_RESOURCE_ATTRIBUTE_TESTED |
239 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
240 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
241 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
242 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
243 ),
244 BASE_1MB,
245 LowMemorySize
246 );
247
248 S3PeiMemBase = 0;
249 S3PeiMemSize = 0;
250 Status = GetS3MemoryInfo (&S3PeiMemSize, &S3PeiMemBase);
251 ASSERT_EFI_ERROR (Status);
252 DEBUG((DEBUG_INFO, "S3 memory %Xh - %Xh bytes\n", S3PeiMemBase, S3PeiMemSize));
253
254 //
255 // Make sure Stack and PeiMemory are not overlap
256 //
257
258 Status = PeiServicesInstallPeiMemory (
259 S3PeiMemBase,
260 S3PeiMemSize
261 );
262 ASSERT_EFI_ERROR (Status);
263 } else {
264 PeiMemSize = GetPeiMemSize (PeiServices, BootMode);
265 DEBUG((DEBUG_INFO, "PEI memory size = %Xh bytes\n", PeiMemSize));
266
267 //
268 // Capsule mode
269 //
270 Capsule = NULL;
271 CapsuleBuffer = NULL;
272 CapsuleBufferLength = 0;
273 if (BootMode == BOOT_ON_FLASH_UPDATE) {
274 Status = PeiServicesLocatePpi (
275 &gEfiPeiCapsulePpiGuid,
276 0,
277 NULL,
278 (VOID **) &Capsule
279 );
280 ASSERT_EFI_ERROR (Status);
281
282 if (Status == EFI_SUCCESS) {
283 //
284 // Make sure Stack and CapsuleBuffer are not overlap
285 //
286 CapsuleBuffer = (VOID *)(UINTN)BASE_1MB;
287 CapsuleBufferLength = (UINTN)(LowMemorySize - PeiMemSize);
288 //
289 // Call the Capsule PPI Coalesce function to coalesce the capsule data.
290 //
291 Status = Capsule->Coalesce (PeiServices, &CapsuleBuffer, &CapsuleBufferLength);
292 }
293 }
294
295 RequiredMemSize = RetrieveRequiredMemorySize (PeiServices);
296 DEBUG((DEBUG_INFO, "Required memory size = %Xh bytes\n", RequiredMemSize));
297
298 //
299 // Report the main memory
300 //
301 BuildResourceDescriptorHob (
302 EFI_RESOURCE_SYSTEM_MEMORY,
303 (
304 EFI_RESOURCE_ATTRIBUTE_PRESENT |
305 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
306 EFI_RESOURCE_ATTRIBUTE_TESTED |
307 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
308 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
309 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
310 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
311 ),
312 BASE_1MB,
313 LowMemorySize
314 );
315
316 //
317 // Make sure Stack and CapsuleBuffer are not overlap
318 //
319
320 //
321 // Install efi memory
322 //
323 PeiMemBase = BASE_1MB + LowMemorySize - PeiMemSize;
324 Status = PeiServicesInstallPeiMemory (
325 PeiMemBase,
326 PeiMemSize - RequiredMemSize
327 );
328 ASSERT_EFI_ERROR (Status);
329
330 if (Capsule != NULL) {
331 Status = Capsule->CreateState (PeiServices, CapsuleBuffer, CapsuleBufferLength);
332 }
333 }
334
335 return EFI_SUCCESS;
336 }
337
338 /**
339 Process FSP HOB list
340
341 @param[in] FspHobList Pointer to the HOB data structure produced by FSP.
342
343 **/
344 VOID
345 ProcessFspHobList (
346 IN VOID *FspHobList
347 )
348 {
349 EFI_PEI_HOB_POINTERS FspHob;
350
351 FspHob.Raw = FspHobList;
352
353 //
354 // Add all the HOBs from FSP binary to FSP wrapper
355 //
356 while (!END_OF_HOB_LIST (FspHob)) {
357 if (FspHob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION) {
358 //
359 // Skip FSP binary creates PcdDataBaseHobGuid
360 //
361 if (!CompareGuid(&FspHob.Guid->Name, &gPcdDataBaseHobGuid)) {
362 BuildGuidDataHob (
363 &FspHob.Guid->Name,
364 GET_GUID_HOB_DATA(FspHob),
365 GET_GUID_HOB_DATA_SIZE(FspHob)
366 );
367 }
368 }
369 FspHob.Raw = GET_NEXT_HOB (FspHob);
370 }
371 }
372
373 /**
374 BIOS process FspBobList for other data (not Memory Resource Descriptor).
375
376 @param[in] FspHobList Pointer to the HOB data structure produced by FSP.
377
378 @return If platform process the FSP hob list successfully.
379 **/
380 EFI_STATUS
381 EFIAPI
382 FspHobProcessForOtherData (
383 IN VOID *FspHobList
384 )
385 {
386 ProcessFspHobList (FspHobList);
387
388 return EFI_SUCCESS;
389 }
390
391 /**
392 BIOS process FspBobList.
393
394 @param[in] FspHobList Pointer to the HOB data structure produced by FSP.
395
396 @return If platform process the FSP hob list successfully.
397 **/
398 EFI_STATUS
399 EFIAPI
400 FspHobProcess (
401 IN VOID *FspHobList
402 )
403 {
404 EFI_STATUS Status;
405
406 Status = FspHobProcessForMemoryResource (FspHobList);
407 if (EFI_ERROR (Status)) {
408 return Status;
409 }
410 Status = FspHobProcessForOtherData (FspHobList);
411
412 return Status;
413 }