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