Home | History | Annotate | Download | only in PeiHobLib
      1 /*++
      2 
      3 Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
      4 This program and the accompanying materials
      5 are licensed and made available under the terms and conditions of the BSD License
      6 which accompanies this distribution.  The full text of the license may be found at
      7 http://opensource.org/licenses/bsd-license.php
      8 
      9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     11 
     12 
     13 Module Name:
     14 
     15   HobLib.c
     16 
     17 Abstract:
     18 
     19   HOB Library.
     20 
     21 --*/
     22 
     23 #include "EdkIIGluePeim.h"
     24 
     25 /**
     26   Returns the pointer to the HOB list.
     27 
     28   This function returns the pointer to first HOB in the list.
     29 
     30   @return The pointer to the HOB list.
     31 
     32 **/
     33 VOID *
     34 EFIAPI
     35 GetHobList (
     36   VOID
     37   )
     38 {
     39   EFI_STATUS            Status;
     40   VOID                  *HobList;
     41 
     42   Status = PeiServicesGetHobList (&HobList);
     43   ASSERT_EFI_ERROR (Status);
     44   ASSERT (HobList != NULL);
     45 
     46   return HobList;
     47 }
     48 
     49 /**
     50   Returns the next instance of a HOB type from the starting HOB.
     51 
     52   This function searches the first instance of a HOB type from the starting HOB pointer.
     53   If there does not exist such HOB type from the starting HOB pointer, it will return NULL.
     54   In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
     55   unconditionally: it returns HobStart back if HobStart itself meets the requirement;
     56   caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
     57   If HobStart is NULL, then ASSERT().
     58 
     59   @param  Type          The HOB type to return.
     60   @param  HobStart      The starting HOB pointer to search from.
     61 
     62   @return The next instance of a HOB type from the starting HOB.
     63 
     64 **/
     65 VOID *
     66 EFIAPI
     67 GetNextHob (
     68   IN UINT16                 Type,
     69   IN CONST VOID             *HobStart
     70   )
     71 {
     72   EFI_PEI_HOB_POINTERS  Hob;
     73 
     74   ASSERT (HobStart != NULL);
     75 
     76   Hob.Raw = (UINT8 *) HobStart;
     77   //
     78   // Parse the HOB list until end of list or matching type is found.
     79   //
     80   while (!END_OF_HOB_LIST (Hob)) {
     81     if (Hob.Header->HobType == Type) {
     82       return Hob.Raw;
     83     }
     84     Hob.Raw = GET_NEXT_HOB (Hob);
     85   }
     86   return NULL;
     87 }
     88 
     89 /**
     90   Returns the first instance of a HOB type among the whole HOB list.
     91 
     92   This function searches the first instance of a HOB type among the whole HOB list.
     93   If there does not exist such HOB type in the HOB list, it will return NULL.
     94 
     95   @param  Type          The HOB type to return.
     96 
     97   @return The next instance of a HOB type from the starting HOB.
     98 
     99 **/
    100 VOID *
    101 EFIAPI
    102 GetFirstHob (
    103   IN UINT16                 Type
    104   )
    105 {
    106   VOID      *HobList;
    107 
    108   HobList = GetHobList ();
    109   return GetNextHob (Type, HobList);
    110 }
    111 
    112 /**
    113   This function searches the first instance of a HOB from the starting HOB pointer.
    114   Such HOB should satisfy two conditions:
    115   its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
    116   If there does not exist such HOB from the starting HOB pointer, it will return NULL.
    117   Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
    118   to extract the data section and its size info respectively.
    119   In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
    120   unconditionally: it returns HobStart back if HobStart itself meets the requirement;
    121   caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
    122   If Guid is NULL, then ASSERT().
    123   If HobStart is NULL, then ASSERT().
    124 
    125   @param  Guid          The GUID to match with in the HOB list.
    126   @param  HobStart      A pointer to a Guid.
    127 
    128   @return The next instance of the matched GUID HOB from the starting HOB.
    129 
    130 **/
    131 VOID *
    132 EFIAPI
    133 GlueGetNextGuidHob (
    134   IN CONST EFI_GUID         *Guid,
    135   IN CONST VOID             *HobStart
    136   )
    137 {
    138   EFI_PEI_HOB_POINTERS  GuidHob;
    139 
    140   GuidHob.Raw = (UINT8 *) HobStart;
    141   while ((GuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GuidHob.Raw)) != NULL) {
    142     if (CompareGuid (Guid, &GuidHob.Guid->Name)) {
    143       break;
    144     }
    145     GuidHob.Raw = GET_NEXT_HOB (GuidHob);
    146   }
    147   return GuidHob.Raw;
    148 }
    149 
    150 /**
    151   This function searches the first instance of a HOB among the whole HOB list.
    152   Such HOB should satisfy two conditions:
    153   its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
    154   If there does not exist such HOB from the starting HOB pointer, it will return NULL.
    155   Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
    156   to extract the data section and its size info respectively.
    157   If Guid is NULL, then ASSERT().
    158 
    159   @param  Guid          The GUID to match with in the HOB list.
    160 
    161   @return The first instance of the matched GUID HOB among the whole HOB list.
    162 
    163 **/
    164 VOID *
    165 EFIAPI
    166 GlueGetFirstGuidHob (
    167   IN CONST EFI_GUID         *Guid
    168   )
    169 {
    170   VOID      *HobList;
    171 
    172   HobList = GetHobList ();
    173   return GetNextGuidHob (Guid, HobList);
    174 }
    175 
    176 /**
    177   Get the Boot Mode from the HOB list.
    178 
    179   This function returns the system boot mode information from the
    180   PHIT HOB in HOB list.
    181 
    182   @param  VOID
    183 
    184   @return The Boot Mode.
    185 
    186 **/
    187 EFI_BOOT_MODE
    188 EFIAPI
    189 GetBootModeHob (
    190   VOID
    191   )
    192 {
    193   EFI_STATUS             Status;
    194   EFI_BOOT_MODE          BootMode;
    195 
    196   Status = PeiServicesGetBootMode (&BootMode);
    197   ASSERT_EFI_ERROR (Status);
    198 
    199   return BootMode;
    200 }
    201 
    202 /**
    203   Adds a new HOB to the HOB List.
    204 
    205   This internal function enables PEIMs to create various types of HOBs.
    206 
    207   @param  Type          Type of the new HOB.
    208   @param  Length        Length of the new HOB to allocate.
    209 
    210   @retval  NULL         The HOB could not be allocated.
    211   @retval  others       The address of new HOB.
    212 
    213 **/
    214 STATIC
    215 VOID *
    216 InternalPeiCreateHob (
    217   IN UINT16                      Type,
    218   IN UINT16                      Length
    219   )
    220 {
    221   EFI_STATUS        Status;
    222   VOID              *Hob;
    223 
    224   Status = PeiServicesCreateHob (Type, Length, &Hob);
    225   if (EFI_ERROR (Status)) {
    226     Hob = NULL;
    227   }
    228   //
    229   // Assume the process of HOB building is always successful.
    230   //
    231   ASSERT (Hob != NULL);
    232   return Hob;
    233 }
    234 
    235 /**
    236   Builds a HOB for a loaded PE32 module.
    237 
    238   This function builds a HOB for a loaded PE32 module.
    239   It can only be invoked during PEI phase;
    240   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
    241   If ModuleName is NULL, then ASSERT().
    242   If there is no additional space for HOB creation, then ASSERT().
    243 
    244   @param  ModuleName              The GUID File Name of the module.
    245   @param  MemoryAllocationModule  The 64 bit physical address of the module.
    246   @param  ModuleLength            The length of the module in bytes.
    247   @param  EntryPoint              The 64 bit physical address of the module's entry point.
    248 
    249 **/
    250 VOID
    251 EFIAPI
    252 GlueBuildModuleHob (
    253   IN CONST EFI_GUID         *ModuleName,
    254   IN EFI_PHYSICAL_ADDRESS   MemoryAllocationModule,
    255   IN UINT64                 ModuleLength,
    256   IN EFI_PHYSICAL_ADDRESS   EntryPoint
    257   )
    258 {
    259   EFI_HOB_MEMORY_ALLOCATION_MODULE  *Hob;
    260 
    261   Hob = InternalPeiCreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, (UINT16) sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));
    262   if (Hob == NULL) {
    263     return;
    264   }
    265 
    266   CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid);
    267   Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule;
    268   Hob->MemoryAllocationHeader.MemoryLength      = ModuleLength;
    269   Hob->MemoryAllocationHeader.MemoryType        = EfiBootServicesCode;
    270 
    271   //
    272   // Zero the reserved space to match HOB spec
    273   //
    274   ZeroMem (Hob->MemoryAllocationHeader.Reserved, sizeof (Hob->MemoryAllocationHeader.Reserved));
    275 
    276   CopyGuid (&Hob->ModuleName, ModuleName);
    277   Hob->EntryPoint = EntryPoint;
    278 }
    279 
    280 /**
    281   Builds a HOB that describes a chunk of system memory.
    282 
    283   This function builds a HOB that describes a chunk of system memory.
    284   It can only be invoked during PEI phase;
    285   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
    286   If there is no additional space for HOB creation, then ASSERT().
    287 
    288   @param  ResourceType        The type of resource described by this HOB.
    289   @param  ResourceAttribute   The resource attributes of the memory described by this HOB.
    290   @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.
    291   @param  NumberOfBytes       The length of the memory described by this HOB in bytes.
    292 
    293 **/
    294 VOID
    295 EFIAPI
    296 BuildResourceDescriptorHob (
    297   IN EFI_RESOURCE_TYPE            ResourceType,
    298   IN EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute,
    299   IN EFI_PHYSICAL_ADDRESS         PhysicalStart,
    300   IN UINT64                       NumberOfBytes
    301   )
    302 {
    303   EFI_HOB_RESOURCE_DESCRIPTOR  *Hob;
    304 
    305   Hob = InternalPeiCreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, (UINT16) sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));
    306   if (Hob == NULL) {
    307     return;
    308   }
    309 
    310   Hob->ResourceType      = ResourceType;
    311   Hob->ResourceAttribute = ResourceAttribute;
    312   Hob->PhysicalStart     = PhysicalStart;
    313   Hob->ResourceLength    = NumberOfBytes;
    314 }
    315 
    316 /**
    317   Builds a GUID HOB with a certain data length.
    318 
    319   This function builds a customized HOB tagged with a GUID for identification
    320   and returns the start address of GUID HOB data so that caller can fill the customized data.
    321   The HOB Header and Name field is already stripped.
    322   It can only be invoked during PEI phase;
    323   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
    324   If Guid is NULL, then ASSERT().
    325   If there is no additional space for HOB creation, then ASSERT().
    326   If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
    327 
    328   @param  Guid          The GUID to tag the customized HOB.
    329   @param  DataLength    The size of the data payload for the GUID HOB.
    330 
    331   @retval  NULL         The GUID HOB could not be allocated.
    332   @retval  others       The start address of GUID HOB data.
    333 
    334 **/
    335 VOID *
    336 EFIAPI
    337 BuildGuidHob (
    338   IN CONST EFI_GUID              *Guid,
    339   IN UINTN                       DataLength
    340   )
    341 {
    342   EFI_HOB_GUID_TYPE *Hob;
    343 
    344   //
    345   // Make sure Guid is valid
    346   //
    347   ASSERT (Guid != NULL);
    348 
    349   //
    350   // Make sure that data length is not too long.
    351   //
    352   ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE)));
    353 
    354   Hob = InternalPeiCreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength));
    355   if (Hob == NULL) {
    356     return Hob;
    357   }
    358   CopyGuid (&Hob->Name, Guid);
    359   return Hob + 1;
    360 }
    361 
    362 /**
    363   Copies a data buffer to a newly-built HOB.
    364 
    365   This function builds a customized HOB tagged with a GUID for identification,
    366   copies the input data to the HOB data field and returns the start address of the GUID HOB data.
    367   The HOB Header and Name field is already stripped.
    368   It can only be invoked during PEI phase;
    369   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
    370   If Guid is NULL, then ASSERT().
    371   If Data is NULL and DataLength > 0, then ASSERT().
    372   If there is no additional space for HOB creation, then ASSERT().
    373   If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
    374 
    375   @param  Guid          The GUID to tag the customized HOB.
    376   @param  Data          The data to be copied into the data field of the GUID HOB.
    377   @param  DataLength    The size of the data payload for the GUID HOB.
    378 
    379   @retval  NULL         The GUID HOB could not be allocated.
    380   @retval  others       The start address of GUID HOB data.
    381 
    382 **/
    383 VOID *
    384 EFIAPI
    385 BuildGuidDataHob (
    386   IN CONST EFI_GUID              *Guid,
    387   IN VOID                        *Data,
    388   IN UINTN                       DataLength
    389   )
    390 {
    391   VOID  *HobData;
    392 
    393   ASSERT (Data != NULL || DataLength == 0);
    394 
    395   HobData = BuildGuidHob (Guid, DataLength);
    396   if (HobData == NULL) {
    397     return HobData;
    398   }
    399 
    400   return CopyMem (HobData, Data, DataLength);
    401 }
    402 
    403 /**
    404   Builds a Firmware Volume HOB.
    405 
    406   This function builds a Firmware Volume HOB.
    407   It can only be invoked during PEI phase;
    408   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
    409   If there is no additional space for HOB creation, then ASSERT().
    410 
    411   @param  BaseAddress   The base address of the Firmware Volume.
    412   @param  Length        The size of the Firmware Volume in bytes.
    413 
    414 **/
    415 VOID
    416 EFIAPI
    417 BuildFvHob (
    418   IN EFI_PHYSICAL_ADDRESS        BaseAddress,
    419   IN UINT64                      Length
    420   )
    421 {
    422   EFI_HOB_FIRMWARE_VOLUME  *Hob;
    423 
    424   //
    425   // Check FV Signature
    426   //
    427   ASSERT (((EFI_FIRMWARE_VOLUME_HEADER*)((UINTN)BaseAddress))->Signature == EFI_FVH_SIGNATURE);
    428   Hob = InternalPeiCreateHob (EFI_HOB_TYPE_FV, (UINT16) sizeof (EFI_HOB_FIRMWARE_VOLUME));
    429   if (Hob == NULL) {
    430     return;
    431   }
    432 
    433   Hob->BaseAddress = BaseAddress;
    434   Hob->Length      = Length;
    435 }
    436 
    437 /**
    438   Builds a Capsule Volume HOB.
    439 
    440   This function builds a Capsule Volume HOB.
    441   It can only be invoked during PEI phase;
    442   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
    443   If there is no additional space for HOB creation, then ASSERT().
    444 
    445   @param  BaseAddress   The base address of the Capsule Volume.
    446   @param  Length        The size of the Capsule Volume in bytes.
    447 
    448 **/
    449 VOID
    450 EFIAPI
    451 BuildCvHob (
    452   IN EFI_PHYSICAL_ADDRESS        BaseAddress,
    453   IN UINT64                      Length
    454   )
    455 {
    456   EFI_HOB_CAPSULE_VOLUME  *Hob;
    457 
    458   Hob = InternalPeiCreateHob (EFI_HOB_TYPE_CV, (UINT16) sizeof (EFI_HOB_CAPSULE_VOLUME));
    459   if (Hob == NULL) {
    460     return;
    461   }
    462 
    463   Hob->BaseAddress  = BaseAddress;
    464   Hob->Length       = Length;
    465 }
    466 
    467 /**
    468   Builds a HOB for the CPU.
    469 
    470   This function builds a HOB for the CPU.
    471   It can only be invoked during PEI phase;
    472   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
    473   If there is no additional space for HOB creation, then ASSERT().
    474 
    475   @param  SizeOfMemorySpace   The maximum physical memory addressability of the processor.
    476   @param  SizeOfIoSpace       The maximum physical I/O addressability of the processor.
    477 
    478 **/
    479 VOID
    480 EFIAPI
    481 BuildCpuHob (
    482   IN UINT8                       SizeOfMemorySpace,
    483   IN UINT8                       SizeOfIoSpace
    484   )
    485 {
    486   EFI_HOB_CPU  *Hob;
    487 
    488   Hob = InternalPeiCreateHob (EFI_HOB_TYPE_CPU, (UINT16) sizeof (EFI_HOB_CPU));
    489   if (Hob == NULL) {
    490     return;
    491   }
    492 
    493   Hob->SizeOfMemorySpace = SizeOfMemorySpace;
    494   Hob->SizeOfIoSpace     = SizeOfIoSpace;
    495 
    496   //
    497   // Zero the reserved space to match HOB spec
    498   //
    499   ZeroMem (Hob->Reserved, sizeof (Hob->Reserved));
    500 }
    501 
    502 /**
    503   Builds a HOB for the Stack.
    504 
    505   This function builds a HOB for the stack.
    506   It can only be invoked during PEI phase;
    507   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
    508   If there is no additional space for HOB creation, then ASSERT().
    509 
    510   @param  BaseAddress   The 64 bit physical address of the Stack.
    511   @param  Length        The length of the stack in bytes.
    512 
    513 **/
    514 VOID
    515 EFIAPI
    516 BuildStackHob (
    517   IN EFI_PHYSICAL_ADDRESS        BaseAddress,
    518   IN UINT64                      Length
    519   )
    520 {
    521   EFI_HOB_MEMORY_ALLOCATION_STACK  *Hob;
    522 
    523   Hob = InternalPeiCreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, (UINT16) sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK));
    524   if (Hob == NULL) {
    525     return;
    526   }
    527 
    528   CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocStackGuid);
    529   Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
    530   Hob->AllocDescriptor.MemoryLength      = Length;
    531   Hob->AllocDescriptor.MemoryType        = EfiBootServicesData;
    532 
    533   //
    534   // Zero the reserved space to match HOB spec
    535   //
    536   ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
    537 }
    538 
    539 /**
    540   Builds a HOB for the BSP store.
    541 
    542   This function builds a HOB for BSP store.
    543   It can only be invoked during PEI phase;
    544   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
    545   If there is no additional space for HOB creation, then ASSERT().
    546 
    547   @param  BaseAddress   The 64 bit physical address of the BSP.
    548   @param  Length        The length of the BSP store in bytes.
    549   @param  MemoryType    Type of memory allocated by this HOB.
    550 
    551 **/
    552 VOID
    553 EFIAPI
    554 BuildBspStoreHob (
    555   IN EFI_PHYSICAL_ADDRESS        BaseAddress,
    556   IN UINT64                      Length,
    557   IN EFI_MEMORY_TYPE             MemoryType
    558   )
    559 {
    560   EFI_HOB_MEMORY_ALLOCATION_BSP_STORE  *Hob;
    561 
    562   Hob = InternalPeiCreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, (UINT16) sizeof (EFI_HOB_MEMORY_ALLOCATION_BSP_STORE));
    563   if (Hob == NULL) {
    564     return;
    565   }
    566 
    567   CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocBspStoreGuid);
    568   Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
    569   Hob->AllocDescriptor.MemoryLength      = Length;
    570   Hob->AllocDescriptor.MemoryType        = MemoryType;
    571 
    572   //
    573   // Zero the reserved space to match HOB spec
    574   //
    575   ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
    576 }
    577 
    578 /**
    579   Builds a HOB for the memory allocation.
    580 
    581   This function builds a HOB for the memory allocation.
    582   It can only be invoked during PEI phase;
    583   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
    584   If there is no additional space for HOB creation, then ASSERT().
    585 
    586   @param  BaseAddress   The 64 bit physical address of the memory.
    587   @param  Length        The length of the memory allocation in bytes.
    588   @param  MemoryType    Type of memory allocated by this HOB.
    589 
    590 **/
    591 VOID
    592 EFIAPI
    593 GlueBuildMemoryAllocationHob (
    594   IN EFI_PHYSICAL_ADDRESS        BaseAddress,
    595   IN UINT64                      Length,
    596   IN EFI_MEMORY_TYPE             MemoryType
    597   )
    598 {
    599   EFI_HOB_MEMORY_ALLOCATION  *Hob;
    600 
    601   Hob = InternalPeiCreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, (UINT16) sizeof (EFI_HOB_MEMORY_ALLOCATION));
    602   if (Hob == NULL) {
    603     return;
    604   }
    605 
    606   ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));
    607   Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
    608   Hob->AllocDescriptor.MemoryLength      = Length;
    609   Hob->AllocDescriptor.MemoryType        = MemoryType;
    610   //
    611   // Zero the reserved space to match HOB spec
    612   //
    613   ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
    614 }
    615