2 Sample to provide FSP wrapper hob process related function.
4 Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
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/FspWrapperPlatformLib.h>
20 #include <Guid/GuidHobFspEas.h>
21 #include <Guid/MemoryTypeInformation.h>
22 #include <Guid/PcdDataBaseHobGuid.h>
23 #include <Ppi/Capsule.h>
26 // Additional pages are used by DXE memory manager.
27 // It should be consistent between RetrieveRequiredMemorySize() and GetPeiMemSize()
29 #define PEI_ADDITIONAL_MEMORY_SIZE (16 * EFI_PAGE_SIZE)
32 Get the mem size in memory type information table.
34 @param[in] PeiServices PEI Services table.
36 @return the mem size in memory type information table.
39 GetMemorySizeInMemoryTypeInformation (
40 IN EFI_PEI_SERVICES
**PeiServices
44 EFI_PEI_HOB_POINTERS Hob
;
45 EFI_MEMORY_TYPE_INFORMATION
*MemoryData
;
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
))
56 MemoryData
= (EFI_MEMORY_TYPE_INFORMATION
*)(Hob
.Raw
+ sizeof (EFI_HOB_GENERIC_HEADER
) + sizeof (EFI_GUID
));
60 Hob
.Raw
= GET_NEXT_HOB (Hob
);
63 if (MemoryData
== NULL
) {
68 for (Index
= 0; MemoryData
[Index
].Type
!= EfiMaxMemoryType
; Index
++) {
70 // Accumulate default memory size requirements
72 TempPageNum
+= MemoryData
[Index
].NumberOfPages
;
75 return TempPageNum
* EFI_PAGE_SIZE
;
79 Get the mem size need to be reserved in PEI phase.
81 @param[in] PeiServices PEI Services table.
83 @return the mem size need to be reserved in PEI phase.
86 RetrieveRequiredMemorySize (
87 IN EFI_PEI_SERVICES
**PeiServices
92 Size
= GetMemorySizeInMemoryTypeInformation (PeiServices
);
93 return Size
+ PEI_ADDITIONAL_MEMORY_SIZE
;
97 Get the mem size need to be consumed and reserved in PEI phase.
99 @param[in] PeiServices PEI Services table.
100 @param[in] BootMode Current boot mode.
102 @return the mem size need to be consumed and reserved in PEI phase.
106 IN EFI_PEI_SERVICES
**PeiServices
,
113 if (BootMode
== BOOT_IN_RECOVERY_MODE
) {
114 return PcdGet32 (PcdPeiRecoveryMinMemSize
);
117 Size
= GetMemorySizeInMemoryTypeInformation (PeiServices
);
119 if (BootMode
== BOOT_ON_FLASH_UPDATE
) {
121 // Maybe more size when in CapsuleUpdate phase ?
123 MinSize
= PcdGet32 (PcdPeiMinMemSize
);
125 MinSize
= PcdGet32 (PcdPeiMinMemSize
);
128 return MinSize
+ Size
+ PEI_ADDITIONAL_MEMORY_SIZE
;
132 Post FSP-M HOB process for Memory Resource Descriptor.
134 @param[in] FspHobList Pointer to the HOB data structure produced by FSP.
136 @return If platform process the FSP hob list successfully.
144 EFI_PEI_HOB_POINTERS Hob
;
145 UINT64 LowMemorySize
;
146 UINT64 FspMemorySize
;
147 EFI_PHYSICAL_ADDRESS FspMemoryBase
;
149 EFI_PHYSICAL_ADDRESS PeiMemBase
;
151 EFI_PHYSICAL_ADDRESS S3PeiMemBase
;
152 BOOLEAN FoundFspMemHob
;
154 EFI_BOOT_MODE BootMode
;
155 EFI_PEI_CAPSULE_PPI
*Capsule
;
157 UINTN CapsuleBufferLength
;
158 UINT64 RequiredMemSize
;
159 EFI_PEI_SERVICES
**PeiServices
;
161 PeiServices
= (EFI_PEI_SERVICES
**)GetPeiServicesTablePointer ();
163 PeiServicesGetBootMode (&BootMode
);
169 FoundFspMemHob
= FALSE
;
172 // Parse the hob list from fsp
173 // Report all the resource hob except the memory between 1M and 4G
175 Hob
.Raw
= (UINT8
*)(UINTN
)FspHobList
;
176 DEBUG ((DEBUG_INFO
, "FspHobList - 0x%x\n", FspHobList
));
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
))
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
));
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
))
193 LowMemorySize
+= Hob
.ResourceDescriptor
->ResourceLength
;
194 Hob
.Raw
= GET_NEXT_HOB (Hob
);
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
)))
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
));
210 // Report the resource hob
212 BuildResourceDescriptorHob (
213 Hob
.ResourceDescriptor
->ResourceType
,
214 Hob
.ResourceDescriptor
->ResourceAttribute
,
215 Hob
.ResourceDescriptor
->PhysicalStart
,
216 Hob
.ResourceDescriptor
->ResourceLength
219 Hob
.Raw
= GET_NEXT_HOB (Hob
);
222 if (!FoundFspMemHob
) {
223 DEBUG ((DEBUG_INFO
, "Didn't find the fsp used memory information.\n"));
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
));
231 if (BootMode
== BOOT_ON_S3_RESUME
) {
232 BuildResourceDescriptorHob (
233 EFI_RESOURCE_SYSTEM_MEMORY
,
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
249 Status
= GetS3MemoryInfo (&S3PeiMemSize
, &S3PeiMemBase
);
250 ASSERT_EFI_ERROR (Status
);
251 DEBUG ((DEBUG_INFO
, "S3 memory %Xh - %Xh bytes\n", S3PeiMemBase
, S3PeiMemSize
));
254 // Make sure Stack and PeiMemory are not overlap
257 Status
= PeiServicesInstallPeiMemory (
261 ASSERT_EFI_ERROR (Status
);
263 PeiMemSize
= GetPeiMemSize (PeiServices
, BootMode
);
264 DEBUG ((DEBUG_INFO
, "PEI memory size = %Xh bytes\n", PeiMemSize
));
270 CapsuleBuffer
= NULL
;
271 CapsuleBufferLength
= 0;
272 if (BootMode
== BOOT_ON_FLASH_UPDATE
) {
273 Status
= PeiServicesLocatePpi (
274 &gEfiPeiCapsulePpiGuid
,
279 ASSERT_EFI_ERROR (Status
);
281 if (Status
== EFI_SUCCESS
) {
283 // Make sure Stack and CapsuleBuffer are not overlap
285 CapsuleBuffer
= (VOID
*)(UINTN
)BASE_1MB
;
286 CapsuleBufferLength
= (UINTN
)(LowMemorySize
- PeiMemSize
);
288 // Call the Capsule PPI Coalesce function to coalesce the capsule data.
290 Status
= Capsule
->Coalesce (PeiServices
, &CapsuleBuffer
, &CapsuleBufferLength
);
294 RequiredMemSize
= RetrieveRequiredMemorySize (PeiServices
);
295 DEBUG ((DEBUG_INFO
, "Required memory size = %Xh bytes\n", RequiredMemSize
));
298 // Report the main memory
300 BuildResourceDescriptorHob (
301 EFI_RESOURCE_SYSTEM_MEMORY
,
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
316 // Make sure Stack and CapsuleBuffer are not overlap
320 // Install efi memory
322 PeiMemBase
= BASE_1MB
+ LowMemorySize
- PeiMemSize
;
323 Status
= PeiServicesInstallPeiMemory (
325 PeiMemSize
- RequiredMemSize
327 ASSERT_EFI_ERROR (Status
);
329 if (Capsule
!= NULL
) {
330 Status
= Capsule
->CreateState (PeiServices
, CapsuleBuffer
, CapsuleBufferLength
);
340 @param[in] FspHobList Pointer to the HOB data structure produced by FSP.
348 EFI_PEI_HOB_POINTERS FspHob
;
350 FspHob
.Raw
= FspHobList
;
353 // Add all the HOBs from FSP binary to FSP wrapper
355 while (!END_OF_HOB_LIST (FspHob
)) {
356 if (FspHob
.Header
->HobType
== EFI_HOB_TYPE_GUID_EXTENSION
) {
358 // Skip FSP binary creates PcdDataBaseHobGuid
360 if (!CompareGuid (&FspHob
.Guid
->Name
, &gPcdDataBaseHobGuid
)) {
363 GET_GUID_HOB_DATA (FspHob
),
364 GET_GUID_HOB_DATA_SIZE (FspHob
)
369 FspHob
.Raw
= GET_NEXT_HOB (FspHob
);
374 Post FSP-S HOB process (not Memory Resource Descriptor).
376 @param[in] FspHobList Pointer to the HOB data structure produced by FSP.
378 @return If platform process the FSP hob list successfully.
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.
392 if (PcdGet8 (PcdFspModeSelection
) == 1) {
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.
397 ASSERT (FspHobList
!= NULL
);
398 ProcessFspHobList (FspHobList
);