TianoCore EDK2 master
Loading...
Searching...
No Matches
FspWrapperHobProcessLibSample.c
Go to the documentation of this file.
1
9#include <PiPei.h>
10
13#include <Library/BaseLib.h>
14#include <Library/DebugLib.h>
16#include <Library/HobLib.h>
17#include <Library/PcdLib.h>
19
20#include <Guid/GuidHobFspEas.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
38UINT64
40 IN EFI_PEI_SERVICES **PeiServices
41 )
42{
43 EFI_STATUS Status;
46 UINT8 Index;
47 UINTN TempPageNum;
48
49 MemoryData = NULL;
50 Status = (*PeiServices)->GetHobList ((CONST EFI_PEI_SERVICES **)PeiServices, (VOID **)&Hob.Raw);
51 ASSERT_EFI_ERROR (Status);
52 while (!END_OF_HOB_LIST (Hob)) {
53 if ((Hob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION) &&
54 CompareGuid (&Hob.Guid->Name, &gEfiMemoryTypeInformationGuid))
55 {
56 MemoryData = (EFI_MEMORY_TYPE_INFORMATION *)(Hob.Raw + sizeof (EFI_HOB_GENERIC_HEADER) + sizeof (EFI_GUID));
57 break;
58 }
59
60 Hob.Raw = GET_NEXT_HOB (Hob);
61 }
62
63 if (MemoryData == NULL) {
64 return 0;
65 }
66
67 TempPageNum = 0;
68 for (Index = 0; MemoryData[Index].Type != EfiMaxMemoryType; Index++) {
69 //
70 // Accumulate default memory size requirements
71 //
72 TempPageNum += MemoryData[Index].NumberOfPages;
73 }
74
75 return TempPageNum * EFI_PAGE_SIZE;
76}
77
85UINT64
87 IN EFI_PEI_SERVICES **PeiServices
88 )
89{
90 UINT64 Size;
91
92 Size = GetMemorySizeInMemoryTypeInformation (PeiServices);
93 return Size + PEI_ADDITIONAL_MEMORY_SIZE;
94}
95
104UINT64
106 IN EFI_PEI_SERVICES **PeiServices,
107 IN UINT32 BootMode
108 )
109{
110 UINT64 Size;
111 UINT64 MinSize;
112
113 if (BootMode == BOOT_IN_RECOVERY_MODE) {
114 return PcdGet32 (PcdPeiRecoveryMinMemSize);
115 }
116
117 Size = GetMemorySizeInMemoryTypeInformation (PeiServices);
118
119 if (BootMode == BOOT_ON_FLASH_UPDATE) {
120 //
121 // Maybe more size when in CapsuleUpdate phase ?
122 //
123 MinSize = PcdGet32 (PcdPeiMinMemSize);
124 } else {
125 MinSize = PcdGet32 (PcdPeiMinMemSize);
126 }
127
128 return MinSize + Size + PEI_ADDITIONAL_MEMORY_SIZE;
129}
130
139EFIAPI
141 IN VOID *FspHobList
142 )
143{
145 UINT64 LowMemorySize;
146 UINT64 FspMemorySize;
147 EFI_PHYSICAL_ADDRESS FspMemoryBase;
148 UINT64 PeiMemSize;
149 EFI_PHYSICAL_ADDRESS PeiMemBase;
150 UINT64 S3PeiMemSize;
151 EFI_PHYSICAL_ADDRESS S3PeiMemBase;
152 BOOLEAN FoundFspMemHob;
153 EFI_STATUS Status;
154 EFI_BOOT_MODE BootMode;
155 EFI_PEI_CAPSULE_PPI *Capsule;
156 VOID *CapsuleBuffer;
157 UINTN CapsuleBufferLength;
158 UINT64 RequiredMemSize;
159 EFI_PEI_SERVICES **PeiServices;
160
161 PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer ();
162
163 PeiServicesGetBootMode (&BootMode);
164
165 PeiMemBase = 0;
166 LowMemorySize = 0;
167 FspMemorySize = 0;
168 FspMemoryBase = 0;
169 FoundFspMemHob = FALSE;
170
171 //
172 // Parse the hob list from fsp
173 // Report all the resource hob except the memory between 1M and 4G
174 //
175 Hob.Raw = (UINT8 *)(UINTN)FspHobList;
176 DEBUG ((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList));
177
178 while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw)) != NULL) {
179 DEBUG ((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType));
180 if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) ||
181 (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED))
182 {
183 DEBUG ((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));
184 DEBUG ((DEBUG_INFO, "PhysicalStart: 0x%x\n", Hob.ResourceDescriptor->PhysicalStart));
185 DEBUG ((DEBUG_INFO, "ResourceLength: 0x%x\n", Hob.ResourceDescriptor->ResourceLength));
186 DEBUG ((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));
187 }
188
189 if ( (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) // Found the low memory length below 4G
190 && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB)
191 && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB))
192 {
193 LowMemorySize += Hob.ResourceDescriptor->ResourceLength;
194 Hob.Raw = GET_NEXT_HOB (Hob);
195 continue;
196 }
197
198 if ( (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED) // Found the low memory length below 4G
199 && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB)
200 && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB)
201 && (CompareGuid (&Hob.ResourceDescriptor->Owner, &gFspReservedMemoryResourceHobGuid)))
202 {
203 FoundFspMemHob = TRUE;
204 FspMemoryBase = Hob.ResourceDescriptor->PhysicalStart;
205 FspMemorySize = Hob.ResourceDescriptor->ResourceLength;
206 DEBUG ((DEBUG_INFO, "Find fsp mem hob, base 0x%x, len 0x%x\n", FspMemoryBase, FspMemorySize));
207 }
208
209 //
210 // Report the resource hob
211 //
213 Hob.ResourceDescriptor->ResourceType,
214 Hob.ResourceDescriptor->ResourceAttribute,
215 Hob.ResourceDescriptor->PhysicalStart,
216 Hob.ResourceDescriptor->ResourceLength
217 );
218
219 Hob.Raw = GET_NEXT_HOB (Hob);
220 }
221
222 if (!FoundFspMemHob) {
223 DEBUG ((DEBUG_INFO, "Didn't find the fsp used memory information.\n"));
224 // ASSERT(FALSE);
225 }
226
227 DEBUG ((DEBUG_INFO, "LowMemorySize: 0x%x.\n", LowMemorySize));
228 DEBUG ((DEBUG_INFO, "FspMemoryBase: 0x%x.\n", FspMemoryBase));
229 DEBUG ((DEBUG_INFO, "FspMemorySize: 0x%x.\n", FspMemorySize));
230
231 if (BootMode == BOOT_ON_S3_RESUME) {
233 EFI_RESOURCE_SYSTEM_MEMORY,
234 (
235 EFI_RESOURCE_ATTRIBUTE_PRESENT |
236 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
237 // EFI_RESOURCE_ATTRIBUTE_TESTED |
238 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
239 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
240 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
241 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
242 ),
243 BASE_1MB,
244 LowMemorySize
245 );
246
247 S3PeiMemBase = 0;
248 S3PeiMemSize = 0;
249 Status = GetS3MemoryInfo (&S3PeiMemSize, &S3PeiMemBase);
250 ASSERT_EFI_ERROR (Status);
251 DEBUG ((DEBUG_INFO, "S3 memory %Xh - %Xh bytes\n", S3PeiMemBase, S3PeiMemSize));
252
253 //
254 // Make sure Stack and PeiMemory are not overlap
255 //
256
258 S3PeiMemBase,
259 S3PeiMemSize
260 );
261 ASSERT_EFI_ERROR (Status);
262 } else {
263 PeiMemSize = GetPeiMemSize (PeiServices, BootMode);
264 DEBUG ((DEBUG_INFO, "PEI memory size = %Xh bytes\n", PeiMemSize));
265
266 //
267 // Capsule mode
268 //
269 Capsule = NULL;
270 CapsuleBuffer = NULL;
271 CapsuleBufferLength = 0;
272 if (BootMode == BOOT_ON_FLASH_UPDATE) {
273 Status = PeiServicesLocatePpi (
274 &gEfiPeiCapsulePpiGuid,
275 0,
276 NULL,
277 (VOID **)&Capsule
278 );
279 ASSERT_EFI_ERROR (Status);
280
281 if (Status == EFI_SUCCESS) {
282 //
283 // Make sure Stack and CapsuleBuffer are not overlap
284 //
285 CapsuleBuffer = (VOID *)(UINTN)BASE_1MB;
286 CapsuleBufferLength = (UINTN)(LowMemorySize - PeiMemSize);
287 //
288 // Call the Capsule PPI Coalesce function to coalesce the capsule data.
289 //
290 Status = Capsule->Coalesce (PeiServices, &CapsuleBuffer, &CapsuleBufferLength);
291 }
292 }
293
294 RequiredMemSize = RetrieveRequiredMemorySize (PeiServices);
295 DEBUG ((DEBUG_INFO, "Required memory size = %Xh bytes\n", RequiredMemSize));
296
297 //
298 // Report the main memory
299 //
301 EFI_RESOURCE_SYSTEM_MEMORY,
302 (
303 EFI_RESOURCE_ATTRIBUTE_PRESENT |
304 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
305 EFI_RESOURCE_ATTRIBUTE_TESTED |
306 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
307 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
308 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
309 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
310 ),
311 BASE_1MB,
312 LowMemorySize
313 );
314
315 //
316 // Make sure Stack and CapsuleBuffer are not overlap
317 //
318
319 //
320 // Install efi memory
321 //
322 PeiMemBase = BASE_1MB + LowMemorySize - PeiMemSize;
324 PeiMemBase,
325 PeiMemSize - RequiredMemSize
326 );
327 ASSERT_EFI_ERROR (Status);
328
329 if (Capsule != NULL) {
330 Status = Capsule->CreateState (PeiServices, CapsuleBuffer, CapsuleBufferLength);
331 }
332 }
333
334 return EFI_SUCCESS;
335}
336
343VOID
345 IN VOID *FspHobList
346 )
347{
349
350 FspHob.Raw = FspHobList;
351
352 //
353 // Add all the HOBs from FSP binary to FSP wrapper
354 //
355 while (!END_OF_HOB_LIST (FspHob)) {
356 if (FspHob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION) {
357 //
358 // Skip FSP binary creates PcdDataBaseHobGuid
359 //
360 if (!CompareGuid (&FspHob.Guid->Name, &gPcdDataBaseHobGuid)) {
362 &FspHob.Guid->Name,
363 GET_GUID_HOB_DATA (FspHob),
364 GET_GUID_HOB_DATA_SIZE (FspHob)
365 );
366 }
367 }
368
369 FspHob.Raw = GET_NEXT_HOB (FspHob);
370 }
371}
372
381EFIAPI
383 IN VOID *FspHobList
384 )
385{
386 //
387 // PostFspsHobProcess () will be called in both FSP API and Dispatch modes to
388 // align the same behavior and support a variety of boot loader implementations.
389 // Boot loader provided library function is recommended to support both API and
390 // Dispatch modes by checking PcdFspModeSelection.
391 //
392 if (PcdGet8 (PcdFspModeSelection) == 1) {
393 //
394 // Only in FSP API mode the wrapper has to build hobs basing on FSP output data.
395 // In this case FspHobList cannot be NULL.
396 //
397 ASSERT (FspHobList != NULL);
398 ProcessFspHobList (FspHobList);
399 }
400
401 return EFI_SUCCESS;
402}
UINT64 UINTN
CONST EFI_PEI_SERVICES **EFIAPI GetPeiServicesTablePointer(VOID)
VOID *EFIAPI BuildGuidDataHob(IN CONST EFI_GUID *Guid, IN VOID *Data, IN UINTN DataLength)
Definition: HobLib.c:375
VOID EFIAPI BuildResourceDescriptorHob(IN EFI_RESOURCE_TYPE ResourceType, IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute, IN EFI_PHYSICAL_ADDRESS PhysicalStart, IN UINT64 NumberOfBytes)
Definition: HobLib.c:299
VOID *EFIAPI GetNextHob(IN UINT16 Type, IN CONST VOID *HobStart)
Definition: HobLib.c:103
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
EFI_STATUS EFIAPI PeiServicesGetBootMode(OUT EFI_BOOT_MODE *BootMode)
EFI_STATUS EFIAPI PeiServicesLocatePpi(IN CONST EFI_GUID *Guid, IN UINTN Instance, IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, IN OUT VOID **Ppi)
EFI_STATUS EFIAPI PeiServicesInstallPeiMemory(IN EFI_PHYSICAL_ADDRESS MemoryBegin, IN UINT64 MemoryLength)
UINT64 GetMemorySizeInMemoryTypeInformation(IN EFI_PEI_SERVICES **PeiServices)
EFI_STATUS EFIAPI PostFspsHobProcess(IN VOID *FspHobList)
EFI_STATUS EFIAPI PostFspmHobProcess(IN VOID *FspHobList)
VOID ProcessFspHobList(IN VOID *FspHobList)
UINT64 GetPeiMemSize(IN EFI_PEI_SERVICES **PeiServices, IN UINT32 BootMode)
UINT64 RetrieveRequiredMemorySize(IN EFI_PEI_SERVICES **PeiServices)
EFI_STATUS EFIAPI GetS3MemoryInfo(OUT UINT64 *S3PeiMemSize, OUT EFI_PHYSICAL_ADDRESS *S3PeiMemBase)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define PcdGet8(TokenName)
Definition: PcdLib.h:336
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
UINT32 EFI_BOOT_MODE
Definition: PiBootMode.h:18
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
GUID EFI_GUID
Definition: UefiBaseType.h:25
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_GUID Name
Definition: PiHob.h:347
EFI_PHYSICAL_ADDRESS PhysicalStart
Definition: PiHob.h:328
EFI_RESOURCE_TYPE ResourceType
Definition: PiHob.h:320
EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute
Definition: PiHob.h:324
UINT32 NumberOfPages
The pages of this type memory.
UINT32 Type
EFI memory type defined in UEFI specification.