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