Home | History | Annotate | Download | only in PeiLib
      1 /*++
      2 
      3 Copyright (c) 2004 - 2010, 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 Module Name:
     13 
     14   PeiLib.c
     15 
     16 Abstract:
     17 
     18   PEI Library Functions
     19 
     20 --*/
     21 
     22 #include "TianoCommon.h"
     23 #include "PeiHob.h"
     24 #include "Pei.h"
     25 #include "PeiLib.h"
     26 #include "EfiCommonLib.h"
     27 
     28 VOID
     29 PeiCopyMem (
     30   IN VOID   *Destination,
     31   IN VOID   *Source,
     32   IN UINTN  Length
     33   );
     34 
     35 VOID
     36 ZeroMem (
     37   IN VOID   *Buffer,
     38   IN UINTN  Size
     39   )
     40 /*++
     41 
     42 Routine Description:
     43 
     44   Set Buffer to zero for Size bytes.
     45 
     46 Arguments:
     47 
     48   Buffer  - Memory to set.
     49 
     50   Size    - Number of bytes to set
     51 
     52 Returns:
     53 
     54   None
     55 
     56 --*/
     57 {
     58   EfiCommonLibZeroMem (Buffer, Size);
     59 }
     60 
     61 VOID
     62 PeiCopyMem (
     63   IN VOID   *Destination,
     64   IN VOID   *Source,
     65   IN UINTN  Length
     66   )
     67 /*++
     68 
     69 Routine Description:
     70 
     71   Copy Length bytes from Source to Destination.
     72 
     73 Arguments:
     74 
     75   Destination - Target of copy
     76 
     77   Source      - Place to copy from
     78 
     79   Length      - Number of bytes to copy
     80 
     81 Returns:
     82 
     83   None
     84 
     85 --*/
     86 {
     87   EfiCommonLibCopyMem (Destination, Source, Length);
     88 }
     89 
     90 VOID
     91 CopyMem (
     92   IN VOID   *Destination,
     93   IN VOID   *Source,
     94   IN UINTN  Length
     95   )
     96 /*++
     97 
     98 Routine Description:
     99 
    100   Copy Length bytes from Source to Destination.
    101 
    102 Arguments:
    103 
    104   Destination - Target of copy
    105 
    106   Source      - Place to copy from
    107 
    108   Length      - Number of bytes to copy
    109 
    110 Returns:
    111 
    112   None
    113 
    114 --*/
    115 {
    116   EfiCommonLibCopyMem (Destination, Source, Length);
    117 }
    118 
    119 
    120 BOOLEAN
    121 CompareGuid (
    122   IN EFI_GUID     *Guid1,
    123   IN EFI_GUID     *Guid2
    124   )
    125 /*++
    126 
    127 Routine Description:
    128 
    129   Compares two GUIDs
    130 
    131 Arguments:
    132 
    133   Guid1 - guid to compare
    134   Guid2 - guid to compare
    135 
    136 Returns:
    137   = TRUE  if Guid1 == Guid2
    138   = FALSE if Guid1 != Guid2
    139 
    140 --*/
    141 {
    142   if ((((INT32 *) Guid1)[0] - ((INT32 *) Guid2)[0]) == 0) {
    143     if ((((INT32 *) Guid1)[1] - ((INT32 *) Guid2)[1]) == 0) {
    144       if ((((INT32 *) Guid1)[2] - ((INT32 *) Guid2)[2]) == 0) {
    145         if ((((INT32 *) Guid1)[3] - ((INT32 *) Guid2)[3]) == 0) {
    146           return TRUE;
    147         }
    148       }
    149     }
    150   }
    151 
    152   return FALSE;
    153 }
    154 
    155 
    156 EFI_STATUS
    157 EFIAPI
    158 PeiLibPciCfgModify (
    159   IN EFI_PEI_SERVICES         **PeiServices,
    160   IN PEI_PCI_CFG_PPI          *PciCfg,
    161   IN PEI_PCI_CFG_PPI_WIDTH    Width,
    162   IN UINT64                   Address,
    163   IN UINTN                    SetBits,
    164   IN UINTN                    ClearBits
    165   )
    166 /*++
    167 
    168 Routine Description:
    169 
    170   PCI read-modify-write operations.
    171 
    172   PIWG's PI specification replaces Inte's EFI Specification 1.10.
    173   EFI_PEI_PCI_CFG_PPI defined in Inte's EFI Specification 1.10 is replaced by
    174   EFI_PEI_PCI_CFG2_PPI in PI 1.0. "Modify" function  in these two PPI are not
    175   compatibile with each other.
    176 
    177 
    178   For Framework code that make the following call:
    179 
    180       PciCfg->Modify (
    181                        PeiServices,
    182                        PciCfg,
    183                        Width,
    184                        Address,
    185                        SetBits,
    186                        ClearBits
    187                        );
    188    it will be updated to the following code which call this library API:
    189       PeiLibPciCfgModify (
    190           PeiServices,
    191           PciCfg,
    192           Width,
    193           Address,
    194           SetBits,
    195           ClearBits
    196           );
    197 
    198    The
    199 
    200 Arguments:
    201 
    202   PeiServices     An indirect pointer to the PEI Services Table
    203                           published by the PEI Foundation.
    204   PciCfg          A pointer to the this pointer of EFI_PEI_PCI_CFG_PPI.
    205                           This parameter is unused as a place holder to make
    206                           the parameter list identical to PEI_PCI_CFG_PPI_RW.
    207   Width           The width of the access. Enumerated in bytes. Type
    208                           EFI_PEI_PCI_CFG_PPI_WIDTH is defined in Read().
    209 
    210   Address         The physical address of the access.
    211 
    212   SetBits         Points to value to bitwise-OR with the read configuration value.
    213 
    214                           The size of the value is determined by Width.
    215 
    216   ClearBits       Points to the value to negate and bitwise-AND with the read configuration value.
    217                           The size of the value is determined by Width.
    218 
    219 
    220 Returns:
    221 
    222   EFI_SUCCESS           The function completed successfully.
    223 
    224   EFI_DEVICE_ERROR      There was a problem with the transaction.
    225 
    226 --*/
    227 {
    228   EFI_STATUS            Status;
    229   EFI_PEI_PCI_CFG2_PPI  *PciCfg2;
    230 
    231   Status = (*PeiServices)->LocatePpi (
    232                              PeiServices,
    233                              &gPeiPciCfg2PpiGuid,
    234                              0,
    235                              NULL,
    236                              (VOID **) &PciCfg2
    237                              );
    238   ASSERT_PEI_ERROR ((CONST EFI_PEI_SERVICES **) PeiServices, Status);
    239 
    240   Status = PciCfg2->Modify (
    241                       (CONST EFI_PEI_SERVICES **) PeiServices,
    242                       PciCfg2,
    243                       (EFI_PEI_PCI_CFG_PPI_WIDTH) Width,
    244                       Address,
    245                       &SetBits,
    246                       &ClearBits
    247                       );
    248 
    249   return Status;
    250 }
    251 
    252 
    253 #if (PI_SPECIFICATION_VERSION >= 0x00010000)
    254 
    255 VOID *
    256 EFIAPI
    257 ScanGuid (
    258   IN VOID        *Buffer,
    259   IN UINTN       Length,
    260   IN EFI_GUID    *Guid
    261   )
    262 /*++
    263 
    264 Routine Description:
    265 
    266   Scans a target buffer for a GUID, and returns a pointer to the matching GUID
    267   in the target buffer.
    268 
    269   This function searches target the buffer specified by Buffer and Length from
    270   the lowest address to the highest address at 128-bit increments for the 128-bit
    271   GUID value that matches Guid.  If a match is found, then a pointer to the matching
    272   GUID in the target buffer is returned.  If no match is found, then NULL is returned.
    273   If Length is 0, then NULL is returned.
    274   If Length > 0 and Buffer is NULL, then ASSERT().
    275   If Buffer is not aligned on a 32-bit boundary, then ASSERT().
    276   If Length is not aligned on a 128-bit boundary, then ASSERT().
    277   If Length is greater than (EFI_MAX_ADDRESS ?Buffer + 1), then ASSERT().
    278 
    279 Arguments:
    280 
    281   Buffer - Pointer to the target buffer to scan.
    282   Length - Number of bytes in Buffer to scan.
    283   Guid   - Value to search for in the target buffer.
    284 
    285 Returns:
    286   A pointer to the matching Guid in the target buffer or NULL otherwise.
    287 
    288 --*/
    289 {
    290   EFI_GUID                 *GuidPtr;
    291   EFI_PEI_SERVICES         **PeiServices;
    292 
    293   PeiServices = GetPeiServicesTablePointer();
    294   PEI_ASSERT(PeiServices, (((UINTN)Buffer & (sizeof (Guid->Data1) - 1)) == 0));
    295   PEI_ASSERT(PeiServices, (Length <= (EFI_MAX_ADDRESS - (UINTN)Buffer + 1)));
    296   PEI_ASSERT(PeiServices, ((Length & (sizeof (*GuidPtr) - 1)) == 0));
    297 
    298   GuidPtr = (EFI_GUID*)Buffer;
    299   Buffer  = GuidPtr + Length / sizeof (*GuidPtr);
    300   while (GuidPtr < (EFI_GUID*)Buffer) {
    301     if (CompareGuid (GuidPtr, Guid)) {
    302       return (VOID*)GuidPtr;
    303     }
    304     GuidPtr++;
    305   }
    306   return NULL;
    307 }
    308 
    309 
    310 VOID *
    311 EFIAPI
    312 InvalidateInstructionCacheRange (
    313   IN      VOID                      *Address,
    314   IN      UINTN                     Length
    315   )
    316 /*++
    317 
    318 Routine Description:
    319 
    320   Invalidates a range of instruction cache lines in the cache coherency domain
    321   of the calling CPU.
    322 
    323   Invalidates the instruction cache lines specified by Address and Length. If
    324   Address is not aligned on a cache line boundary, then entire instruction
    325   cache line containing Address is invalidated. If Address + Length is not
    326   aligned on a cache line boundary, then the entire instruction cache line
    327   containing Address + Length -1 is invalidated. This function may choose to
    328   invalidate the entire instruction cache if that is more efficient than
    329   invalidating the specified range. If Length is 0, the no instruction cache
    330   lines are invalidated. Address is returned.
    331 
    332   If Length is greater than (EFI_MAX_ADDRESS - Address + 1), then ASSERT().
    333 
    334 Arguments:
    335 
    336   Address   -     The base address of the instruction cache lines to
    337                   invalidate. If the CPU is in a physical addressing mode, then
    338                   Address is a physical address. If the CPU is in a virtual
    339                   addressing mode, then Address is a virtual address.
    340 
    341   Length    -      The number of bytes to invalidate from the instruction cache.
    342 
    343  Returns:
    344   Address
    345 
    346 **/
    347 {
    348   PEI_ASSERT(GetPeiServicesTablePointer() , (Length <= EFI_MAX_ADDRESS - (UINTN)Address + 1));
    349   return Address;
    350 }
    351 
    352 
    353 EFI_STATUS
    354 EFIAPI
    355 PeiLibFfsFindNextVolume (
    356   IN UINTN                          Instance,
    357   IN OUT EFI_PEI_FV_HANDLE          *VolumeHandle
    358   )
    359 /*++
    360 
    361 Routine Description:
    362 
    363   The wrapper of Pei Core Service function FfsFindNextVolume.
    364 
    365 Arguments:
    366 
    367   Instance     - The Fv Volume Instance.
    368   VolumeHandle - Pointer to the current Fv Volume to search.
    369 
    370 Returns:
    371   EFI_STATUS
    372 
    373 --*/
    374 
    375 {
    376   EFI_PEI_SERVICES  **PeiServices;
    377 
    378   PeiServices = GetPeiServicesTablePointer();
    379   return (*PeiServices)->FfsFindNextVolume (PeiServices, Instance, VolumeHandle);
    380 }
    381 
    382 EFI_STATUS
    383 EFIAPI
    384 PeiLibFfsFindNextFile (
    385   IN EFI_FV_FILETYPE            SearchType,
    386   IN EFI_PEI_FV_HANDLE          FvHandle,
    387   IN OUT EFI_PEI_FILE_HANDLE    *FileHandle
    388   )
    389 /*++
    390 
    391 Routine Description:
    392 
    393   The wrapper of Pei Core Service function FfsFindNextFile.
    394 
    395 Arguments:
    396 
    397   SearchType   - Filter to find only file of this type.
    398   FvHandle     - Pointer to the current FV to search.
    399   FileHandle   - Pointer to the file matching SearchType in FwVolHeader.
    400                - NULL if file not found
    401 
    402 Returns:
    403   EFI_STATUS
    404 
    405 --*/
    406 {
    407   EFI_PEI_SERVICES  **PeiServices;
    408 
    409   PeiServices = GetPeiServicesTablePointer();
    410   return (*PeiServices)->FfsFindNextFile (PeiServices, SearchType, FvHandle, FileHandle);
    411 }
    412 
    413 
    414 EFI_STATUS
    415 EFIAPI
    416 PeiLibFfsFindFileByName (
    417   IN  EFI_GUID              *FileName,
    418   IN  EFI_PEI_FV_HANDLE     VolumeHandle,
    419   OUT EFI_PEI_FILE_HANDLE   *FileHandle
    420   )
    421 /*++
    422 
    423 Routine Description:
    424 
    425   The wrapper of Pei Core Service function FfsFindFileByName.
    426 
    427 Arguments:
    428 
    429   FileName      - File name to search.
    430   VolumeHandle  - The current FV to search.
    431   FileHandle    - Pointer to the file matching name in VolumeHandle.
    432                 - NULL if file not found
    433 
    434 Returns:
    435    EFI_STATUS
    436 
    437 --*/
    438 {
    439   EFI_PEI_SERVICES  **PeiServices;
    440 
    441   PeiServices = GetPeiServicesTablePointer();
    442   return (*PeiServices)->FfsFindFileByName (FileName, VolumeHandle, FileHandle);
    443 }
    444 
    445 
    446 
    447 EFI_STATUS
    448 EFIAPI
    449 PeiLibFfsFindSectionData (
    450   IN EFI_SECTION_TYPE           SectionType,
    451   IN EFI_FFS_FILE_HEADER        *FfsFileHeader,
    452   IN OUT VOID                   **SectionData
    453   )
    454 /*++
    455 
    456 Routine Description:
    457 
    458   The wrapper of Pei Core Service function FfsFindSectionData.
    459 
    460 Arguments:
    461 
    462   SearchType      - Filter to find only sections of this type.
    463   FileHandle      - Pointer to the current file to search.
    464   SectionData     - Pointer to the Section matching SectionType in FfsFileHeader.
    465                   - NULL if section not found
    466 
    467 Returns:
    468   EFI_STATUS
    469 --*/
    470 {
    471   EFI_PEI_SERVICES  **PeiServices;
    472 
    473   PeiServices = GetPeiServicesTablePointer();
    474   return (*PeiServices)->FfsFindSectionData (PeiServices, SectionType, (EFI_PEI_FILE_HANDLE)FfsFileHeader, SectionData);
    475 }
    476 
    477 EFI_STATUS
    478 EFIAPI
    479 PeiLibFfsGetVolumeInfo (
    480   IN EFI_PEI_FV_HANDLE  VolumeHandle,
    481   OUT EFI_FV_INFO       *VolumeInfo
    482   )
    483 /*++
    484 
    485 Routine Description:
    486 
    487   The wrapper of Pei Core Service function FfsGetVolumeInfo.
    488 
    489 Arguments:
    490 
    491   VolumeHandle    - The handle to Fv Volume.
    492   VolumeInfo      - The pointer to volume information.
    493 
    494 Returns:
    495   EFI_STATUS
    496 --*/
    497 {
    498   EFI_PEI_SERVICES  **PeiServices;
    499 
    500   PeiServices = GetPeiServicesTablePointer();
    501   return (*PeiServices)->FfsGetVolumeInfo (VolumeHandle, VolumeInfo);
    502 }
    503 
    504 
    505 
    506 VOID
    507 EFIAPI
    508 BuildFvHob (
    509   IN EFI_PHYSICAL_ADDRESS        BaseAddress,
    510   IN UINT64                      Length
    511   )
    512 /*++
    513 
    514 Routine Description:
    515 
    516   Build FvHob.
    517 
    518 Arguments:
    519 
    520   BaseAddress    - Fv base address.
    521   Length         - Fv Length.
    522 
    523 Returns:
    524   NONE.
    525 --*/
    526 {
    527 
    528   EFI_STATUS               Status;
    529   EFI_HOB_FIRMWARE_VOLUME  *Hob;
    530   EFI_PEI_SERVICES  **PeiServices;
    531 
    532   PeiServices = GetPeiServicesTablePointer();
    533 
    534   //
    535   // Check FV Signature
    536   //
    537   PEI_ASSERT (PeiServices, ((EFI_FIRMWARE_VOLUME_HEADER*)((UINTN)BaseAddress))->Signature == EFI_FVH_SIGNATURE);
    538 
    539 
    540   Status = (*PeiServices)->CreateHob (
    541                              PeiServices,
    542                              EFI_HOB_TYPE_FV,
    543                              sizeof (EFI_HOB_FIRMWARE_VOLUME),
    544                              &Hob
    545                              );
    546   Hob->BaseAddress = BaseAddress;
    547   Hob->Length      = Length;
    548 }
    549 
    550 VOID
    551 EFIAPI
    552 BuildFvHob2 (
    553   IN EFI_PHYSICAL_ADDRESS        BaseAddress,
    554   IN UINT64                      Length,
    555   IN EFI_GUID                    *FvNameGuid,
    556   IN EFI_GUID                    *FileNameGuid
    557   )
    558 /*++
    559 
    560 Routine Description:
    561 
    562   Build FvHob2.
    563 
    564 Arguments:
    565 
    566   BaseAddress  - Fv base address.
    567   Length       - Fv length.
    568   FvNameGuid   - Fv name.
    569   FileNameGuid - File name which contians encapsulated Fv.
    570 
    571 Returns:
    572    NONE.
    573 --*/
    574 {
    575 
    576   EFI_STATUS               Status;
    577   EFI_HOB_FIRMWARE_VOLUME2  *Hob;
    578   EFI_PEI_SERVICES  **PeiServices;
    579 
    580   PeiServices = GetPeiServicesTablePointer();
    581 
    582   //
    583   // Check FV Signature
    584   //
    585   PEI_ASSERT (PeiServices, ((EFI_FIRMWARE_VOLUME_HEADER*)((UINTN)BaseAddress))->Signature == EFI_FVH_SIGNATURE);
    586 
    587   Status = (*PeiServices)->CreateHob (
    588                              PeiServices,
    589                              EFI_HOB_TYPE_FV2,
    590                              sizeof (EFI_HOB_FIRMWARE_VOLUME2),
    591                              &Hob
    592                              );
    593   Hob->BaseAddress = BaseAddress;
    594   Hob->Length      = Length;
    595   CopyMem ((VOID*)&Hob->FvName, FvNameGuid, sizeof(EFI_GUID));
    596   CopyMem ((VOID*)&Hob->FileName, FileNameGuid, sizeof(EFI_GUID));
    597 }
    598 
    599 EFI_STATUS
    600 EFIAPI
    601 PeiServicesLocatePpi (
    602   IN EFI_GUID                   *Guid,
    603   IN UINTN                      Instance,
    604   IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor,
    605   IN OUT VOID                   **Ppi
    606   )
    607 /*++
    608 
    609 Routine Description:
    610 
    611   The wrapper of Pei Core Service function LocatePpi.
    612 
    613 Arguments:
    614 
    615   Guid          - Pointer to GUID of the PPI.
    616   Instance      - Instance Number to discover.
    617   PpiDescriptor - Pointer to reference the found descriptor. If not NULL,
    618                 returns a pointer to the descriptor (includes flags, etc)
    619   Ppi           - Pointer to reference the found PPI
    620 
    621 Returns:
    622 
    623   Status -  EFI_SUCCESS   if the PPI is in the database
    624             EFI_NOT_FOUND if the PPI is not in the database
    625 --*/
    626 {
    627   EFI_PEI_SERVICES  **PeiServices;
    628 
    629   PeiServices = GetPeiServicesTablePointer();
    630   return (*PeiServices)->LocatePpi (PeiServices, Guid, Instance, PpiDescriptor, Ppi);
    631 }
    632 
    633 
    634 VOID
    635 EFIAPI
    636 BuildGuidDataHob (
    637   IN EFI_GUID                   *Guid,
    638   IN VOID                        *Data,
    639   IN UINTN                       DataLength
    640   )
    641 /*++
    642 
    643 Routine Description:
    644 
    645   Build Guid data Hob.
    646 
    647 Arguments:
    648 
    649   Guid        - guid to build data hob.
    650   Data        - data to build data hob.
    651   DataLength  - the length of data.
    652 
    653 Returns:
    654   NONE
    655 --*/
    656 {
    657   VOID              *HobData;
    658   EFI_HOB_GUID_TYPE *Hob;
    659   EFI_PEI_SERVICES  **PeiServices;
    660 
    661   PeiServices = GetPeiServicesTablePointer();
    662   (*PeiServices)->CreateHob (
    663                      PeiServices,
    664                      EFI_HOB_TYPE_GUID_EXTENSION,
    665                      (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength),
    666                      &Hob
    667                      );
    668   CopyMem ((VOID*)&Hob->Name, (VOID*)Guid, sizeof(EFI_GUID));
    669 
    670   HobData =  Hob + 1;
    671 
    672   CopyMem (HobData, Data, DataLength);
    673 }
    674 
    675 
    676 VOID *
    677 EFIAPI
    678 AllocatePages (
    679   IN UINTN  Pages
    680   )
    681 /*++
    682 
    683 Routine Description:
    684 
    685   Allocate Memory.
    686 
    687 Arguments:
    688 
    689   Pages - Pages to allocate.
    690 
    691 Returns:
    692   = Address if successful to allocate memory.
    693   = NULL    if fail to allocate memory.
    694 
    695 --*/
    696 {
    697   EFI_STATUS            Status;
    698   EFI_PHYSICAL_ADDRESS  Memory;
    699   EFI_PEI_SERVICES      **PeiServices;
    700 
    701   if (Pages == 0) {
    702     return NULL;
    703   }
    704 
    705   PeiServices = GetPeiServicesTablePointer();
    706   Status = (*PeiServices)->AllocatePages (PeiServices, EfiBootServicesData, Pages, &Memory);
    707   if (EFI_ERROR (Status)) {
    708     Memory = 0;
    709   }
    710   return (VOID *) (UINTN) Memory;
    711 
    712 }
    713 
    714 #endif
    715