1 /** @file
2 Null instance of Platform Sec Lib.
3
4 Copyright (c) 2014, 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.
9
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.
12
13 **/
14
15 #include <PiPei.h>
16
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/FspPlatformInfoLib.h>
25
26 #include <Guid/GuidHobFsp.h>
27 #include <Guid/MemoryTypeInformation.h>
28 #include <Ppi/Capsule.h>
29
30 #include <PlatformFspLib.h>
31 #include <Guid/SmramMemoryReserve.h>
32 EFI_GUID gFspReservedMemoryResourceHobTsegGuid = {0xd038747c, 0xd00c, 0x4980, {0xb3, 0x19, 0x49, 0x01, 0x99, 0xa4, 0x7d, 0x55}};
33
34 //
35 // Additional pages are used by DXE memory manager.
36 // It should be consistent between RetrieveRequiredMemorySize() and GetPeiMemSize()
37 //
38 #define PEI_ADDITIONAL_MEMORY_SIZE (16 * EFI_PAGE_SIZE)
39
40 /**
41 Get the mem size in memory type infromation table.
42
43 @param PeiServices PEI Services table.
44
45 @return the mem size in memory type infromation table.
46 **/
47 UINT64
GetMemorySizeInMemoryTypeInformation(IN EFI_PEI_SERVICES ** PeiServices)48 GetMemorySizeInMemoryTypeInformation (
49 IN EFI_PEI_SERVICES **PeiServices
50 )
51 {
52 EFI_PEI_HOB_POINTERS Hob;
53 EFI_MEMORY_TYPE_INFORMATION *MemoryData;
54 UINT8 Index;
55 UINTN TempPageNum;
56
57 MemoryData = NULL;
58 (*PeiServices)->GetHobList ((CONST EFI_PEI_SERVICES **)PeiServices, (VOID **) &Hob.Raw);
59 while (!END_OF_HOB_LIST (Hob)) {
60 if (Hob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION &&
61 CompareGuid (&Hob.Guid->Name, &gEfiMemoryTypeInformationGuid)) {
62 MemoryData = (EFI_MEMORY_TYPE_INFORMATION *) (Hob.Raw + sizeof (EFI_HOB_GENERIC_HEADER) + sizeof (EFI_GUID));
63 break;
64 }
65
66 Hob.Raw = GET_NEXT_HOB (Hob);
67 }
68
69 if (MemoryData == NULL) {
70 return 0;
71 }
72
73 TempPageNum = 0;
74 for (Index = 0; MemoryData[Index].Type != EfiMaxMemoryType; Index++) {
75 //
76 // Accumulate default memory size requirements
77 //
78 TempPageNum += MemoryData[Index].NumberOfPages;
79 }
80
81 return TempPageNum * EFI_PAGE_SIZE;
82 }
83
84 /**
85 Get the mem size need to be reserved in PEI phase.
86
87 @param PeiServices PEI Services table.
88
89 @return the mem size need to be reserved in PEI phase.
90 **/
91 UINT64
RetrieveRequiredMemorySize(IN EFI_PEI_SERVICES ** PeiServices)92 RetrieveRequiredMemorySize (
93 IN EFI_PEI_SERVICES **PeiServices
94 )
95 {
96 UINT64 Size;
97
98 Size = GetMemorySizeInMemoryTypeInformation (PeiServices);
99 return Size + PEI_ADDITIONAL_MEMORY_SIZE;
100 }
101
102 /**
103 Get the mem size need to be consumed and reserved in PEI phase.
104
105 @param PeiServices PEI Services table.
106 @param BootMode Current boot mode.
107
108 @return the mem size need to be consumed and reserved in PEI phase.
109 **/
110 UINT64
GetPeiMemSize(IN EFI_PEI_SERVICES ** PeiServices,IN UINT32 BootMode)111 GetPeiMemSize (
112 IN EFI_PEI_SERVICES **PeiServices,
113 IN UINT32 BootMode
114 )
115 {
116 UINT64 Size;
117 UINT64 MinSize;
118
119 if (BootMode == BOOT_IN_RECOVERY_MODE) {
120 return PcdGet32 (PcdPeiRecoveryMinMemSize);
121 }
122
123 Size = GetMemorySizeInMemoryTypeInformation (PeiServices);
124
125 if (BootMode == BOOT_ON_FLASH_UPDATE) {
126 //
127 // Maybe more size when in CapsuleUpdate phase ?
128 //
129 MinSize = PcdGet32 (PcdPeiMinMemSize);
130 } else {
131 MinSize = PcdGet32 (PcdPeiMinMemSize);
132 }
133
134 return MinSize + Size + PEI_ADDITIONAL_MEMORY_SIZE;
135 }
136
137 /**
138 BIOS process FspBobList.
139
140 @param FspHobList Pointer to the HOB data structure produced by FSP.
141
142 @return If platform process the FSP hob list successfully.
143 **/
144 EFI_STATUS
145 EFIAPI
FspHobProcessForMemoryResource(IN VOID * FspHobList)146 FspHobProcessForMemoryResource (
147 IN VOID *FspHobList
148 )
149 {
150 EFI_PEI_HOB_POINTERS Hob;
151 UINT64 LowMemorySize;
152 UINT64 FspMemorySize;
153 EFI_PHYSICAL_ADDRESS FspMemoryBase;
154 UINT64 PeiMemSize;
155 EFI_PHYSICAL_ADDRESS PeiMemBase;
156 UINT64 S3PeiMemSize;
157 EFI_PHYSICAL_ADDRESS S3PeiMemBase;
158 BOOLEAN FoundFspMemHob;
159 EFI_STATUS Status;
160 EFI_BOOT_MODE BootMode;
161 PEI_CAPSULE_PPI *Capsule;
162 VOID *CapsuleBuffer;
163 UINTN CapsuleBufferLength;
164 UINT64 RequiredMemSize;
165 EFI_PEI_SERVICES **PeiServices;
166 UINT64 TsegSize;
167 EFI_PHYSICAL_ADDRESS TsegBase;
168 BOOLEAN FoundTsegHob;
169
170 PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer ();
171
172 PeiServicesGetBootMode (&BootMode);
173
174 PeiMemBase = 0;
175 LowMemorySize = 0;
176 FspMemorySize = 0;
177 FspMemoryBase = 0;
178 FoundFspMemHob = FALSE;
179 TsegSize = 0;
180 TsegBase = 0;
181 FoundTsegHob = FALSE;
182
183 //
184 // Parse the hob list from fsp
185 // Report all the resource hob except the memory between 1M and 4G
186 //
187 Hob.Raw = (UINT8 *)(UINTN)FspHobList;
188 DEBUG((DEBUG_INFO, "FspHobList - 0x%x\n", FspHobList));
189
190 while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw)) != NULL) {
191 DEBUG((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType));
192 if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) ||
193 (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED)) {
194 DEBUG((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));
195 DEBUG((DEBUG_INFO, "PhysicalStart: 0x%x\n", Hob.ResourceDescriptor->PhysicalStart));
196 DEBUG((DEBUG_INFO, "ResourceLength: 0x%x\n", Hob.ResourceDescriptor->ResourceLength));
197 DEBUG((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));
198 }
199
200 if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) // Found the low memory length below 4G
201 && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB)
202 && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB)) {
203 LowMemorySize += Hob.ResourceDescriptor->ResourceLength;
204 Hob.Raw = GET_NEXT_HOB (Hob);
205 continue;
206 }
207
208 if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED) // Found the low memory length below 4G
209 && (Hob.ResourceDescriptor->PhysicalStart >= BASE_1MB)
210 && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= BASE_4GB)
211 && (CompareGuid (&Hob.ResourceDescriptor->Owner, &gFspReservedMemoryResourceHobGuid))) {
212 FoundFspMemHob = TRUE;
213 FspMemoryBase = Hob.ResourceDescriptor->PhysicalStart;
214 FspMemorySize = Hob.ResourceDescriptor->ResourceLength;
215 DEBUG((DEBUG_INFO, "Find fsp mem hob, base 0x%x, len 0x%x\n", FspMemoryBase, FspMemorySize));
216 }
217
218 if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED) // Found the low memory length below 4G
219 && (Hob.ResourceDescriptor->PhysicalStart >= 0x100000)
220 && (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength <= 0x100000000)
221 && (CompareGuid (&Hob.ResourceDescriptor->Owner, &gFspReservedMemoryResourceHobTsegGuid))) {
222 FoundTsegHob = TRUE;
223 TsegBase = Hob.ResourceDescriptor->PhysicalStart;
224
225
226 if ((Hob.ResourceDescriptor->ResourceLength == 0 ) || (Hob.ResourceDescriptor->ResourceLength > 0x800000)){
227 Hob.ResourceDescriptor->ResourceLength = 0x800000;
228 }
229
230
231 TsegSize = Hob.ResourceDescriptor->ResourceLength;
232 DEBUG((EFI_D_ERROR, "Find Tseg mem hob, base 0x%lx, len 0x%lx\n", TsegBase, TsegSize));
233 }
234
235 //
236 // Report the resource hob
237 //
238 BuildResourceDescriptorHob (
239 Hob.ResourceDescriptor->ResourceType,
240 Hob.ResourceDescriptor->ResourceAttribute,
241 Hob.ResourceDescriptor->PhysicalStart,
242 Hob.ResourceDescriptor->ResourceLength
243 );
244
245 Hob.Raw = GET_NEXT_HOB (Hob);
246 }
247
248 if (!FoundFspMemHob) {
249 DEBUG((DEBUG_INFO, "Didn't find the fsp used memory information.\n"));
250 //ASSERT(FALSE);
251 }
252
253 DEBUG((DEBUG_INFO, "LowMemorySize: 0x%x.\n", LowMemorySize));
254 DEBUG((DEBUG_INFO, "FspMemoryBase: 0x%x.\n", FspMemoryBase));
255 DEBUG((DEBUG_INFO, "FspMemorySize: 0x%x.\n", FspMemorySize));
256
257 if (BootMode == BOOT_ON_S3_RESUME) {
258 BuildResourceDescriptorHob (
259 EFI_RESOURCE_SYSTEM_MEMORY,
260 (
261 EFI_RESOURCE_ATTRIBUTE_PRESENT |
262 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
263 // EFI_RESOURCE_ATTRIBUTE_TESTED |
264 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
265 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
266 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
267 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
268 ),
269 BASE_1MB,
270 LowMemorySize
271 );
272
273 Status = GetS3MemoryInfo (&S3PeiMemBase, &S3PeiMemSize);
274 ASSERT_EFI_ERROR (Status);
275 DEBUG((DEBUG_INFO, "S3 memory %Xh - %Xh bytes\n", S3PeiMemBase, S3PeiMemSize));
276
277 //
278 // Make sure Stack and PeiMemory are not overlap - JYAO1
279 //
280
281 Status = PeiServicesInstallPeiMemory (
282 S3PeiMemBase,
283 S3PeiMemSize
284 );
285 ASSERT_EFI_ERROR (Status);
286 } else {
287 PeiMemSize = GetPeiMemSize (PeiServices, BootMode);
288 DEBUG((DEBUG_INFO, "PEI memory size = %Xh bytes\n", PeiMemSize));
289
290 //
291 // Capsule mode
292 //
293 Capsule = NULL;
294 CapsuleBuffer = NULL;
295 CapsuleBufferLength = 0;
296 if (BootMode == BOOT_ON_FLASH_UPDATE) {
297 Status = PeiServicesLocatePpi (
298 &gPeiCapsulePpiGuid,
299 0,
300 NULL,
301 (VOID **) &Capsule
302 );
303 ASSERT_EFI_ERROR (Status);
304
305 if (Status == EFI_SUCCESS) {
306 //
307 // Make sure Stack and CapsuleBuffer are not overlap - JYAO1
308 //
309 CapsuleBuffer = (VOID *)(UINTN)BASE_1MB;
310 CapsuleBufferLength = (UINTN)(LowMemorySize - PeiMemSize);
311 //
312 // Call the Capsule PPI Coalesce function to coalesce the capsule data.
313 //
314 Status = Capsule->Coalesce (PeiServices, &CapsuleBuffer, &CapsuleBufferLength);
315 }
316 }
317
318 RequiredMemSize = RetrieveRequiredMemorySize (PeiServices);
319 DEBUG((DEBUG_INFO, "Required memory size = %Xh bytes\n", RequiredMemSize));
320
321 //
322 // Report the main memory
323 //
324 BuildResourceDescriptorHob (
325 EFI_RESOURCE_SYSTEM_MEMORY,
326 (
327 EFI_RESOURCE_ATTRIBUTE_PRESENT |
328 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
329 EFI_RESOURCE_ATTRIBUTE_TESTED |
330 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
331 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
332 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
333 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
334 ),
335 BASE_1MB,
336 LowMemorySize
337 );
338
339 //
340 // Make sure Stack and CapsuleBuffer are not overlap - JYAO1
341 //
342
343 //
344 // Install efi memory
345 //
346 PeiMemBase = BASE_1MB + LowMemorySize - PeiMemSize;
347 Status = PeiServicesInstallPeiMemory (
348 PeiMemBase,
349 PeiMemSize - RequiredMemSize
350 );
351 ASSERT_EFI_ERROR (Status);
352
353 if (Capsule != NULL) {
354 Status = Capsule->CreateState (PeiServices, CapsuleBuffer, CapsuleBufferLength);
355 }
356 }
357
358 //
359 // Report GUIDed HOB for reserving SMRAM regions
360 //
361 if (FoundTsegHob) {
362 EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *SmramHobDescriptorBlock;
363
364 SmramHobDescriptorBlock = BuildGuidHob (
365 &gEfiSmmPeiSmramMemoryReserveGuid,
366 sizeof (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK)
367 );
368 ASSERT (SmramHobDescriptorBlock != NULL);
369
370 SmramHobDescriptorBlock->NumberOfSmmReservedRegions = 1;
371
372 SmramHobDescriptorBlock->Descriptor[0].PhysicalStart = TsegBase;
373 SmramHobDescriptorBlock->Descriptor[0].CpuStart = TsegBase;
374 SmramHobDescriptorBlock->Descriptor[0].PhysicalSize = TsegSize;
375 SmramHobDescriptorBlock->Descriptor[0].RegionState = EFI_SMRAM_CLOSED;
376 }
377 return EFI_SUCCESS;
378 }
379
380 /**
381 BIOS process FspBobList for other data (not Memory Resource Descriptor).
382
383 @param[in] FspHobList Pointer to the HOB data structure produced by FSP.
384
385 @return If platform process the FSP hob list successfully.
386 **/
387 EFI_STATUS
388 EFIAPI
FspHobProcessForOtherData(IN VOID * FspHobList)389 FspHobProcessForOtherData (
390 IN VOID *FspHobList
391 )
392 {
393 EFI_PEI_SERVICES **PeiServices;
394
395 PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer ();
396
397 //
398 // Other hob for platform
399 //
400 PlatformHobCreateFromFsp ((CONST EFI_PEI_SERVICES **) PeiServices, FspHobList);
401
402 return EFI_SUCCESS;
403 }
404
405 /**
406 BIOS process FspBobList.
407
408 @param[in] FspHobList Pointer to the HOB data structure produced by FSP.
409
410 @return If platform process the FSP hob list successfully.
411 **/
412 EFI_STATUS
413 EFIAPI
FspHobProcess(IN VOID * FspHobList)414 FspHobProcess (
415 IN VOID *FspHobList
416 )
417 {
418 EFI_STATUS Status;
419
420 Status = FspHobProcessForMemoryResource (FspHobList);
421 if (EFI_ERROR (Status)) {
422 return Status;
423 }
424 Status = FspHobProcessForOtherData (FspHobList);
425
426 return Status;
427 }
428