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