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
)) {
55 MemoryData
= (EFI_MEMORY_TYPE_INFORMATION
*) (Hob
.Raw
+ sizeof (EFI_HOB_GENERIC_HEADER
) + sizeof (EFI_GUID
));
59 Hob
.Raw
= GET_NEXT_HOB (Hob
);
62 if (MemoryData
== NULL
) {
67 for (Index
= 0; MemoryData
[Index
].Type
!= EfiMaxMemoryType
; Index
++) {
69 // Accumulate default memory size requirements
71 TempPageNum
+= MemoryData
[Index
].NumberOfPages
;
74 return TempPageNum
* EFI_PAGE_SIZE
;
78 Get the mem size need to be reserved in PEI phase.
80 @param[in] PeiServices PEI Services table.
82 @return the mem size need to be reserved in PEI phase.
85 RetrieveRequiredMemorySize (
86 IN EFI_PEI_SERVICES
**PeiServices
91 Size
= GetMemorySizeInMemoryTypeInformation (PeiServices
);
92 return Size
+ PEI_ADDITIONAL_MEMORY_SIZE
;
96 Get the mem size need to be consumed and reserved in PEI phase.
98 @param[in] PeiServices PEI Services table.
99 @param[in] BootMode Current boot mode.
101 @return the mem size need to be consumed and reserved in PEI phase.
105 IN EFI_PEI_SERVICES
**PeiServices
,
112 if (BootMode
== BOOT_IN_RECOVERY_MODE
) {
113 return PcdGet32 (PcdPeiRecoveryMinMemSize
);
116 Size
= GetMemorySizeInMemoryTypeInformation (PeiServices
);
118 if (BootMode
== BOOT_ON_FLASH_UPDATE
) {
120 // Maybe more size when in CapsuleUpdate phase ?
122 MinSize
= PcdGet32 (PcdPeiMinMemSize
);
124 MinSize
= PcdGet32 (PcdPeiMinMemSize
);
127 return MinSize
+ Size
+ PEI_ADDITIONAL_MEMORY_SIZE
;
131 Post FSP-M HOB process for Memory Resource Descriptor.
133 @param[in] FspHobList Pointer to the HOB data structure produced by FSP.
135 @return If platform process the FSP hob list successfully.
143 EFI_PEI_HOB_POINTERS Hob
;
144 UINT64 LowMemorySize
;
145 UINT64 FspMemorySize
;
146 EFI_PHYSICAL_ADDRESS FspMemoryBase
;
148 EFI_PHYSICAL_ADDRESS PeiMemBase
;
150 EFI_PHYSICAL_ADDRESS S3PeiMemBase
;
151 BOOLEAN FoundFspMemHob
;
153 EFI_BOOT_MODE BootMode
;
154 EFI_PEI_CAPSULE_PPI
*Capsule
;
156 UINTN CapsuleBufferLength
;
157 UINT64 RequiredMemSize
;
158 EFI_PEI_SERVICES
**PeiServices
;
160 PeiServices
= (EFI_PEI_SERVICES
**)GetPeiServicesTablePointer ();
162 PeiServicesGetBootMode (&BootMode
);
168 FoundFspMemHob
= FALSE
;
171 // Parse the hob list from fsp
172 // Report all the resource hob except the memory between 1M and 4G
174 Hob
.Raw
= (UINT8
*)(UINTN
)FspHobList
;
175 DEBUG((DEBUG_INFO
, "FspHobList - 0x%x\n", FspHobList
));
177 while ((Hob
.Raw
= GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR
, Hob
.Raw
)) != NULL
) {
178 DEBUG((DEBUG_INFO
, "\nResourceType: 0x%x\n", Hob
.ResourceDescriptor
->ResourceType
));
179 if ((Hob
.ResourceDescriptor
->ResourceType
== EFI_RESOURCE_SYSTEM_MEMORY
) ||
180 (Hob
.ResourceDescriptor
->ResourceType
== EFI_RESOURCE_MEMORY_RESERVED
)) {
181 DEBUG((DEBUG_INFO
, "ResourceAttribute: 0x%x\n", Hob
.ResourceDescriptor
->ResourceAttribute
));
182 DEBUG((DEBUG_INFO
, "PhysicalStart: 0x%x\n", Hob
.ResourceDescriptor
->PhysicalStart
));
183 DEBUG((DEBUG_INFO
, "ResourceLength: 0x%x\n", Hob
.ResourceDescriptor
->ResourceLength
));
184 DEBUG((DEBUG_INFO
, "Owner: %g\n\n", &Hob
.ResourceDescriptor
->Owner
));
187 if ((Hob
.ResourceDescriptor
->ResourceType
== EFI_RESOURCE_SYSTEM_MEMORY
) // Found the low memory length below 4G
188 && (Hob
.ResourceDescriptor
->PhysicalStart
>= BASE_1MB
)
189 && (Hob
.ResourceDescriptor
->PhysicalStart
+ Hob
.ResourceDescriptor
->ResourceLength
<= BASE_4GB
)) {
190 LowMemorySize
+= Hob
.ResourceDescriptor
->ResourceLength
;
191 Hob
.Raw
= GET_NEXT_HOB (Hob
);
195 if ((Hob
.ResourceDescriptor
->ResourceType
== EFI_RESOURCE_MEMORY_RESERVED
) // Found the low memory length below 4G
196 && (Hob
.ResourceDescriptor
->PhysicalStart
>= BASE_1MB
)
197 && (Hob
.ResourceDescriptor
->PhysicalStart
+ Hob
.ResourceDescriptor
->ResourceLength
<= BASE_4GB
)
198 && (CompareGuid (&Hob
.ResourceDescriptor
->Owner
, &gFspReservedMemoryResourceHobGuid
))) {
199 FoundFspMemHob
= TRUE
;
200 FspMemoryBase
= Hob
.ResourceDescriptor
->PhysicalStart
;
201 FspMemorySize
= Hob
.ResourceDescriptor
->ResourceLength
;
202 DEBUG((DEBUG_INFO
, "Find fsp mem hob, base 0x%x, len 0x%x\n", FspMemoryBase
, FspMemorySize
));
206 // Report the resource hob
208 BuildResourceDescriptorHob (
209 Hob
.ResourceDescriptor
->ResourceType
,
210 Hob
.ResourceDescriptor
->ResourceAttribute
,
211 Hob
.ResourceDescriptor
->PhysicalStart
,
212 Hob
.ResourceDescriptor
->ResourceLength
215 Hob
.Raw
= GET_NEXT_HOB (Hob
);
218 if (!FoundFspMemHob
) {
219 DEBUG((DEBUG_INFO
, "Didn't find the fsp used memory information.\n"));
223 DEBUG((DEBUG_INFO
, "LowMemorySize: 0x%x.\n", LowMemorySize
));
224 DEBUG((DEBUG_INFO
, "FspMemoryBase: 0x%x.\n", FspMemoryBase
));
225 DEBUG((DEBUG_INFO
, "FspMemorySize: 0x%x.\n", FspMemorySize
));
227 if (BootMode
== BOOT_ON_S3_RESUME
) {
228 BuildResourceDescriptorHob (
229 EFI_RESOURCE_SYSTEM_MEMORY
,
231 EFI_RESOURCE_ATTRIBUTE_PRESENT
|
232 EFI_RESOURCE_ATTRIBUTE_INITIALIZED
|
233 // EFI_RESOURCE_ATTRIBUTE_TESTED |
234 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE
|
235 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE
|
236 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE
|
237 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
245 Status
= GetS3MemoryInfo (&S3PeiMemSize
, &S3PeiMemBase
);
246 ASSERT_EFI_ERROR (Status
);
247 DEBUG((DEBUG_INFO
, "S3 memory %Xh - %Xh bytes\n", S3PeiMemBase
, S3PeiMemSize
));
250 // Make sure Stack and PeiMemory are not overlap
253 Status
= PeiServicesInstallPeiMemory (
257 ASSERT_EFI_ERROR (Status
);
259 PeiMemSize
= GetPeiMemSize (PeiServices
, BootMode
);
260 DEBUG((DEBUG_INFO
, "PEI memory size = %Xh bytes\n", PeiMemSize
));
266 CapsuleBuffer
= NULL
;
267 CapsuleBufferLength
= 0;
268 if (BootMode
== BOOT_ON_FLASH_UPDATE
) {
269 Status
= PeiServicesLocatePpi (
270 &gEfiPeiCapsulePpiGuid
,
275 ASSERT_EFI_ERROR (Status
);
277 if (Status
== EFI_SUCCESS
) {
279 // Make sure Stack and CapsuleBuffer are not overlap
281 CapsuleBuffer
= (VOID
*)(UINTN
)BASE_1MB
;
282 CapsuleBufferLength
= (UINTN
)(LowMemorySize
- PeiMemSize
);
284 // Call the Capsule PPI Coalesce function to coalesce the capsule data.
286 Status
= Capsule
->Coalesce (PeiServices
, &CapsuleBuffer
, &CapsuleBufferLength
);
290 RequiredMemSize
= RetrieveRequiredMemorySize (PeiServices
);
291 DEBUG((DEBUG_INFO
, "Required memory size = %Xh bytes\n", RequiredMemSize
));
294 // Report the main memory
296 BuildResourceDescriptorHob (
297 EFI_RESOURCE_SYSTEM_MEMORY
,
299 EFI_RESOURCE_ATTRIBUTE_PRESENT
|
300 EFI_RESOURCE_ATTRIBUTE_INITIALIZED
|
301 EFI_RESOURCE_ATTRIBUTE_TESTED
|
302 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE
|
303 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE
|
304 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE
|
305 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
312 // Make sure Stack and CapsuleBuffer are not overlap
316 // Install efi memory
318 PeiMemBase
= BASE_1MB
+ LowMemorySize
- PeiMemSize
;
319 Status
= PeiServicesInstallPeiMemory (
321 PeiMemSize
- RequiredMemSize
323 ASSERT_EFI_ERROR (Status
);
325 if (Capsule
!= NULL
) {
326 Status
= Capsule
->CreateState (PeiServices
, CapsuleBuffer
, CapsuleBufferLength
);
336 @param[in] FspHobList Pointer to the HOB data structure produced by FSP.
344 EFI_PEI_HOB_POINTERS FspHob
;
346 FspHob
.Raw
= FspHobList
;
349 // Add all the HOBs from FSP binary to FSP wrapper
351 while (!END_OF_HOB_LIST (FspHob
)) {
352 if (FspHob
.Header
->HobType
== EFI_HOB_TYPE_GUID_EXTENSION
) {
354 // Skip FSP binary creates PcdDataBaseHobGuid
356 if (!CompareGuid(&FspHob
.Guid
->Name
, &gPcdDataBaseHobGuid
)) {
359 GET_GUID_HOB_DATA(FspHob
),
360 GET_GUID_HOB_DATA_SIZE(FspHob
)
364 FspHob
.Raw
= GET_NEXT_HOB (FspHob
);
369 Post FSP-S HOB process (not Memory Resource Descriptor).
371 @param[in] FspHobList Pointer to the HOB data structure produced by FSP.
373 @return If platform process the FSP hob list successfully.
382 // PostFspsHobProcess () will be called in both FSP API and Dispatch modes to
383 // align the same behavior and support a variety of boot loader implementations.
384 // Boot loader provided library function is recommended to support both API and
385 // Dispatch modes by checking PcdFspModeSelection.
387 if (PcdGet8 (PcdFspModeSelection
) == 1) {
389 // Only in FSP API mode the wrapper has to build hobs basing on FSP output data.
390 // In this case FspHobList cannot be NULL.
392 ASSERT (FspHobList
!= NULL
);
393 ProcessFspHobList (FspHobList
);