Home | History | Annotate | Download | only in PrePiHobLib
      1 /** @file
      2 
      3   Copyright (c) 2010, Apple Inc. All rights reserved.<BR>
      4 
      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/BaseLib.h>
     18 #include <Library/BaseMemoryLib.h>
     19 #include <Library/DebugLib.h>
     20 #include <Library/PeCoffLib.h>
     21 #include <Library/HobLib.h>
     22 #include <Library/PcdLib.h>
     23 #include <Library/PrePiHobListPointerLib.h>
     24 
     25 #include <Protocol/PeCoffLoader.h>
     26 #include <Guid/ExtractSection.h>
     27 #include <Guid/MemoryTypeInformation.h>
     28 #include <Guid/MemoryAllocationHob.h>
     29 
     30 VOID
     31 BuildMemoryTypeInformationHob (
     32   VOID
     33   );
     34 
     35 /**
     36   Returns the pointer to the HOB list.
     37 
     38   This function returns the pointer to first HOB in the list.
     39 
     40   @return The pointer to the HOB list.
     41 
     42 **/
     43 VOID *
     44 EFIAPI
     45 GetHobList (
     46   VOID
     47   )
     48 {
     49   return PrePeiGetHobList ();
     50 }
     51 
     52 
     53 
     54 /**
     55   Updates the pointer to the HOB list.
     56 
     57   @param  HobList       Hob list pointer to store
     58 
     59 **/
     60 EFI_STATUS
     61 EFIAPI
     62 SetHobList (
     63   IN  VOID      *HobList
     64   )
     65 {
     66   return PrePeiSetHobList (HobList);
     67 }
     68 
     69 /**
     70 
     71 
     72 **/
     73 EFI_HOB_HANDOFF_INFO_TABLE*
     74 HobConstructor (
     75   IN VOID   *EfiMemoryBegin,
     76   IN UINTN  EfiMemoryLength,
     77   IN VOID   *EfiFreeMemoryBottom,
     78   IN VOID   *EfiFreeMemoryTop
     79   )
     80 {
     81   EFI_HOB_HANDOFF_INFO_TABLE  *Hob;
     82   EFI_HOB_GENERIC_HEADER      *HobEnd;
     83 
     84   Hob    = EfiFreeMemoryBottom;
     85   HobEnd = (EFI_HOB_GENERIC_HEADER *)(Hob+1);
     86 
     87   Hob->Header.HobType     = EFI_HOB_TYPE_HANDOFF;
     88   Hob->Header.HobLength   = sizeof(EFI_HOB_HANDOFF_INFO_TABLE);
     89   Hob->Header.Reserved    = 0;
     90 
     91   HobEnd->HobType     = EFI_HOB_TYPE_END_OF_HOB_LIST;
     92   HobEnd->HobLength   = sizeof(EFI_HOB_GENERIC_HEADER);
     93   HobEnd->Reserved    = 0;
     94 
     95   Hob->Version             = EFI_HOB_HANDOFF_TABLE_VERSION;
     96   Hob->BootMode            = BOOT_WITH_FULL_CONFIGURATION;
     97 
     98   Hob->EfiMemoryTop        = (UINTN)EfiMemoryBegin + EfiMemoryLength;
     99   Hob->EfiMemoryBottom     = (UINTN)EfiMemoryBegin;
    100   Hob->EfiFreeMemoryTop    = (UINTN)EfiFreeMemoryTop;
    101   Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)(HobEnd+1);
    102   Hob->EfiEndOfHobList     = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;
    103 
    104   return Hob;
    105 }
    106 
    107 VOID *
    108 CreateHob (
    109   IN  UINT16    HobType,
    110   IN  UINT16    HobLength
    111   )
    112 {
    113   EFI_HOB_HANDOFF_INFO_TABLE  *HandOffHob;
    114   EFI_HOB_GENERIC_HEADER      *HobEnd;
    115   EFI_PHYSICAL_ADDRESS        FreeMemory;
    116   VOID                        *Hob;
    117 
    118   HandOffHob = GetHobList ();
    119 
    120   HobLength = (UINT16)((HobLength + 0x7) & (~0x7));
    121 
    122   FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob->EfiFreeMemoryBottom;
    123 
    124   if (FreeMemory < HobLength) {
    125       return NULL;
    126   }
    127 
    128   Hob = (VOID*) (UINTN) HandOffHob->EfiEndOfHobList;
    129   ((EFI_HOB_GENERIC_HEADER*) Hob)->HobType = HobType;
    130   ((EFI_HOB_GENERIC_HEADER*) Hob)->HobLength = HobLength;
    131   ((EFI_HOB_GENERIC_HEADER*) Hob)->Reserved = 0;
    132 
    133   HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN)Hob + HobLength);
    134   HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
    135 
    136   HobEnd->HobType   = EFI_HOB_TYPE_END_OF_HOB_LIST;
    137   HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
    138   HobEnd->Reserved  = 0;
    139   HobEnd++;
    140   HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
    141 
    142   return Hob;
    143 }
    144 
    145 /**
    146   Builds a HOB that describes a chunk of system memory.
    147 
    148   This function builds a HOB that describes a chunk of system memory.
    149   If there is no additional space for HOB creation, then ASSERT().
    150 
    151   @param  ResourceType        The type of resource described by this HOB.
    152   @param  ResourceAttribute   The resource attributes of the memory described by this HOB.
    153   @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.
    154   @param  NumberOfBytes       The length of the memory described by this HOB in bytes.
    155 
    156 **/
    157 VOID
    158 EFIAPI
    159 BuildResourceDescriptorHob (
    160   IN EFI_RESOURCE_TYPE            ResourceType,
    161   IN EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute,
    162   IN EFI_PHYSICAL_ADDRESS         PhysicalStart,
    163   IN UINT64                       NumberOfBytes
    164   )
    165 {
    166   EFI_HOB_RESOURCE_DESCRIPTOR  *Hob;
    167 
    168   Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));
    169   ASSERT(Hob != NULL);
    170 
    171   Hob->ResourceType      = ResourceType;
    172   Hob->ResourceAttribute = ResourceAttribute;
    173   Hob->PhysicalStart     = PhysicalStart;
    174   Hob->ResourceLength    = NumberOfBytes;
    175 }
    176 
    177 /**
    178 
    179 
    180 **/
    181 VOID
    182 CreateHobList (
    183   IN VOID   *MemoryBegin,
    184   IN UINTN  MemoryLength,
    185   IN VOID   *HobBase,
    186   IN VOID   *StackBase
    187   )
    188 {
    189   EFI_HOB_HANDOFF_INFO_TABLE  *Hob;
    190   EFI_RESOURCE_ATTRIBUTE_TYPE Attributes;
    191 
    192   Hob = HobConstructor (MemoryBegin,MemoryLength,HobBase,StackBase);
    193   SetHobList (Hob);
    194 
    195   BuildCpuHob (PcdGet8 (PcdPrePiCpuMemorySize), PcdGet8 (PcdPrePiCpuIoSize));
    196 
    197   Attributes =(
    198     EFI_RESOURCE_ATTRIBUTE_PRESENT |
    199     EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
    200     EFI_RESOURCE_ATTRIBUTE_TESTED |
    201     EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
    202     EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
    203     EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
    204     EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
    205   );
    206 
    207   BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY, Attributes, (UINTN)MemoryBegin, MemoryLength);
    208 
    209   BuildStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN)StackBase, ((UINTN)MemoryBegin + MemoryLength) - (UINTN)StackBase);
    210 
    211   if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) {
    212     // Optional feature that helps prevent EFI memory map fragmentation.
    213     BuildMemoryTypeInformationHob ();
    214   }
    215 }
    216 
    217 
    218 VOID
    219 EFIAPI
    220 BuildFvHobs (
    221   IN EFI_PHYSICAL_ADDRESS         PhysicalStart,
    222   IN UINT64                       NumberOfBytes,
    223   IN EFI_RESOURCE_ATTRIBUTE_TYPE  *ResourceAttribute
    224   )
    225 {
    226 
    227   EFI_RESOURCE_ATTRIBUTE_TYPE Resource;
    228 
    229   BuildFvHob (PhysicalStart, NumberOfBytes);
    230 
    231   if (ResourceAttribute == NULL) {
    232     Resource = (EFI_RESOURCE_ATTRIBUTE_PRESENT    |
    233                 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
    234                 EFI_RESOURCE_ATTRIBUTE_TESTED |
    235                 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE);
    236   } else {
    237     Resource = *ResourceAttribute;
    238   }
    239 
    240   BuildResourceDescriptorHob (EFI_RESOURCE_FIRMWARE_DEVICE, Resource, PhysicalStart, NumberOfBytes);
    241 }
    242 
    243 /**
    244   Returns the next instance of a HOB type from the starting HOB.
    245 
    246   This function searches the first instance of a HOB type from the starting HOB pointer.
    247   If there does not exist such HOB type from the starting HOB pointer, it will return NULL.
    248   In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
    249   unconditionally: it returns HobStart back if HobStart itself meets the requirement;
    250   caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
    251   If HobStart is NULL, then ASSERT().
    252 
    253   @param  Type          The HOB type to return.
    254   @param  HobStart      The starting HOB pointer to search from.
    255 
    256   @return The next instance of a HOB type from the starting HOB.
    257 
    258 **/
    259 VOID *
    260 EFIAPI
    261 GetNextHob (
    262   IN UINT16                 Type,
    263   IN CONST VOID             *HobStart
    264   )
    265 {
    266   EFI_PEI_HOB_POINTERS  Hob;
    267 
    268   ASSERT (HobStart != NULL);
    269 
    270   Hob.Raw = (UINT8 *) HobStart;
    271   //
    272   // Parse the HOB list until end of list or matching type is found.
    273   //
    274   while (!END_OF_HOB_LIST (Hob)) {
    275     if (Hob.Header->HobType == Type) {
    276       return Hob.Raw;
    277     }
    278     Hob.Raw = GET_NEXT_HOB (Hob);
    279   }
    280   return NULL;
    281 }
    282 
    283 
    284 
    285 /**
    286   Returns the first instance of a HOB type among the whole HOB list.
    287 
    288   This function searches the first instance of a HOB type among the whole HOB list.
    289   If there does not exist such HOB type in the HOB list, it will return NULL.
    290 
    291   @param  Type          The HOB type to return.
    292 
    293   @return The next instance of a HOB type from the starting HOB.
    294 
    295 **/
    296 VOID *
    297 EFIAPI
    298 GetFirstHob (
    299   IN UINT16                 Type
    300   )
    301 {
    302   VOID      *HobList;
    303 
    304   HobList = GetHobList ();
    305   return GetNextHob (Type, HobList);
    306 }
    307 
    308 
    309 /**
    310   This function searches the first instance of a HOB from the starting HOB pointer.
    311   Such HOB should satisfy two conditions:
    312   its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
    313   If there does not exist such HOB from the starting HOB pointer, it will return NULL.
    314   Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
    315   to extract the data section and its size info respectively.
    316   In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
    317   unconditionally: it returns HobStart back if HobStart itself meets the requirement;
    318   caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
    319   If Guid is NULL, then ASSERT().
    320   If HobStart is NULL, then ASSERT().
    321 
    322   @param  Guid          The GUID to match with in the HOB list.
    323   @param  HobStart      A pointer to a Guid.
    324 
    325   @return The next instance of the matched GUID HOB from the starting HOB.
    326 
    327 **/
    328 VOID *
    329 EFIAPI
    330 GetNextGuidHob (
    331   IN CONST EFI_GUID         *Guid,
    332   IN CONST VOID             *HobStart
    333   ){
    334   EFI_PEI_HOB_POINTERS  GuidHob;
    335 
    336   GuidHob.Raw = (UINT8 *) HobStart;
    337   while ((GuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GuidHob.Raw)) != NULL) {
    338     if (CompareGuid (Guid, &GuidHob.Guid->Name)) {
    339       break;
    340     }
    341     GuidHob.Raw = GET_NEXT_HOB (GuidHob);
    342   }
    343   return GuidHob.Raw;
    344 }
    345 
    346 
    347 /**
    348   This function searches the first instance of a HOB among the whole HOB list.
    349   Such HOB should satisfy two conditions:
    350   its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
    351   If there does not exist such HOB from the starting HOB pointer, it will return NULL.
    352   Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
    353   to extract the data section and its size info respectively.
    354   If Guid is NULL, then ASSERT().
    355 
    356   @param  Guid          The GUID to match with in the HOB list.
    357 
    358   @return The first instance of the matched GUID HOB among the whole HOB list.
    359 
    360 **/
    361 VOID *
    362 EFIAPI
    363 GetFirstGuidHob (
    364   IN CONST EFI_GUID         *Guid
    365   )
    366 {
    367   VOID      *HobList;
    368 
    369   HobList = GetHobList ();
    370   return GetNextGuidHob (Guid, HobList);
    371 }
    372 
    373 
    374 /**
    375   Get the Boot Mode from the HOB list.
    376 
    377   This function returns the system boot mode information from the
    378   PHIT HOB in HOB list.
    379 
    380   @param  VOID
    381 
    382   @return The Boot Mode.
    383 
    384 **/
    385 EFI_BOOT_MODE
    386 EFIAPI
    387 GetBootMode (
    388   VOID
    389   )
    390 {
    391   EFI_PEI_HOB_POINTERS  Hob;
    392 
    393   Hob.Raw = GetHobList ();
    394   return Hob.HandoffInformationTable->BootMode;
    395 }
    396 
    397 
    398 /**
    399   Get the Boot Mode from the HOB list.
    400 
    401   This function returns the system boot mode information from the
    402   PHIT HOB in HOB list.
    403 
    404   @param  VOID
    405 
    406   @return The Boot Mode.
    407 
    408 **/
    409 EFI_STATUS
    410 EFIAPI
    411 SetBootMode (
    412   IN  EFI_BOOT_MODE   BootMode
    413   )
    414 {
    415   EFI_PEI_HOB_POINTERS  Hob;
    416 
    417   Hob.Raw = GetHobList ();
    418   Hob.HandoffInformationTable->BootMode = BootMode;
    419   return BootMode;
    420 }
    421 
    422 /**
    423   Builds a HOB for a loaded PE32 module.
    424 
    425   This function builds a HOB for a loaded PE32 module.
    426   It can only be invoked during PEI phase;
    427   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
    428   If ModuleName is NULL, then ASSERT().
    429   If there is no additional space for HOB creation, then ASSERT().
    430 
    431   @param  ModuleName              The GUID File Name of the module.
    432   @param  MemoryAllocationModule  The 64 bit physical address of the module.
    433   @param  ModuleLength            The length of the module in bytes.
    434   @param  EntryPoint              The 64 bit physical address of the module entry point.
    435 
    436 **/
    437 VOID
    438 EFIAPI
    439 BuildModuleHob (
    440   IN CONST EFI_GUID         *ModuleName,
    441   IN EFI_PHYSICAL_ADDRESS   MemoryAllocationModule,
    442   IN UINT64                 ModuleLength,
    443   IN EFI_PHYSICAL_ADDRESS   EntryPoint
    444   )
    445 {
    446   EFI_HOB_MEMORY_ALLOCATION_MODULE  *Hob;
    447 
    448   ASSERT (((MemoryAllocationModule & (EFI_PAGE_SIZE - 1)) == 0) &&
    449           ((ModuleLength & (EFI_PAGE_SIZE - 1)) == 0));
    450 
    451   Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));
    452 
    453   CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid);
    454   Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule;
    455   Hob->MemoryAllocationHeader.MemoryLength      = ModuleLength;
    456   Hob->MemoryAllocationHeader.MemoryType        = EfiBootServicesCode;
    457 
    458   //
    459   // Zero the reserved space to match HOB spec
    460   //
    461   ZeroMem (Hob->MemoryAllocationHeader.Reserved, sizeof (Hob->MemoryAllocationHeader.Reserved));
    462 
    463   CopyGuid (&Hob->ModuleName, ModuleName);
    464   Hob->EntryPoint = EntryPoint;
    465 }
    466 
    467 /**
    468   Builds a GUID HOB with a certain data length.
    469 
    470   This function builds a customized HOB tagged with a GUID for identification
    471   and returns the start address of GUID HOB data so that caller can fill the customized data.
    472   The HOB Header and Name field is already stripped.
    473   It can only be invoked during PEI phase;
    474   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
    475   If Guid is NULL, then ASSERT().
    476   If there is no additional space for HOB creation, then ASSERT().
    477   If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
    478 
    479   @param  Guid          The GUID to tag the customized HOB.
    480   @param  DataLength    The size of the data payload for the GUID HOB.
    481 
    482   @return The start address of GUID HOB data.
    483 
    484 **/
    485 VOID *
    486 EFIAPI
    487 BuildGuidHob (
    488   IN CONST EFI_GUID              *Guid,
    489   IN UINTN                       DataLength
    490   )
    491 {
    492   EFI_HOB_GUID_TYPE *Hob;
    493 
    494   //
    495   // Make sure that data length is not too long.
    496   //
    497   ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE)));
    498 
    499   Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength));
    500   CopyGuid (&Hob->Name, Guid);
    501   return Hob + 1;
    502 }
    503 
    504 
    505 /**
    506   Copies a data buffer to a newly-built HOB.
    507 
    508   This function builds a customized HOB tagged with a GUID for identification,
    509   copies the input data to the HOB data field and returns the start address of the GUID HOB data.
    510   The HOB Header and Name field is already stripped.
    511   It can only be invoked during PEI phase;
    512   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
    513   If Guid is NULL, then ASSERT().
    514   If Data is NULL and DataLength > 0, then ASSERT().
    515   If there is no additional space for HOB creation, then ASSERT().
    516   If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
    517 
    518   @param  Guid          The GUID to tag the customized HOB.
    519   @param  Data          The data to be copied into the data field of the GUID HOB.
    520   @param  DataLength    The size of the data payload for the GUID HOB.
    521 
    522   @return The start address of GUID HOB data.
    523 
    524 **/
    525 VOID *
    526 EFIAPI
    527 BuildGuidDataHob (
    528   IN CONST EFI_GUID              *Guid,
    529   IN VOID                        *Data,
    530   IN UINTN                       DataLength
    531   )
    532 {
    533   VOID  *HobData;
    534 
    535   ASSERT (Data != NULL || DataLength == 0);
    536 
    537   HobData = BuildGuidHob (Guid, DataLength);
    538 
    539   return CopyMem (HobData, Data, DataLength);
    540 }
    541 
    542 
    543 /**
    544   Builds a Firmware Volume HOB.
    545 
    546   This function builds a Firmware Volume HOB.
    547   It can only be invoked during PEI phase;
    548   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
    549   If there is no additional space for HOB creation, then ASSERT().
    550 
    551   @param  BaseAddress   The base address of the Firmware Volume.
    552   @param  Length        The size of the Firmware Volume in bytes.
    553 
    554 **/
    555 VOID
    556 EFIAPI
    557 BuildFvHob (
    558   IN EFI_PHYSICAL_ADDRESS        BaseAddress,
    559   IN UINT64                      Length
    560   )
    561 {
    562   EFI_HOB_FIRMWARE_VOLUME  *Hob;
    563 
    564   Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME));
    565 
    566   Hob->BaseAddress = BaseAddress;
    567   Hob->Length      = Length;
    568 }
    569 
    570 
    571 /**
    572   Builds a EFI_HOB_TYPE_FV2 HOB.
    573 
    574   This function builds a EFI_HOB_TYPE_FV2 HOB.
    575   It can only be invoked during PEI phase;
    576   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
    577   If there is no additional space for HOB creation, then ASSERT().
    578 
    579   @param  BaseAddress   The base address of the Firmware Volume.
    580   @param  Length        The size of the Firmware Volume in bytes.
    581   @param  FvName       The name of the Firmware Volume.
    582   @param  FileName      The name of the file.
    583 
    584 **/
    585 VOID
    586 EFIAPI
    587 BuildFv2Hob (
    588   IN          EFI_PHYSICAL_ADDRESS        BaseAddress,
    589   IN          UINT64                      Length,
    590   IN CONST    EFI_GUID                    *FvName,
    591   IN CONST    EFI_GUID                    *FileName
    592   )
    593 {
    594   EFI_HOB_FIRMWARE_VOLUME2  *Hob;
    595 
    596   Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2));
    597 
    598   Hob->BaseAddress = BaseAddress;
    599   Hob->Length      = Length;
    600   CopyGuid (&Hob->FvName, FvName);
    601   CopyGuid (&Hob->FileName, FileName);
    602 }
    603 
    604 
    605 
    606 /**
    607   Builds a Capsule Volume HOB.
    608 
    609   This function builds a Capsule Volume HOB.
    610   It can only be invoked during PEI phase;
    611   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
    612   If there is no additional space for HOB creation, then ASSERT().
    613 
    614   @param  BaseAddress   The base address of the Capsule Volume.
    615   @param  Length        The size of the Capsule Volume in bytes.
    616 
    617 **/
    618 VOID
    619 EFIAPI
    620 BuildCvHob (
    621   IN EFI_PHYSICAL_ADDRESS        BaseAddress,
    622   IN UINT64                      Length
    623   )
    624 {
    625   ASSERT (FALSE);
    626 }
    627 
    628 
    629 /**
    630   Builds a HOB for the CPU.
    631 
    632   This function builds a HOB for the CPU.
    633   It can only be invoked during PEI phase;
    634   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
    635   If there is no additional space for HOB creation, then ASSERT().
    636 
    637   @param  SizeOfMemorySpace   The maximum physical memory addressability of the processor.
    638   @param  SizeOfIoSpace       The maximum physical I/O addressability of the processor.
    639 
    640 **/
    641 VOID
    642 EFIAPI
    643 BuildCpuHob (
    644   IN UINT8                       SizeOfMemorySpace,
    645   IN UINT8                       SizeOfIoSpace
    646   )
    647 {
    648   EFI_HOB_CPU  *Hob;
    649 
    650   Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU));
    651 
    652   Hob->SizeOfMemorySpace = SizeOfMemorySpace;
    653   Hob->SizeOfIoSpace     = SizeOfIoSpace;
    654 
    655   //
    656   // Zero the reserved space to match HOB spec
    657   //
    658   ZeroMem (Hob->Reserved, sizeof (Hob->Reserved));
    659 }
    660 
    661 
    662 /**
    663   Builds a HOB for the Stack.
    664 
    665   This function builds a HOB for the stack.
    666   It can only be invoked during PEI phase;
    667   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
    668   If there is no additional space for HOB creation, then ASSERT().
    669 
    670   @param  BaseAddress   The 64 bit physical address of the Stack.
    671   @param  Length        The length of the stack in bytes.
    672 
    673 **/
    674 VOID
    675 EFIAPI
    676 BuildStackHob (
    677   IN EFI_PHYSICAL_ADDRESS        BaseAddress,
    678   IN UINT64                      Length
    679   )
    680 {
    681   EFI_HOB_MEMORY_ALLOCATION_STACK  *Hob;
    682 
    683   ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
    684           ((Length & (EFI_PAGE_SIZE - 1)) == 0));
    685 
    686   Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK));
    687 
    688   CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocStackGuid);
    689   Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
    690   Hob->AllocDescriptor.MemoryLength      = Length;
    691   Hob->AllocDescriptor.MemoryType        = EfiBootServicesData;
    692 
    693   //
    694   // Zero the reserved space to match HOB spec
    695   //
    696   ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
    697 }
    698 
    699 
    700 /**
    701   Update the Stack Hob if the stack has been moved
    702 
    703   @param  BaseAddress   The 64 bit physical address of the Stack.
    704   @param  Length        The length of the stack in bytes.
    705 
    706 **/
    707 VOID
    708 UpdateStackHob (
    709   IN EFI_PHYSICAL_ADDRESS        BaseAddress,
    710   IN UINT64                      Length
    711   )
    712 {
    713   EFI_PEI_HOB_POINTERS           Hob;
    714 
    715   Hob.Raw = GetHobList ();
    716   while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {
    717     if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) {
    718       //
    719       // Build a new memory allocation HOB with old stack info with EfiConventionalMemory type
    720       // to be reclaimed by DXE core.
    721       //
    722       BuildMemoryAllocationHob (
    723         Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress,
    724         Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength,
    725         EfiConventionalMemory
    726         );
    727       //
    728       // Update the BSP Stack Hob to reflect the new stack info.
    729       //
    730       Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress = BaseAddress;
    731       Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength = Length;
    732       break;
    733     }
    734     Hob.Raw = GET_NEXT_HOB (Hob);
    735   }
    736 }
    737 
    738 
    739 
    740 /**
    741   Builds a HOB for the memory allocation.
    742 
    743   This function builds a HOB for the memory allocation.
    744   It can only be invoked during PEI phase;
    745   for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
    746   If there is no additional space for HOB creation, then ASSERT().
    747 
    748   @param  BaseAddress   The 64 bit physical address of the memory.
    749   @param  Length        The length of the memory allocation in bytes.
    750   @param  MemoryType    Type of memory allocated by this HOB.
    751 
    752 **/
    753 VOID
    754 EFIAPI
    755 BuildMemoryAllocationHob (
    756   IN EFI_PHYSICAL_ADDRESS        BaseAddress,
    757   IN UINT64                      Length,
    758   IN EFI_MEMORY_TYPE             MemoryType
    759   )
    760 {
    761   EFI_HOB_MEMORY_ALLOCATION  *Hob;
    762 
    763   ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
    764           ((Length & (EFI_PAGE_SIZE - 1)) == 0));
    765 
    766   Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION));
    767 
    768   ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));
    769   Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
    770   Hob->AllocDescriptor.MemoryLength      = Length;
    771   Hob->AllocDescriptor.MemoryType        = MemoryType;
    772   //
    773   // Zero the reserved space to match HOB spec
    774   //
    775   ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
    776 }
    777 
    778 
    779 
    780 VOID
    781 EFIAPI
    782 BuildExtractSectionHob (
    783   IN  EFI_GUID                                  *Guid,
    784   IN  EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER   SectionGetInfo,
    785   IN  EXTRACT_GUIDED_SECTION_DECODE_HANDLER     SectionExtraction
    786   )
    787 {
    788   EXTRACT_SECTION_DATA Data;
    789 
    790   Data.SectionGetInfo    = SectionGetInfo;
    791   Data.SectionExtraction = SectionExtraction;
    792   BuildGuidDataHob (Guid, &Data, sizeof (Data));
    793 }
    794 
    795 PE_COFF_LOADER_PROTOCOL gPeCoffProtocol = {
    796   PeCoffLoaderGetImageInfo,
    797   PeCoffLoaderLoadImage,
    798   PeCoffLoaderRelocateImage,
    799   PeCoffLoaderImageReadFromMemory,
    800   PeCoffLoaderRelocateImageForRuntime,
    801   PeCoffLoaderUnloadImage
    802 };
    803 
    804 
    805 
    806 VOID
    807 EFIAPI
    808 BuildPeCoffLoaderHob (
    809   VOID
    810   )
    811 {
    812   VOID  *Ptr;
    813 
    814   Ptr = &gPeCoffProtocol;
    815   BuildGuidDataHob (&gPeCoffLoaderProtocolGuid, &Ptr, sizeof (VOID *));
    816 }
    817 
    818 // May want to put this into a library so you only need the PCD setings if you are using the feature?
    819 VOID
    820 BuildMemoryTypeInformationHob (
    821   VOID
    822   )
    823 {
    824   EFI_MEMORY_TYPE_INFORMATION   Info[10];
    825 
    826   Info[0].Type          = EfiACPIReclaimMemory;
    827   Info[0].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory);
    828   Info[1].Type          = EfiACPIMemoryNVS;
    829   Info[1].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS);
    830   Info[2].Type          = EfiReservedMemoryType;
    831   Info[2].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiReservedMemoryType);
    832   Info[3].Type          = EfiRuntimeServicesData;
    833   Info[3].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesData);
    834   Info[4].Type          = EfiRuntimeServicesCode;
    835   Info[4].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode);
    836   Info[5].Type          = EfiBootServicesCode;
    837   Info[5].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesCode);
    838   Info[6].Type          = EfiBootServicesData;
    839   Info[6].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesData);
    840   Info[7].Type          = EfiLoaderCode;
    841   Info[7].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderCode);
    842   Info[8].Type          = EfiLoaderData;
    843   Info[8].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderData);
    844 
    845   // Terminator for the list
    846   Info[9].Type          = EfiMaxMemoryType;
    847   Info[9].NumberOfPages = 0;
    848 
    849 
    850   BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, &Info, sizeof (Info));
    851 }
    852 
    853