• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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