Home | History | Annotate | Download | only in PeiFspHobProcessLibVlv2
      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
     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
     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
    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
    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
    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
    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