2008-03-19 10:01:03 +01:00
/** @file
2008-07-16 11:40:06 +02:00
Pei Core Firmware File System service routines .
2010-04-24 11:49:11 +02:00
Copyright ( c ) 2006 - 2010 , Intel Corporation . All rights reserved . < BR >
This program and the accompanying materials
2007-07-04 09:51:48 +02:00
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 .
2008-03-19 10:01:03 +01:00
* */
2007-07-04 09:51:48 +02:00
2009-11-11 04:27:39 +01:00
# include "FwVol.h"
2007-07-04 09:51:48 +02:00
2008-10-30 07:05:06 +01:00
EFI_PEI_NOTIFY_DESCRIPTOR mNotifyOnFvInfoList = {
2007-09-24 13:38:43 +02:00
( EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST ) ,
& gEfiPeiFirmwareVolumeInfoPpiGuid ,
FirmwareVolmeInfoPpiNotifyCallback
} ;
2009-11-11 04:27:39 +01:00
EFI_PEI_FIRMWARE_VOLUME_PPI mPeiFfs2FvPpi = {
PeiFfs2FvPpiProcessVolume ,
PeiFfs2FvPpiFindFileByType ,
PeiFfs2FvPpiFindFileByName ,
PeiFfs2FvPpiGetFileInfo ,
PeiFfs2FvPpiGetVolumeInfo ,
PeiFfs2FvPpiFindSectionByType
} ;
EFI_PEI_PPI_DESCRIPTOR mPeiFfs2FvPpiList = {
( EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST ) ,
& gEfiFirmwareFileSystem2Guid ,
& mPeiFfs2FvPpi
} ;
2008-07-16 11:40:06 +02:00
/**
2008-08-08 05:33:16 +02:00
Returns the file state set by the highest zero bit in the State field
2007-07-04 09:51:48 +02:00
2008-07-16 11:40:06 +02:00
@ param ErasePolarity Erase Polarity as defined by EFI_FVB2_ERASE_POLARITY
in the Attributes field .
@ param FfsHeader Pointer to FFS File Header .
2007-07-04 09:51:48 +02:00
2008-08-08 05:33:16 +02:00
@ retval EFI_FFS_FILE_STATE File state is set by the highest none zero bit
in the header State field .
2008-07-16 11:40:06 +02:00
* */
EFI_FFS_FILE_STATE
GetFileState (
IN UINT8 ErasePolarity ,
IN EFI_FFS_FILE_HEADER * FfsHeader
)
2007-07-04 09:51:48 +02:00
{
EFI_FFS_FILE_STATE FileState ;
EFI_FFS_FILE_STATE HighestBit ;
FileState = FfsHeader - > State ;
if ( ErasePolarity ! = 0 ) {
FileState = ( EFI_FFS_FILE_STATE ) ~ FileState ;
}
2008-08-08 05:33:16 +02:00
//
// Get file state set by its highest none zero bit.
//
2007-07-04 09:51:48 +02:00
HighestBit = 0x80 ;
while ( HighestBit ! = 0 & & ( HighestBit & FileState ) = = 0 ) {
HighestBit > > = 1 ;
}
return HighestBit ;
}
2008-07-16 11:40:06 +02:00
/**
Calculates the checksum of the header of a file .
@ param FileHeader Pointer to FFS File Header .
@ return Checksum of the header .
Zero means the header is good .
Non - zero means the header is bad .
* */
2007-07-04 09:51:48 +02:00
UINT8
CalculateHeaderChecksum (
IN EFI_FFS_FILE_HEADER * FileHeader
)
{
2008-08-08 05:33:16 +02:00
EFI_FFS_FILE_HEADER TestFileHeader ;
2007-07-04 09:51:48 +02:00
2008-08-08 05:33:16 +02:00
CopyMem ( & TestFileHeader , FileHeader , sizeof ( EFI_FFS_FILE_HEADER ) ) ;
2007-07-04 09:51:48 +02:00
//
2008-08-08 05:33:16 +02:00
// Ingore State and File field in FFS header.
2007-07-04 09:51:48 +02:00
//
2008-08-08 05:33:16 +02:00
TestFileHeader . State = 0 ;
TestFileHeader . IntegrityCheck . Checksum . File = 0 ;
2007-07-04 09:51:48 +02:00
2008-08-08 05:33:16 +02:00
return CalculateSum8 ( ( CONST UINT8 * ) & TestFileHeader , sizeof ( EFI_FFS_FILE_HEADER ) ) ;
2007-07-04 09:51:48 +02:00
}
2008-07-16 11:40:06 +02:00
/**
2009-11-11 04:27:39 +01:00
Find FV handler according to FileHandle in that FV .
2008-07-16 11:40:06 +02:00
@ param FileHandle Handle of file image
2009-11-11 04:27:39 +01:00
@ return Pointer to instance of PEI_CORE_FV_HANDLE .
2008-07-16 11:40:06 +02:00
* */
2009-11-11 04:27:39 +01:00
PEI_CORE_FV_HANDLE *
FileHandleToVolume (
IN EFI_PEI_FILE_HANDLE FileHandle
2007-09-24 13:38:43 +02:00
)
{
UINTN Index ;
PEI_CORE_INSTANCE * PrivateData ;
EFI_FIRMWARE_VOLUME_HEADER * FwVolHeader ;
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS ( GetPeiServicesTablePointer ( ) ) ;
2009-11-11 04:27:39 +01:00
2007-09-24 13:38:43 +02:00
for ( Index = 0 ; Index < PrivateData - > FvCount ; Index + + ) {
FwVolHeader = PrivateData - > Fv [ Index ] . FvHeader ;
2007-10-09 11:30:52 +02:00
if ( ( ( UINT64 ) ( UINTN ) FileHandle > ( UINT64 ) ( UINTN ) FwVolHeader ) & & \
( ( UINT64 ) ( UINTN ) FileHandle < = ( ( UINT64 ) ( UINTN ) FwVolHeader + FwVolHeader - > FvLength - 1 ) ) ) {
2009-11-11 04:27:39 +01:00
return & PrivateData - > Fv [ Index ] ;
2007-09-24 13:38:43 +02:00
}
}
2009-11-11 04:27:39 +01:00
return NULL ;
2007-09-24 13:38:43 +02:00
}
2008-07-16 11:40:06 +02:00
/**
2008-08-08 05:33:16 +02:00
Given the input file pointer , search for the first matching file in the
2008-07-16 11:40:06 +02:00
FFS volume as defined by SearchType . The search starts from FileHeader inside
the Firmware Volume defined by FwVolHeader .
2008-08-08 05:33:16 +02:00
If SearchType is EFI_FV_FILETYPE_ALL , the first FFS file will return without check its file type .
If SearchType is PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE ,
the first PEIM , or COMBINED PEIM or FV file type FFS file will return .
2008-07-16 11:40:06 +02:00
@ param FvHandle Pointer to the FV header of the volume to search
@ param FileName File name
@ param SearchType Filter to find only files of this type .
Type EFI_FV_FILETYPE_ALL causes no filtering to be done .
@ param FileHandle This parameter must point to a valid FFS volume .
@ param AprioriFile Pointer to AprioriFile image in this FV if has
2007-09-24 13:38:43 +02:00
2008-07-16 11:40:06 +02:00
@ return EFI_NOT_FOUND No files matching the search criteria were found
@ retval EFI_SUCCESS Success to search given file
* */
2007-07-04 09:51:48 +02:00
EFI_STATUS
2009-11-11 04:27:39 +01:00
FindFileEx (
2007-09-24 13:38:43 +02:00
IN CONST EFI_PEI_FV_HANDLE FvHandle ,
IN CONST EFI_GUID * FileName , OPTIONAL
IN EFI_FV_FILETYPE SearchType ,
IN OUT EFI_PEI_FILE_HANDLE * FileHandle ,
IN OUT EFI_PEI_FV_HANDLE * AprioriFile OPTIONAL
2007-07-04 09:51:48 +02:00
)
{
2007-09-24 13:38:43 +02:00
EFI_FIRMWARE_VOLUME_HEADER * FwVolHeader ;
EFI_FFS_FILE_HEADER * * FileHeader ;
EFI_FFS_FILE_HEADER * FfsFileHeader ;
UINT32 FileLength ;
UINT32 FileOccupiedSize ;
UINT32 FileOffset ;
UINT64 FvLength ;
UINT8 ErasePolarity ;
UINT8 FileState ;
2009-11-11 04:27:39 +01:00
//
// Convert the handle of FV to FV header for memory-mapped firmware volume
//
FwVolHeader = ( EFI_FIRMWARE_VOLUME_HEADER * ) FvHandle ;
2007-09-24 13:38:43 +02:00
FileHeader = ( EFI_FFS_FILE_HEADER * * ) FileHandle ;
2007-07-04 09:51:48 +02:00
FvLength = FwVolHeader - > FvLength ;
2008-10-20 15:33:43 +02:00
if ( ( FwVolHeader - > Attributes & EFI_FVB2_ERASE_POLARITY ) ! = 0 ) {
2007-07-04 09:51:48 +02:00
ErasePolarity = 1 ;
} else {
ErasePolarity = 0 ;
}
//
2007-09-24 13:38:43 +02:00
// If FileHeader is not specified (NULL) or FileName is not NULL,
// start with the first file in the firmware volume. Otherwise,
// start from the FileHeader.
2007-07-04 09:51:48 +02:00
//
2007-09-24 13:38:43 +02:00
if ( ( * FileHeader = = NULL ) | | ( FileName ! = NULL ) ) {
2007-07-04 09:51:48 +02:00
FfsFileHeader = ( EFI_FFS_FILE_HEADER * ) ( ( UINT8 * ) FwVolHeader + FwVolHeader - > HeaderLength ) ;
} else {
//
// Length is 24 bits wide so mask upper 8 bits
// FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
//
FileLength = * ( UINT32 * ) ( * FileHeader ) - > Size & 0x00FFFFFF ;
2007-09-24 13:38:43 +02:00
FileOccupiedSize = GET_OCCUPIED_SIZE ( FileLength , 8 ) ;
2007-07-04 09:51:48 +02:00
FfsFileHeader = ( EFI_FFS_FILE_HEADER * ) ( ( UINT8 * ) * FileHeader + FileOccupiedSize ) ;
}
2007-10-31 12:46:42 +01:00
2007-07-04 09:51:48 +02:00
FileOffset = ( UINT32 ) ( ( UINT8 * ) FfsFileHeader - ( UINT8 * ) FwVolHeader ) ;
ASSERT ( FileOffset < = 0xFFFFFFFF ) ;
2007-10-31 12:46:42 +01:00
2007-09-24 13:38:43 +02:00
while ( FileOffset < ( FvLength - sizeof ( EFI_FFS_FILE_HEADER ) ) ) {
2007-07-04 09:51:48 +02:00
//
// Get FileState which is the highest bit of the State
//
FileState = GetFileState ( ErasePolarity , FfsFileHeader ) ;
switch ( FileState ) {
case EFI_FILE_HEADER_INVALID :
2008-07-23 11:15:14 +02:00
FileOffset + = sizeof ( EFI_FFS_FILE_HEADER ) ;
FfsFileHeader = ( EFI_FFS_FILE_HEADER * ) ( ( UINT8 * ) FfsFileHeader + sizeof ( EFI_FFS_FILE_HEADER ) ) ;
2007-07-04 09:51:48 +02:00
break ;
case EFI_FILE_DATA_VALID :
case EFI_FILE_MARKED_FOR_UPDATE :
2007-09-24 13:38:43 +02:00
if ( CalculateHeaderChecksum ( FfsFileHeader ) ! = 0 ) {
2007-07-04 09:51:48 +02:00
ASSERT ( FALSE ) ;
2007-10-31 12:46:42 +01:00
* FileHeader = NULL ;
2007-07-04 09:51:48 +02:00
return EFI_NOT_FOUND ;
}
2007-09-24 13:38:43 +02:00
2008-07-23 11:15:14 +02:00
FileLength = * ( UINT32 * ) ( FfsFileHeader - > Size ) & 0x00FFFFFF ;
2007-09-24 13:38:43 +02:00
FileOccupiedSize = GET_OCCUPIED_SIZE ( FileLength , 8 ) ;
if ( FileName ! = NULL ) {
if ( CompareGuid ( & FfsFileHeader - > Name , ( EFI_GUID * ) FileName ) ) {
* FileHeader = FfsFileHeader ;
return EFI_SUCCESS ;
}
} else if ( SearchType = = PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE ) {
if ( ( FfsFileHeader - > Type = = EFI_FV_FILETYPE_PEIM ) | |
2007-12-06 10:52:27 +01:00
( FfsFileHeader - > Type = = EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER ) | |
( FfsFileHeader - > Type = = EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE ) ) {
2007-09-24 13:38:43 +02:00
* FileHeader = FfsFileHeader ;
return EFI_SUCCESS ;
} else if ( AprioriFile ! = NULL ) {
if ( FfsFileHeader - > Type = = EFI_FV_FILETYPE_FREEFORM ) {
if ( CompareGuid ( & FfsFileHeader - > Name , & gPeiAprioriFileNameGuid ) ) {
* AprioriFile = FfsFileHeader ;
}
}
}
2007-11-19 09:02:39 +01:00
} else if ( ( ( SearchType = = FfsFileHeader - > Type ) | | ( SearchType = = EFI_FV_FILETYPE_ALL ) ) & &
( FfsFileHeader - > Type ! = EFI_FV_FILETYPE_FFS_PAD ) ) {
2007-09-24 13:38:43 +02:00
* FileHeader = FfsFileHeader ;
return EFI_SUCCESS ;
}
2008-07-23 11:15:14 +02:00
FileOffset + = FileOccupiedSize ;
FfsFileHeader = ( EFI_FFS_FILE_HEADER * ) ( ( UINT8 * ) FfsFileHeader + FileOccupiedSize ) ;
2007-07-04 09:51:48 +02:00
break ;
case EFI_FILE_DELETED :
2008-07-23 11:15:14 +02:00
FileLength = * ( UINT32 * ) ( FfsFileHeader - > Size ) & 0x00FFFFFF ;
FileOccupiedSize = GET_OCCUPIED_SIZE ( FileLength , 8 ) ;
FileOffset + = FileOccupiedSize ;
FfsFileHeader = ( EFI_FFS_FILE_HEADER * ) ( ( UINT8 * ) FfsFileHeader + FileOccupiedSize ) ;
2007-07-04 09:51:48 +02:00
break ;
default :
2007-10-31 12:46:42 +01:00
* FileHeader = NULL ;
2007-07-04 09:51:48 +02:00
return EFI_NOT_FOUND ;
}
}
2007-10-31 12:46:42 +01:00
* FileHeader = NULL ;
2007-07-04 09:51:48 +02:00
return EFI_NOT_FOUND ;
}
2008-07-16 11:40:06 +02:00
/**
Initialize PeiCore Fv List .
@ param PrivateData - Pointer to PEI_CORE_INSTANCE .
@ param SecCoreData - Pointer to EFI_SEC_PEI_HAND_OFF .
* */
2007-09-24 13:38:43 +02:00
VOID
PeiInitializeFv (
IN PEI_CORE_INSTANCE * PrivateData ,
IN CONST EFI_SEC_PEI_HAND_OFF * SecCoreData
)
{
2009-11-11 04:27:39 +01:00
EFI_STATUS Status ;
EFI_PEI_FIRMWARE_VOLUME_PPI * FvPpi ;
EFI_PEI_FV_HANDLE FvHandle ;
EFI_FIRMWARE_VOLUME_HEADER * BfvHeader ;
2007-09-24 13:38:43 +02:00
//
2009-11-11 04:27:39 +01:00
// Install FV_PPI for FFS2 file system.
2007-09-24 13:38:43 +02:00
//
2009-11-11 04:27:39 +01:00
PeiServicesInstallPpi ( & mPeiFfs2FvPpiList ) ;
BfvHeader = ( EFI_FIRMWARE_VOLUME_HEADER * ) SecCoreData - > BootFirmwareVolumeBase ;
//
// The FV_PPI in BFV's format should be installed.
//
Status = PeiServicesLocatePpi (
& BfvHeader - > FileSystemGuid ,
0 ,
NULL ,
( VOID * * ) & FvPpi
) ;
ASSERT_EFI_ERROR ( Status ) ;
//
// Get handle of BFV
//
FvPpi - > ProcessVolume (
FvPpi ,
SecCoreData - > BootFirmwareVolumeBase ,
( UINTN ) BfvHeader - > FvLength ,
& FvHandle
) ;
2009-12-03 06:41:05 +01:00
//
// Update internal PEI_CORE_FV array.
//
PrivateData - > Fv [ PrivateData - > FvCount ] . FvHeader = BfvHeader ;
PrivateData - > Fv [ PrivateData - > FvCount ] . FvPpi = FvPpi ;
PrivateData - > Fv [ PrivateData - > FvCount ] . FvHandle = FvHandle ;
DEBUG ( (
EFI_D_INFO ,
" The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p \n " ,
( UINT32 ) PrivateData - > FvCount ,
( VOID * ) BfvHeader ,
BfvHeader - > FvLength ,
FvHandle
) ) ;
PrivateData - > FvCount + + ;
2007-09-24 13:38:43 +02:00
//
// Post a call-back for the FvInfoPPI services to expose
// additional Fvs to PeiCore.
//
Status = PeiServicesNotifyPpi ( & mNotifyOnFvInfoList ) ;
ASSERT_EFI_ERROR ( Status ) ;
}
2009-11-11 04:27:39 +01:00
2008-07-16 11:40:06 +02:00
/**
Process Firmware Volum Information once FvInfoPPI install .
2008-08-08 05:33:16 +02:00
The FV Info will be registered into PeiCore private data structure .
And search the inside FV image , if found , the new FV INFO PPI will be installed .
2008-07-16 11:40:06 +02:00
2008-08-08 05:33:16 +02:00
@ param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
2008-08-08 05:05:03 +02:00
@ param NotifyDescriptor Address of the notification descriptor data structure .
@ param Ppi Address of the PPI that was installed .
2008-07-16 11:40:06 +02:00
2008-08-08 05:33:16 +02:00
@ retval EFI_SUCCESS The FV Info is registered into PeiCore private data structure .
2008-09-03 08:25:35 +02:00
@ return if not EFI_SUCESS , fail to verify FV .
2008-07-16 11:40:06 +02:00
* */
2007-09-24 13:38:43 +02:00
EFI_STATUS
EFIAPI
FirmwareVolmeInfoPpiNotifyCallback (
IN EFI_PEI_SERVICES * * PeiServices ,
IN EFI_PEI_NOTIFY_DESCRIPTOR * NotifyDescriptor ,
IN VOID * Ppi
)
{
2009-11-11 04:27:39 +01:00
EFI_PEI_FIRMWARE_VOLUME_INFO_PPI * FvInfoPpi ;
EFI_PEI_FIRMWARE_VOLUME_PPI * FvPpi ;
2007-09-24 13:38:43 +02:00
PEI_CORE_INSTANCE * PrivateData ;
2007-12-06 10:52:27 +01:00
EFI_STATUS Status ;
2009-11-11 04:27:39 +01:00
EFI_PEI_FV_HANDLE FvHandle ;
UINTN FvIndex ;
2009-12-03 06:41:05 +01:00
EFI_PEI_FILE_HANDLE FileHandle ;
VOID * DepexData ;
2007-09-24 13:38:43 +02:00
2007-12-06 10:52:27 +01:00
Status = EFI_SUCCESS ;
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS ( PeiServices ) ;
2007-09-24 13:38:43 +02:00
2010-02-11 03:33:16 +01:00
if ( PrivateData - > FvCount > = FixedPcdGet32 ( PcdPeiCoreMaxFvSupported ) ) {
DEBUG ( ( EFI_D_ERROR , " The number of Fv Images (%d) exceed the max supported FVs (%d) in Pei " , PrivateData - > FvCount + 1 , FixedPcdGet32 ( PcdPeiCoreMaxFvSupported ) ) ) ;
2009-03-05 06:05:57 +01:00
DEBUG ( ( EFI_D_ERROR , " PcdPeiCoreMaxFvSupported value need be reconfigurated in DSC " ) ) ;
2007-09-24 13:38:43 +02:00
ASSERT ( FALSE ) ;
}
2009-11-11 04:27:39 +01:00
FvInfoPpi = ( EFI_PEI_FIRMWARE_VOLUME_INFO_PPI * ) Ppi ;
2007-09-24 13:38:43 +02:00
2009-03-05 06:05:57 +01:00
//
2009-11-11 04:27:39 +01:00
// Locate the corresponding FV_PPI according to founded FV's format guid
2009-03-05 06:05:57 +01:00
//
2009-11-11 04:27:39 +01:00
Status = PeiServicesLocatePpi (
& FvInfoPpi - > FvFormat ,
0 ,
NULL ,
( VOID * * ) & FvPpi
) ;
if ( ! EFI_ERROR ( Status ) ) {
//
// Process new found FV and get FV handle.
//
Status = FvPpi - > ProcessVolume ( FvPpi , FvInfoPpi - > FvInfo , FvInfoPpi - > FvInfoSize , & FvHandle ) ;
if ( EFI_ERROR ( Status ) ) {
2009-12-03 06:41:05 +01:00
DEBUG ( ( EFI_D_ERROR , " Fail to process new found FV, FV may be corrupted! \n " ) ) ;
2008-09-03 08:25:35 +02:00
return Status ;
}
2009-12-03 06:41:05 +01:00
//
// Check whether the FV has already been processed.
//
for ( FvIndex = 0 ; FvIndex < PrivateData - > FvCount ; FvIndex + + ) {
if ( PrivateData - > Fv [ FvIndex ] . FvHandle = = FvHandle ) {
DEBUG ( ( EFI_D_INFO , " The Fv %p has already been processed! \n " , FvInfoPpi - > FvInfo ) ) ;
return EFI_SUCCESS ;
}
}
//
// Update internal PEI_CORE_FV array.
//
PrivateData - > Fv [ PrivateData - > FvCount ] . FvHeader = ( EFI_FIRMWARE_VOLUME_HEADER * ) FvInfoPpi - > FvInfo ;
PrivateData - > Fv [ PrivateData - > FvCount ] . FvPpi = FvPpi ;
PrivateData - > Fv [ PrivateData - > FvCount ] . FvHandle = FvHandle ;
DEBUG ( (
EFI_D_INFO ,
" The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p \n " ,
( UINT32 ) PrivateData - > FvCount ,
( VOID * ) FvInfoPpi - > FvInfo ,
FvInfoPpi - > FvInfoSize ,
FvHandle
) ) ;
PrivateData - > FvCount + + ;
//
// Scan and process the new discoveried FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
//
FileHandle = NULL ;
do {
Status = FvPpi - > FindFileByType (
FvPpi ,
EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE ,
FvHandle ,
& FileHandle
) ;
if ( ! EFI_ERROR ( Status ) ) {
Status = FvPpi - > FindSectionByType (
FvPpi ,
EFI_SECTION_PEI_DEPEX ,
FileHandle ,
( VOID * * ) & DepexData
) ;
if ( ! EFI_ERROR ( Status ) ) {
if ( ! PeimDispatchReadiness ( PeiServices , DepexData ) ) {
//
// Dependency is not satisfied.
//
continue ;
}
}
DEBUG ( ( EFI_D_INFO , " Found firmware volume Image File %p in FV[%d] %p \n " , FileHandle , PrivateData - > FvCount - 1 , FvHandle ) ) ;
ProcessFvFile ( & PrivateData - > Fv [ PrivateData - > FvCount - 1 ] , FileHandle ) ;
}
} while ( FileHandle ! = NULL ) ;
2009-11-11 04:27:39 +01:00
} else {
DEBUG ( ( EFI_D_ERROR , " Fail to process FV %p because no corresponding EFI_FIRMWARE_VOLUME_PPI is found! \n " , FvInfoPpi - > FvInfo ) ) ;
2008-09-03 08:25:35 +02:00
2009-12-25 03:28:47 +01:00
AddUnknownFormatFvInfo ( PrivateData , & FvInfoPpi - > FvFormat , FvInfoPpi - > FvInfo , FvInfoPpi - > FvInfoSize ) ;
2007-12-06 10:52:27 +01:00
}
2009-11-11 04:27:39 +01:00
2007-09-24 13:38:43 +02:00
return EFI_SUCCESS ;
}
2008-07-16 11:40:06 +02:00
/**
2008-08-08 05:33:16 +02:00
Go through the file to search SectionType section .
Search within encapsulation sections ( compression and GUIDed ) recursively ,
until the match section is found .
2009-11-11 04:27:39 +01:00
@ param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation .
@ param SectionType Filter to find only section of this type .
@ param Section From where to search .
@ param SectionSize The file size to search .
@ param OutputBuffer A pointer to the discovered section , if successful .
2008-08-08 05:33:16 +02:00
NULL if section not found
2008-07-16 11:40:06 +02:00
2008-08-08 05:33:16 +02:00
@ return EFI_NOT_FOUND The match section is not found .
@ return EFI_SUCCESS The match section is found .
2008-07-16 11:40:06 +02:00
* */
2007-09-24 13:38:43 +02:00
EFI_STATUS
2009-11-11 04:27:39 +01:00
ProcessSection (
2007-09-24 13:38:43 +02:00
IN CONST EFI_PEI_SERVICES * * PeiServices ,
IN EFI_SECTION_TYPE SectionType ,
IN EFI_COMMON_SECTION_HEADER * Section ,
IN UINTN SectionSize ,
2007-12-06 10:52:27 +01:00
OUT VOID * * OutputBuffer
2007-09-24 13:38:43 +02:00
)
{
EFI_STATUS Status ;
UINT32 SectionLength ;
UINT32 ParsedLength ;
EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI * GuidSectionPpi ;
EFI_PEI_DECOMPRESS_PPI * DecompressPpi ;
VOID * PpiOutput ;
UINTN PpiOutputSize ;
2007-12-06 10:52:27 +01:00
UINTN Index ;
UINT32 Authentication ;
PEI_CORE_INSTANCE * PrivateData ;
2007-09-24 13:38:43 +02:00
2007-12-06 10:52:27 +01:00
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS ( PeiServices ) ;
2007-09-24 13:38:43 +02:00
* OutputBuffer = NULL ;
2007-12-06 10:52:27 +01:00
ParsedLength = 0 ;
Index = 0 ;
Status = EFI_NOT_FOUND ;
PpiOutput = NULL ;
PpiOutputSize = 0 ;
2007-09-24 13:38:43 +02:00
while ( ParsedLength < SectionSize ) {
if ( Section - > Type = = SectionType ) {
* OutputBuffer = ( VOID * ) ( Section + 1 ) ;
return EFI_SUCCESS ;
2007-12-06 10:52:27 +01:00
} else if ( ( Section - > Type = = EFI_SECTION_GUID_DEFINED ) | | ( Section - > Type = = EFI_SECTION_COMPRESSION ) ) {
//
// Check the encapsulated section is extracted into the cache data.
//
for ( Index = 0 ; Index < PrivateData - > CacheSection . AllSectionCount ; Index + + ) {
if ( Section = = PrivateData - > CacheSection . Section [ Index ] ) {
PpiOutput = PrivateData - > CacheSection . SectionData [ Index ] ;
PpiOutputSize = PrivateData - > CacheSection . SectionSize [ Index ] ;
//
// Search section directly from the cache data.
//
2009-11-11 04:27:39 +01:00
return ProcessSection (
PeiServices ,
SectionType ,
PpiOutput ,
PpiOutputSize ,
OutputBuffer
) ;
2007-09-24 13:38:43 +02:00
}
}
2007-12-06 10:52:27 +01:00
Status = EFI_NOT_FOUND ;
if ( Section - > Type = = EFI_SECTION_GUID_DEFINED ) {
Status = PeiServicesLocatePpi (
& ( ( EFI_GUID_DEFINED_SECTION * ) Section ) - > SectionDefinitionGuid ,
0 ,
NULL ,
( VOID * * ) & GuidSectionPpi
) ;
2007-09-24 13:38:43 +02:00
if ( ! EFI_ERROR ( Status ) ) {
2007-12-06 10:52:27 +01:00
Status = GuidSectionPpi - > ExtractSection (
2009-11-11 04:27:39 +01:00
GuidSectionPpi ,
Section ,
& PpiOutput ,
& PpiOutputSize ,
& Authentication
) ;
2007-12-06 10:52:27 +01:00
}
} else if ( Section - > Type = = EFI_SECTION_COMPRESSION ) {
Status = PeiServicesLocatePpi ( & gEfiPeiDecompressPpiGuid , 0 , NULL , ( VOID * * ) & DecompressPpi ) ;
if ( ! EFI_ERROR ( Status ) ) {
Status = DecompressPpi - > Decompress (
DecompressPpi ,
( CONST EFI_COMPRESSION_SECTION * ) Section ,
& PpiOutput ,
& PpiOutputSize
) ;
2007-09-24 13:38:43 +02:00
}
}
2007-12-06 10:52:27 +01:00
if ( ! EFI_ERROR ( Status ) ) {
//
// Update cache section data.
//
if ( PrivateData - > CacheSection . AllSectionCount < CACHE_SETION_MAX_NUMBER ) {
PrivateData - > CacheSection . AllSectionCount + + ;
}
PrivateData - > CacheSection . Section [ PrivateData - > CacheSection . SectionIndex ] = Section ;
PrivateData - > CacheSection . SectionData [ PrivateData - > CacheSection . SectionIndex ] = PpiOutput ;
PrivateData - > CacheSection . SectionSize [ PrivateData - > CacheSection . SectionIndex ] = PpiOutputSize ;
PrivateData - > CacheSection . SectionIndex = ( PrivateData - > CacheSection . SectionIndex + 1 ) % CACHE_SETION_MAX_NUMBER ;
2009-11-11 04:27:39 +01:00
return ProcessSection (
PeiServices ,
SectionType ,
PpiOutput ,
PpiOutputSize ,
OutputBuffer
) ;
2007-12-06 10:52:27 +01:00
}
2007-09-24 13:38:43 +02:00
}
//
// Size is 24 bits wide so mask upper 8 bits.
// SectionLength is adjusted it is 4 byte aligned.
// Go to the next section
//
SectionLength = * ( UINT32 * ) Section - > Size & 0x00FFFFFF ;
SectionLength = GET_OCCUPIED_SIZE ( SectionLength , 4 ) ;
ASSERT ( SectionLength ! = 0 ) ;
ParsedLength + = SectionLength ;
Section = ( EFI_COMMON_SECTION_HEADER * ) ( ( UINT8 * ) Section + SectionLength ) ;
}
return EFI_NOT_FOUND ;
}
2007-07-04 09:51:48 +02:00
2008-07-16 11:40:06 +02:00
/**
2009-11-11 04:27:39 +01:00
Searches for the next matching section within the specified file .
2008-07-16 11:40:06 +02:00
2008-08-08 05:33:16 +02:00
@ param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
2008-07-16 11:40:06 +02:00
@ param SectionType Filter to find only sections of this type .
@ param FileHandle Pointer to the current file to search .
2008-08-08 05:33:16 +02:00
@ param SectionData A pointer to the discovered section , if successful .
2008-07-16 11:40:06 +02:00
NULL if section not found
2009-11-11 04:27:39 +01:00
@ retval EFI_NOT_FOUND The section was not found .
@ retval EFI_SUCCESS The section was found .
2008-07-16 11:40:06 +02:00
* */
2007-07-04 09:51:48 +02:00
EFI_STATUS
EFIAPI
PeiFfsFindSectionData (
2009-11-11 04:27:39 +01:00
IN CONST EFI_PEI_SERVICES * * PeiServices ,
2007-07-04 09:51:48 +02:00
IN EFI_SECTION_TYPE SectionType ,
2007-09-04 08:12:48 +02:00
IN EFI_PEI_FILE_HANDLE FileHandle ,
2009-11-11 04:27:39 +01:00
OUT VOID * * SectionData
2007-07-04 09:51:48 +02:00
)
{
2009-11-11 04:27:39 +01:00
PEI_CORE_FV_HANDLE * CoreFvHandle ;
CoreFvHandle = FileHandleToVolume ( FileHandle ) ;
if ( ( CoreFvHandle = = NULL ) | | ( CoreFvHandle - > FvPpi = = NULL ) ) {
return EFI_NOT_FOUND ;
}
return CoreFvHandle - > FvPpi - > FindSectionByType ( CoreFvHandle - > FvPpi , SectionType , FileHandle , SectionData ) ;
2007-07-04 09:51:48 +02:00
}
2008-07-16 11:40:06 +02:00
/**
2009-11-11 04:27:39 +01:00
Searches for the next matching file in the firmware volume .
2008-07-16 11:40:06 +02:00
2008-08-08 05:22:23 +02:00
@ param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation .
2008-07-16 11:40:06 +02:00
@ param SearchType Filter to find only files of this type .
Type EFI_FV_FILETYPE_ALL causes no filtering to be done .
2010-01-15 09:03:23 +01:00
@ param FvHandle Handle of firmware volume in which to search .
2009-11-11 04:27:39 +01:00
@ param FileHandle On entry , points to the current handle from which to begin searching or NULL to start
at the beginning of the firmware volume . On exit , points the file handle of the next file
in the volume or NULL if there are no more files .
@ retval EFI_NOT_FOUND The file was not found .
@ retval EFI_NOT_FOUND The header checksum was not zero .
@ retval EFI_SUCCESS The file was found .
2008-07-16 11:40:06 +02:00
* */
2007-07-04 09:51:48 +02:00
EFI_STATUS
EFIAPI
PeiFfsFindNextFile (
2007-09-04 08:12:48 +02:00
IN CONST EFI_PEI_SERVICES * * PeiServices ,
IN UINT8 SearchType ,
2009-11-11 04:27:39 +01:00
IN EFI_PEI_FV_HANDLE FvHandle ,
2007-09-04 08:12:48 +02:00
IN OUT EFI_PEI_FILE_HANDLE * FileHandle
2007-07-04 09:51:48 +02:00
)
{
2009-11-11 04:27:39 +01:00
PEI_CORE_FV_HANDLE * CoreFvHandle ;
CoreFvHandle = FvHandleToCoreHandle ( FvHandle ) ;
2009-11-11 06:51:45 +01:00
//
// To make backward compatiblity, if can not find corresponding the handle of FV
// then treat FV as build-in FFS2 format and memory mapped FV that FV handle is pointed
// to the address of first byte of FV.
//
if ( ( CoreFvHandle = = NULL ) & & FeaturePcdGet ( PcdFrameworkCompatibilitySupport ) ) {
return FindFileEx ( FvHandle , NULL , SearchType , FileHandle , NULL ) ;
}
2009-11-11 04:27:39 +01:00
if ( ( CoreFvHandle = = NULL ) | | CoreFvHandle - > FvPpi = = NULL ) {
return EFI_NOT_FOUND ;
}
return CoreFvHandle - > FvPpi - > FindFileByType ( CoreFvHandle - > FvPpi , SearchType , FvHandle , FileHandle ) ;
2007-07-04 09:51:48 +02:00
}
2007-09-24 13:38:43 +02:00
2008-07-16 11:40:06 +02:00
/**
2008-08-08 05:33:16 +02:00
Search the firmware volumes by index
2008-07-16 11:40:06 +02:00
2008-08-08 05:33:16 +02:00
@ param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
2009-11-11 04:27:39 +01:00
@ param Instance This instance of the firmware volume to find . The value 0 is the Boot Firmware
Volume ( BFV ) .
@ param VolumeHandle On exit , points to the next volume handle or NULL if it does not exist .
2008-07-16 11:40:06 +02:00
2009-11-11 04:27:39 +01:00
@ retval EFI_INVALID_PARAMETER VolumeHandle is NULL
@ retval EFI_NOT_FOUND The volume was not found .
@ retval EFI_SUCCESS The volume was found .
2008-07-16 11:40:06 +02:00
* */
2007-07-04 09:51:48 +02:00
EFI_STATUS
EFIAPI
2009-11-11 04:27:39 +01:00
PeiFfsFindNextVolume (
2008-08-21 09:51:03 +02:00
IN CONST EFI_PEI_SERVICES * * PeiServices ,
2007-07-04 09:51:48 +02:00
IN UINTN Instance ,
2007-09-04 08:12:48 +02:00
IN OUT EFI_PEI_FV_HANDLE * VolumeHandle
2007-07-04 09:51:48 +02:00
)
{
2009-11-11 04:27:39 +01:00
PEI_CORE_INSTANCE * Private ;
PEI_CORE_FV_HANDLE * CoreFvHandle ;
2009-11-25 07:26:03 +01:00
if ( VolumeHandle = = NULL ) {
return EFI_INVALID_PARAMETER ;
}
2007-09-24 13:38:43 +02:00
Private = PEI_CORE_INSTANCE_FROM_PS_THIS ( PeiServices ) ;
2008-08-21 09:51:03 +02:00
2009-11-11 04:27:39 +01:00
CoreFvHandle = FindNextCoreFvHandle ( Private , Instance ) ;
if ( CoreFvHandle = = NULL ) {
* VolumeHandle = NULL ;
return EFI_NOT_FOUND ;
2008-08-21 09:51:03 +02:00
}
2009-11-11 04:27:39 +01:00
* VolumeHandle = CoreFvHandle - > FvHandle ;
2007-09-24 13:38:43 +02:00
return EFI_SUCCESS ;
}
2007-07-04 09:51:48 +02:00
2008-07-16 11:40:06 +02:00
/**
2008-08-08 05:33:16 +02:00
Find a file within a volume by its name .
2008-07-16 11:40:06 +02:00
2008-08-08 05:33:16 +02:00
@ param FileName A pointer to the name of the file to find within the firmware volume .
@ param VolumeHandle The firmware volume to search
@ param FileHandle Upon exit , points to the found file ' s handle
or NULL if it could not be found .
2008-07-16 11:40:06 +02:00
2008-08-08 05:33:16 +02:00
@ retval EFI_SUCCESS File was found .
@ retval EFI_NOT_FOUND File was not found .
@ retval EFI_INVALID_PARAMETER VolumeHandle or FileHandle or FileName was NULL .
2008-07-16 11:40:06 +02:00
* */
2007-09-24 13:38:43 +02:00
EFI_STATUS
EFIAPI
PeiFfsFindFileByName (
IN CONST EFI_GUID * FileName ,
IN EFI_PEI_FV_HANDLE VolumeHandle ,
OUT EFI_PEI_FILE_HANDLE * FileHandle
)
{
2009-11-11 04:27:39 +01:00
PEI_CORE_FV_HANDLE * CoreFvHandle ;
2007-09-24 13:38:43 +02:00
if ( ( VolumeHandle = = NULL ) | | ( FileName = = NULL ) | | ( FileHandle = = NULL ) ) {
2007-07-04 09:51:48 +02:00
return EFI_INVALID_PARAMETER ;
}
2009-11-11 04:27:39 +01:00
CoreFvHandle = FvHandleToCoreHandle ( VolumeHandle ) ;
if ( ( CoreFvHandle = = NULL ) | | ( CoreFvHandle - > FvPpi = = NULL ) ) {
return EFI_NOT_FOUND ;
2007-09-24 13:38:43 +02:00
}
2009-11-11 04:27:39 +01:00
return CoreFvHandle - > FvPpi - > FindFileByName ( CoreFvHandle - > FvPpi , FileName , & VolumeHandle , FileHandle ) ;
2007-09-24 13:38:43 +02:00
}
2008-07-16 11:40:06 +02:00
/**
Returns information about a specific file .
2009-11-11 04:27:39 +01:00
@ param FileHandle Handle of the file .
2010-03-09 06:58:00 +01:00
@ param FileInfo Upon exit , points to the file ' s information .
2008-07-16 11:40:06 +02:00
2009-11-11 04:27:39 +01:00
@ retval EFI_INVALID_PARAMETER If FileInfo is NULL .
@ retval EFI_INVALID_PARAMETER If FileHandle does not represent a valid file .
@ retval EFI_SUCCESS File information returned .
2008-07-16 11:40:06 +02:00
* */
2007-09-24 13:38:43 +02:00
EFI_STATUS
EFIAPI
PeiFfsGetFileInfo (
IN EFI_PEI_FILE_HANDLE FileHandle ,
OUT EFI_FV_FILE_INFO * FileInfo
)
{
2009-11-11 04:27:39 +01:00
PEI_CORE_FV_HANDLE * CoreFvHandle ;
2007-09-24 13:38:43 +02:00
if ( ( FileHandle = = NULL ) | | ( FileInfo = = NULL ) ) {
return EFI_INVALID_PARAMETER ;
}
//
// Retrieve the FirmwareVolume which the file resides in.
//
2009-11-11 04:27:39 +01:00
CoreFvHandle = FileHandleToVolume ( FileHandle ) ;
if ( ( CoreFvHandle = = NULL ) | | ( CoreFvHandle - > FvPpi = = NULL ) ) {
2007-09-24 13:38:43 +02:00
return EFI_INVALID_PARAMETER ;
}
2009-11-11 04:27:39 +01:00
return CoreFvHandle - > FvPpi - > GetFileInfo ( CoreFvHandle - > FvPpi , FileHandle , FileInfo ) ;
2007-09-24 13:38:43 +02:00
}
2008-07-16 11:40:06 +02:00
/**
2009-11-11 04:27:39 +01:00
Returns information about the specified volume .
2008-07-16 11:40:06 +02:00
2009-11-17 16:00:28 +01:00
This function returns information about a specific firmware
volume , including its name , type , attributes , starting address
and size .
@ param VolumeHandle Handle of the volume .
@ param VolumeInfo Upon exit , points to the volume ' s information .
@ retval EFI_SUCCESS Volume information returned .
@ retval EFI_INVALID_PARAMETER If VolumeHandle does not represent a valid volume .
@ retval EFI_INVALID_PARAMETER If VolumeHandle is NULL .
@ retval EFI_SUCCESS Information successfully returned .
@ retval EFI_INVALID_PARAMETER The volume designated by the VolumeHandle is not available .
2008-07-16 11:40:06 +02:00
* */
2007-09-24 13:38:43 +02:00
EFI_STATUS
EFIAPI
PeiFfsGetVolumeInfo (
IN EFI_PEI_FV_HANDLE VolumeHandle ,
OUT EFI_FV_INFO * VolumeInfo
)
{
2009-11-11 04:27:39 +01:00
PEI_CORE_FV_HANDLE * CoreHandle ;
2010-01-04 06:20:18 +01:00
if ( ( VolumeInfo = = NULL ) | | ( VolumeHandle = = NULL ) ) {
2007-09-24 13:38:43 +02:00
return EFI_INVALID_PARAMETER ;
2007-07-04 09:51:48 +02:00
}
2007-12-06 10:52:27 +01:00
2009-11-11 04:27:39 +01:00
CoreHandle = FvHandleToCoreHandle ( VolumeHandle ) ;
if ( ( CoreHandle = = NULL ) | | ( CoreHandle - > FvPpi = = NULL ) ) {
2007-12-06 10:52:27 +01:00
return EFI_INVALID_PARAMETER ;
}
2009-11-11 04:27:39 +01:00
return CoreHandle - > FvPpi - > GetVolumeInfo ( CoreHandle - > FvPpi , VolumeHandle , VolumeInfo ) ;
2007-07-04 09:51:48 +02:00
}
2007-09-24 13:38:43 +02:00
2008-09-03 09:26:40 +02:00
/**
Get Fv image from the FV type file , then install FV INFO ppi , Build FV hob .
2009-11-11 04:27:39 +01:00
@ param ParentFvCoreHandle Pointer of EFI_CORE_FV_HANDLE to parent Fv image that contain this Fv image .
2009-03-05 06:05:57 +01:00
@ param ParentFvFileHandle File handle of a Fv type file that contain this Fv image .
2008-09-03 09:26:40 +02:00
@ retval EFI_NOT_FOUND FV image can ' t be found .
@ retval EFI_SUCCESS Successfully to process it .
@ retval EFI_OUT_OF_RESOURCES Can not allocate page when aligning FV image
@ retval Others Can not find EFI_SECTION_FIRMWARE_VOLUME_IMAGE section
* */
EFI_STATUS
ProcessFvFile (
2009-11-11 04:27:39 +01:00
IN PEI_CORE_FV_HANDLE * ParentFvCoreHandle ,
IN EFI_PEI_FILE_HANDLE ParentFvFileHandle
2008-09-03 09:26:40 +02:00
)
{
2009-11-11 04:27:39 +01:00
EFI_STATUS Status ;
EFI_FV_INFO ParentFvImageInfo ;
UINT32 FvAlignment ;
VOID * NewFvBuffer ;
EFI_PEI_HOB_POINTERS HobPtr ;
EFI_PEI_FIRMWARE_VOLUME_PPI * ParentFvPpi ;
EFI_PEI_FV_HANDLE ParentFvHandle ;
EFI_FIRMWARE_VOLUME_HEADER * FvHeader ;
EFI_FV_FILE_INFO FileInfo ;
2010-01-25 10:56:20 +01:00
UINT64 FvLength ;
2009-11-11 04:27:39 +01:00
2008-09-03 09:26:40 +02:00
//
// Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
// been extracted.
//
HobPtr . Raw = GetHobList ( ) ;
while ( ( HobPtr . Raw = GetNextHob ( EFI_HOB_TYPE_FV2 , HobPtr . Raw ) ) ! = NULL ) {
2009-03-05 06:05:57 +01:00
if ( CompareGuid ( & ( ( ( EFI_FFS_FILE_HEADER * ) ParentFvFileHandle ) - > Name ) , & HobPtr . FirmwareVolume2 - > FileName ) ) {
2008-09-03 09:26:40 +02:00
//
// this FILE has been dispatched, it will not be dispatched again.
//
2009-11-11 04:27:39 +01:00
DEBUG ( ( EFI_D_INFO , " FV file %p has been dispatched! \r \n " , ParentFvFileHandle ) ) ;
2008-09-03 09:26:40 +02:00
return EFI_SUCCESS ;
}
HobPtr . Raw = GET_NEXT_HOB ( HobPtr ) ;
}
2009-11-11 04:27:39 +01:00
ParentFvHandle = ParentFvCoreHandle - > FvHandle ;
ParentFvPpi = ParentFvCoreHandle - > FvPpi ;
2008-09-03 09:26:40 +02:00
//
// Find FvImage in FvFile
//
2009-11-11 04:27:39 +01:00
Status = ParentFvPpi - > FindSectionByType (
ParentFvPpi ,
EFI_SECTION_FIRMWARE_VOLUME_IMAGE ,
ParentFvFileHandle ,
( VOID * * ) & FvHeader
) ;
2008-09-03 09:26:40 +02:00
if ( EFI_ERROR ( Status ) ) {
return Status ;
}
2009-03-05 06:05:57 +01:00
//
2009-11-11 04:27:39 +01:00
// FvAlignment must be more than 8 bytes required by FvHeader structure.
2008-09-03 09:26:40 +02:00
//
2010-01-25 10:56:20 +01:00
FvAlignment = 1 < < ( ( ReadUnaligned32 ( & FvHeader - > Attributes ) & EFI_FVB2_ALIGNMENT ) > > 16 ) ;
2008-09-03 09:26:40 +02:00
if ( FvAlignment < 8 ) {
FvAlignment = 8 ;
}
//
// Check FvImage
//
2009-11-11 04:27:39 +01:00
if ( ( UINTN ) FvHeader % FvAlignment ! = 0 ) {
2010-01-25 10:56:20 +01:00
FvLength = ReadUnaligned64 ( & FvHeader - > FvLength ) ;
NewFvBuffer = AllocateAlignedPages ( EFI_SIZE_TO_PAGES ( ( UINT32 ) FvLength ) , FvAlignment ) ;
2009-11-11 04:27:39 +01:00
if ( NewFvBuffer = = NULL ) {
2008-09-03 09:26:40 +02:00
return EFI_OUT_OF_RESOURCES ;
}
2010-01-25 10:56:20 +01:00
CopyMem ( NewFvBuffer , FvHeader , ( UINTN ) FvLength ) ;
2009-11-11 04:27:39 +01:00
FvHeader = ( EFI_FIRMWARE_VOLUME_HEADER * ) NewFvBuffer ;
2008-09-03 09:26:40 +02:00
}
2009-11-11 04:27:39 +01:00
Status = ParentFvPpi - > GetVolumeInfo ( ParentFvPpi , ParentFvHandle , & ParentFvImageInfo ) ;
ASSERT_EFI_ERROR ( Status ) ;
Status = ParentFvPpi - > GetFileInfo ( ParentFvPpi , ParentFvFileHandle , & FileInfo ) ;
ASSERT_EFI_ERROR ( Status ) ;
2008-09-03 09:26:40 +02:00
//
// Install FvPpi and Build FvHob
//
2008-11-13 10:17:38 +01:00
PeiServicesInstallFvInfoPpi (
2009-11-11 04:27:39 +01:00
& FvHeader - > FileSystemGuid ,
( VOID * * ) FvHeader ,
( UINT32 ) FvHeader - > FvLength ,
2009-03-05 06:05:57 +01:00
& ParentFvImageInfo . FvName ,
2009-11-11 04:27:39 +01:00
& FileInfo . FileName
2008-09-03 09:26:40 +02:00
) ;
//
// Inform the extracted FvImage to Fv HOB consumer phase, i.e. DXE phase
//
2008-09-19 07:05:40 +02:00
BuildFvHob (
2009-11-11 04:27:39 +01:00
( EFI_PHYSICAL_ADDRESS ) ( UINTN ) FvHeader ,
FvHeader - > FvLength
2009-03-11 03:53:15 +01:00
) ;
2008-09-03 09:26:40 +02:00
//
// Makes the encapsulated volume show up in DXE phase to skip processing of
// encapsulated file again.
//
BuildFv2Hob (
2009-11-11 04:27:39 +01:00
( EFI_PHYSICAL_ADDRESS ) ( UINTN ) FvHeader ,
FvHeader - > FvLength ,
2009-03-05 06:05:57 +01:00
& ParentFvImageInfo . FvName ,
2009-11-11 04:27:39 +01:00
& FileInfo . FileName
2008-09-03 09:26:40 +02:00
) ;
return EFI_SUCCESS ;
}
2009-11-11 04:27:39 +01:00
/**
Process a firmware volume and create a volume handle .
Create a volume handle from the information in the buffer . For
memory - mapped firmware volumes , Buffer and BufferSize refer to
the start of the firmware volume and the firmware volume size .
For non memory - mapped firmware volumes , this points to a
buffer which contains the necessary information for creating
the firmware volume handle . Normally , these values are derived
from the EFI_FIRMWARE_VOLUME_INFO_PPI .
@ param This Points to this instance of the
EFI_PEI_FIRMWARE_VOLUME_PPI .
@ param Buffer Points to the start of the buffer .
@ param BufferSize Size of the buffer .
@ param FvHandle Points to the returned firmware volume
handle . The firmware volume handle must
be unique within the system .
@ retval EFI_SUCCESS Firmware volume handle created .
@ retval EFI_VOLUME_CORRUPTED Volume was corrupt .
* */
EFI_STATUS
EFIAPI
PeiFfs2FvPpiProcessVolume (
IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI * This ,
IN VOID * Buffer ,
IN UINTN BufferSize ,
OUT EFI_PEI_FV_HANDLE * FvHandle
)
{
EFI_STATUS Status ;
2009-12-03 06:41:05 +01:00
ASSERT ( FvHandle ! = NULL ) ;
if ( Buffer = = NULL ) {
return EFI_VOLUME_CORRUPTED ;
}
2009-11-11 04:27:39 +01:00
//
// The build-in EFI_PEI_FIRMWARE_VOLUME_PPI for FFS2 support memory-mapped
// FV image and the handle is pointed to Fv image's buffer.
//
* FvHandle = ( EFI_PEI_FV_HANDLE ) Buffer ;
//
// Do verify for given FV buffer.
//
Status = VerifyFv ( ( EFI_FIRMWARE_VOLUME_HEADER * ) Buffer ) ;
if ( EFI_ERROR ( Status ) ) {
DEBUG ( ( EFI_D_ERROR , " Fail to verify FV which address is 0x%11p " , Buffer ) ) ;
return EFI_VOLUME_CORRUPTED ;
}
return EFI_SUCCESS ;
}
/**
Finds the next file of the specified type .
This service enables PEI modules to discover additional firmware files .
The FileHandle must be unique within the system .
@ param This Points to this instance of the
EFI_PEI_FIRMWARE_VOLUME_PPI .
@ param SearchType A filter to find only files of this type . Type
EFI_FV_FILETYPE_ALL causes no filtering to be
done .
@ param FvHandle Handle of firmware volume in which to
search .
@ param FileHandle Points to the current handle from which to
begin searching or NULL to start at the
beginning of the firmware volume . Updated
upon return to reflect the file found .
@ retval EFI_SUCCESS The file was found .
@ retval EFI_NOT_FOUND The file was not found . FileHandle contains NULL .
* */
EFI_STATUS
EFIAPI
PeiFfs2FvPpiFindFileByType (
IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI * This ,
IN EFI_FV_FILETYPE SearchType ,
IN EFI_PEI_FV_HANDLE FvHandle ,
IN OUT EFI_PEI_FILE_HANDLE * FileHandle
)
{
return FindFileEx ( FvHandle , NULL , SearchType , FileHandle , NULL ) ;
}
/**
Find a file within a volume by its name .
This service searches for files with a specific name , within
either the specified firmware volume or all firmware volumes .
@ param This Points to this instance of the
EFI_PEI_FIRMWARE_VOLUME_PPI .
@ param FileName A pointer to the name of the file to find
within the firmware volume .
@ param FvHandle Upon entry , the pointer to the firmware
volume to search or NULL if all firmware
volumes should be searched . Upon exit , the
actual firmware volume in which the file was
found .
@ param FileHandle Upon exit , points to the found file ' s
handle or NULL if it could not be found .
@ retval EFI_SUCCESS File was found .
@ retval EFI_NOT_FOUND File was not found .
@ retval EFI_INVALID_PARAMETER FvHandle or FileHandle or
FileName was NULL .
* */
EFI_STATUS
EFIAPI
PeiFfs2FvPpiFindFileByName (
IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI * This ,
IN CONST EFI_GUID * FileName ,
IN EFI_PEI_FV_HANDLE * FvHandle ,
OUT EFI_PEI_FILE_HANDLE * FileHandle
)
{
EFI_STATUS Status ;
PEI_CORE_INSTANCE * PrivateData ;
UINTN Index ;
if ( ( FvHandle = = NULL ) | | ( FileName = = NULL ) | | ( FileHandle = = NULL ) ) {
return EFI_INVALID_PARAMETER ;
}
if ( * FvHandle ! = NULL ) {
Status = FindFileEx ( * FvHandle , FileName , 0 , FileHandle , NULL ) ;
if ( Status = = EFI_NOT_FOUND ) {
* FileHandle = NULL ;
}
} else {
//
// If *FvHandle = NULL, so search all FV for given filename
//
Status = EFI_NOT_FOUND ;
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS ( GetPeiServicesTablePointer ( ) ) ;
for ( Index = 0 ; Index < PrivateData - > FvCount ; Index + + ) {
//
// Only search the FV which is associated with a EFI_PEI_FIRMWARE_VOLUME_PPI instance.
//
if ( PrivateData - > Fv [ Index ] . FvPpi ! = NULL ) {
Status = FindFileEx ( PrivateData - > Fv [ Index ] . FvHandle , FileName , 0 , FileHandle , NULL ) ;
if ( ! EFI_ERROR ( Status ) ) {
* FvHandle = PrivateData - > Fv [ Index ] . FvHandle ;
2010-01-14 06:31:07 +01:00
break ;
2009-11-11 04:27:39 +01:00
}
}
}
}
return Status ;
}
/**
Returns information about a specific file .
This function returns information about a specific
file , including its file name , type , attributes , starting
address and size .
@ param This Points to this instance of the
EFI_PEI_FIRMWARE_VOLUME_PPI .
@ param FileHandle Handle of the file .
@ param FileInfo Upon exit , points to the file ' s
information .
@ retval EFI_SUCCESS File information returned .
@ retval EFI_INVALID_PARAMETER If FileHandle does not
represent a valid file .
@ retval EFI_INVALID_PARAMETER If FileInfo is NULL .
* */
EFI_STATUS
EFIAPI
PeiFfs2FvPpiGetFileInfo (
IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI * This ,
IN EFI_PEI_FILE_HANDLE FileHandle ,
OUT EFI_FV_FILE_INFO * FileInfo
)
{
UINT8 FileState ;
UINT8 ErasePolarity ;
EFI_FFS_FILE_HEADER * FileHeader ;
PEI_CORE_FV_HANDLE * CoreFvHandle ;
if ( ( FileHandle = = NULL ) | | ( FileInfo = = NULL ) ) {
return EFI_INVALID_PARAMETER ;
}
//
// Retrieve the FirmwareVolume which the file resides in.
//
CoreFvHandle = FileHandleToVolume ( FileHandle ) ;
if ( CoreFvHandle = = NULL ) {
return EFI_INVALID_PARAMETER ;
}
2010-02-11 03:33:16 +01:00
if ( ( CoreFvHandle - > FvHeader - > Attributes & EFI_FVB2_ERASE_POLARITY ) ! = 0 ) {
2009-11-11 04:27:39 +01:00
ErasePolarity = 1 ;
} else {
ErasePolarity = 0 ;
}
//
// Get FileState which is the highest bit of the State
//
FileState = GetFileState ( ErasePolarity , ( EFI_FFS_FILE_HEADER * ) FileHandle ) ;
switch ( FileState ) {
case EFI_FILE_DATA_VALID :
case EFI_FILE_MARKED_FOR_UPDATE :
break ;
default :
return EFI_INVALID_PARAMETER ;
}
FileHeader = ( EFI_FFS_FILE_HEADER * ) FileHandle ;
CopyMem ( & FileInfo - > FileName , & FileHeader - > Name , sizeof ( EFI_GUID ) ) ;
FileInfo - > FileType = FileHeader - > Type ;
FileInfo - > FileAttributes = FileHeader - > Attributes ;
FileInfo - > BufferSize = ( ( * ( UINT32 * ) FileHeader - > Size ) & 0x00FFFFFF ) - sizeof ( EFI_FFS_FILE_HEADER ) ;
FileInfo - > Buffer = ( FileHeader + 1 ) ;
return EFI_SUCCESS ;
}
/**
This function returns information about the firmware volume .
@ param This Points to this instance of the
EFI_PEI_FIRMWARE_VOLUME_PPI .
@ param FvHandle Handle to the firmware handle .
@ param VolumeInfo Points to the returned firmware volume
information .
@ retval EFI_SUCCESS Information returned successfully .
@ retval EFI_INVALID_PARAMETER FvHandle does not indicate a valid
firmware volume or VolumeInfo is NULL .
* */
EFI_STATUS
EFIAPI
PeiFfs2FvPpiGetVolumeInfo (
IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI * This ,
IN EFI_PEI_FV_HANDLE FvHandle ,
OUT EFI_FV_INFO * VolumeInfo
)
{
EFI_FIRMWARE_VOLUME_HEADER FwVolHeader ;
EFI_FIRMWARE_VOLUME_EXT_HEADER * FwVolExHeaderInfo ;
2010-01-04 06:20:18 +01:00
if ( ( VolumeInfo = = NULL ) | | ( FvHandle = = NULL ) ) {
2009-11-11 04:27:39 +01:00
return EFI_INVALID_PARAMETER ;
}
//
// VolumeHandle may not align at 8 byte,
// but FvLength is UINT64 type, which requires FvHeader align at least 8 byte.
// So, Copy FvHeader into the local FvHeader structure.
//
CopyMem ( & FwVolHeader , FvHandle , sizeof ( EFI_FIRMWARE_VOLUME_HEADER ) ) ;
//
// Check Fv Image Signature
//
if ( FwVolHeader . Signature ! = EFI_FVH_SIGNATURE ) {
return EFI_INVALID_PARAMETER ;
}
ZeroMem ( VolumeInfo , sizeof ( EFI_FV_INFO ) ) ;
VolumeInfo - > FvAttributes = FwVolHeader . Attributes ;
VolumeInfo - > FvStart = ( VOID * ) FvHandle ;
VolumeInfo - > FvSize = FwVolHeader . FvLength ;
CopyMem ( & VolumeInfo - > FvFormat , & FwVolHeader . FileSystemGuid , sizeof ( EFI_GUID ) ) ;
if ( FwVolHeader . ExtHeaderOffset ! = 0 ) {
FwVolExHeaderInfo = ( EFI_FIRMWARE_VOLUME_EXT_HEADER * ) ( ( ( UINT8 * ) FvHandle ) + FwVolHeader . ExtHeaderOffset ) ;
CopyMem ( & VolumeInfo - > FvName , & FwVolExHeaderInfo - > FvName , sizeof ( EFI_GUID ) ) ;
}
return EFI_SUCCESS ;
}
/**
Find the next matching section in the firmware file .
This service enables PEI modules to discover sections
of a given type within a valid file .
@ param This Points to this instance of the
EFI_PEI_FIRMWARE_VOLUME_PPI .
@ param SearchType A filter to find only sections of this
type .
@ param FileHandle Handle of firmware file in which to
search .
@ param SectionData Updated upon return to point to the
section found .
@ retval EFI_SUCCESS Section was found .
@ retval EFI_NOT_FOUND Section of the specified type was not
found . SectionData contains NULL .
* */
EFI_STATUS
EFIAPI
PeiFfs2FvPpiFindSectionByType (
IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI * This ,
IN EFI_SECTION_TYPE SearchType ,
IN EFI_PEI_FILE_HANDLE FileHandle ,
OUT VOID * * SectionData
)
{
EFI_FFS_FILE_HEADER * FfsFileHeader ;
UINT32 FileSize ;
EFI_COMMON_SECTION_HEADER * Section ;
FfsFileHeader = ( EFI_FFS_FILE_HEADER * ) ( FileHandle ) ;
//
// Size is 24 bits wide so mask upper 8 bits.
// Does not include FfsFileHeader header size
// FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
//
Section = ( EFI_COMMON_SECTION_HEADER * ) ( FfsFileHeader + 1 ) ;
FileSize = * ( UINT32 * ) ( FfsFileHeader - > Size ) & 0x00FFFFFF ;
FileSize - = sizeof ( EFI_FFS_FILE_HEADER ) ;
return ProcessSection (
GetPeiServicesTablePointer ( ) ,
SearchType ,
Section ,
FileSize ,
SectionData
) ;
}
/**
Convert the handle of FV to pointer of corresponding PEI_CORE_FV_HANDLE .
@ param FvHandle The handle of a FV .
@ retval NULL if can not find .
@ return Pointer of corresponding PEI_CORE_FV_HANDLE .
* */
PEI_CORE_FV_HANDLE *
FvHandleToCoreHandle (
IN EFI_PEI_FV_HANDLE FvHandle
)
{
UINTN Index ;
PEI_CORE_INSTANCE * PrivateData ;
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS ( GetPeiServicesTablePointer ( ) ) ;
for ( Index = 0 ; Index < PrivateData - > FvCount ; Index + + ) {
if ( FvHandle = = PrivateData - > Fv [ Index ] . FvHandle ) {
return & PrivateData - > Fv [ Index ] ;
}
}
return NULL ;
}
/**
Get instance of PEI_CORE_FV_HANDLE for next volume according to given index .
This routine also will install FvInfo ppi for FV hob in PI ways .
@ param Private Pointer of PEI_CORE_INSTANCE
@ param Instance The index of FV want to be searched .
@ return Instance of PEI_CORE_FV_HANDLE .
* */
PEI_CORE_FV_HANDLE *
FindNextCoreFvHandle (
IN PEI_CORE_INSTANCE * Private ,
IN UINTN Instance
)
{
UINTN Index ;
BOOLEAN Match ;
EFI_HOB_FIRMWARE_VOLUME * FvHob ;
//
// Handle Framework FvHob and Install FvInfo Ppi for it.
//
if ( FeaturePcdGet ( PcdFrameworkCompatibilitySupport ) ) {
//
// Loop to search the wanted FirmwareVolume which supports FFS
//
FvHob = ( EFI_HOB_FIRMWARE_VOLUME * ) GetFirstHob ( EFI_HOB_TYPE_FV ) ;
while ( FvHob ! = NULL ) {
2010-02-11 06:49:48 +01:00
//
// Search whether FvHob has been installed into PeiCore's FV database.
// If found, no need install new FvInfoPpi for it.
//
2009-11-11 04:27:39 +01:00
for ( Index = 0 , Match = FALSE ; Index < Private - > FvCount ; Index + + ) {
if ( ( EFI_PEI_FV_HANDLE ) ( UINTN ) FvHob - > BaseAddress = = Private - > Fv [ Index ] . FvHeader ) {
Match = TRUE ;
break ;
}
}
2010-02-11 06:49:48 +01:00
2009-11-11 04:27:39 +01:00
//
2010-02-11 06:49:48 +01:00
// Search whether FvHob has been cached into PeiCore's Unknown FV database.
// If found, no need install new FvInfoPpi for it.
//
if ( ! Match ) {
for ( Index = 0 ; Index < Private - > UnknownFvInfoCount ; Index + + ) {
if ( ( UINTN ) FvHob - > BaseAddress = = ( UINTN ) Private - > UnknownFvInfo [ Index ] . FvInfo ) {
Match = TRUE ;
break ;
}
}
}
//
// If the Fv in FvHob has not been installed into PeiCore's FV database and has
// not been cached into PeiCore's Unknown FV database, install a new FvInfoPpi
// for it then PeiCore will dispatch it in callback of FvInfoPpi.
2009-11-11 04:27:39 +01:00
//
if ( ! Match ) {
PeiServicesInstallFvInfoPpi (
& ( ( ( EFI_FIRMWARE_VOLUME_HEADER * ) ( UINTN ) FvHob - > BaseAddress ) - > FileSystemGuid ) ,
( VOID * ) ( UINTN ) FvHob - > BaseAddress ,
( UINT32 ) FvHob - > Length ,
NULL ,
NULL
) ;
}
2010-02-11 06:49:48 +01:00
2009-11-11 04:27:39 +01:00
FvHob = ( EFI_HOB_FIRMWARE_VOLUME * ) GetNextHob ( EFI_HOB_TYPE_FV , ( VOID * ) ( ( UINTN ) FvHob + FvHob - > Header . HobLength ) ) ;
}
}
2010-03-03 10:40:16 +01:00
ASSERT ( Private - > FvCount < = FixedPcdGet32 ( PcdPeiCoreMaxFvSupported ) ) ;
2009-11-11 04:27:39 +01:00
if ( Instance > = Private - > FvCount ) {
return NULL ;
}
2008-09-03 09:26:40 +02:00
2009-11-11 04:27:39 +01:00
return & Private - > Fv [ Instance ] ;
}
2009-12-03 03:48:05 +01:00
/**
After PeiCore image is shadowed into permanent memory , all build - in FvPpi should
be re - installed with the instance in permanent memory and all cached FvPpi pointers in
PrivateData - > Fv [ ] array should be fixed up to be pointed to the one in permenant
memory .
@ param PrivateData Pointer to PEI_CORE_INSTANCE .
* */
VOID
PeiReinitializeFv (
IN PEI_CORE_INSTANCE * PrivateData
)
{
2009-12-03 03:51:50 +01:00
VOID * OldFfs2FvPpi ;
EFI_PEI_PPI_DESCRIPTOR * OldDescriptor ;
UINTN Index ;
EFI_STATUS Status ;
//
// Locate old build-in Ffs2 EFI_PEI_FIRMWARE_VOLUME_PPI which
// in flash.
//
Status = PeiServicesLocatePpi (
& gEfiFirmwareFileSystem2Guid ,
0 ,
& OldDescriptor ,
& OldFfs2FvPpi
) ;
ASSERT_EFI_ERROR ( Status ) ;
//
// Re-install the EFI_PEI_FIRMWARE_VOLUME_PPI for build-in Ffs2
// which is shadowed from flash to permanent memory within PeiCore image.
//
Status = PeiServicesReInstallPpi ( OldDescriptor , & mPeiFfs2FvPpiList ) ;
ASSERT_EFI_ERROR ( Status ) ;
//
// Fixup all FvPpi pointers for the implementation in flash to permanent memory.
//
2010-02-11 03:33:16 +01:00
for ( Index = 0 ; Index < FixedPcdGet32 ( PcdPeiCoreMaxFvSupported ) ; Index + + ) {
2009-12-03 03:51:50 +01:00
if ( PrivateData - > Fv [ Index ] . FvPpi = = OldFfs2FvPpi ) {
PrivateData - > Fv [ Index ] . FvPpi = & mPeiFfs2FvPpi ;
}
}
2009-12-03 03:48:05 +01:00
}
2009-12-25 03:28:47 +01:00
/**
Report the information for a new discoveried FV in unknown third - party format .
If the EFI_PEI_FIRMWARE_VOLUME_PPI has not been installed for third - party FV format , but
the FV in this format has been discoveried , then this FV ' s information will be cached into
PEI_CORE_INSTANCE ' s UnknownFvInfo array .
Also a notification would be installed for unknown third - party FV format guid , if EFI_PEI_FIRMWARE_VOLUME_PPI
is installed later by platform ' s PEIM , the original unknown third - party FV will be processed by
using new installed EFI_PEI_FIRMWARE_VOLUME_PPI .
@ param PrivateData Point to instance of PEI_CORE_INSTANCE
@ param Format Point to the unknown third - party format guid .
@ param FvInfo Point to FvInfo buffer .
@ param FvInfoSize The size of FvInfo buffer .
@ retval EFI_OUT_OF_RESOURCES The FV info array in PEI_CORE_INSTANCE has no more spaces .
@ retval EFI_SUCCESS Success to add the information for unknown FV .
* */
EFI_STATUS
AddUnknownFormatFvInfo (
IN PEI_CORE_INSTANCE * PrivateData ,
IN EFI_GUID * Format ,
IN VOID * FvInfo ,
IN UINT32 FvInfoSize
)
{
PEI_CORE_UNKNOW_FORMAT_FV_INFO * NewUnknownFv ;
2010-03-03 10:40:16 +01:00
if ( PrivateData - > UnknownFvInfoCount + 1 > = FixedPcdGet32 ( PcdPeiCoreMaxFvSupported ) ) {
2009-12-25 03:28:47 +01:00
return EFI_OUT_OF_RESOURCES ;
}
NewUnknownFv = & PrivateData - > UnknownFvInfo [ PrivateData - > UnknownFvInfoCount ] ;
PrivateData - > UnknownFvInfoCount + + ;
CopyGuid ( & NewUnknownFv - > FvFormat , Format ) ;
NewUnknownFv - > FvInfo = FvInfo ;
NewUnknownFv - > FvInfoSize = FvInfoSize ;
NewUnknownFv - > NotifyDescriptor . Flags = ( EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST ) ;
NewUnknownFv - > NotifyDescriptor . Guid = & NewUnknownFv - > FvFormat ;
NewUnknownFv - > NotifyDescriptor . Notify = ThirdPartyFvPpiNotifyCallback ;
PeiServicesNotifyPpi ( & NewUnknownFv - > NotifyDescriptor ) ;
return EFI_SUCCESS ;
}
/**
Find the FV information according to third - party FV format guid .
This routine also will remove the FV information found by given FV format guid from
PrivateData - > UnknownFvInfo [ ] .
@ param PrivateData Point to instance of PEI_CORE_INSTANCE
@ param Format Point to given FV format guid
@ param FvInfo On return , the pointer of FV information buffer
@ param FvInfoSize On return , the size of FV information buffer .
@ retval EFI_NOT_FOUND The FV is not found for new installed EFI_PEI_FIRMWARE_VOLUME_PPI
@ retval EFI_SUCCESS Success to find a FV which could be processed by new installed EFI_PEI_FIRMWARE_VOLUME_PPI .
* */
EFI_STATUS
FindUnknownFormatFvInfo (
IN PEI_CORE_INSTANCE * PrivateData ,
IN EFI_GUID * Format ,
OUT VOID * * FvInfo ,
OUT UINT32 * FvInfoSize
)
{
UINTN Index ;
UINTN Index2 ;
Index = 0 ;
for ( ; Index < PrivateData - > UnknownFvInfoCount ; Index + + ) {
if ( CompareGuid ( Format , & PrivateData - > UnknownFvInfo [ Index ] . FvFormat ) ) {
break ;
}
}
if ( Index = = PrivateData - > UnknownFvInfoCount ) {
return EFI_NOT_FOUND ;
}
* FvInfo = PrivateData - > UnknownFvInfo [ Index ] . FvInfo ;
* FvInfoSize = PrivateData - > UnknownFvInfo [ Index ] . FvInfoSize ;
//
// Remove an entry from UnknownFvInfo array.
//
Index2 = Index + 1 ;
for ( ; Index2 < PrivateData - > UnknownFvInfoCount ; Index2 + + , Index + + ) {
CopyMem ( & PrivateData - > UnknownFvInfo [ Index ] , & PrivateData - > UnknownFvInfo [ Index2 ] , sizeof ( PEI_CORE_UNKNOW_FORMAT_FV_INFO ) ) ;
}
PrivateData - > UnknownFvInfoCount - - ;
return EFI_SUCCESS ;
}
/**
Notification callback function for EFI_PEI_FIRMWARE_VOLUME_PPI .
When a EFI_PEI_FIRMWARE_VOLUME_PPI is installed to support new FV format , this
routine is called to process all discoveried FVs in this format .
@ param PeiServices An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation
@ param NotifyDescriptor Address of the notification descriptor data structure .
@ param Ppi Address of the PPI that was installed .
@ retval EFI_SUCCESS The notification callback is processed correctly .
* */
EFI_STATUS
EFIAPI
ThirdPartyFvPpiNotifyCallback (
IN EFI_PEI_SERVICES * * PeiServices ,
IN EFI_PEI_NOTIFY_DESCRIPTOR * NotifyDescriptor ,
IN VOID * Ppi
)
{
PEI_CORE_INSTANCE * PrivateData ;
EFI_PEI_FIRMWARE_VOLUME_PPI * FvPpi ;
VOID * FvInfo ;
UINT32 FvInfoSize ;
EFI_STATUS Status ;
EFI_PEI_FV_HANDLE FvHandle ;
BOOLEAN IsProcessed ;
UINTN FvIndex ;
EFI_PEI_FILE_HANDLE FileHandle ;
VOID * DepexData ;
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS ( PeiServices ) ;
FvPpi = ( EFI_PEI_FIRMWARE_VOLUME_PPI * ) Ppi ;
do {
Status = FindUnknownFormatFvInfo ( PrivateData , NotifyDescriptor - > Guid , & FvInfo , & FvInfoSize ) ;
if ( EFI_ERROR ( Status ) ) {
return EFI_SUCCESS ;
}
//
// Process new found FV and get FV handle.
//
Status = FvPpi - > ProcessVolume ( FvPpi , FvInfo , FvInfoSize , & FvHandle ) ;
if ( EFI_ERROR ( Status ) ) {
DEBUG ( ( EFI_D_ERROR , " Fail to process the FV 0x%p, FV may be corrupted! \n " , FvInfo ) ) ;
continue ;
}
//
// Check whether the FV has already been processed.
//
IsProcessed = FALSE ;
for ( FvIndex = 0 ; FvIndex < PrivateData - > FvCount ; FvIndex + + ) {
if ( PrivateData - > Fv [ FvIndex ] . FvHandle = = FvHandle ) {
DEBUG ( ( EFI_D_INFO , " The Fv %p has already been processed! \n " , FvInfo ) ) ;
IsProcessed = TRUE ;
break ;
}
}
if ( IsProcessed ) {
continue ;
}
2010-03-01 09:59:00 +01:00
if ( PrivateData - > FvCount > = FixedPcdGet32 ( PcdPeiCoreMaxFvSupported ) ) {
DEBUG ( ( EFI_D_ERROR , " The number of Fv Images (%d) exceed the max supported FVs (%d) in Pei " , PrivateData - > FvCount + 1 , FixedPcdGet32 ( PcdPeiCoreMaxFvSupported ) ) ) ;
DEBUG ( ( EFI_D_ERROR , " PcdPeiCoreMaxFvSupported value need be reconfigurated in DSC " ) ) ;
ASSERT ( FALSE ) ;
}
2009-12-25 03:28:47 +01:00
//
// Update internal PEI_CORE_FV array.
//
PrivateData - > Fv [ PrivateData - > FvCount ] . FvHeader = ( EFI_FIRMWARE_VOLUME_HEADER * ) FvInfo ;
PrivateData - > Fv [ PrivateData - > FvCount ] . FvPpi = FvPpi ;
PrivateData - > Fv [ PrivateData - > FvCount ] . FvHandle = FvHandle ;
DEBUG ( (
EFI_D_INFO ,
" The %dth FV start address is 0x%11p, size is 0x%08x, handle is 0x%p \n " ,
( UINT32 ) PrivateData - > FvCount ,
( VOID * ) FvInfo ,
FvInfoSize ,
FvHandle
) ) ;
PrivateData - > FvCount + + ;
//
// Scan and process the new discoveried FV for EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
//
FileHandle = NULL ;
do {
Status = FvPpi - > FindFileByType (
FvPpi ,
EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE ,
FvHandle ,
& FileHandle
) ;
if ( ! EFI_ERROR ( Status ) ) {
Status = FvPpi - > FindSectionByType (
FvPpi ,
EFI_SECTION_PEI_DEPEX ,
FileHandle ,
( VOID * * ) & DepexData
) ;
if ( ! EFI_ERROR ( Status ) ) {
if ( ! PeimDispatchReadiness ( PeiServices , DepexData ) ) {
//
// Dependency is not satisfied.
//
continue ;
}
}
DEBUG ( ( EFI_D_INFO , " Found firmware volume Image File %p in FV[%d] %p \n " , FileHandle , PrivateData - > FvCount - 1 , FvHandle ) ) ;
ProcessFvFile ( & PrivateData - > Fv [ PrivateData - > FvCount - 1 ] , FileHandle ) ;
}
} while ( FileHandle ! = NULL ) ;
} while ( TRUE ) ;
}