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