diff options
Diffstat (limited to 'EDK/Foundation/Library/Pei/PeiLib/PeiLib.c')
-rw-r--r-- | EDK/Foundation/Library/Pei/PeiLib/PeiLib.c | 714 |
1 files changed, 714 insertions, 0 deletions
diff --git a/EDK/Foundation/Library/Pei/PeiLib/PeiLib.c b/EDK/Foundation/Library/Pei/PeiLib/PeiLib.c new file mode 100644 index 0000000..772319f --- /dev/null +++ b/EDK/Foundation/Library/Pei/PeiLib/PeiLib.c @@ -0,0 +1,714 @@ +/*++ + +Copyright (c) 2004 - 2006, Intel Corporation +All rights reserved. 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. + +Module Name: + + PeiLib.c + +Abstract: + + PEI Library Functions + +--*/ + +#include "TianoCommon.h" +#include "PeiHob.h" +#include "Pei.h" +#include "PeiLib.h" +#include "EfiCommonLib.h" + +VOID +PeiCopyMem ( + IN VOID *Destination, + IN VOID *Source, + IN UINTN Length + ); + +VOID +ZeroMem ( + IN VOID *Buffer, + IN UINTN Size + ) +/*++ + +Routine Description: + + Set Buffer to zero for Size bytes. + +Arguments: + + Buffer - Memory to set. + + Size - Number of bytes to set + +Returns: + + None + +--*/ +{ + EfiCommonLibZeroMem (Buffer, Size); +} + +VOID +PeiCopyMem ( + IN VOID *Destination, + IN VOID *Source, + IN UINTN Length + ) +/*++ + +Routine Description: + + Copy Length bytes from Source to Destination. + +Arguments: + + Destination - Target of copy + + Source - Place to copy from + + Length - Number of bytes to copy + +Returns: + + None + +--*/ +{ + EfiCommonLibCopyMem (Destination, Source, Length); +} + +VOID +CopyMem ( + IN VOID *Destination, + IN VOID *Source, + IN UINTN Length + ) +/*++ + +Routine Description: + + Copy Length bytes from Source to Destination. + +Arguments: + + Destination - Target of copy + + Source - Place to copy from + + Length - Number of bytes to copy + +Returns: + + None + +--*/ +{ + EfiCommonLibCopyMem (Destination, Source, Length); +} + + +BOOLEAN +CompareGuid ( + IN EFI_GUID *Guid1, + IN EFI_GUID *Guid2 + ) +/*++ + +Routine Description: + + Compares two GUIDs + +Arguments: + + Guid1 - guid to compare + Guid2 - guid to compare + +Returns: + = TRUE if Guid1 == Guid2 + = FALSE if Guid1 != Guid2 + +--*/ +{ + if ((((INT32 *) Guid1)[0] - ((INT32 *) Guid2)[0]) == 0) { + if ((((INT32 *) Guid1)[1] - ((INT32 *) Guid2)[1]) == 0) { + if ((((INT32 *) Guid1)[2] - ((INT32 *) Guid2)[2]) == 0) { + if ((((INT32 *) Guid1)[3] - ((INT32 *) Guid2)[3]) == 0) { + return TRUE; + } + } + } + } + + return FALSE; +} + + +EFI_STATUS +EFIAPI +PeiLibPciCfgModify ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_PCI_CFG_PPI *PciCfg, + IN PEI_PCI_CFG_PPI_WIDTH Width, + IN UINT64 Address, + IN UINTN SetBits, + IN UINTN ClearBits + ) +/*++ + +Routine Description: + + PCI read-modify-write operations. + + PIWG's PI specification replaces Inte's EFI Specification 1.10. + EFI_PEI_PCI_CFG_PPI defined in Inte's EFI Specification 1.10 is replaced by + EFI_PEI_PCI_CFG2_PPI in PI 1.0. "Modify" function in these two PPI are not + compatibile with each other. + + + For Framework code that make the following call: + + PciCfg->Modify ( + PeiServices, + PciCfg, + Width, + Address, + SetBits, + ClearBits + ); + it will be updated to the following code which call this library API: + PeiLibPciCfgModify ( + PeiServices, + PciCfg, + Width, + Address, + SetBits, + ClearBits + ); + + The + +Arguments: + + PeiServices An indirect pointer to the PEI Services Table + published by the PEI Foundation. + PciCfg A pointer to the this pointer of EFI_PEI_PCI_CFG_PPI. + This parameter is unused as a place holder to make + the parameter list identical to PEI_PCI_CFG_PPI_RW. + Width The width of the access. Enumerated in bytes. Type + EFI_PEI_PCI_CFG_PPI_WIDTH is defined in Read(). + + Address The physical address of the access. + + SetBits Points to value to bitwise-OR with the read configuration value. + + The size of the value is determined by Width. + + ClearBits Points to the value to negate and bitwise-AND with the read configuration value. + The size of the value is determined by Width. + + +Returns: + + EFI_SUCCESS The function completed successfully. + + EFI_DEVICE_ERROR There was a problem with the transaction. + +--*/ +{ + EFI_STATUS Status; + EFI_PEI_PCI_CFG2_PPI *PciCfg2; + + Status = (*PeiServices)->LocatePpi ( + PeiServices, + &gPeiPciCfg2PpiGuid, + 0, + NULL, + (VOID **) &PciCfg2 + ); + ASSERT_PEI_ERROR (PeiServices, Status); + + Status = PciCfg2->Modify ( + (CONST EFI_PEI_SERVICES **) PeiServices, + PciCfg2, + (EFI_PEI_PCI_CFG_PPI_WIDTH) Width, + Address, + &SetBits, + &ClearBits + ); + + return Status; +} + +//;;## ...AMI_OVERRIDE... Support PI1.x +#if (PI_SPECIFICATION_VERSION >= 0x00010000) + +VOID * +EFIAPI +ScanGuid ( + IN VOID *Buffer, + IN UINTN Length, + IN EFI_GUID *Guid + ) +/*++ + +Routine Description: + + Scans a target buffer for a GUID, and returns a pointer to the matching GUID + in the target buffer. + + This function searches target the buffer specified by Buffer and Length from + the lowest address to the highest address at 128-bit increments for the 128-bit + GUID value that matches Guid. If a match is found, then a pointer to the matching + GUID in the target buffer is returned. If no match is found, then NULL is returned. + If Length is 0, then NULL is returned. + If Length > 0 and Buffer is NULL, then ASSERT(). + If Buffer is not aligned on a 32-bit boundary, then ASSERT(). + If Length is not aligned on a 128-bit boundary, then ASSERT(). + If Length is greater than (EFI_MAX_ADDRESS ?Buffer + 1), then ASSERT(). + +Arguments: + + Buffer - Pointer to the target buffer to scan. + Length - Number of bytes in Buffer to scan. + Guid - Value to search for in the target buffer. + +Returns: + A pointer to the matching Guid in the target buffer or NULL otherwise. + +--*/ +{ + EFI_GUID *GuidPtr; + EFI_PEI_SERVICES **PeiServices; + + PeiServices = GetPeiServicesTablePointer(); + PEI_ASSERT(PeiServices, (((UINTN)Buffer & (sizeof (Guid->Data1) - 1)) == 0)); + PEI_ASSERT(PeiServices, (Length <= (EFI_MAX_ADDRESS - (UINTN)Buffer + 1))); + PEI_ASSERT(PeiServices, ((Length & (sizeof (*GuidPtr) - 1)) == 0)); + + GuidPtr = (EFI_GUID*)Buffer; + Buffer = GuidPtr + Length / sizeof (*GuidPtr); + while (GuidPtr < (EFI_GUID*)Buffer) { + if (CompareGuid (GuidPtr, Guid)) { + return (VOID*)GuidPtr; + } + GuidPtr++; + } + return NULL; +} + + +VOID * +EFIAPI +InvalidateInstructionCacheRange ( + IN VOID *Address, + IN UINTN Length + ) +/*++ + +Routine Description: + + Invalidates a range of instruction cache lines in the cache coherency domain + of the calling CPU. + + Invalidates the instruction cache lines specified by Address and Length. If + Address is not aligned on a cache line boundary, then entire instruction + cache line containing Address is invalidated. If Address + Length is not + aligned on a cache line boundary, then the entire instruction cache line + containing Address + Length -1 is invalidated. This function may choose to + invalidate the entire instruction cache if that is more efficient than + invalidating the specified range. If Length is 0, the no instruction cache + lines are invalidated. Address is returned. + + If Length is greater than (EFI_MAX_ADDRESS - Address + 1), then ASSERT(). + +Arguments: + + Address - The base address of the instruction cache lines to + invalidate. If the CPU is in a physical addressing mode, then + Address is a physical address. If the CPU is in a virtual + addressing mode, then Address is a virtual address. + + Length - The number of bytes to invalidate from the instruction cache. + + Returns: + Address + +**/ +{ + PEI_ASSERT(GetPeiServicesTablePointer() , (Length <= EFI_MAX_ADDRESS - (UINTN)Address + 1)); + return Address; +} + + +EFI_STATUS +EFIAPI +PeiLibFfsFindNextVolume ( + IN UINTN Instance, + IN OUT EFI_PEI_FV_HANDLE *VolumeHandle + ) +/*++ + +Routine Description: + + The wrapper of Pei Core Service function FfsFindNextVolume. + +Arguments: + + Instance - The Fv Volume Instance. + VolumeHandle - Pointer to the current Fv Volume to search. + +Returns: + EFI_STATUS + +--*/ + +{ + EFI_PEI_SERVICES **PeiServices; + + PeiServices = GetPeiServicesTablePointer(); + return (*PeiServices)->FfsFindNextVolume (PeiServices, Instance, VolumeHandle); +} + +EFI_STATUS +EFIAPI +PeiLibFfsFindNextFile ( + IN EFI_FV_FILETYPE SearchType, + IN EFI_PEI_FV_HANDLE FvHandle, + IN OUT EFI_PEI_FILE_HANDLE *FileHandle + ) +/*++ + +Routine Description: + + The wrapper of Pei Core Service function FfsFindNextFile. + +Arguments: + + SearchType - Filter to find only file of this type. + FvHandle - Pointer to the current FV to search. + FileHandle - Pointer to the file matching SearchType in FwVolHeader. + - NULL if file not found + +Returns: + EFI_STATUS + +--*/ +{ + EFI_PEI_SERVICES **PeiServices; + + PeiServices = GetPeiServicesTablePointer(); + return (*PeiServices)->FfsFindNextFile (PeiServices, SearchType, FvHandle, FileHandle); +} + + +EFI_STATUS +EFIAPI +PeiLibFfsFindFileByName ( + IN EFI_GUID *FileName, + IN EFI_PEI_FV_HANDLE VolumeHandle, + OUT EFI_PEI_FILE_HANDLE *FileHandle + ) +/*++ + +Routine Description: + + The wrapper of Pei Core Service function FfsFindFileByName. + +Arguments: + + FileName - File name to search. + VolumeHandle - The current FV to search. + FileHandle - Pointer to the file matching name in VolumeHandle. + - NULL if file not found + +Returns: + EFI_STATUS + +--*/ +{ + EFI_PEI_SERVICES **PeiServices; + + PeiServices = GetPeiServicesTablePointer(); + return (*PeiServices)->FfsFindFileByName (FileName, VolumeHandle, FileHandle); +} + + + +EFI_STATUS +EFIAPI +PeiLibFfsFindSectionData ( + IN EFI_SECTION_TYPE SectionType, + IN EFI_FFS_FILE_HEADER *FfsFileHeader, + IN OUT VOID **SectionData + ) +/*++ + +Routine Description: + + The wrapper of Pei Core Service function FfsFindSectionData. + +Arguments: + + SearchType - Filter to find only sections of this type. + FileHandle - Pointer to the current file to search. + SectionData - Pointer to the Section matching SectionType in FfsFileHeader. + - NULL if section not found + +Returns: + EFI_STATUS +--*/ +{ + EFI_PEI_SERVICES **PeiServices; + + PeiServices = GetPeiServicesTablePointer(); + return (*PeiServices)->FfsFindSectionData (PeiServices, SectionType, (EFI_PEI_FILE_HANDLE)FfsFileHeader, SectionData); +} + +EFI_STATUS +EFIAPI +PeiLibFfsGetVolumeInfo ( + IN EFI_PEI_FV_HANDLE VolumeHandle, + OUT EFI_FV_INFO *VolumeInfo + ) +/*++ + +Routine Description: + + The wrapper of Pei Core Service function FfsGetVolumeInfo. + +Arguments: + + VolumeHandle - The handle to Fv Volume. + VolumeInfo - The pointer to volume information. + +Returns: + EFI_STATUS +--*/ +{ + EFI_PEI_SERVICES **PeiServices; + + PeiServices = GetPeiServicesTablePointer(); + return (*PeiServices)->FfsGetVolumeInfo (VolumeHandle, VolumeInfo); +} + + + +VOID +EFIAPI +BuildFvHob ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length + ) +/*++ + +Routine Description: + + Build FvHob. + +Arguments: + + BaseAddress - Fv base address. + Length - Fv Length. + +Returns: + NONE. +--*/ +{ + + EFI_STATUS Status; + EFI_HOB_FIRMWARE_VOLUME *Hob; + EFI_PEI_SERVICES **PeiServices; + + PeiServices = GetPeiServicesTablePointer(); + + // + // Check FV Signature + // + PEI_ASSERT (PeiServices, ((EFI_FIRMWARE_VOLUME_HEADER*)((UINTN)BaseAddress))->Signature == EFI_FVH_SIGNATURE); + + + Status = (*PeiServices)->CreateHob ( + PeiServices, + EFI_HOB_TYPE_FV, + sizeof (EFI_HOB_FIRMWARE_VOLUME), + &Hob + ); + Hob->BaseAddress = BaseAddress; + Hob->Length = Length; +} + +VOID +EFIAPI +BuildFvHob2 ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN EFI_GUID *FvNameGuid, + IN EFI_GUID *FileNameGuid + ) +/*++ + +Routine Description: + + Build FvHob2. + +Arguments: + + BaseAddress - Fv base address. + Length - Fv length. + FvNameGuid - Fv name. + FileNameGuid - File name which contians encapsulated Fv. + +Returns: + NONE. +--*/ +{ + + EFI_STATUS Status; + EFI_HOB_FIRMWARE_VOLUME2 *Hob; + EFI_PEI_SERVICES **PeiServices; + + PeiServices = GetPeiServicesTablePointer(); + + // + // Check FV Signature + // + PEI_ASSERT (PeiServices, ((EFI_FIRMWARE_VOLUME_HEADER*)((UINTN)BaseAddress))->Signature == EFI_FVH_SIGNATURE); + + Status = (*PeiServices)->CreateHob ( + PeiServices, + EFI_HOB_TYPE_FV2, + sizeof (EFI_HOB_FIRMWARE_VOLUME2), + &Hob + ); + Hob->BaseAddress = BaseAddress; + Hob->Length = Length; + CopyMem ((VOID*)&Hob->FvName, FvNameGuid, sizeof(EFI_GUID)); + CopyMem ((VOID*)&Hob->FileName, FileNameGuid, sizeof(EFI_GUID)); +} + +EFI_STATUS +EFIAPI +PeiServicesLocatePpi ( + IN EFI_GUID *Guid, + IN UINTN Instance, + IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, + IN OUT VOID **Ppi + ) +/*++ + +Routine Description: + + The wrapper of Pei Core Service function LocatePpi. + +Arguments: + + Guid - Pointer to GUID of the PPI. + Instance - Instance Number to discover. + PpiDescriptor - Pointer to reference the found descriptor. If not NULL, + returns a pointer to the descriptor (includes flags, etc) + Ppi - Pointer to reference the found PPI + +Returns: + + Status - EFI_SUCCESS if the PPI is in the database + EFI_NOT_FOUND if the PPI is not in the database +--*/ +{ + EFI_PEI_SERVICES **PeiServices; + + PeiServices = GetPeiServicesTablePointer(); + return (*PeiServices)->LocatePpi (PeiServices, Guid, Instance, PpiDescriptor, Ppi); +} + + +VOID +EFIAPI +BuildGuidDataHob ( + IN EFI_GUID *Guid, + IN VOID *Data, + IN UINTN DataLength + ) +/*++ + +Routine Description: + + Build Guid data Hob. + +Arguments: + + Guid - guid to build data hob. + Data - data to build data hob. + DataLength - the length of data. + +Returns: + NONE +--*/ +{ + VOID *HobData; + EFI_HOB_GUID_TYPE *Hob; + EFI_PEI_SERVICES **PeiServices; + + PeiServices = GetPeiServicesTablePointer(); + (*PeiServices)->CreateHob ( + PeiServices, + EFI_HOB_TYPE_GUID_EXTENSION, + (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength), + &Hob + ); + CopyMem ((VOID*)&Hob->Name, (VOID*)Guid, sizeof(EFI_GUID)); + + HobData = Hob + 1; + + CopyMem (HobData, Data, DataLength); +} + + +VOID * +EFIAPI +AllocatePages ( + IN UINTN Pages + ) +/*++ + +Routine Description: + + Allocate Memory. + +Arguments: + + Pages - Pages to allocate. + +Returns: + = Address if successful to allocate memory. + = NULL if fail to allocate memory. + +--*/ +{ + EFI_STATUS Status; + EFI_PHYSICAL_ADDRESS Memory; + EFI_PEI_SERVICES **PeiServices; + + if (Pages == 0) { + return NULL; + } + + PeiServices = GetPeiServicesTablePointer(); + Status = (*PeiServices)->AllocatePages (PeiServices, EfiBootServicesData, Pages, &Memory); + if (EFI_ERROR (Status)) { + Memory = 0; + } + return (VOID *) (UINTN) Memory; + +} + +#endif |