Update IntelFspWrapperPkg according to FSP1.1.
[mirror_edk2.git] / IntelFspWrapperPkg / Library / PeiFspHobProcessLibSample / FspHobProcessLibSample.c
CommitLineData
a33a2f62
JY
1/** @file\r
2 Sample to provide FSP hob process related function.\r
3\r
d8043ce9 4 Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>\r
a33a2f62
JY
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php.\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include <PiPei.h>\r
16\r
17#include <Library/PeiServicesLib.h>\r
18#include <Library/PeiServicesTablePointerLib.h>\r
19#include <Library/BaseLib.h>\r
20#include <Library/DebugLib.h>\r
21#include <Library/BaseMemoryLib.h>\r
22#include <Library/HobLib.h>\r
23#include <Library/PcdLib.h>\r
24#include <Library/FspPlatformInfoLib.h>\r
25\r
26#include <Guid/GuidHobFspEas.h>\r
27#include <Guid/MemoryTypeInformation.h>\r
28#include <Ppi/Capsule.h>\r
29\r
30//\r
31// Additional pages are used by DXE memory manager.\r
32// It should be consistent between RetrieveRequiredMemorySize() and GetPeiMemSize()\r
33//\r
34#define PEI_ADDITIONAL_MEMORY_SIZE (16 * EFI_PAGE_SIZE)\r
35\r
36/**\r
37 Get the mem size in memory type infromation table.\r
38\r
39 @param[in] PeiServices PEI Services table.\r
40\r
41 @return the mem size in memory type infromation table.\r
42**/\r
43UINT64\r
44GetMemorySizeInMemoryTypeInformation (\r
45 IN EFI_PEI_SERVICES **PeiServices\r
46 )\r
47{\r
48 EFI_STATUS Status;\r
49 EFI_PEI_HOB_POINTERS Hob;\r
50 EFI_MEMORY_TYPE_INFORMATION *MemoryData;\r
51 UINT8 Index;\r
52 UINTN TempPageNum;\r
53\r
54 MemoryData = NULL;\r
55 Status = (*PeiServices)->GetHobList ((CONST EFI_PEI_SERVICES**)PeiServices, (VOID **) &Hob.Raw);\r
56 while (!END_OF_HOB_LIST (Hob)) {\r
57 if (Hob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION &&\r
58 CompareGuid (&Hob.Guid->Name, &gEfiMemoryTypeInformationGuid)) {\r
59 MemoryData = (EFI_MEMORY_TYPE_INFORMATION *) (Hob.Raw + sizeof (EFI_HOB_GENERIC_HEADER) + sizeof (EFI_GUID));\r
60 break;\r
61 }\r
62\r
63 Hob.Raw = GET_NEXT_HOB (Hob);\r
64 }\r
65\r
66 if (MemoryData == NULL) {\r
67 return 0;\r
68 }\r
69\r
70 TempPageNum = 0;\r
71 for (Index = 0; MemoryData[Index].Type != EfiMaxMemoryType; Index++) {\r
72 //\r
73 // Accumulate default memory size requirements\r
74 //\r
75 TempPageNum += MemoryData[Index].NumberOfPages;\r
76 }\r
77\r
78 return TempPageNum * EFI_PAGE_SIZE;\r
79}\r
80\r
81/**\r
82 Get the mem size need to be reserved in PEI phase.\r
83\r
84 @param[in] PeiServices PEI Services table.\r
85\r
86 @return the mem size need to be reserved in PEI phase.\r
87**/\r
88UINT64\r
89RetrieveRequiredMemorySize (\r
90 IN EFI_PEI_SERVICES **PeiServices\r
91 )\r
92{\r
93 UINT64 Size;\r
94\r
95 Size = GetMemorySizeInMemoryTypeInformation (PeiServices);\r
96 return Size + PEI_ADDITIONAL_MEMORY_SIZE;\r
97}\r
98\r
99/**\r
100 Get the mem size need to be consumed and reserved in PEI phase.\r
101\r
102 @param[in] PeiServices PEI Services table.\r
103 @param[in] BootMode Current boot mode.\r
104\r
105 @return the mem size need to be consumed and reserved in PEI phase.\r
106**/\r
107UINT64\r
108GetPeiMemSize (\r
109 IN EFI_PEI_SERVICES **PeiServices,\r
110 IN UINT32 BootMode\r
111 )\r
112{\r
113 UINT64 Size;\r
114 UINT64 MinSize;\r
115\r
116 if (BootMode == BOOT_IN_RECOVERY_MODE) {\r
117 return PcdGet32 (PcdPeiRecoveryMinMemSize);\r
118 }\r
119\r
120 Size = GetMemorySizeInMemoryTypeInformation (PeiServices);\r
121\r
122 if (BootMode == BOOT_ON_FLASH_UPDATE) {\r
123 //\r
124 // Maybe more size when in CapsuleUpdate phase ?\r
125 //\r
126 MinSize = PcdGet32 (PcdPeiMinMemSize);\r
127 } else {\r
128 MinSize = PcdGet32 (PcdPeiMinMemSize);\r
129 }\r
130\r
131 return MinSize + Size + PEI_ADDITIONAL_MEMORY_SIZE;\r
132}\r
133\r
134/**\r
d8043ce9 135 BIOS process FspBobList for Memory Resource Descriptor.\r
a33a2f62
JY
136\r
137 @param[in] FspHobList Pointer to the HOB data structure produced by FSP.\r
138\r
139 @return If platform process the FSP hob list successfully.\r
140**/\r
141EFI_STATUS\r
142EFIAPI\r
d8043ce9 143FspHobProcessForMemoryResource (\r
a33a2f62
JY
144 IN VOID *FspHobList\r
145 )\r
146{\r
147 EFI_PEI_HOB_POINTERS Hob;\r
148 UINT64 LowMemorySize;\r
149 UINT64 FspMemorySize;\r
150 EFI_PHYSICAL_ADDRESS FspMemoryBase;\r
151 UINT64 PeiMemSize;\r
152 EFI_PHYSICAL_ADDRESS PeiMemBase;\r
153 UINT64 S3PeiMemSize;\r
154 EFI_PHYSICAL_ADDRESS S3PeiMemBase;\r
155 BOOLEAN FoundFspMemHob;\r
156 EFI_STATUS Status;\r
157 EFI_BOOT_MODE BootMode;\r
158 PEI_CAPSULE_PPI *Capsule;\r
159 VOID *CapsuleBuffer;\r
160 UINTN CapsuleBufferLength;\r
161 UINT64 RequiredMemSize;\r
162 EFI_PEI_SERVICES **PeiServices;\r
163\r
164 PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer ();\r
165\r
166 PeiServicesGetBootMode (&BootMode);\r
167\r
168 PeiMemBase = 0;\r
169 LowMemorySize = 0;\r
170 FspMemorySize = 0;\r
171 FspMemoryBase = 0;\r
172 FoundFspMemHob = FALSE;\r
173\r
174 //\r
175 // Parse the hob list from fsp\r
176 // Report all the resource hob except the memory between 1M and 4G\r
177 //\r
178 Hob.Raw = (UINT8 *)(UINTN)FspHobList;\r
179 DEBUG((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList));\r
180\r
181 while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw)) != NULL) {\r
182 DEBUG((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType));\r
183 if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) ||\r
184 (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED)) {\r
185 DEBUG((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));\r
186 DEBUG((DEBUG_INFO, "PhysicalStart: 0x%x\n", Hob.ResourceDescriptor->PhysicalStart));\r
187 DEBUG((DEBUG_INFO, "ResourceLength: 0x%x\n", Hob.ResourceDescriptor->ResourceLength));\r
188 DEBUG((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));\r
189 }\r
190\r
191 if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) // Found the low memory length below 4G\r
192 && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB)\r
193 && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB)) {\r
194 LowMemorySize += Hob.ResourceDescriptor->ResourceLength;\r
195 Hob.Raw = GET_NEXT_HOB (Hob);\r
196 continue;\r
197 }\r
198\r
199 if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED) // Found the low memory length below 4G\r
200 && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB)\r
201 && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB)\r
202 && (CompareGuid (&Hob.ResourceDescriptor->Owner, &gFspReservedMemoryResourceHobGuid))) {\r
203 FoundFspMemHob = TRUE;\r
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
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
223 DEBUG((DEBUG_INFO, "Didn't find the fsp used memory information.\n"));\r
224 //ASSERT(FALSE);\r
225 }\r
226\r
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
230\r
231 if (BootMode == BOOT_ON_S3_RESUME) {\r
232 BuildResourceDescriptorHob (\r
233 EFI_RESOURCE_SYSTEM_MEMORY,\r
234 (\r
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
242 ),\r
243 BASE_1MB,\r
244 LowMemorySize\r
245 );\r
246\r
a0e0fb6d
JY
247 S3PeiMemBase = 0;\r
248 S3PeiMemSize = 0;\r
a33a2f62
JY
249 Status = GetS3MemoryInfo (&S3PeiMemBase, &S3PeiMemSize);\r
250 ASSERT_EFI_ERROR (Status);\r
251 DEBUG((DEBUG_INFO, "S3 memory %Xh - %Xh bytes\n", S3PeiMemBase, S3PeiMemSize));\r
252\r
253 //\r
b5fd61fe 254 // Make sure Stack and PeiMemory are not overlap\r
a33a2f62
JY
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
264 DEBUG((DEBUG_INFO, "PEI memory size = %Xh bytes\n", PeiMemSize));\r
265\r
266 //\r
267 // Capsule mode\r
268 //\r
269 Capsule = NULL;\r
270 CapsuleBuffer = NULL;\r
271 CapsuleBufferLength = 0;\r
272 if (BootMode == BOOT_ON_FLASH_UPDATE) {\r
273 Status = PeiServicesLocatePpi (\r
274 &gPeiCapsulePpiGuid,\r
275 0,\r
276 NULL,\r
277 (VOID **) &Capsule\r
278 );\r
279 ASSERT_EFI_ERROR (Status);\r
280\r
281 if (Status == EFI_SUCCESS) {\r
282 //\r
b5fd61fe 283 // Make sure Stack and CapsuleBuffer are not overlap\r
a33a2f62
JY
284 //\r
285 CapsuleBuffer = (VOID *)(UINTN)BASE_1MB;\r
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
295 DEBUG((DEBUG_INFO, "Required memory size = %Xh bytes\n", RequiredMemSize));\r
296\r
297 //\r
298 // Report the main memory\r
299 //\r
300 BuildResourceDescriptorHob (\r
301 EFI_RESOURCE_SYSTEM_MEMORY,\r
302 (\r
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
310 ),\r
311 BASE_1MB,\r
312 LowMemorySize\r
313 );\r
314\r
315 //\r
b5fd61fe 316 // Make sure Stack and CapsuleBuffer are not overlap\r
a33a2f62
JY
317 //\r
318\r
319 //\r
320 // Install efi memory\r
321 //\r
322 PeiMemBase = BASE_1MB + LowMemorySize - PeiMemSize;\r
323 Status = PeiServicesInstallPeiMemory (\r
324 PeiMemBase,\r
325 PeiMemSize - RequiredMemSize\r
326 );\r
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
d8043ce9
JY
334 return EFI_SUCCESS;\r
335}\r
336\r
337/**\r
338 BIOS process FspBobList for other data (not Memory Resource Descriptor).\r
339\r
340 @param[in] FspHobList Pointer to the HOB data structure produced by FSP.\r
a33a2f62 341\r
d8043ce9
JY
342 @return If platform process the FSP hob list successfully.\r
343**/\r
344EFI_STATUS\r
345EFIAPI\r
346FspHobProcessForOtherData (\r
347 IN VOID *FspHobList\r
348 )\r
349{\r
a33a2f62
JY
350 return EFI_SUCCESS;\r
351}\r
d8043ce9
JY
352\r
353/**\r
354 BIOS process FspBobList.\r
355\r
356 @param[in] FspHobList Pointer to the HOB data structure produced by FSP.\r
357\r
358 @return If platform process the FSP hob list successfully.\r
359**/\r
360EFI_STATUS\r
361EFIAPI\r
362FspHobProcess (\r
363 IN VOID *FspHobList\r
364 )\r
365{\r
366 EFI_STATUS Status;\r
367\r
368 Status = FspHobProcessForMemoryResource (FspHobList);\r
369 if (EFI_ERROR (Status)) {\r
370 return Status;\r
371 }\r
372 Status = FspHobProcessForOtherData (FspHobList);\r
373\r
374 return Status;\r
375}\r