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