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