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_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
     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
    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
    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
    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
    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