Home | History | Annotate | Download | only in Hob
      1 /** @file
      2   This module provide Hand-Off Block manupulation.
      3 
      4 Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials
      6 are licensed and made available under the terms and conditions of the BSD License
      7 which accompanies this distribution.  The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include "PeiMain.h"
     16 
     17 /**
     18 
     19   Gets the pointer to the HOB List.
     20 
     21   @param PeiServices                   An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
     22   @param HobList                       Pointer to the HOB List.
     23 
     24   @retval EFI_SUCCESS                  Get the pointer of HOB List
     25   @retval EFI_NOT_AVAILABLE_YET        the HOB List is not yet published
     26   @retval EFI_INVALID_PARAMETER        HobList is NULL (in debug mode)
     27 
     28 **/
     29 EFI_STATUS
     30 EFIAPI
     31 PeiGetHobList (
     32   IN CONST EFI_PEI_SERVICES  **PeiServices,
     33   IN OUT VOID          **HobList
     34   )
     35 {
     36   PEI_CORE_INSTANCE *PrivateData;
     37 
     38   //
     39   // Only check this parameter in debug mode
     40   //
     41 
     42   DEBUG_CODE_BEGIN ();
     43     if (HobList == NULL) {
     44       return EFI_INVALID_PARAMETER;
     45     }
     46   DEBUG_CODE_END ();
     47 
     48   PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
     49 
     50   *HobList    = PrivateData->HobList.Raw;
     51 
     52   return EFI_SUCCESS;
     53 }
     54 
     55 
     56 /**
     57   Add a new HOB to the HOB List.
     58 
     59   @param PeiServices      An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
     60   @param Type             Type of the new HOB.
     61   @param Length           Length of the new HOB to allocate.
     62   @param Hob              Pointer to the new HOB.
     63 
     64   @return  EFI_SUCCESS           Success to create hob.
     65   @retval  EFI_INVALID_PARAMETER if Hob is NULL
     66   @retval  EFI_NOT_AVAILABLE_YET if HobList is still not available.
     67   @retval  EFI_OUT_OF_RESOURCES  if there is no more memory to grow the Hoblist.
     68 
     69 **/
     70 EFI_STATUS
     71 EFIAPI
     72 PeiCreateHob (
     73   IN CONST EFI_PEI_SERVICES  **PeiServices,
     74   IN UINT16            Type,
     75   IN UINT16            Length,
     76   IN OUT VOID          **Hob
     77   )
     78 {
     79   EFI_STATUS                           Status;
     80   EFI_HOB_HANDOFF_INFO_TABLE           *HandOffHob;
     81   EFI_HOB_GENERIC_HEADER               *HobEnd;
     82   EFI_PHYSICAL_ADDRESS                 FreeMemory;
     83 
     84 
     85   Status = PeiGetHobList (PeiServices, Hob);
     86   if (EFI_ERROR(Status)) {
     87     return Status;
     88   }
     89 
     90   HandOffHob = *Hob;
     91 
     92   //
     93   // Check Length to avoid data overflow.
     94   //
     95   if (0x10000 - Length <= 0x7) {
     96     return EFI_INVALID_PARAMETER;
     97   }
     98   Length     = (UINT16)((Length + 0x7) & (~0x7));
     99 
    100   FreeMemory = HandOffHob->EfiFreeMemoryTop -
    101                HandOffHob->EfiFreeMemoryBottom;
    102 
    103   if (FreeMemory < Length) {
    104     DEBUG ((EFI_D_ERROR, "PeiCreateHob fail: Length - 0x%08x\n", (UINTN)Length));
    105     DEBUG ((EFI_D_ERROR, "  FreeMemoryTop    - 0x%08x\n", (UINTN)HandOffHob->EfiFreeMemoryTop));
    106     DEBUG ((EFI_D_ERROR, "  FreeMemoryBottom - 0x%08x\n", (UINTN)HandOffHob->EfiFreeMemoryBottom));
    107     return EFI_OUT_OF_RESOURCES;
    108   }
    109 
    110   *Hob = (VOID*) (UINTN) HandOffHob->EfiEndOfHobList;
    111   ((EFI_HOB_GENERIC_HEADER*) *Hob)->HobType   = Type;
    112   ((EFI_HOB_GENERIC_HEADER*) *Hob)->HobLength = Length;
    113   ((EFI_HOB_GENERIC_HEADER*) *Hob)->Reserved  = 0;
    114 
    115   HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN) *Hob + Length);
    116   HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
    117 
    118   HobEnd->HobType   = EFI_HOB_TYPE_END_OF_HOB_LIST;
    119   HobEnd->HobLength = (UINT16) sizeof (EFI_HOB_GENERIC_HEADER);
    120   HobEnd->Reserved  = 0;
    121   HobEnd++;
    122   HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
    123 
    124   return EFI_SUCCESS;
    125 }
    126 
    127 /**
    128 
    129   Builds a Handoff Information Table HOB
    130 
    131   @param BootMode        - Current Bootmode
    132   @param MemoryBegin     - Start Memory Address.
    133   @param MemoryLength    - Length of Memory.
    134 
    135   @return EFI_SUCCESS Always success to initialize HOB.
    136 
    137 **/
    138 EFI_STATUS
    139 PeiCoreBuildHobHandoffInfoTable (
    140   IN EFI_BOOT_MODE         BootMode,
    141   IN EFI_PHYSICAL_ADDRESS  MemoryBegin,
    142   IN UINT64                MemoryLength
    143   )
    144 {
    145   EFI_HOB_HANDOFF_INFO_TABLE   *Hob;
    146   EFI_HOB_GENERIC_HEADER       *HobEnd;
    147 
    148   Hob                      = (VOID *)(UINTN)MemoryBegin;
    149   HobEnd                   = (EFI_HOB_GENERIC_HEADER*) (Hob+1);
    150   Hob->Header.HobType      = EFI_HOB_TYPE_HANDOFF;
    151   Hob->Header.HobLength    = (UINT16) sizeof (EFI_HOB_HANDOFF_INFO_TABLE);
    152   Hob->Header.Reserved     = 0;
    153 
    154   HobEnd->HobType          = EFI_HOB_TYPE_END_OF_HOB_LIST;
    155   HobEnd->HobLength        = (UINT16) sizeof (EFI_HOB_GENERIC_HEADER);
    156   HobEnd->Reserved         = 0;
    157 
    158   Hob->Version             = EFI_HOB_HANDOFF_TABLE_VERSION;
    159   Hob->BootMode            = BootMode;
    160 
    161   Hob->EfiMemoryTop        = MemoryBegin + MemoryLength;
    162   Hob->EfiMemoryBottom     = MemoryBegin;
    163   Hob->EfiFreeMemoryTop    = MemoryBegin + MemoryLength;
    164   Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) (HobEnd + 1);
    165   Hob->EfiEndOfHobList     = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
    166 
    167   return EFI_SUCCESS;
    168 }
    169