2 Sample to provide FSP wrapper hob process related function.
4 Copyright (c) 2014 - 2018, 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.
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.
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/FspWrapperPlatformLib.h>
26 #include <Guid/GuidHobFspEas.h>
27 #include <Guid/MemoryTypeInformation.h>
28 #include <Guid/PcdDataBaseHobGuid.h>
29 #include <Ppi/Capsule.h>
32 // Additional pages are used by DXE memory manager.
33 // It should be consistent between RetrieveRequiredMemorySize() and GetPeiMemSize()
35 #define PEI_ADDITIONAL_MEMORY_SIZE (16 * EFI_PAGE_SIZE)
38 Get the mem size in memory type infromation table.
40 @param[in] PeiServices PEI Services table.
42 @return the mem size in memory type infromation table.
45 GetMemorySizeInMemoryTypeInformation (
46 IN EFI_PEI_SERVICES
**PeiServices
50 EFI_PEI_HOB_POINTERS Hob
;
51 EFI_MEMORY_TYPE_INFORMATION
*MemoryData
;
56 Status
= (*PeiServices
)->GetHobList ((CONST EFI_PEI_SERVICES
**)PeiServices
, (VOID
**) &Hob
.Raw
);
57 ASSERT_EFI_ERROR (Status
);
58 while (!END_OF_HOB_LIST (Hob
)) {
59 if (Hob
.Header
->HobType
== EFI_HOB_TYPE_GUID_EXTENSION
&&
60 CompareGuid (&Hob
.Guid
->Name
, &gEfiMemoryTypeInformationGuid
)) {
61 MemoryData
= (EFI_MEMORY_TYPE_INFORMATION
*) (Hob
.Raw
+ sizeof (EFI_HOB_GENERIC_HEADER
) + sizeof (EFI_GUID
));
65 Hob
.Raw
= GET_NEXT_HOB (Hob
);
68 if (MemoryData
== NULL
) {
73 for (Index
= 0; MemoryData
[Index
].Type
!= EfiMaxMemoryType
; Index
++) {
75 // Accumulate default memory size requirements
77 TempPageNum
+= MemoryData
[Index
].NumberOfPages
;
80 return TempPageNum
* EFI_PAGE_SIZE
;
84 Get the mem size need to be reserved in PEI phase.
86 @param[in] PeiServices PEI Services table.
88 @return the mem size need to be reserved in PEI phase.
91 RetrieveRequiredMemorySize (
92 IN EFI_PEI_SERVICES
**PeiServices
97 Size
= GetMemorySizeInMemoryTypeInformation (PeiServices
);
98 return Size
+ PEI_ADDITIONAL_MEMORY_SIZE
;
102 Get the mem size need to be consumed and reserved in PEI phase.
104 @param[in] PeiServices PEI Services table.
105 @param[in] BootMode Current boot mode.
107 @return the mem size need to be consumed and reserved in PEI phase.
111 IN EFI_PEI_SERVICES
**PeiServices
,
118 if (BootMode
== BOOT_IN_RECOVERY_MODE
) {
119 return PcdGet32 (PcdPeiRecoveryMinMemSize
);
122 Size
= GetMemorySizeInMemoryTypeInformation (PeiServices
);
124 if (BootMode
== BOOT_ON_FLASH_UPDATE
) {
126 // Maybe more size when in CapsuleUpdate phase ?
128 MinSize
= PcdGet32 (PcdPeiMinMemSize
);
130 MinSize
= PcdGet32 (PcdPeiMinMemSize
);
133 return MinSize
+ Size
+ PEI_ADDITIONAL_MEMORY_SIZE
;
137 Post FSP-M HOB process for Memory Resource Descriptor.
139 @param[in] FspHobList Pointer to the HOB data structure produced by FSP.
141 @return If platform process the FSP hob list successfully.
149 EFI_PEI_HOB_POINTERS Hob
;
150 UINT64 LowMemorySize
;
151 UINT64 FspMemorySize
;
152 EFI_PHYSICAL_ADDRESS FspMemoryBase
;
154 EFI_PHYSICAL_ADDRESS PeiMemBase
;
156 EFI_PHYSICAL_ADDRESS S3PeiMemBase
;
157 BOOLEAN FoundFspMemHob
;
159 EFI_BOOT_MODE BootMode
;
160 EFI_PEI_CAPSULE_PPI
*Capsule
;
162 UINTN CapsuleBufferLength
;
163 UINT64 RequiredMemSize
;
164 EFI_PEI_SERVICES
**PeiServices
;
166 PeiServices
= (EFI_PEI_SERVICES
**)GetPeiServicesTablePointer ();
168 PeiServicesGetBootMode (&BootMode
);
174 FoundFspMemHob
= FALSE
;
177 // Parse the hob list from fsp
178 // Report all the resource hob except the memory between 1M and 4G
180 Hob
.Raw
= (UINT8
*)(UINTN
)FspHobList
;
181 DEBUG((DEBUG_INFO
, "FspHobList - 0x%x\n", FspHobList
));
183 while ((Hob
.Raw
= GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR
, Hob
.Raw
)) != NULL
) {
184 DEBUG((DEBUG_INFO
, "\nResourceType: 0x%x\n", Hob
.ResourceDescriptor
->ResourceType
));
185 if ((Hob
.ResourceDescriptor
->ResourceType
== EFI_RESOURCE_SYSTEM_MEMORY
) ||
186 (Hob
.ResourceDescriptor
->ResourceType
== EFI_RESOURCE_MEMORY_RESERVED
)) {
187 DEBUG((DEBUG_INFO
, "ResourceAttribute: 0x%x\n", Hob
.ResourceDescriptor
->ResourceAttribute
));
188 DEBUG((DEBUG_INFO
, "PhysicalStart: 0x%x\n", Hob
.ResourceDescriptor
->PhysicalStart
));
189 DEBUG((DEBUG_INFO
, "ResourceLength: 0x%x\n", Hob
.ResourceDescriptor
->ResourceLength
));
190 DEBUG((DEBUG_INFO
, "Owner: %g\n\n", &Hob
.ResourceDescriptor
->Owner
));
193 if ((Hob
.ResourceDescriptor
->ResourceType
== EFI_RESOURCE_SYSTEM_MEMORY
) // Found the low memory length below 4G
194 && (Hob
.ResourceDescriptor
->PhysicalStart
>= BASE_1MB
)
195 && (Hob
.ResourceDescriptor
->PhysicalStart
+ Hob
.ResourceDescriptor
->ResourceLength
<= BASE_4GB
)) {
196 LowMemorySize
+= Hob
.ResourceDescriptor
->ResourceLength
;
197 Hob
.Raw
= GET_NEXT_HOB (Hob
);
201 if ((Hob
.ResourceDescriptor
->ResourceType
== EFI_RESOURCE_MEMORY_RESERVED
) // Found the low memory length below 4G
202 && (Hob
.ResourceDescriptor
->PhysicalStart
>= BASE_1MB
)
203 && (Hob
.ResourceDescriptor
->PhysicalStart
+ Hob
.ResourceDescriptor
->ResourceLength
<= BASE_4GB
)
204 && (CompareGuid (&Hob
.ResourceDescriptor
->Owner
, &gFspReservedMemoryResourceHobGuid
))) {
205 FoundFspMemHob
= TRUE
;
206 FspMemoryBase
= Hob
.ResourceDescriptor
->PhysicalStart
;
207 FspMemorySize
= Hob
.ResourceDescriptor
->ResourceLength
;
208 DEBUG((DEBUG_INFO
, "Find fsp mem hob, base 0x%x, len 0x%x\n", FspMemoryBase
, FspMemorySize
));
212 // Report the resource hob
214 BuildResourceDescriptorHob (
215 Hob
.ResourceDescriptor
->ResourceType
,
216 Hob
.ResourceDescriptor
->ResourceAttribute
,
217 Hob
.ResourceDescriptor
->PhysicalStart
,
218 Hob
.ResourceDescriptor
->ResourceLength
221 Hob
.Raw
= GET_NEXT_HOB (Hob
);
224 if (!FoundFspMemHob
) {
225 DEBUG((DEBUG_INFO
, "Didn't find the fsp used memory information.\n"));
229 DEBUG((DEBUG_INFO
, "LowMemorySize: 0x%x.\n", LowMemorySize
));
230 DEBUG((DEBUG_INFO
, "FspMemoryBase: 0x%x.\n", FspMemoryBase
));
231 DEBUG((DEBUG_INFO
, "FspMemorySize: 0x%x.\n", FspMemorySize
));
233 if (BootMode
== BOOT_ON_S3_RESUME
) {
234 BuildResourceDescriptorHob (
235 EFI_RESOURCE_SYSTEM_MEMORY
,
237 EFI_RESOURCE_ATTRIBUTE_PRESENT
|
238 EFI_RESOURCE_ATTRIBUTE_INITIALIZED
|
239 // EFI_RESOURCE_ATTRIBUTE_TESTED |
240 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE
|
241 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE
|
242 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE
|
243 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
251 Status
= GetS3MemoryInfo (&S3PeiMemSize
, &S3PeiMemBase
);
252 ASSERT_EFI_ERROR (Status
);
253 DEBUG((DEBUG_INFO
, "S3 memory %Xh - %Xh bytes\n", S3PeiMemBase
, S3PeiMemSize
));
256 // Make sure Stack and PeiMemory are not overlap
259 Status
= PeiServicesInstallPeiMemory (
263 ASSERT_EFI_ERROR (Status
);
265 PeiMemSize
= GetPeiMemSize (PeiServices
, BootMode
);
266 DEBUG((DEBUG_INFO
, "PEI memory size = %Xh bytes\n", PeiMemSize
));
272 CapsuleBuffer
= NULL
;
273 CapsuleBufferLength
= 0;
274 if (BootMode
== BOOT_ON_FLASH_UPDATE
) {
275 Status
= PeiServicesLocatePpi (
276 &gEfiPeiCapsulePpiGuid
,
281 ASSERT_EFI_ERROR (Status
);
283 if (Status
== EFI_SUCCESS
) {
285 // Make sure Stack and CapsuleBuffer are not overlap
287 CapsuleBuffer
= (VOID
*)(UINTN
)BASE_1MB
;
288 CapsuleBufferLength
= (UINTN
)(LowMemorySize
- PeiMemSize
);
290 // Call the Capsule PPI Coalesce function to coalesce the capsule data.
292 Status
= Capsule
->Coalesce (PeiServices
, &CapsuleBuffer
, &CapsuleBufferLength
);
296 RequiredMemSize
= RetrieveRequiredMemorySize (PeiServices
);
297 DEBUG((DEBUG_INFO
, "Required memory size = %Xh bytes\n", RequiredMemSize
));
300 // Report the main memory
302 BuildResourceDescriptorHob (
303 EFI_RESOURCE_SYSTEM_MEMORY
,
305 EFI_RESOURCE_ATTRIBUTE_PRESENT
|
306 EFI_RESOURCE_ATTRIBUTE_INITIALIZED
|
307 EFI_RESOURCE_ATTRIBUTE_TESTED
|
308 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE
|
309 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE
|
310 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE
|
311 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
318 // Make sure Stack and CapsuleBuffer are not overlap
322 // Install efi memory
324 PeiMemBase
= BASE_1MB
+ LowMemorySize
- PeiMemSize
;
325 Status
= PeiServicesInstallPeiMemory (
327 PeiMemSize
- RequiredMemSize
329 ASSERT_EFI_ERROR (Status
);
331 if (Capsule
!= NULL
) {
332 Status
= Capsule
->CreateState (PeiServices
, CapsuleBuffer
, CapsuleBufferLength
);
342 @param[in] FspHobList Pointer to the HOB data structure produced by FSP.
350 EFI_PEI_HOB_POINTERS FspHob
;
352 FspHob
.Raw
= FspHobList
;
355 // Add all the HOBs from FSP binary to FSP wrapper
357 while (!END_OF_HOB_LIST (FspHob
)) {
358 if (FspHob
.Header
->HobType
== EFI_HOB_TYPE_GUID_EXTENSION
) {
360 // Skip FSP binary creates PcdDataBaseHobGuid
362 if (!CompareGuid(&FspHob
.Guid
->Name
, &gPcdDataBaseHobGuid
)) {
365 GET_GUID_HOB_DATA(FspHob
),
366 GET_GUID_HOB_DATA_SIZE(FspHob
)
370 FspHob
.Raw
= GET_NEXT_HOB (FspHob
);
375 Post FSP-S HOB process (not Memory Resource Descriptor).
377 @param[in] FspHobList Pointer to the HOB data structure produced by FSP.
379 @return If platform process the FSP hob list successfully.
387 ProcessFspHobList (FspHobList
);