]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmbeddedPkg/Library/PrePiHobLib/Hob.c
ARM Packages: Fixed line endings
[mirror_edk2.git] / EmbeddedPkg / Library / PrePiHobLib / Hob.c
index a92a1de52e986460da30e8b1c08b98b47b1247eb..320dddfc256aa876cfa251e4db2cc430af9959fb 100644 (file)
-/** @file
-
-  Copyright (c) 2010, Apple Inc. All rights reserved.<BR>
-  
-  This program and the accompanying materials
-  are licensed and made available under the terms and conditions of the BSD License
-  which accompanies this distribution.  The full text of the license may be found at
-  http://opensource.org/licenses/bsd-license.php
-
-  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#include <PiPei.h>
-
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/PeCoffLib.h>
-#include <Library/HobLib.h>
-#include <Library/PcdLib.h>
-#include <Library/PrePiHobListPointerLib.h>
-
-#include <Protocol/PeCoffLoader.h>
-#include <Guid/ExtractSection.h>
-#include <Guid/MemoryTypeInformation.h>
-#include <Guid/MemoryAllocationHob.h>
-
-VOID
-BuildMemoryTypeInformationHob (
-  VOID
-  );
-
-/**
-  Returns the pointer to the HOB list.
-
-  This function returns the pointer to first HOB in the list.
-
-  @return The pointer to the HOB list.
-
-**/
-VOID *
-EFIAPI
-GetHobList (
-  VOID
-  )
-{
-  return PrePeiGetHobList ();
-}
-
-
-
-/**
-  Updates the pointer to the HOB list.
-
-  @param  HobList       Hob list pointer to store
-
-**/
-EFI_STATUS
-EFIAPI
-SetHobList (
-  IN  VOID      *HobList
-  )
-{
-  return PrePeiSetHobList (HobList);
-}
-
-/**
-
-
-**/
-EFI_HOB_HANDOFF_INFO_TABLE*
-HobConstructor (
-  IN VOID   *EfiMemoryBegin,
-  IN UINTN  EfiMemoryLength,
-  IN VOID   *EfiFreeMemoryBottom,
-  IN VOID   *EfiFreeMemoryTop
-  )
-{
-  EFI_HOB_HANDOFF_INFO_TABLE  *Hob;
-  EFI_HOB_GENERIC_HEADER      *HobEnd;
-
-  Hob    = EfiFreeMemoryBottom;
-  HobEnd = (EFI_HOB_GENERIC_HEADER *)(Hob+1);
-
-  Hob->Header.HobType     = EFI_HOB_TYPE_HANDOFF;
-  Hob->Header.HobLength   = sizeof(EFI_HOB_HANDOFF_INFO_TABLE);
-  Hob->Header.Reserved    = 0;
-
-  HobEnd->HobType     = EFI_HOB_TYPE_END_OF_HOB_LIST;
-  HobEnd->HobLength   = sizeof(EFI_HOB_GENERIC_HEADER);
-  HobEnd->Reserved    = 0;
-
-  Hob->Version             = EFI_HOB_HANDOFF_TABLE_VERSION;
-  Hob->BootMode            = BOOT_WITH_FULL_CONFIGURATION;
-
-  Hob->EfiMemoryTop        = (UINTN)EfiMemoryBegin + EfiMemoryLength;
-  Hob->EfiMemoryBottom     = (UINTN)EfiMemoryBegin;
-  Hob->EfiFreeMemoryTop    = (UINTN)EfiFreeMemoryTop;
-  Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)(HobEnd+1);
-  Hob->EfiEndOfHobList     = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;
-
-  return Hob;
-}
-
-VOID *
-CreateHob (
-  IN  UINT16    HobType,
-  IN  UINT16    HobLength
-  )
-{
-  EFI_HOB_HANDOFF_INFO_TABLE  *HandOffHob;
-  EFI_HOB_GENERIC_HEADER      *HobEnd;
-  EFI_PHYSICAL_ADDRESS        FreeMemory;
-  VOID                        *Hob;
-
-  HandOffHob = GetHobList ();
-
-  HobLength = (UINT16)((HobLength + 0x7) & (~0x7));
-
-  FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob->EfiFreeMemoryBottom;
-
-  if (FreeMemory < HobLength) {
-      return NULL;
-  }
-
-  Hob = (VOID*) (UINTN) HandOffHob->EfiEndOfHobList;
-  ((EFI_HOB_GENERIC_HEADER*) Hob)->HobType = HobType;
-  ((EFI_HOB_GENERIC_HEADER*) Hob)->HobLength = HobLength;
-  ((EFI_HOB_GENERIC_HEADER*) Hob)->Reserved = 0;
-
-  HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN)Hob + HobLength);
-  HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
-
-  HobEnd->HobType   = EFI_HOB_TYPE_END_OF_HOB_LIST;
-  HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
-  HobEnd->Reserved  = 0;
-  HobEnd++;
-  HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
-
-  return Hob;
-}
-
-/**
-  Builds a HOB that describes a chunk of system memory.
-
-  This function builds a HOB that describes a chunk of system memory.
-  If there is no additional space for HOB creation, then ASSERT().
-
-  @param  ResourceType        The type of resource described by this HOB.
-  @param  ResourceAttribute   The resource attributes of the memory described by this HOB.
-  @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.
-  @param  NumberOfBytes       The length of the memory described by this HOB in bytes.
-
-**/
-VOID
-EFIAPI
-BuildResourceDescriptorHob (
-  IN EFI_RESOURCE_TYPE            ResourceType,
-  IN EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute,
-  IN EFI_PHYSICAL_ADDRESS         PhysicalStart,
-  IN UINT64                       NumberOfBytes
-  )
-{
-  EFI_HOB_RESOURCE_DESCRIPTOR  *Hob;
-
-  Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));
-  ASSERT(Hob != NULL);
-
-  Hob->ResourceType      = ResourceType;
-  Hob->ResourceAttribute = ResourceAttribute;
-  Hob->PhysicalStart     = PhysicalStart;
-  Hob->ResourceLength    = NumberOfBytes;
-}
-
-/**
-
-
-**/
-VOID
-CreateHobList (
-  IN VOID   *MemoryBegin,
-  IN UINTN  MemoryLength,
-  IN VOID   *HobBase,
-  IN VOID   *StackBase
-  )
-{
-  EFI_HOB_HANDOFF_INFO_TABLE  *Hob;
-  EFI_RESOURCE_ATTRIBUTE_TYPE Attributes;
-
-  Hob = HobConstructor (MemoryBegin,MemoryLength,HobBase,StackBase);
-  SetHobList (Hob);
-
-  BuildCpuHob (PcdGet8 (PcdPrePiCpuMemorySize), PcdGet8 (PcdPrePiCpuIoSize));
-  
-  Attributes =(
-    EFI_RESOURCE_ATTRIBUTE_PRESENT |
-    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
-    EFI_RESOURCE_ATTRIBUTE_TESTED |
-    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
-    EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
-    EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
-    EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
-  );
-
-  BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY, Attributes, (UINTN)MemoryBegin, MemoryLength);
-
-  BuildStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN)StackBase, ((UINTN)MemoryBegin + MemoryLength) - (UINTN)StackBase);
-
-  if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) {
-    // Optional feature that helps prevent EFI memory map fragmentation. 
-    BuildMemoryTypeInformationHob ();
-  }
-}  
-  
-
-VOID
-EFIAPI
-BuildFvHobs (  
-  IN EFI_PHYSICAL_ADDRESS         PhysicalStart,
-  IN UINT64                       NumberOfBytes,
-  IN EFI_RESOURCE_ATTRIBUTE_TYPE  *ResourceAttribute
-  ) 
-{
-
-  EFI_RESOURCE_ATTRIBUTE_TYPE Resource;
-  
-  BuildFvHob (PhysicalStart, NumberOfBytes);
-  
-  if (ResourceAttribute == NULL) {
-    Resource = (EFI_RESOURCE_ATTRIBUTE_PRESENT    |
-                EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
-                EFI_RESOURCE_ATTRIBUTE_TESTED |
-                EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE);
-  } else {
-    Resource = *ResourceAttribute;
-  }
-  
-  BuildResourceDescriptorHob (EFI_RESOURCE_FIRMWARE_DEVICE, Resource, PhysicalStart, NumberOfBytes);
-}
-
-/**
-  Returns the next instance of a HOB type from the starting HOB.
-
-  This function searches the first instance of a HOB type from the starting HOB pointer. 
-  If there does not exist such HOB type from the starting HOB pointer, it will return NULL.
-  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
-  unconditionally: it returns HobStart back if HobStart itself meets the requirement;
-  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
-  If HobStart is NULL, then ASSERT().
-
-  @param  Type          The HOB type to return.
-  @param  HobStart      The starting HOB pointer to search from.
-
-  @return The next instance of a HOB type from the starting HOB.
-
-**/
-VOID *
-EFIAPI
-GetNextHob (
-  IN UINT16                 Type,
-  IN CONST VOID             *HobStart
-  )
-{
-  EFI_PEI_HOB_POINTERS  Hob;
-
-  ASSERT (HobStart != NULL);
-   
-  Hob.Raw = (UINT8 *) HobStart;
-  //
-  // Parse the HOB list until end of list or matching type is found.
-  //
-  while (!END_OF_HOB_LIST (Hob)) {
-    if (Hob.Header->HobType == Type) {
-      return Hob.Raw;
-    }
-    Hob.Raw = GET_NEXT_HOB (Hob);
-  }
-  return NULL;
-}
-  
-  
-
-/**
-  Returns the first instance of a HOB type among the whole HOB list.
-
-  This function searches the first instance of a HOB type among the whole HOB list. 
-  If there does not exist such HOB type in the HOB list, it will return NULL. 
-
-  @param  Type          The HOB type to return.
-
-  @return The next instance of a HOB type from the starting HOB.
-
-**/
-VOID *
-EFIAPI
-GetFirstHob (
-  IN UINT16                 Type
-  )
-{
-  VOID      *HobList;
-
-  HobList = GetHobList ();
-  return GetNextHob (Type, HobList);
-}
-
-
-/**
-  This function searches the first instance of a HOB from the starting HOB pointer. 
-  Such HOB should satisfy two conditions: 
-  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid. 
-  If there does not exist such HOB from the starting HOB pointer, it will return NULL. 
-  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
-  to extract the data section and its size info respectively.
-  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer
-  unconditionally: it returns HobStart back if HobStart itself meets the requirement;
-  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.
-  If Guid is NULL, then ASSERT().
-  If HobStart is NULL, then ASSERT().
-
-  @param  Guid          The GUID to match with in the HOB list.
-  @param  HobStart      A pointer to a Guid.
-
-  @return The next instance of the matched GUID HOB from the starting HOB.
-
-**/
-VOID *
-EFIAPI
-GetNextGuidHob (
-  IN CONST EFI_GUID         *Guid,
-  IN CONST VOID             *HobStart
-  ){
-  EFI_PEI_HOB_POINTERS  GuidHob;
-
-  GuidHob.Raw = (UINT8 *) HobStart;
-  while ((GuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GuidHob.Raw)) != NULL) {
-    if (CompareGuid (Guid, &GuidHob.Guid->Name)) {
-      break;
-    }
-    GuidHob.Raw = GET_NEXT_HOB (GuidHob);
-  }
-  return GuidHob.Raw;
-}
-
-
-/**
-  This function searches the first instance of a HOB among the whole HOB list. 
-  Such HOB should satisfy two conditions:
-  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.
-  If there does not exist such HOB from the starting HOB pointer, it will return NULL.
-  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()
-  to extract the data section and its size info respectively.
-  If Guid is NULL, then ASSERT().
-
-  @param  Guid          The GUID to match with in the HOB list.
-
-  @return The first instance of the matched GUID HOB among the whole HOB list.
-
-**/
-VOID *
-EFIAPI
-GetFirstGuidHob (
-  IN CONST EFI_GUID         *Guid
-  )
-{
-  VOID      *HobList;
-
-  HobList = GetHobList ();
-  return GetNextGuidHob (Guid, HobList);
-}
-
-
-/**
-  Get the Boot Mode from the HOB list.
-
-  This function returns the system boot mode information from the 
-  PHIT HOB in HOB list.
-
-  @param  VOID
-
-  @return The Boot Mode.
-
-**/
-EFI_BOOT_MODE
-EFIAPI
-GetBootMode (
-  VOID
-  )
-{
-  EFI_PEI_HOB_POINTERS  Hob;
-
-  Hob.Raw = GetHobList ();
-  return Hob.HandoffInformationTable->BootMode;
-}
-
-
-/**
-  Get the Boot Mode from the HOB list.
-
-  This function returns the system boot mode information from the 
-  PHIT HOB in HOB list.
-
-  @param  VOID
-
-  @return The Boot Mode.
-
-**/
-EFI_STATUS
-EFIAPI
-SetBootMode (
-  IN  EFI_BOOT_MODE   BootMode
-  )
-{
-  EFI_PEI_HOB_POINTERS  Hob;
-
-  Hob.Raw = GetHobList ();
-  Hob.HandoffInformationTable->BootMode = BootMode;
-  return BootMode;
-}
-
-/**
-  Builds a HOB for a loaded PE32 module.
-
-  This function builds a HOB for a loaded PE32 module.
-  It can only be invoked during PEI phase;
-  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
-  If ModuleName is NULL, then ASSERT().
-  If there is no additional space for HOB creation, then ASSERT().
-
-  @param  ModuleName              The GUID File Name of the module.
-  @param  MemoryAllocationModule  The 64 bit physical address of the module.
-  @param  ModuleLength            The length of the module in bytes.
-  @param  EntryPoint              The 64 bit physical address of the module entry point.
-
-**/
-VOID
-EFIAPI
-BuildModuleHob (
-  IN CONST EFI_GUID         *ModuleName,
-  IN EFI_PHYSICAL_ADDRESS   MemoryAllocationModule,
-  IN UINT64                 ModuleLength,
-  IN EFI_PHYSICAL_ADDRESS   EntryPoint
-  )
-{
-  EFI_HOB_MEMORY_ALLOCATION_MODULE  *Hob;
-
-  ASSERT (((MemoryAllocationModule & (EFI_PAGE_SIZE - 1)) == 0) &&
-          ((ModuleLength & (EFI_PAGE_SIZE - 1)) == 0));
-
-  Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));
-
-  CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid);
-  Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule;
-  Hob->MemoryAllocationHeader.MemoryLength      = ModuleLength;
-  Hob->MemoryAllocationHeader.MemoryType        = EfiBootServicesCode;
-
-  //
-  // Zero the reserved space to match HOB spec
-  //
-  ZeroMem (Hob->MemoryAllocationHeader.Reserved, sizeof (Hob->MemoryAllocationHeader.Reserved));
-  
-  CopyGuid (&Hob->ModuleName, ModuleName);
-  Hob->EntryPoint = EntryPoint;
-}
-
-/**
-  Builds a GUID HOB with a certain data length.
-
-  This function builds a customized HOB tagged with a GUID for identification 
-  and returns the start address of GUID HOB data so that caller can fill the customized data. 
-  The HOB Header and Name field is already stripped.
-  It can only be invoked during PEI phase;
-  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
-  If Guid is NULL, then ASSERT().
-  If there is no additional space for HOB creation, then ASSERT().
-  If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
-
-  @param  Guid          The GUID to tag the customized HOB.
-  @param  DataLength    The size of the data payload for the GUID HOB.
-
-  @return The start address of GUID HOB data.
-
-**/
-VOID *
-EFIAPI
-BuildGuidHob (
-  IN CONST EFI_GUID              *Guid,
-  IN UINTN                       DataLength
-  )
-{
-  EFI_HOB_GUID_TYPE *Hob;
-
-  //
-  // Make sure that data length is not too long.
-  //
-  ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE)));
-
-  Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength));
-  CopyGuid (&Hob->Name, Guid);
-  return Hob + 1;
-}
-
-
-/**
-  Copies a data buffer to a newly-built HOB.
-
-  This function builds a customized HOB tagged with a GUID for identification,
-  copies the input data to the HOB data field and returns the start address of the GUID HOB data.
-  The HOB Header and Name field is already stripped.
-  It can only be invoked during PEI phase;
-  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
-  If Guid is NULL, then ASSERT().
-  If Data is NULL and DataLength > 0, then ASSERT().
-  If there is no additional space for HOB creation, then ASSERT().
-  If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().
-
-  @param  Guid          The GUID to tag the customized HOB.
-  @param  Data          The data to be copied into the data field of the GUID HOB.
-  @param  DataLength    The size of the data payload for the GUID HOB.
-
-  @return The start address of GUID HOB data.
-
-**/
-VOID *
-EFIAPI
-BuildGuidDataHob (
-  IN CONST EFI_GUID              *Guid,
-  IN VOID                        *Data,
-  IN UINTN                       DataLength
-  )
-{
-  VOID  *HobData;
-
-  ASSERT (Data != NULL || DataLength == 0);
-
-  HobData = BuildGuidHob (Guid, DataLength);
-
-  return CopyMem (HobData, Data, DataLength);
-}
-
-
-/**
-  Builds a Firmware Volume HOB.
-
-  This function builds a Firmware Volume HOB.
-  It can only be invoked during PEI phase;
-  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
-  If there is no additional space for HOB creation, then ASSERT().
-
-  @param  BaseAddress   The base address of the Firmware Volume.
-  @param  Length        The size of the Firmware Volume in bytes.
-
-**/
-VOID
-EFIAPI
-BuildFvHob (
-  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
-  IN UINT64                      Length
-  )
-{
-  EFI_HOB_FIRMWARE_VOLUME  *Hob;
-
-  Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME));
-
-  Hob->BaseAddress = BaseAddress;
-  Hob->Length      = Length;
-}
-
-
-/**
-  Builds a EFI_HOB_TYPE_FV2 HOB.
-
-  This function builds a EFI_HOB_TYPE_FV2 HOB.
-  It can only be invoked during PEI phase;
-  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
-  If there is no additional space for HOB creation, then ASSERT().
-
-  @param  BaseAddress   The base address of the Firmware Volume.
-  @param  Length        The size of the Firmware Volume in bytes.
-  @param  FvName       The name of the Firmware Volume.
-  @param  FileName      The name of the file.
-  
-**/
-VOID
-EFIAPI
-BuildFv2Hob (
-  IN          EFI_PHYSICAL_ADDRESS        BaseAddress,
-  IN          UINT64                      Length,
-  IN CONST    EFI_GUID                    *FvName,
-  IN CONST    EFI_GUID                    *FileName
-  )
-{
-  EFI_HOB_FIRMWARE_VOLUME2  *Hob;
-
-  Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2));
-
-  Hob->BaseAddress = BaseAddress;
-  Hob->Length      = Length;
-  CopyGuid (&Hob->FvName, FvName);
-  CopyGuid (&Hob->FileName, FileName);
-}
-
-
-
-/**
-  Builds a Capsule Volume HOB.
-
-  This function builds a Capsule Volume HOB.
-  It can only be invoked during PEI phase;
-  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
-  If there is no additional space for HOB creation, then ASSERT().
-
-  @param  BaseAddress   The base address of the Capsule Volume.
-  @param  Length        The size of the Capsule Volume in bytes.
-
-**/
-VOID
-EFIAPI
-BuildCvHob (
-  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
-  IN UINT64                      Length
-  )
-{
-  ASSERT (FALSE);
-}
-
-
-/**
-  Builds a HOB for the CPU.
-
-  This function builds a HOB for the CPU.
-  It can only be invoked during PEI phase;
-  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
-  If there is no additional space for HOB creation, then ASSERT().
-
-  @param  SizeOfMemorySpace   The maximum physical memory addressability of the processor.
-  @param  SizeOfIoSpace       The maximum physical I/O addressability of the processor.
-
-**/
-VOID
-EFIAPI
-BuildCpuHob (
-  IN UINT8                       SizeOfMemorySpace,
-  IN UINT8                       SizeOfIoSpace
-  )
-{
-  EFI_HOB_CPU  *Hob;
-
-  Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU));
-
-  Hob->SizeOfMemorySpace = SizeOfMemorySpace;
-  Hob->SizeOfIoSpace     = SizeOfIoSpace;
-
-  //
-  // Zero the reserved space to match HOB spec
-  //
-  ZeroMem (Hob->Reserved, sizeof (Hob->Reserved)); 
-}
-
-
-/**
-  Builds a HOB for the Stack.
-
-  This function builds a HOB for the stack.
-  It can only be invoked during PEI phase;
-  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
-  If there is no additional space for HOB creation, then ASSERT().
-
-  @param  BaseAddress   The 64 bit physical address of the Stack.
-  @param  Length        The length of the stack in bytes.
-
-**/
-VOID
-EFIAPI
-BuildStackHob (
-  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
-  IN UINT64                      Length
-  )
-{
-  EFI_HOB_MEMORY_ALLOCATION_STACK  *Hob;
-
-  ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
-          ((Length & (EFI_PAGE_SIZE - 1)) == 0));
-
-  Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK));
-
-  CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocStackGuid);
-  Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
-  Hob->AllocDescriptor.MemoryLength      = Length;
-  Hob->AllocDescriptor.MemoryType        = EfiBootServicesData;
-
-  //
-  // Zero the reserved space to match HOB spec
-  //
-  ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
-}
-
-
-/**
-  Update the Stack Hob if the stack has been moved
-
-  @param  BaseAddress   The 64 bit physical address of the Stack.
-  @param  Length        The length of the stack in bytes.
-
-**/
-VOID
-UpdateStackHob (
-  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
-  IN UINT64                      Length
-  )
-{
-  EFI_PEI_HOB_POINTERS           Hob;
-
-  Hob.Raw = GetHobList ();
-  while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {
-    if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) {
-      //
-      // Build a new memory allocation HOB with old stack info with EfiConventionalMemory type
-      // to be reclaimed by DXE core.
-      //
-      BuildMemoryAllocationHob (
-        Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress,
-        Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength,
-        EfiConventionalMemory
-        );
-      //
-      // Update the BSP Stack Hob to reflect the new stack info.
-      //
-      Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress = BaseAddress;
-      Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength = Length;
-      break;
-    }
-    Hob.Raw = GET_NEXT_HOB (Hob);
-  }
-}
-
-
-
-/**
-  Builds a HOB for the memory allocation.
-
-  This function builds a HOB for the memory allocation.
-  It can only be invoked during PEI phase;
-  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
-  If there is no additional space for HOB creation, then ASSERT().
-
-  @param  BaseAddress   The 64 bit physical address of the memory.
-  @param  Length        The length of the memory allocation in bytes.
-  @param  MemoryType    Type of memory allocated by this HOB.
-
-**/
-VOID
-EFIAPI
-BuildMemoryAllocationHob (
-  IN EFI_PHYSICAL_ADDRESS        BaseAddress,
-  IN UINT64                      Length,
-  IN EFI_MEMORY_TYPE             MemoryType
-  )
-{
-  EFI_HOB_MEMORY_ALLOCATION  *Hob;
-
-  ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&
-          ((Length & (EFI_PAGE_SIZE - 1)) == 0));
-  
-  Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION));
-  
-  ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));
-  Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
-  Hob->AllocDescriptor.MemoryLength      = Length;
-  Hob->AllocDescriptor.MemoryType        = MemoryType;
-  //
-  // Zero the reserved space to match HOB spec
-  //
-  ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));
-}
-
-
-
-VOID
-EFIAPI
-BuildExtractSectionHob (
-  IN  EFI_GUID                                  *Guid,
-  IN  EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER   SectionGetInfo,
-  IN  EXTRACT_GUIDED_SECTION_DECODE_HANDLER     SectionExtraction
-  )
-{
-  EXTRACT_SECTION_DATA Data;
-  
-  Data.SectionGetInfo    = SectionGetInfo;
-  Data.SectionExtraction = SectionExtraction;
-  BuildGuidDataHob (Guid, &Data, sizeof (Data));
-}
-
-PE_COFF_LOADER_PROTOCOL gPeCoffProtocol = {
-  PeCoffLoaderGetImageInfo,
-  PeCoffLoaderLoadImage,
-  PeCoffLoaderRelocateImage,
-  PeCoffLoaderImageReadFromMemory,
-  PeCoffLoaderRelocateImageForRuntime,
-  PeCoffLoaderUnloadImage
-};
-
-
-
-VOID
-EFIAPI
-BuildPeCoffLoaderHob (
-  VOID
-  )
-{
-  VOID  *Ptr;      
-  
-  Ptr = &gPeCoffProtocol;
-  BuildGuidDataHob (&gPeCoffLoaderProtocolGuid, &Ptr, sizeof (VOID *));  
-}
-
-// May want to put this into a library so you only need the PCD setings if you are using the feature?
-VOID
-BuildMemoryTypeInformationHob (
-  VOID
-  )
-{
-  EFI_MEMORY_TYPE_INFORMATION   Info[10];
-
-  Info[0].Type          = EfiACPIReclaimMemory;
-  Info[0].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory);
-  Info[1].Type          = EfiACPIMemoryNVS;
-  Info[1].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS);
-  Info[2].Type          = EfiReservedMemoryType;
-  Info[2].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiReservedMemoryType);
-  Info[3].Type          = EfiRuntimeServicesData;
-  Info[3].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesData);
-  Info[4].Type          = EfiRuntimeServicesCode;
-  Info[4].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode);
-  Info[5].Type          = EfiBootServicesCode;
-  Info[5].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesCode);
-  Info[6].Type          = EfiBootServicesData;
-  Info[6].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesData);
-  Info[7].Type          = EfiLoaderCode;
-  Info[7].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderCode);
-  Info[8].Type          = EfiLoaderData;
-  Info[8].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderData);
-
-  // Terminator for the list
-  Info[9].Type          = EfiMaxMemoryType;
-  Info[9].NumberOfPages = 0;
-
-
-  BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, &Info, sizeof (Info));
-}
-
+/** @file\r
+\r
+  Copyright (c) 2010, Apple Inc. All rights reserved.<BR>\r
+  \r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <PiPei.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/PeCoffLib.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/PrePiHobListPointerLib.h>\r
+\r
+#include <Protocol/PeCoffLoader.h>\r
+#include <Guid/ExtractSection.h>\r
+#include <Guid/MemoryTypeInformation.h>\r
+#include <Guid/MemoryAllocationHob.h>\r
+\r
+VOID\r
+BuildMemoryTypeInformationHob (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Returns the pointer to the HOB list.\r
+\r
+  This function returns the pointer to first HOB in the list.\r
+\r
+  @return The pointer to the HOB list.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+GetHobList (\r
+  VOID\r
+  )\r
+{\r
+  return PrePeiGetHobList ();\r
+}\r
+\r
+\r
+\r
+/**\r
+  Updates the pointer to the HOB list.\r
+\r
+  @param  HobList       Hob list pointer to store\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SetHobList (\r
+  IN  VOID      *HobList\r
+  )\r
+{\r
+  return PrePeiSetHobList (HobList);\r
+}\r
+\r
+/**\r
+\r
+\r
+**/\r
+EFI_HOB_HANDOFF_INFO_TABLE*\r
+HobConstructor (\r
+  IN VOID   *EfiMemoryBegin,\r
+  IN UINTN  EfiMemoryLength,\r
+  IN VOID   *EfiFreeMemoryBottom,\r
+  IN VOID   *EfiFreeMemoryTop\r
+  )\r
+{\r
+  EFI_HOB_HANDOFF_INFO_TABLE  *Hob;\r
+  EFI_HOB_GENERIC_HEADER      *HobEnd;\r
+\r
+  Hob    = EfiFreeMemoryBottom;\r
+  HobEnd = (EFI_HOB_GENERIC_HEADER *)(Hob+1);\r
+\r
+  Hob->Header.HobType     = EFI_HOB_TYPE_HANDOFF;\r
+  Hob->Header.HobLength   = sizeof(EFI_HOB_HANDOFF_INFO_TABLE);\r
+  Hob->Header.Reserved    = 0;\r
+\r
+  HobEnd->HobType     = EFI_HOB_TYPE_END_OF_HOB_LIST;\r
+  HobEnd->HobLength   = sizeof(EFI_HOB_GENERIC_HEADER);\r
+  HobEnd->Reserved    = 0;\r
+\r
+  Hob->Version             = EFI_HOB_HANDOFF_TABLE_VERSION;\r
+  Hob->BootMode            = BOOT_WITH_FULL_CONFIGURATION;\r
+\r
+  Hob->EfiMemoryTop        = (UINTN)EfiMemoryBegin + EfiMemoryLength;\r
+  Hob->EfiMemoryBottom     = (UINTN)EfiMemoryBegin;\r
+  Hob->EfiFreeMemoryTop    = (UINTN)EfiFreeMemoryTop;\r
+  Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS)(UINTN)(HobEnd+1);\r
+  Hob->EfiEndOfHobList     = (EFI_PHYSICAL_ADDRESS)(UINTN)HobEnd;\r
+\r
+  return Hob;\r
+}\r
+\r
+VOID *\r
+CreateHob (\r
+  IN  UINT16    HobType,\r
+  IN  UINT16    HobLength\r
+  )\r
+{\r
+  EFI_HOB_HANDOFF_INFO_TABLE  *HandOffHob;\r
+  EFI_HOB_GENERIC_HEADER      *HobEnd;\r
+  EFI_PHYSICAL_ADDRESS        FreeMemory;\r
+  VOID                        *Hob;\r
+\r
+  HandOffHob = GetHobList ();\r
+\r
+  HobLength = (UINT16)((HobLength + 0x7) & (~0x7));\r
+\r
+  FreeMemory = HandOffHob->EfiFreeMemoryTop - HandOffHob->EfiFreeMemoryBottom;\r
+\r
+  if (FreeMemory < HobLength) {\r
+      return NULL;\r
+  }\r
+\r
+  Hob = (VOID*) (UINTN) HandOffHob->EfiEndOfHobList;\r
+  ((EFI_HOB_GENERIC_HEADER*) Hob)->HobType = HobType;\r
+  ((EFI_HOB_GENERIC_HEADER*) Hob)->HobLength = HobLength;\r
+  ((EFI_HOB_GENERIC_HEADER*) Hob)->Reserved = 0;\r
+\r
+  HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN)Hob + HobLength);\r
+  HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;\r
+\r
+  HobEnd->HobType   = EFI_HOB_TYPE_END_OF_HOB_LIST;\r
+  HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);\r
+  HobEnd->Reserved  = 0;\r
+  HobEnd++;\r
+  HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;\r
+\r
+  return Hob;\r
+}\r
+\r
+/**\r
+  Builds a HOB that describes a chunk of system memory.\r
+\r
+  This function builds a HOB that describes a chunk of system memory.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  ResourceType        The type of resource described by this HOB.\r
+  @param  ResourceAttribute   The resource attributes of the memory described by this HOB.\r
+  @param  PhysicalStart       The 64 bit physical address of memory described by this HOB.\r
+  @param  NumberOfBytes       The length of the memory described by this HOB in bytes.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+BuildResourceDescriptorHob (\r
+  IN EFI_RESOURCE_TYPE            ResourceType,\r
+  IN EFI_RESOURCE_ATTRIBUTE_TYPE  ResourceAttribute,\r
+  IN EFI_PHYSICAL_ADDRESS         PhysicalStart,\r
+  IN UINT64                       NumberOfBytes\r
+  )\r
+{\r
+  EFI_HOB_RESOURCE_DESCRIPTOR  *Hob;\r
+\r
+  Hob = CreateHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, sizeof (EFI_HOB_RESOURCE_DESCRIPTOR));\r
+  ASSERT(Hob != NULL);\r
+\r
+  Hob->ResourceType      = ResourceType;\r
+  Hob->ResourceAttribute = ResourceAttribute;\r
+  Hob->PhysicalStart     = PhysicalStart;\r
+  Hob->ResourceLength    = NumberOfBytes;\r
+}\r
+\r
+/**\r
+\r
+\r
+**/\r
+VOID\r
+CreateHobList (\r
+  IN VOID   *MemoryBegin,\r
+  IN UINTN  MemoryLength,\r
+  IN VOID   *HobBase,\r
+  IN VOID   *StackBase\r
+  )\r
+{\r
+  EFI_HOB_HANDOFF_INFO_TABLE  *Hob;\r
+  EFI_RESOURCE_ATTRIBUTE_TYPE Attributes;\r
+\r
+  Hob = HobConstructor (MemoryBegin,MemoryLength,HobBase,StackBase);\r
+  SetHobList (Hob);\r
+\r
+  BuildCpuHob (PcdGet8 (PcdPrePiCpuMemorySize), PcdGet8 (PcdPrePiCpuIoSize));\r
+  \r
+  Attributes =(\r
+    EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
+    EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
+    EFI_RESOURCE_ATTRIBUTE_TESTED |\r
+    EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
+    EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
+    EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
+    EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE\r
+  );\r
+\r
+  BuildResourceDescriptorHob (EFI_RESOURCE_SYSTEM_MEMORY, Attributes, (UINTN)MemoryBegin, MemoryLength);\r
+\r
+  BuildStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN)StackBase, ((UINTN)MemoryBegin + MemoryLength) - (UINTN)StackBase);\r
+\r
+  if (FeaturePcdGet (PcdPrePiProduceMemoryTypeInformationHob)) {\r
+    // Optional feature that helps prevent EFI memory map fragmentation. \r
+    BuildMemoryTypeInformationHob ();\r
+  }\r
+}  \r
+  \r
+\r
+VOID\r
+EFIAPI\r
+BuildFvHobs (  \r
+  IN EFI_PHYSICAL_ADDRESS         PhysicalStart,\r
+  IN UINT64                       NumberOfBytes,\r
+  IN EFI_RESOURCE_ATTRIBUTE_TYPE  *ResourceAttribute\r
+  ) \r
+{\r
+\r
+  EFI_RESOURCE_ATTRIBUTE_TYPE Resource;\r
+  \r
+  BuildFvHob (PhysicalStart, NumberOfBytes);\r
+  \r
+  if (ResourceAttribute == NULL) {\r
+    Resource = (EFI_RESOURCE_ATTRIBUTE_PRESENT    |\r
+                EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
+                EFI_RESOURCE_ATTRIBUTE_TESTED |\r
+                EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE);\r
+  } else {\r
+    Resource = *ResourceAttribute;\r
+  }\r
+  \r
+  BuildResourceDescriptorHob (EFI_RESOURCE_FIRMWARE_DEVICE, Resource, PhysicalStart, NumberOfBytes);\r
+}\r
+\r
+/**\r
+  Returns the next instance of a HOB type from the starting HOB.\r
+\r
+  This function searches the first instance of a HOB type from the starting HOB pointer. \r
+  If there does not exist such HOB type from the starting HOB pointer, it will return NULL.\r
+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer\r
+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;\r
+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.\r
+  If HobStart is NULL, then ASSERT().\r
+\r
+  @param  Type          The HOB type to return.\r
+  @param  HobStart      The starting HOB pointer to search from.\r
+\r
+  @return The next instance of a HOB type from the starting HOB.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+GetNextHob (\r
+  IN UINT16                 Type,\r
+  IN CONST VOID             *HobStart\r
+  )\r
+{\r
+  EFI_PEI_HOB_POINTERS  Hob;\r
+\r
+  ASSERT (HobStart != NULL);\r
+   \r
+  Hob.Raw = (UINT8 *) HobStart;\r
+  //\r
+  // Parse the HOB list until end of list or matching type is found.\r
+  //\r
+  while (!END_OF_HOB_LIST (Hob)) {\r
+    if (Hob.Header->HobType == Type) {\r
+      return Hob.Raw;\r
+    }\r
+    Hob.Raw = GET_NEXT_HOB (Hob);\r
+  }\r
+  return NULL;\r
+}\r
+  \r
+  \r
+\r
+/**\r
+  Returns the first instance of a HOB type among the whole HOB list.\r
+\r
+  This function searches the first instance of a HOB type among the whole HOB list. \r
+  If there does not exist such HOB type in the HOB list, it will return NULL. \r
+\r
+  @param  Type          The HOB type to return.\r
+\r
+  @return The next instance of a HOB type from the starting HOB.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+GetFirstHob (\r
+  IN UINT16                 Type\r
+  )\r
+{\r
+  VOID      *HobList;\r
+\r
+  HobList = GetHobList ();\r
+  return GetNextHob (Type, HobList);\r
+}\r
+\r
+\r
+/**\r
+  This function searches the first instance of a HOB from the starting HOB pointer. \r
+  Such HOB should satisfy two conditions: \r
+  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid. \r
+  If there does not exist such HOB from the starting HOB pointer, it will return NULL. \r
+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()\r
+  to extract the data section and its size info respectively.\r
+  In contrast with macro GET_NEXT_HOB(), this function does not skip the starting HOB pointer\r
+  unconditionally: it returns HobStart back if HobStart itself meets the requirement;\r
+  caller is required to use GET_NEXT_HOB() if it wishes to skip current HobStart.\r
+  If Guid is NULL, then ASSERT().\r
+  If HobStart is NULL, then ASSERT().\r
+\r
+  @param  Guid          The GUID to match with in the HOB list.\r
+  @param  HobStart      A pointer to a Guid.\r
+\r
+  @return The next instance of the matched GUID HOB from the starting HOB.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+GetNextGuidHob (\r
+  IN CONST EFI_GUID         *Guid,\r
+  IN CONST VOID             *HobStart\r
+  ){\r
+  EFI_PEI_HOB_POINTERS  GuidHob;\r
+\r
+  GuidHob.Raw = (UINT8 *) HobStart;\r
+  while ((GuidHob.Raw = GetNextHob (EFI_HOB_TYPE_GUID_EXTENSION, GuidHob.Raw)) != NULL) {\r
+    if (CompareGuid (Guid, &GuidHob.Guid->Name)) {\r
+      break;\r
+    }\r
+    GuidHob.Raw = GET_NEXT_HOB (GuidHob);\r
+  }\r
+  return GuidHob.Raw;\r
+}\r
+\r
+\r
+/**\r
+  This function searches the first instance of a HOB among the whole HOB list. \r
+  Such HOB should satisfy two conditions:\r
+  its HOB type is EFI_HOB_TYPE_GUID_EXTENSION and its GUID Name equals to the input Guid.\r
+  If there does not exist such HOB from the starting HOB pointer, it will return NULL.\r
+  Caller is required to apply GET_GUID_HOB_DATA () and GET_GUID_HOB_DATA_SIZE ()\r
+  to extract the data section and its size info respectively.\r
+  If Guid is NULL, then ASSERT().\r
+\r
+  @param  Guid          The GUID to match with in the HOB list.\r
+\r
+  @return The first instance of the matched GUID HOB among the whole HOB list.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+GetFirstGuidHob (\r
+  IN CONST EFI_GUID         *Guid\r
+  )\r
+{\r
+  VOID      *HobList;\r
+\r
+  HobList = GetHobList ();\r
+  return GetNextGuidHob (Guid, HobList);\r
+}\r
+\r
+\r
+/**\r
+  Get the Boot Mode from the HOB list.\r
+\r
+  This function returns the system boot mode information from the \r
+  PHIT HOB in HOB list.\r
+\r
+  @param  VOID\r
+\r
+  @return The Boot Mode.\r
+\r
+**/\r
+EFI_BOOT_MODE\r
+EFIAPI\r
+GetBootMode (\r
+  VOID\r
+  )\r
+{\r
+  EFI_PEI_HOB_POINTERS  Hob;\r
+\r
+  Hob.Raw = GetHobList ();\r
+  return Hob.HandoffInformationTable->BootMode;\r
+}\r
+\r
+\r
+/**\r
+  Get the Boot Mode from the HOB list.\r
+\r
+  This function returns the system boot mode information from the \r
+  PHIT HOB in HOB list.\r
+\r
+  @param  VOID\r
+\r
+  @return The Boot Mode.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SetBootMode (\r
+  IN  EFI_BOOT_MODE   BootMode\r
+  )\r
+{\r
+  EFI_PEI_HOB_POINTERS  Hob;\r
+\r
+  Hob.Raw = GetHobList ();\r
+  Hob.HandoffInformationTable->BootMode = BootMode;\r
+  return BootMode;\r
+}\r
+\r
+/**\r
+  Builds a HOB for a loaded PE32 module.\r
+\r
+  This function builds a HOB for a loaded PE32 module.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If ModuleName is NULL, then ASSERT().\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  ModuleName              The GUID File Name of the module.\r
+  @param  MemoryAllocationModule  The 64 bit physical address of the module.\r
+  @param  ModuleLength            The length of the module in bytes.\r
+  @param  EntryPoint              The 64 bit physical address of the module entry point.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+BuildModuleHob (\r
+  IN CONST EFI_GUID         *ModuleName,\r
+  IN EFI_PHYSICAL_ADDRESS   MemoryAllocationModule,\r
+  IN UINT64                 ModuleLength,\r
+  IN EFI_PHYSICAL_ADDRESS   EntryPoint\r
+  )\r
+{\r
+  EFI_HOB_MEMORY_ALLOCATION_MODULE  *Hob;\r
+\r
+  ASSERT (((MemoryAllocationModule & (EFI_PAGE_SIZE - 1)) == 0) &&\r
+          ((ModuleLength & (EFI_PAGE_SIZE - 1)) == 0));\r
+\r
+  Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_MODULE));\r
+\r
+  CopyGuid (&(Hob->MemoryAllocationHeader.Name), &gEfiHobMemoryAllocModuleGuid);\r
+  Hob->MemoryAllocationHeader.MemoryBaseAddress = MemoryAllocationModule;\r
+  Hob->MemoryAllocationHeader.MemoryLength      = ModuleLength;\r
+  Hob->MemoryAllocationHeader.MemoryType        = EfiBootServicesCode;\r
+\r
+  //\r
+  // Zero the reserved space to match HOB spec\r
+  //\r
+  ZeroMem (Hob->MemoryAllocationHeader.Reserved, sizeof (Hob->MemoryAllocationHeader.Reserved));\r
+  \r
+  CopyGuid (&Hob->ModuleName, ModuleName);\r
+  Hob->EntryPoint = EntryPoint;\r
+}\r
+\r
+/**\r
+  Builds a GUID HOB with a certain data length.\r
+\r
+  This function builds a customized HOB tagged with a GUID for identification \r
+  and returns the start address of GUID HOB data so that caller can fill the customized data. \r
+  The HOB Header and Name field is already stripped.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If Guid is NULL, then ASSERT().\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+  If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().\r
+\r
+  @param  Guid          The GUID to tag the customized HOB.\r
+  @param  DataLength    The size of the data payload for the GUID HOB.\r
+\r
+  @return The start address of GUID HOB data.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+BuildGuidHob (\r
+  IN CONST EFI_GUID              *Guid,\r
+  IN UINTN                       DataLength\r
+  )\r
+{\r
+  EFI_HOB_GUID_TYPE *Hob;\r
+\r
+  //\r
+  // Make sure that data length is not too long.\r
+  //\r
+  ASSERT (DataLength <= (0xffff - sizeof (EFI_HOB_GUID_TYPE)));\r
+\r
+  Hob = CreateHob (EFI_HOB_TYPE_GUID_EXTENSION, (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength));\r
+  CopyGuid (&Hob->Name, Guid);\r
+  return Hob + 1;\r
+}\r
+\r
+\r
+/**\r
+  Copies a data buffer to a newly-built HOB.\r
+\r
+  This function builds a customized HOB tagged with a GUID for identification,\r
+  copies the input data to the HOB data field and returns the start address of the GUID HOB data.\r
+  The HOB Header and Name field is already stripped.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If Guid is NULL, then ASSERT().\r
+  If Data is NULL and DataLength > 0, then ASSERT().\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+  If DataLength >= (0x10000 - sizeof (EFI_HOB_GUID_TYPE)), then ASSERT().\r
+\r
+  @param  Guid          The GUID to tag the customized HOB.\r
+  @param  Data          The data to be copied into the data field of the GUID HOB.\r
+  @param  DataLength    The size of the data payload for the GUID HOB.\r
+\r
+  @return The start address of GUID HOB data.\r
+\r
+**/\r
+VOID *\r
+EFIAPI\r
+BuildGuidDataHob (\r
+  IN CONST EFI_GUID              *Guid,\r
+  IN VOID                        *Data,\r
+  IN UINTN                       DataLength\r
+  )\r
+{\r
+  VOID  *HobData;\r
+\r
+  ASSERT (Data != NULL || DataLength == 0);\r
+\r
+  HobData = BuildGuidHob (Guid, DataLength);\r
+\r
+  return CopyMem (HobData, Data, DataLength);\r
+}\r
+\r
+\r
+/**\r
+  Builds a Firmware Volume HOB.\r
+\r
+  This function builds a Firmware Volume HOB.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  BaseAddress   The base address of the Firmware Volume.\r
+  @param  Length        The size of the Firmware Volume in bytes.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+BuildFvHob (\r
+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,\r
+  IN UINT64                      Length\r
+  )\r
+{\r
+  EFI_HOB_FIRMWARE_VOLUME  *Hob;\r
+\r
+  Hob = CreateHob (EFI_HOB_TYPE_FV, sizeof (EFI_HOB_FIRMWARE_VOLUME));\r
+\r
+  Hob->BaseAddress = BaseAddress;\r
+  Hob->Length      = Length;\r
+}\r
+\r
+\r
+/**\r
+  Builds a EFI_HOB_TYPE_FV2 HOB.\r
+\r
+  This function builds a EFI_HOB_TYPE_FV2 HOB.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  BaseAddress   The base address of the Firmware Volume.\r
+  @param  Length        The size of the Firmware Volume in bytes.\r
+  @param  FvName       The name of the Firmware Volume.\r
+  @param  FileName      The name of the file.\r
+  \r
+**/\r
+VOID\r
+EFIAPI\r
+BuildFv2Hob (\r
+  IN          EFI_PHYSICAL_ADDRESS        BaseAddress,\r
+  IN          UINT64                      Length,\r
+  IN CONST    EFI_GUID                    *FvName,\r
+  IN CONST    EFI_GUID                    *FileName\r
+  )\r
+{\r
+  EFI_HOB_FIRMWARE_VOLUME2  *Hob;\r
+\r
+  Hob = CreateHob (EFI_HOB_TYPE_FV2, sizeof (EFI_HOB_FIRMWARE_VOLUME2));\r
+\r
+  Hob->BaseAddress = BaseAddress;\r
+  Hob->Length      = Length;\r
+  CopyGuid (&Hob->FvName, FvName);\r
+  CopyGuid (&Hob->FileName, FileName);\r
+}\r
+\r
+\r
+\r
+/**\r
+  Builds a Capsule Volume HOB.\r
+\r
+  This function builds a Capsule Volume HOB.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  BaseAddress   The base address of the Capsule Volume.\r
+  @param  Length        The size of the Capsule Volume in bytes.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+BuildCvHob (\r
+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,\r
+  IN UINT64                      Length\r
+  )\r
+{\r
+  ASSERT (FALSE);\r
+}\r
+\r
+\r
+/**\r
+  Builds a HOB for the CPU.\r
+\r
+  This function builds a HOB for the CPU.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  SizeOfMemorySpace   The maximum physical memory addressability of the processor.\r
+  @param  SizeOfIoSpace       The maximum physical I/O addressability of the processor.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+BuildCpuHob (\r
+  IN UINT8                       SizeOfMemorySpace,\r
+  IN UINT8                       SizeOfIoSpace\r
+  )\r
+{\r
+  EFI_HOB_CPU  *Hob;\r
+\r
+  Hob = CreateHob (EFI_HOB_TYPE_CPU, sizeof (EFI_HOB_CPU));\r
+\r
+  Hob->SizeOfMemorySpace = SizeOfMemorySpace;\r
+  Hob->SizeOfIoSpace     = SizeOfIoSpace;\r
+\r
+  //\r
+  // Zero the reserved space to match HOB spec\r
+  //\r
+  ZeroMem (Hob->Reserved, sizeof (Hob->Reserved)); \r
+}\r
+\r
+\r
+/**\r
+  Builds a HOB for the Stack.\r
+\r
+  This function builds a HOB for the stack.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  BaseAddress   The 64 bit physical address of the Stack.\r
+  @param  Length        The length of the stack in bytes.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+BuildStackHob (\r
+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,\r
+  IN UINT64                      Length\r
+  )\r
+{\r
+  EFI_HOB_MEMORY_ALLOCATION_STACK  *Hob;\r
+\r
+  ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&\r
+          ((Length & (EFI_PAGE_SIZE - 1)) == 0));\r
+\r
+  Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK));\r
+\r
+  CopyGuid (&(Hob->AllocDescriptor.Name), &gEfiHobMemoryAllocStackGuid);\r
+  Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;\r
+  Hob->AllocDescriptor.MemoryLength      = Length;\r
+  Hob->AllocDescriptor.MemoryType        = EfiBootServicesData;\r
+\r
+  //\r
+  // Zero the reserved space to match HOB spec\r
+  //\r
+  ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));\r
+}\r
+\r
+\r
+/**\r
+  Update the Stack Hob if the stack has been moved\r
+\r
+  @param  BaseAddress   The 64 bit physical address of the Stack.\r
+  @param  Length        The length of the stack in bytes.\r
+\r
+**/\r
+VOID\r
+UpdateStackHob (\r
+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,\r
+  IN UINT64                      Length\r
+  )\r
+{\r
+  EFI_PEI_HOB_POINTERS           Hob;\r
+\r
+  Hob.Raw = GetHobList ();\r
+  while ((Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw)) != NULL) {\r
+    if (CompareGuid (&gEfiHobMemoryAllocStackGuid, &(Hob.MemoryAllocationStack->AllocDescriptor.Name))) {\r
+      //\r
+      // Build a new memory allocation HOB with old stack info with EfiConventionalMemory type\r
+      // to be reclaimed by DXE core.\r
+      //\r
+      BuildMemoryAllocationHob (\r
+        Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress,\r
+        Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength,\r
+        EfiConventionalMemory\r
+        );\r
+      //\r
+      // Update the BSP Stack Hob to reflect the new stack info.\r
+      //\r
+      Hob.MemoryAllocationStack->AllocDescriptor.MemoryBaseAddress = BaseAddress;\r
+      Hob.MemoryAllocationStack->AllocDescriptor.MemoryLength = Length;\r
+      break;\r
+    }\r
+    Hob.Raw = GET_NEXT_HOB (Hob);\r
+  }\r
+}\r
+\r
+\r
+\r
+/**\r
+  Builds a HOB for the memory allocation.\r
+\r
+  This function builds a HOB for the memory allocation.\r
+  It can only be invoked during PEI phase;\r
+  for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.\r
+  If there is no additional space for HOB creation, then ASSERT().\r
+\r
+  @param  BaseAddress   The 64 bit physical address of the memory.\r
+  @param  Length        The length of the memory allocation in bytes.\r
+  @param  MemoryType    Type of memory allocated by this HOB.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+BuildMemoryAllocationHob (\r
+  IN EFI_PHYSICAL_ADDRESS        BaseAddress,\r
+  IN UINT64                      Length,\r
+  IN EFI_MEMORY_TYPE             MemoryType\r
+  )\r
+{\r
+  EFI_HOB_MEMORY_ALLOCATION  *Hob;\r
+\r
+  ASSERT (((BaseAddress & (EFI_PAGE_SIZE - 1)) == 0) &&\r
+          ((Length & (EFI_PAGE_SIZE - 1)) == 0));\r
+  \r
+  Hob = CreateHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, sizeof (EFI_HOB_MEMORY_ALLOCATION));\r
+  \r
+  ZeroMem (&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID));\r
+  Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;\r
+  Hob->AllocDescriptor.MemoryLength      = Length;\r
+  Hob->AllocDescriptor.MemoryType        = MemoryType;\r
+  //\r
+  // Zero the reserved space to match HOB spec\r
+  //\r
+  ZeroMem (Hob->AllocDescriptor.Reserved, sizeof (Hob->AllocDescriptor.Reserved));\r
+}\r
+\r
+\r
+\r
+VOID\r
+EFIAPI\r
+BuildExtractSectionHob (\r
+  IN  EFI_GUID                                  *Guid,\r
+  IN  EXTRACT_GUIDED_SECTION_GET_INFO_HANDLER   SectionGetInfo,\r
+  IN  EXTRACT_GUIDED_SECTION_DECODE_HANDLER     SectionExtraction\r
+  )\r
+{\r
+  EXTRACT_SECTION_DATA Data;\r
+  \r
+  Data.SectionGetInfo    = SectionGetInfo;\r
+  Data.SectionExtraction = SectionExtraction;\r
+  BuildGuidDataHob (Guid, &Data, sizeof (Data));\r
+}\r
+\r
+PE_COFF_LOADER_PROTOCOL gPeCoffProtocol = {\r
+  PeCoffLoaderGetImageInfo,\r
+  PeCoffLoaderLoadImage,\r
+  PeCoffLoaderRelocateImage,\r
+  PeCoffLoaderImageReadFromMemory,\r
+  PeCoffLoaderRelocateImageForRuntime,\r
+  PeCoffLoaderUnloadImage\r
+};\r
+\r
+\r
+\r
+VOID\r
+EFIAPI\r
+BuildPeCoffLoaderHob (\r
+  VOID\r
+  )\r
+{\r
+  VOID  *Ptr;      \r
+  \r
+  Ptr = &gPeCoffProtocol;\r
+  BuildGuidDataHob (&gPeCoffLoaderProtocolGuid, &Ptr, sizeof (VOID *));  \r
+}\r
+\r
+// May want to put this into a library so you only need the PCD setings if you are using the feature?\r
+VOID\r
+BuildMemoryTypeInformationHob (\r
+  VOID\r
+  )\r
+{\r
+  EFI_MEMORY_TYPE_INFORMATION   Info[10];\r
+\r
+  Info[0].Type          = EfiACPIReclaimMemory;\r
+  Info[0].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory);\r
+  Info[1].Type          = EfiACPIMemoryNVS;\r
+  Info[1].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS);\r
+  Info[2].Type          = EfiReservedMemoryType;\r
+  Info[2].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiReservedMemoryType);\r
+  Info[3].Type          = EfiRuntimeServicesData;\r
+  Info[3].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesData);\r
+  Info[4].Type          = EfiRuntimeServicesCode;\r
+  Info[4].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode);\r
+  Info[5].Type          = EfiBootServicesCode;\r
+  Info[5].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesCode);\r
+  Info[6].Type          = EfiBootServicesData;\r
+  Info[6].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesData);\r
+  Info[7].Type          = EfiLoaderCode;\r
+  Info[7].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderCode);\r
+  Info[8].Type          = EfiLoaderData;\r
+  Info[8].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderData);\r
+\r
+  // Terminator for the list\r
+  Info[9].Type          = EfiMaxMemoryType;\r
+  Info[9].NumberOfPages = 0;\r
+\r
+\r
+  BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, &Info, sizeof (Info));\r
+}\r
+\r