mirror of
https://github.com/acidanthera/audk.git
synced 2025-04-07 19:45:07 +02:00
Merge branch of PI tree to main trunk
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3918 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
f6203b7192
commit
b0d803fe3e
@ -490,7 +490,6 @@ Returns:
|
||||
|
||||
CoreReleaseDispatcherLock ();
|
||||
|
||||
|
||||
CoreReportProgressCodeSpecific (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_BEGIN, DriverEntry->ImageHandle);
|
||||
Status = CoreStartImage (DriverEntry->ImageHandle, NULL, NULL);
|
||||
CoreReportProgressCodeSpecific (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_END, DriverEntry->ImageHandle);
|
||||
@ -814,25 +813,12 @@ Returns:
|
||||
--*/
|
||||
{
|
||||
EFI_PEI_HOB_POINTERS HobFv2;
|
||||
EFI_STATUS Status;
|
||||
EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
|
||||
EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
|
||||
EFI_PHYSICAL_ADDRESS FvHeaderAddr;
|
||||
|
||||
HobFv2.Raw = GetHobList ();
|
||||
|
||||
while ((HobFv2.Raw = GetNextHob (EFI_HOB_TYPE_FV2, HobFv2.Raw)) != NULL) {
|
||||
if (CompareGuid (DriverName, &HobFv2.FirmwareVolume2->FileName)) {
|
||||
Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolumeBlockProtocolGuid, (VOID **) &Fvb);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = Fvb->GetPhysicalAddress (Fvb, &FvHeaderAddr);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) FvHeaderAddr;
|
||||
if (CompareGuid (&FvHeader->FileSystemGuid, &HobFv2.FirmwareVolume2->FvName)) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
HobFv2.Raw = GET_NEXT_HOB (HobFv2);
|
||||
}
|
||||
|
@ -32,6 +32,11 @@ Abstract:
|
||||
#include <Ppi/FvLoadFile.h>
|
||||
#include <Ppi/RecoveryModule.h>
|
||||
#include <Ppi/MemoryDiscovered.h>
|
||||
#include <Ppi/Decompress.h>
|
||||
#include <Ppi/FirmwareVolumeInfo.h>
|
||||
|
||||
#include <Guid/FirmwareFileSystem2.h>
|
||||
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/PeimEntryPoint.h>
|
||||
#include <Library/BaseLib.h>
|
||||
@ -67,14 +72,27 @@ PeiFindFile (
|
||||
|
||||
EFI_STATUS
|
||||
PeiLoadFile (
|
||||
IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *PeiEfiPeiPeCoffLoader,
|
||||
IN VOID *Pe32Data,
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
OUT EFI_PHYSICAL_ADDRESS *ImageAddress,
|
||||
OUT UINT64 *ImageSize,
|
||||
OUT EFI_PHYSICAL_ADDRESS *EntryPoint
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
DxeIplAddEncapsulatedFirmwareVolumes (
|
||||
VOID
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
DxeIplFindFirmwareVolumeInstance (
|
||||
IN OUT UINTN *Instance,
|
||||
IN EFI_FV_FILETYPE SeachType,
|
||||
OUT EFI_PEI_FV_HANDLE *VolumeHandle,
|
||||
OUT EFI_PEI_FILE_HANDLE *FileHandle
|
||||
)
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
GetImageReadFunction (
|
||||
@ -133,9 +151,10 @@ PeiProcessFile (
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeimInitializeDxeIpl (
|
||||
IN EFI_FFS_FILE_HEADER *FfsHeader,
|
||||
IN EFI_PEI_FILE_HANDLE FfsHandle,
|
||||
IN EFI_PEI_SERVICES **PeiServices
|
||||
);
|
||||
)
|
||||
;
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -58,8 +58,6 @@
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
IntelFrameworkPkg/IntelFrameworkPkg.dec
|
||||
IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
|
||||
|
||||
|
||||
[LibraryClasses]
|
||||
PeCoffLib
|
||||
@ -91,10 +89,10 @@
|
||||
gEfiPeiS3ResumePpiGuid # PPI SOMETIMES_CONSUMED
|
||||
gEfiPeiRecoveryModulePpiGuid # PPI SOMETIMES_CONSUMED
|
||||
gEfiEndOfPeiSignalPpiGuid # PPI SOMETIMES_PRODUCED
|
||||
gEfiPeiFvFileLoaderPpiGuid # PPI SOMETIMES_PRODUCED
|
||||
gEfiDxeIplPpiGuid # PPI SOMETIMES_PRODUCED
|
||||
gEfiPeiPeCoffLoaderGuid
|
||||
|
||||
gEfiPeiDecompressPpiGuid
|
||||
gEfiPeiFirmwareVolumeInfoPpiGuid
|
||||
|
||||
[FeaturePcd.common]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSupportCustomDecompress
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -87,11 +87,10 @@ Returns:
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
BOOLEAN
|
||||
PeimDispatchReadiness (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN VOID *DependencyExpression,
|
||||
OUT BOOLEAN *Runnable
|
||||
IN VOID *DependencyExpression
|
||||
)
|
||||
/*++
|
||||
|
||||
@ -130,7 +129,6 @@ Returns:
|
||||
EVAL_STACK_ENTRY EvalStack[MAX_GRAMMAR_SIZE];
|
||||
|
||||
Iterator = DependencyExpression;
|
||||
*Runnable = FALSE;
|
||||
|
||||
StackPtr = &EvalStack[0];
|
||||
|
||||
@ -149,7 +147,7 @@ Returns:
|
||||
// EvalStack on the push
|
||||
//
|
||||
if (StackPtr > &EvalStack[MAX_GRAMMAR_SIZE-1]) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
@ -170,7 +168,7 @@ Returns:
|
||||
// did two POPs.
|
||||
//
|
||||
if (StackPtr < &EvalStack[2]) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
@ -208,10 +206,9 @@ Returns:
|
||||
// an error in the dependency grammar, so return EFI_INVALID_PARAMETER.
|
||||
//
|
||||
if (StackPtr != &EvalStack[0]) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
return FALSE;
|
||||
}
|
||||
*Runnable = IsPpiInstalled (PeiServices, StackPtr);
|
||||
return EFI_SUCCESS;
|
||||
return IsPpiInstalled (PeiServices, StackPtr);
|
||||
break;
|
||||
|
||||
case (EFI_DEP_NOT):
|
||||
@ -222,7 +219,7 @@ Returns:
|
||||
// did a POP.
|
||||
//
|
||||
if (StackPtr < &EvalStack[1]) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
return FALSE;
|
||||
}
|
||||
(StackPtr-1)->Result = (BOOLEAN) !IsPpiInstalled (PeiServices, (StackPtr-1));
|
||||
(StackPtr-1)->Operator = NULL;
|
||||
@ -235,7 +232,7 @@ Returns:
|
||||
// EvalStack on the push
|
||||
//
|
||||
if (StackPtr > &EvalStack[MAX_GRAMMAR_SIZE-1]) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
return FALSE;
|
||||
}
|
||||
//
|
||||
// Iterator has increased by 1 after we retrieve the operand, so here we
|
||||
@ -255,7 +252,7 @@ Returns:
|
||||
//
|
||||
// The grammar should never arrive here
|
||||
//
|
||||
return EFI_INVALID_PARAMETER;
|
||||
return FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -23,12 +23,6 @@ Revision History
|
||||
|
||||
#include <PeiMain.h>
|
||||
|
||||
STATIC
|
||||
VOID *
|
||||
TransferOldDataToNewDataRange (
|
||||
IN PEI_CORE_INSTANCE *PrivateData
|
||||
);
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
InvokePeiCore (
|
||||
@ -36,11 +30,165 @@ InvokePeiCore (
|
||||
VOID *Context2
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
|
||||
VOID
|
||||
DiscoverPeimsAndOrderWithApriori (
|
||||
IN PEI_CORE_INSTANCE *Private,
|
||||
IN EFI_PEI_FV_HANDLE VolumeHandle
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Discover all Peims and optional Apriori file in one FV. There is at most one
|
||||
Apriori file in one FV.
|
||||
|
||||
Arguments:
|
||||
|
||||
Private - Pointer to the private data passed in from caller
|
||||
VolumeHandle - Fv handle.
|
||||
Returns:
|
||||
|
||||
NONE
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_PEI_FV_HANDLE FileHandle;
|
||||
EFI_PEI_FV_HANDLE AprioriFileHandle;
|
||||
EFI_GUID *Apriori;
|
||||
UINTN Index;
|
||||
UINTN Index2;
|
||||
UINTN PeimIndex;
|
||||
UINTN PeimCount;
|
||||
EFI_GUID *Guid;
|
||||
EFI_PEI_FV_HANDLE TempFileHandles[PEI_CORE_MAX_PEIM_PER_FV];
|
||||
EFI_GUID FileGuid[PEI_CORE_MAX_PEIM_PER_FV];
|
||||
|
||||
//
|
||||
// Walk the FV and find all the PEIMs and the Apriori file.
|
||||
//
|
||||
AprioriFileHandle = NULL;
|
||||
Private->CurrentFvFileHandles[0] = NULL;
|
||||
Guid = NULL;
|
||||
FileHandle = NULL;
|
||||
|
||||
//
|
||||
// If the current Fv has been scanned, directly get its cachable record.
|
||||
//
|
||||
if (Private->Fv[Private->CurrentPeimFvCount].ScanFv) {
|
||||
CopyMem (Private->CurrentFvFileHandles, Private->Fv[Private->CurrentPeimFvCount].FvFileHandles, sizeof (Private->CurrentFvFileHandles));
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// Go ahead to scan this Fv, and cache FileHandles within it.
|
||||
//
|
||||
for (PeimCount = 0; PeimCount < PEI_CORE_MAX_PEIM_PER_FV; PeimCount++) {
|
||||
Status = PeiFindFileEx (
|
||||
VolumeHandle,
|
||||
NULL,
|
||||
PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE,
|
||||
&FileHandle,
|
||||
&AprioriFileHandle
|
||||
);
|
||||
if (Status != EFI_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
|
||||
Private->CurrentFvFileHandles[PeimCount] = FileHandle;
|
||||
}
|
||||
|
||||
Private->AprioriCount = 0;
|
||||
if (AprioriFileHandle != NULL) {
|
||||
//
|
||||
// Read the Apriori file
|
||||
//
|
||||
Status = PeiServicesFfsFindSectionData (EFI_SECTION_RAW, &AprioriFileHandle, (VOID **) &Apriori);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
//
|
||||
// Calculate the number of PEIMs in the A Priori list
|
||||
//
|
||||
Private->AprioriCount = *(UINT32 *)(((EFI_FFS_FILE_HEADER *)AprioriFileHandle)->Size) & 0x00FFFFFF;
|
||||
Private->AprioriCount -= sizeof (EFI_FFS_FILE_HEADER) - sizeof (EFI_COMMON_SECTION_HEADER);
|
||||
Private->AprioriCount /= sizeof (EFI_GUID);
|
||||
|
||||
SetMem (FileGuid, sizeof (FileGuid), 0);
|
||||
for (Index = 0; Index < PeimCount; Index++) {
|
||||
//
|
||||
// Make an array of file name guids that matches the FileHandle array so we can convert
|
||||
// quickly from file name to file handle
|
||||
//
|
||||
CopyMem (&FileGuid[Index], &((EFI_FFS_FILE_HEADER *)Private->CurrentFvFileHandles[Index])->Name,sizeof(EFI_GUID));
|
||||
}
|
||||
|
||||
//
|
||||
// Walk through FileGuid array to find out who is invalid PEIM guid in Apriori file.
|
||||
// Add avalible PEIMs in Apriori file into TempFileHandles array at first.
|
||||
//
|
||||
Index2 = 0;
|
||||
for (Index = 0; Index2 < Private->AprioriCount; Index++) {
|
||||
while (Index2 < Private->AprioriCount) {
|
||||
Guid = ScanGuid (FileGuid, PeimCount * sizeof (EFI_GUID), &Apriori[Index2++]);
|
||||
if (Guid != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (Guid == NULL) {
|
||||
break;
|
||||
}
|
||||
PeimIndex = ((UINTN)Guid - (UINTN)&FileGuid[0])/sizeof (EFI_GUID);
|
||||
TempFileHandles[Index] = Private->CurrentFvFileHandles[PeimIndex];
|
||||
|
||||
//
|
||||
// Since we have copied the file handle we can remove it from this list.
|
||||
//
|
||||
Private->CurrentFvFileHandles[PeimIndex] = NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Update valid Aprioricount
|
||||
//
|
||||
Private->AprioriCount = Index;
|
||||
|
||||
//
|
||||
// Add in any PEIMs not in the Apriori file
|
||||
//
|
||||
for (;Index < PeimCount; Index++) {
|
||||
for (Index2 = 0; Index2 < PeimCount; Index2++) {
|
||||
if (Private->CurrentFvFileHandles[Index2] != NULL) {
|
||||
TempFileHandles[Index] = Private->CurrentFvFileHandles[Index2];
|
||||
Private->CurrentFvFileHandles[Index2] = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
//Index the end of array contains re-range Pei moudle.
|
||||
//
|
||||
TempFileHandles[Index] = NULL;
|
||||
|
||||
//
|
||||
// Private->CurrentFvFileHandles is currently in PEIM in the FV order.
|
||||
// We need to update it to start with files in the A Priori list and
|
||||
// then the remaining files in PEIM order.
|
||||
//
|
||||
CopyMem (Private->CurrentFvFileHandles, TempFileHandles, sizeof (Private->CurrentFvFileHandles));
|
||||
}
|
||||
}
|
||||
//
|
||||
// Cache the current Fv File Handle. So that we don't have to scan the Fv again.
|
||||
// Instead, we can retrieve the file handles within this Fv from cachable data.
|
||||
//
|
||||
Private->Fv[Private->CurrentPeimFvCount].ScanFv = TRUE;
|
||||
CopyMem (Private->Fv[Private->CurrentPeimFvCount].FvFileHandles, Private->CurrentFvFileHandles, sizeof (Private->CurrentFvFileHandles));
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
PeiDispatcher (
|
||||
IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
|
||||
IN PEI_CORE_INSTANCE *PrivateData,
|
||||
IN PEI_CORE_DISPATCH_DATA *DispatchData
|
||||
IN PEI_CORE_INSTANCE *Private
|
||||
)
|
||||
|
||||
/*++
|
||||
@ -64,24 +212,78 @@ Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
PEI_CORE_TEMP_POINTERS TempPtr;
|
||||
BOOLEAN NextFvFound;
|
||||
EFI_FIRMWARE_VOLUME_HEADER *NextFvAddress;
|
||||
EFI_FIRMWARE_VOLUME_HEADER *DefaultFvAddress;
|
||||
VOID *TopOfStack;
|
||||
PEI_CORE_PARAMETERS PeiCoreParameters;
|
||||
EFI_STATUS Status;
|
||||
UINT32 Index1;
|
||||
UINT32 Index2;
|
||||
EFI_PEI_SERVICES **PeiServices;
|
||||
VOID *PrivateInMem;
|
||||
EFI_PEI_FV_HANDLE VolumeHandle;
|
||||
EFI_PEI_FILE_HANDLE PeiCoreFileHandle;
|
||||
EFI_PEI_FILE_HANDLE PeimFileHandle;
|
||||
UINTN FvCount;
|
||||
UINTN PeimCount;
|
||||
UINT32 AuthenticationState;
|
||||
EFI_PHYSICAL_ADDRESS EntryPoint;
|
||||
EFI_PEIM_ENTRY_POINT PeimEntryPoint;
|
||||
BOOLEAN PeimNeedingDispatch;
|
||||
BOOLEAN PeimDispatchOnThisPass;
|
||||
UINTN SaveCurrentPeimCount;
|
||||
EFI_PEI_FILE_HANDLE SaveCurrentFileHandle;
|
||||
VOID *TopOfStack;
|
||||
PEI_CORE_PARAMETERS PeiCoreParameters;
|
||||
EFI_DEVICE_HANDLE_EXTENDED_DATA ExtendedData;
|
||||
|
||||
//
|
||||
// Debug data for uninstalled Peim list
|
||||
//
|
||||
EFI_GUID DebugFoundPeimList[32];
|
||||
EFI_DEVICE_HANDLE_EXTENDED_DATA ExtendedData;
|
||||
|
||||
//
|
||||
// save the Current FV Address so that we will not process it again if FindFv returns it later
|
||||
//
|
||||
DefaultFvAddress = DispatchData->BootFvAddress;
|
||||
PeiServices = &Private->PS;
|
||||
PeimEntryPoint = NULL;
|
||||
PeimFileHandle = NULL;
|
||||
|
||||
if ((Private->PeiMemoryInstalled) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {
|
||||
//
|
||||
// Once real memory is available, shadow the RegisterForShadow modules. And meanwhile
|
||||
// update the modules' status from PEIM_STATE_REGISITER_FOR_SHADOW to PEIM_STATE_DONE.
|
||||
//
|
||||
SaveCurrentPeimCount = Private->CurrentPeimCount;
|
||||
SaveCurrentFileHandle = Private->CurrentFileHandle;
|
||||
|
||||
for (Index1 = 0;Index1 <= Private->CurrentPeimFvCount; Index1++) {
|
||||
for (Index2 = 0; (Index2 < PEI_CORE_MAX_PEIM_PER_FV) && (Private->Fv[Index1].FvFileHandles[Index2] != NULL); Index2++) {
|
||||
if (Private->Fv[Index1].PeimState[Index2] == PEIM_STATE_REGISITER_FOR_SHADOW) {
|
||||
PeimFileHandle = Private->Fv[Index1].FvFileHandles[Index2];
|
||||
Status = PeiLoadImage (
|
||||
&Private->PS,
|
||||
PeimFileHandle,
|
||||
&EntryPoint,
|
||||
&AuthenticationState
|
||||
);
|
||||
if (Status == EFI_SUCCESS) {
|
||||
//
|
||||
// PEIM_STATE_REGISITER_FOR_SHADOW move to PEIM_STATE_DONE
|
||||
//
|
||||
Private->Fv[Index1].PeimState[Index2]++;
|
||||
Private->CurrentFileHandle = PeimFileHandle;
|
||||
Private->CurrentPeimCount = Index2;
|
||||
//
|
||||
// Call the PEIM entry point
|
||||
//
|
||||
PeimEntryPoint = (EFI_PEIM_ENTRY_POINT)(UINTN)EntryPoint;
|
||||
|
||||
PERF_START (0, "PEIM", NULL, 0);
|
||||
PeimEntryPoint(PeimFileHandle, &Private->PS);
|
||||
PERF_END (0, "PEIM", NULL, 0);
|
||||
}
|
||||
|
||||
//
|
||||
// Process the Notify list and dispatch any notifies for
|
||||
// newly installed PPIs.
|
||||
//
|
||||
ProcessNotifyList (Private);
|
||||
}
|
||||
}
|
||||
}
|
||||
Private->CurrentFileHandle = SaveCurrentFileHandle;
|
||||
Private->CurrentPeimCount = SaveCurrentPeimCount;
|
||||
}
|
||||
|
||||
//
|
||||
// This is the main dispatch loop. It will search known FVs for PEIMs and
|
||||
@ -91,69 +293,50 @@ Returns:
|
||||
// FV where PEIMs are found in the order their dependencies are also
|
||||
// satisfied, this dipatcher should run only once.
|
||||
//
|
||||
for (;;) {
|
||||
//
|
||||
// This is the PEIM search loop. It will scan through all PEIMs it can find
|
||||
// looking for PEIMs to dispatch, and will dipatch them if they have not
|
||||
// already been dispatched and all of their dependencies are met.
|
||||
// If no more PEIMs can be found in this pass through all known FVs,
|
||||
// then it will break out of this loop.
|
||||
//
|
||||
for (;;) {
|
||||
do {
|
||||
PeimNeedingDispatch = FALSE;
|
||||
PeimDispatchOnThisPass = FALSE;
|
||||
|
||||
Status = FindNextPeim (
|
||||
&PrivateData->PS,
|
||||
DispatchData->CurrentFvAddress,
|
||||
&DispatchData->CurrentPeimAddress
|
||||
);
|
||||
for (FvCount = Private->CurrentPeimFvCount; FvCount < Private->FvCount; FvCount++) {
|
||||
Private->CurrentPeimFvCount = FvCount;
|
||||
VolumeHandle = Private->Fv[FvCount].FvHeader;
|
||||
|
||||
if (Private->CurrentPeimCount == 0) {
|
||||
//
|
||||
// When going through each FV, at first, search Apriori file to
|
||||
// reorder all PEIMs to ensure the PEIMs in Apriori file to get
|
||||
// dispatch at first.
|
||||
//
|
||||
DiscoverPeimsAndOrderWithApriori (Private, VolumeHandle);
|
||||
}
|
||||
|
||||
//
|
||||
// If we found a PEIM, check if it is dispatched. If so, go to the
|
||||
// next PEIM. If not, dispatch it if its dependencies are satisfied.
|
||||
// If its dependencies are not satisfied, go to the next PEIM.
|
||||
// Start to dispatch all modules within the current Fv.
|
||||
//
|
||||
if (Status == EFI_SUCCESS) {
|
||||
for (PeimCount = Private->CurrentPeimCount;
|
||||
(PeimCount < PEI_CORE_MAX_PEIM_PER_FV) && (Private->CurrentFvFileHandles[PeimCount] != NULL);
|
||||
PeimCount++) {
|
||||
Private->CurrentPeimCount = PeimCount;
|
||||
PeimFileHandle = Private->CurrentFileHandle = Private->CurrentFvFileHandles[PeimCount];
|
||||
|
||||
DEBUG_CODE_BEGIN ();
|
||||
|
||||
//
|
||||
// Fill list of found Peims for later list of those not installed
|
||||
//
|
||||
CopyMem (
|
||||
&DebugFoundPeimList[DispatchData->CurrentPeim],
|
||||
&DispatchData->CurrentPeimAddress->Name,
|
||||
sizeof (EFI_GUID)
|
||||
);
|
||||
|
||||
DEBUG_CODE_END ();
|
||||
|
||||
if (!Dispatched (
|
||||
DispatchData->CurrentPeim,
|
||||
DispatchData->DispatchedPeimBitMap
|
||||
)) {
|
||||
if (DepexSatisfied (&PrivateData->PS, DispatchData->CurrentPeimAddress)) {
|
||||
if (Private->Fv[FvCount].PeimState[PeimCount] == PEIM_STATE_NOT_DISPATCHED) {
|
||||
if (!DepexSatisfied (Private, PeimFileHandle, PeimCount)) {
|
||||
PeimNeedingDispatch = TRUE;
|
||||
} else {
|
||||
Status = PeiLoadImage (
|
||||
&PrivateData->PS,
|
||||
DispatchData->CurrentPeimAddress,
|
||||
&TempPtr.Raw
|
||||
PeiServices,
|
||||
PeimFileHandle,
|
||||
&EntryPoint,
|
||||
&AuthenticationState
|
||||
);
|
||||
if (Status == EFI_SUCCESS) {
|
||||
|
||||
if ((Status == EFI_SUCCESS)) {
|
||||
//
|
||||
// The PEIM has its dependencies satisfied, and its entry point
|
||||
// has been found, so invoke it.
|
||||
//
|
||||
PERF_START (
|
||||
(VOID *) (UINTN) (DispatchData->CurrentPeimAddress),
|
||||
"PEIM",
|
||||
NULL,
|
||||
0
|
||||
);
|
||||
PERF_START (0, "PEIM", NULL, 0);
|
||||
|
||||
//
|
||||
// BUGBUG: Used to be EFI_PEI_REPORT_STATUS_CODE_CODE
|
||||
//
|
||||
ExtendedData.Handle = (EFI_HANDLE)DispatchData->CurrentPeimAddress;
|
||||
ExtendedData.Handle = (EFI_HANDLE)PeimFileHandle;
|
||||
|
||||
REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
|
||||
EFI_PROGRESS_CODE,
|
||||
@ -162,24 +345,19 @@ Returns:
|
||||
sizeof (ExtendedData)
|
||||
);
|
||||
|
||||
//
|
||||
// Is this a authentic image
|
||||
//
|
||||
Status = VerifyPeim (
|
||||
&PrivateData->PS,
|
||||
DispatchData->CurrentPeimAddress
|
||||
);
|
||||
|
||||
if (Status != EFI_SECURITY_VIOLATION) {
|
||||
Status = VerifyPeim (Private, VolumeHandle, PeimFileHandle);
|
||||
if (Status != EFI_SECURITY_VIOLATION && (AuthenticationState == 0)) {
|
||||
//
|
||||
// PEIM_STATE_NOT_DISPATCHED move to PEIM_STATE_DISPATCHED
|
||||
//
|
||||
Private->Fv[FvCount].PeimState[PeimCount]++;
|
||||
|
||||
//
|
||||
// BUGBUG: Before enable PI, we need cast EFI_FFS_FILE_HEADER* to EFI_PEI_FILE_HANDLE*
|
||||
// Because we use new MdePkg's definition, but they are binary compatible in fact.
|
||||
// Call the PEIM entry point
|
||||
//
|
||||
Status = TempPtr.PeimEntry (
|
||||
(EFI_PEI_FILE_HANDLE*)DispatchData->CurrentPeimAddress,
|
||||
&PrivateData->PS
|
||||
);
|
||||
PeimEntryPoint = (EFI_PEIM_ENTRY_POINT)(UINTN)EntryPoint;
|
||||
PeimEntryPoint (PeimFileHandle, PeiServices);
|
||||
PeimDispatchOnThisPass = TRUE;
|
||||
}
|
||||
|
||||
REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
|
||||
@ -188,189 +366,146 @@ Returns:
|
||||
(VOID *)(&ExtendedData),
|
||||
sizeof (ExtendedData)
|
||||
);
|
||||
PERF_END (0, "PEIM", NULL, 0);
|
||||
|
||||
PERF_END ((VOID *) (UINTN) (DispatchData->CurrentPeimAddress), "PEIM", NULL, 0);
|
||||
}
|
||||
|
||||
//
|
||||
// Process the Notify list and dispatch any notifies for
|
||||
// newly installed PPIs.
|
||||
//
|
||||
ProcessNotifyList (Private);
|
||||
|
||||
//
|
||||
// If permanent memory was discovered and installed by this
|
||||
// PEIM, shadow PEI Core and switch the stacks to the new memory.
|
||||
//
|
||||
if (Private->SwitchStackSignal) {
|
||||
|
||||
//
|
||||
// Mark the PEIM as dispatched so we don't attempt to run it again
|
||||
// Make sure we don't retry the same PEIM that added memory
|
||||
//
|
||||
SetDispatched (
|
||||
&PrivateData->PS,
|
||||
DispatchData->CurrentPeim,
|
||||
&DispatchData->DispatchedPeimBitMap
|
||||
Private->CurrentPeimCount++;
|
||||
|
||||
//
|
||||
// Migrate IDT from CAR into real memory, so after stack switches to
|
||||
// the new memory, the caller can get memory version PeiServiceTable.
|
||||
//
|
||||
//MigrateIdtTable (PeiServices);
|
||||
//
|
||||
// Since we are at dispatch level, only the Core's private data
|
||||
// is preserved, nobody else should have any data on the stack.
|
||||
// So we need to copy PEI core instance data to memory.
|
||||
//
|
||||
PrivateInMem = AllocateCopyPool (sizeof (PEI_CORE_INSTANCE), Private);
|
||||
ASSERT (PrivateInMem != NULL);
|
||||
|
||||
//
|
||||
// Shadow PEI Core. When permanent memory is avaiable, shadow
|
||||
// PEI Core and PEIMs to get high performance.
|
||||
//
|
||||
PeiCoreFileHandle = NULL;
|
||||
//
|
||||
// Find the PEI Core in the BFV
|
||||
//
|
||||
Status = PeiFindFileEx (
|
||||
(EFI_PEI_FV_HANDLE)Private->Fv[0].FvHeader,
|
||||
NULL,
|
||||
EFI_FV_FILETYPE_PEI_CORE,
|
||||
&PeiCoreFileHandle,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Shadow PEI Core into memory so it will run faster
|
||||
//
|
||||
Status = PeiLoadImage (PeiServices, PeiCoreFileHandle, &EntryPoint, &AuthenticationState);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Switch to memory based stack and reenter PEI Core that has been
|
||||
// shadowed to memory.
|
||||
//
|
||||
//
|
||||
// Adjust the top of stack to be aligned at CPU_STACK_ALIGNMENT
|
||||
//
|
||||
TopOfStack = (VOID *)((UINTN)Private->StackBase + (UINTN)Private->StackSize - CPU_STACK_ALIGNMENT);
|
||||
TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
|
||||
|
||||
PeiCoreParameters.SecCoreData = SecCoreData;
|
||||
PeiCoreParameters.PpiList = NULL;
|
||||
PeiCoreParameters.Data = PrivateInMem;
|
||||
ASSERT (PeiCoreParameters.Data != 0);
|
||||
|
||||
PeiSwitchStacks (
|
||||
InvokePeiCore,
|
||||
(VOID*) (UINTN) PeiCore,
|
||||
(VOID*) &PeiCoreParameters,
|
||||
TopOfStack,
|
||||
(VOID*)(UINTN)Private->StackBase
|
||||
);
|
||||
}
|
||||
|
||||
if ((Private->PeiMemoryInstalled) && (Private->Fv[FvCount].PeimState[PeimCount] == PEIM_STATE_REGISITER_FOR_SHADOW) && \
|
||||
(Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {
|
||||
//
|
||||
// If memory is availble we shadow images by default for performance reasons.
|
||||
// We call the entry point a 2nd time so the module knows it's shadowed.
|
||||
//
|
||||
//PERF_START (PeiServices, L"PEIM", PeimFileHandle, 0);
|
||||
PeimEntryPoint (PeimFileHandle, PeiServices);
|
||||
//PERF_END (PeiServices, L"PEIM", PeimFileHandle, 0);
|
||||
|
||||
//
|
||||
// PEIM_STATE_REGISITER_FOR_SHADOW move to PEIM_STATE_DONE
|
||||
//
|
||||
Private->Fv[FvCount].PeimState[PeimCount]++;
|
||||
|
||||
//
|
||||
// Process the Notify list and dispatch any notifies for
|
||||
// newly installed PPIs.
|
||||
//
|
||||
ProcessNotifyList (&PrivateData->PS);
|
||||
|
||||
//
|
||||
// If real system memory was discovered and installed by this
|
||||
// PEIM, switch the stacks to the new memory. Since we are
|
||||
// at dispatch level, only the Core's private data is preserved,
|
||||
// nobody else should have any data on the stack.
|
||||
//
|
||||
if (PrivateData->SwitchStackSignal) {
|
||||
//
|
||||
// Adjust the top of stack to be aligned at CPU_STACK_ALIGNMENT
|
||||
//
|
||||
TopOfStack = (VOID *)((UINTN)PrivateData->StackBase + (UINTN)PrivateData->StackSize - CPU_STACK_ALIGNMENT);
|
||||
TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
|
||||
|
||||
PeiCoreParameters.SecCoreData = SecCoreData;
|
||||
PeiCoreParameters.PpiList = NULL;
|
||||
PeiCoreParameters.Data = TransferOldDataToNewDataRange (PrivateData);
|
||||
ASSERT (PeiCoreParameters.Data != 0);
|
||||
|
||||
PeiSwitchStacks (
|
||||
InvokePeiCore,
|
||||
(VOID*) (UINTN) PeiCore,
|
||||
(VOID*) &PeiCoreParameters,
|
||||
TopOfStack,
|
||||
(VOID*)(UINTN)PrivateData->StackBase
|
||||
);
|
||||
}
|
||||
ProcessNotifyList (Private);
|
||||
}
|
||||
}
|
||||
}
|
||||
DispatchData->CurrentPeim++;
|
||||
continue;
|
||||
|
||||
} else {
|
||||
|
||||
//
|
||||
// If we could not find another PEIM in the current FV, go try
|
||||
// the FindFv PPI to look in other FVs for more PEIMs. If we can
|
||||
// not locate the FindFv PPI, or if the FindFv PPI can not find
|
||||
// anymore FVs, then exit the PEIM search loop.
|
||||
//
|
||||
if (DispatchData->FindFv == NULL) {
|
||||
Status = PeiServicesLocatePpi (
|
||||
&gEfiFindFvPpiGuid,
|
||||
0,
|
||||
NULL,
|
||||
(VOID **)&DispatchData->FindFv
|
||||
);
|
||||
if (Status != EFI_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
NextFvFound = FALSE;
|
||||
while (!NextFvFound) {
|
||||
Status = DispatchData->FindFv->FindFv (
|
||||
DispatchData->FindFv,
|
||||
&PrivateData->PS,
|
||||
&DispatchData->CurrentFv,
|
||||
&NextFvAddress
|
||||
);
|
||||
//
|
||||
// if there is no next fv, get out of this loop of finding FVs
|
||||
//
|
||||
if (Status != EFI_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
//
|
||||
// don't process the default Fv again. (we don't know the order in which the hobs were created)
|
||||
//
|
||||
if ((NextFvAddress != DefaultFvAddress) &&
|
||||
(NextFvAddress != DispatchData->CurrentFvAddress)) {
|
||||
|
||||
//
|
||||
// VerifyFv() is currently returns SUCCESS all the time, add code to it to
|
||||
// actually verify the given FV
|
||||
//
|
||||
Status = VerifyFv (NextFvAddress);
|
||||
if (Status == EFI_SUCCESS) {
|
||||
NextFvFound = TRUE;
|
||||
DispatchData->CurrentFvAddress = NextFvAddress;
|
||||
DispatchData->CurrentPeimAddress = NULL;
|
||||
//
|
||||
// current PRIM number (CurrentPeim) must continue as is, don't reset it here
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
// if there is no next fv, get out of this loop of dispatching PEIMs
|
||||
//
|
||||
if (!NextFvFound) {
|
||||
break;
|
||||
}
|
||||
//
|
||||
// continue in the inner for(;;) loop with a new FV;
|
||||
//
|
||||
}
|
||||
|
||||
//
|
||||
// We set to NULL here to optimize the 2nd entry to this routine after
|
||||
// memory is found. This reprevents rescanning of the FV. We set to
|
||||
// NULL here so we start at the begining of the next FV
|
||||
//
|
||||
Private->CurrentFileHandle = NULL;
|
||||
Private->CurrentPeimCount = 0;
|
||||
//
|
||||
// Before walking through the next FV,Private->CurrentFvFileHandles[]should set to NULL
|
||||
//
|
||||
SetMem (Private->CurrentFvFileHandles, sizeof (Private->CurrentFvFileHandles), 0);
|
||||
}
|
||||
|
||||
//
|
||||
// If all the PEIMs that we have found have been dispatched, then
|
||||
// there is nothing left to dispatch and we don't need to go search
|
||||
// through all PEIMs again.
|
||||
// Before making another pass, we should set Private->CurrentPeimFvCount =0 to go
|
||||
// through all the FV.
|
||||
//
|
||||
if ((~(DispatchData->DispatchedPeimBitMap) &
|
||||
((1 << DispatchData->CurrentPeim)-1)) == 0) {
|
||||
break;
|
||||
}
|
||||
Private->CurrentPeimFvCount = 0;
|
||||
|
||||
//
|
||||
// Check if no more PEIMs that depex was satisfied
|
||||
// PeimNeedingDispatch being TRUE means we found a PEIM that did not get
|
||||
// dispatched. So we need to make another pass
|
||||
//
|
||||
if (DispatchData->DispatchedPeimBitMap == DispatchData->PreviousPeimBitMap) {
|
||||
break;
|
||||
}
|
||||
// PeimDispatchOnThisPass being TRUE means we dispatched a PEIM on this
|
||||
// pass. If we did not dispatch a PEIM there is no point in trying again
|
||||
// as it will fail the next time too (nothing has changed).
|
||||
//
|
||||
} while (PeimNeedingDispatch && PeimDispatchOnThisPass);
|
||||
|
||||
//
|
||||
// Case when Depex is not satisfied and has to traverse the list again
|
||||
//
|
||||
DispatchData->CurrentPeim = 0;
|
||||
DispatchData->CurrentPeimAddress = 0;
|
||||
DispatchData->PreviousPeimBitMap = DispatchData->DispatchedPeimBitMap;
|
||||
|
||||
//
|
||||
// don't go back to the loop without making sure that the CurrentFvAddress is the
|
||||
// same as the 1st (or default) FV we started with. otherwise we will interpret the bimap wrongly and
|
||||
// mess it up, always start processing the PEIMs from the default FV just like in the first time around.
|
||||
//
|
||||
DispatchData->CurrentFv = 0;
|
||||
DispatchData->CurrentFvAddress = DefaultFvAddress;
|
||||
}
|
||||
|
||||
DEBUG_CODE_BEGIN ();
|
||||
//
|
||||
// Debug data for uninstalled Peim list
|
||||
//
|
||||
UINT32 DebugNotDispatchedBitmap;
|
||||
UINT8 DebugFoundPeimPoint;
|
||||
|
||||
DebugFoundPeimPoint = 0;
|
||||
//
|
||||
// Get bitmap of Peims that were not dispatched,
|
||||
//
|
||||
|
||||
DebugNotDispatchedBitmap = ((DispatchData->DispatchedPeimBitMap) ^ ((1 << DispatchData->CurrentPeim)-1));
|
||||
//
|
||||
// Scan bitmap of Peims not installed and print GUIDS
|
||||
//
|
||||
while (DebugNotDispatchedBitmap != 0) {
|
||||
if ((DebugNotDispatchedBitmap & 1) != 0) {
|
||||
DEBUG ((EFI_D_INFO, "WARNING -> InstallPpi: Not Installed: %g\n",
|
||||
&DebugFoundPeimList[DebugFoundPeimPoint]
|
||||
));
|
||||
}
|
||||
DebugFoundPeimPoint++;
|
||||
DebugNotDispatchedBitmap >>= 1;
|
||||
}
|
||||
|
||||
DEBUG_CODE_END ();
|
||||
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
VOID
|
||||
InitializeDispatcherData (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN PEI_CORE_INSTANCE *PrivateData,
|
||||
IN PEI_CORE_INSTANCE *OldCoreData,
|
||||
IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData
|
||||
)
|
||||
@ -395,87 +530,19 @@ Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
PEI_CORE_INSTANCE *PrivateData;
|
||||
|
||||
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
|
||||
|
||||
if (OldCoreData == NULL) {
|
||||
PrivateData->DispatchData.CurrentFvAddress = (EFI_FIRMWARE_VOLUME_HEADER *) SecCoreData->BootFirmwareVolumeBase;
|
||||
PrivateData->DispatchData.BootFvAddress = (EFI_FIRMWARE_VOLUME_HEADER *) SecCoreData->BootFirmwareVolumeBase;
|
||||
} else {
|
||||
|
||||
//
|
||||
// Current peim has been dispatched, but not count
|
||||
//
|
||||
PrivateData->DispatchData.CurrentPeim = (UINT8)(OldCoreData->DispatchData.CurrentPeim + 1);
|
||||
PeiInitializeFv (PrivateData, SecCoreData);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
Dispatched (
|
||||
IN UINT8 CurrentPeim,
|
||||
IN UINT32 DispatchedPeimBitMap
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This routine checks to see if a particular PEIM has been dispatched during
|
||||
the PEI core dispatch.
|
||||
|
||||
Arguments:
|
||||
CurrentPeim - The PEIM/FV in the bit array to check.
|
||||
DispatchedPeimBitMap - Bit array, each bit corresponds to a PEIM/FV.
|
||||
|
||||
Returns:
|
||||
TRUE - PEIM already dispatched
|
||||
FALSE - Otherwise
|
||||
|
||||
--*/
|
||||
{
|
||||
return (BOOLEAN)((DispatchedPeimBitMap & (1 << CurrentPeim)) != 0);
|
||||
}
|
||||
|
||||
VOID
|
||||
SetDispatched (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN UINT8 CurrentPeim,
|
||||
OUT UINT32 *DispatchedPeimBitMap
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This routine sets a PEIM as having been dispatched once its entry
|
||||
point has been invoked.
|
||||
|
||||
Arguments:
|
||||
|
||||
PeiServices - The PEI core services table.
|
||||
CurrentPeim - The PEIM/FV in the bit array to check.
|
||||
DispatchedPeimBitMap - Bit array, each bit corresponds to a PEIM/FV.
|
||||
|
||||
Returns:
|
||||
None
|
||||
|
||||
--*/
|
||||
{
|
||||
//
|
||||
// Check if the total number of PEIMs exceed the bitmap.
|
||||
// CurrentPeim is 0-based
|
||||
//
|
||||
ASSERT (CurrentPeim < (sizeof (*DispatchedPeimBitMap) * 8));
|
||||
*DispatchedPeimBitMap |= (1 << CurrentPeim);
|
||||
return;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
DepexSatisfied (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN VOID *CurrentPeimAddress
|
||||
IN PEI_CORE_INSTANCE *Private,
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
IN UINTN PeimCount
|
||||
)
|
||||
/*++
|
||||
|
||||
@ -495,59 +562,27 @@ Returns:
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
INT8 *DepexData;
|
||||
BOOLEAN Runnable;
|
||||
VOID *DepexData;
|
||||
|
||||
Status = PeiServicesFfsFindSectionData (
|
||||
EFI_SECTION_PEI_DEPEX,
|
||||
CurrentPeimAddress,
|
||||
(VOID **)&DepexData
|
||||
);
|
||||
//
|
||||
// If there is no DEPEX, assume the module can be executed
|
||||
//
|
||||
if (PeimCount < Private->AprioriCount) {
|
||||
//
|
||||
// If its in the A priori file then we set Depex to TRUE
|
||||
//
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Status = PeiServicesFfsFindSectionData (EFI_SECTION_PEI_DEPEX, FileHandle, (VOID **) &DepexData);
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// If there is no DEPEX, assume the module can be executed
|
||||
//
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// Evaluate a given DEPEX
|
||||
//
|
||||
Status = PeimDispatchReadiness (
|
||||
PeiServices,
|
||||
DepexData,
|
||||
&Runnable
|
||||
);
|
||||
|
||||
return Runnable;
|
||||
}
|
||||
|
||||
STATIC
|
||||
VOID *
|
||||
TransferOldDataToNewDataRange (
|
||||
IN PEI_CORE_INSTANCE *PrivateData
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This routine transfers the contents of the pre-permanent memory
|
||||
PEI Core private data to a post-permanent memory data location.
|
||||
|
||||
Arguments:
|
||||
|
||||
PrivateData - Pointer to the current PEI Core private data pre-permanent memory
|
||||
|
||||
Returns:
|
||||
|
||||
Pointer to the PrivateData once the private data has been transferred to permanent memory
|
||||
|
||||
--*/
|
||||
{
|
||||
//
|
||||
//Build private HOB to PEI core to transfer old NEM-range data to new NEM-range
|
||||
//
|
||||
return BuildGuidDataHob (&gEfiPeiCorePrivateGuid, PrivateData, sizeof (PEI_CORE_INSTANCE));
|
||||
return PeimDispatchReadiness (&Private->PS, DepexData);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -589,6 +624,7 @@ PeiRegisterForShadow (
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This routine invoke the PeiCore's entry in new stack environment.
|
||||
|
||||
@ -627,7 +663,3 @@ InvokePeiCore (
|
||||
//
|
||||
ASSERT_EFI_ERROR (FALSE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
Copyright (c) 2006 - 2007, 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
|
||||
@ -21,7 +21,14 @@ Abstract:
|
||||
|
||||
#include <PeiMain.h>
|
||||
|
||||
#define GETOCCUPIEDSIZE(ActualSize, Alignment) \
|
||||
STATIC EFI_PEI_NOTIFY_DESCRIPTOR mNotifyOnFvInfoList = {
|
||||
(EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
|
||||
&gEfiPeiFirmwareVolumeInfoPpiGuid,
|
||||
FirmwareVolmeInfoPpiNotifyCallback
|
||||
};
|
||||
|
||||
|
||||
#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \
|
||||
(ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))
|
||||
|
||||
STATIC
|
||||
@ -121,12 +128,37 @@ Bugbug: For PEI performance reason, we comments this code at this time.
|
||||
}
|
||||
|
||||
STATIC
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
PeiFileHandleToVolume (
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
OUT EFI_PEI_FV_HANDLE *VolumeHandle
|
||||
)
|
||||
{
|
||||
UINTN Index;
|
||||
PEI_CORE_INSTANCE *PrivateData;
|
||||
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
|
||||
|
||||
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
|
||||
for (Index = 0; Index < PrivateData->FvCount; Index++) {
|
||||
FwVolHeader = PrivateData->Fv[Index].FvHeader;
|
||||
if (((UINT64) FileHandle > (UINT64) FwVolHeader ) && \
|
||||
((UINT64) FileHandle <= ((UINT64) FwVolHeader + FwVolHeader->FvLength - 1))) {
|
||||
*VolumeHandle = (EFI_PEI_FV_HANDLE)FwVolHeader;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
PeiFfsFindNextFileEx (
|
||||
IN EFI_FV_FILETYPE SearchType,
|
||||
IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
|
||||
IN OUT EFI_FFS_FILE_HEADER **FileHeader,
|
||||
IN BOOLEAN Flag
|
||||
PeiFindFileEx (
|
||||
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
|
||||
)
|
||||
/*++
|
||||
|
||||
@ -144,53 +176,63 @@ Arguments:
|
||||
FileHeader - Pointer to the current file from which to begin searching.
|
||||
This pointer will be updated upon return to reflect the file found.
|
||||
Flag - Indicator for if this is for PEI Dispath search
|
||||
|
||||
Returns:
|
||||
EFI_NOT_FOUND - No files matching the search criteria were found
|
||||
EFI_SUCCESS
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_FFS_FILE_HEADER *FfsFileHeader;
|
||||
UINT32 FileLength;
|
||||
UINT32 FileOccupiedSize;
|
||||
UINT32 FileOffset;
|
||||
UINT64 FvLength;
|
||||
UINT8 ErasePolarity;
|
||||
UINT8 FileState;
|
||||
|
||||
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
|
||||
EFI_FFS_FILE_HEADER **FileHeader;
|
||||
EFI_FFS_FILE_HEADER *FfsFileHeader;
|
||||
EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExHeaderInfo;
|
||||
UINT32 FileLength;
|
||||
UINT32 FileOccupiedSize;
|
||||
UINT32 FileOffset;
|
||||
UINT64 FvLength;
|
||||
UINT8 ErasePolarity;
|
||||
UINT8 FileState;
|
||||
|
||||
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FvHandle;
|
||||
FileHeader = (EFI_FFS_FILE_HEADER **)FileHandle;
|
||||
|
||||
FvLength = FwVolHeader->FvLength;
|
||||
if (FwVolHeader->Attributes & EFI_FVB2_ERASE_POLARITY) {
|
||||
if (FwVolHeader->Attributes & EFI_FVB_ERASE_POLARITY) {
|
||||
ErasePolarity = 1;
|
||||
} else {
|
||||
ErasePolarity = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// If FileHeader is not specified (NULL) start with the first file in the
|
||||
// firmware volume. Otherwise, start from the FileHeader.
|
||||
// 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.
|
||||
//
|
||||
if (*FileHeader == NULL) {
|
||||
if ((*FileHeader == NULL) || (FileName != NULL)) {
|
||||
FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->HeaderLength);
|
||||
if (FwVolHeader->ExtHeaderOffset != 0) {
|
||||
FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)(((UINT8 *)FwVolHeader) + FwVolHeader->ExtHeaderOffset);
|
||||
FfsFileHeader = (EFI_FFS_FILE_HEADER *)(((UINT8 *)FwVolExHeaderInfo) + FwVolExHeaderInfo->ExtHeaderSize);
|
||||
}
|
||||
} 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;
|
||||
FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);
|
||||
FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);
|
||||
FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)*FileHeader + FileOccupiedSize);
|
||||
}
|
||||
|
||||
FileOffset = (UINT32) ((UINT8 *)FfsFileHeader - (UINT8 *)FwVolHeader);
|
||||
ASSERT (FileOffset <= 0xFFFFFFFF);
|
||||
|
||||
while (FileOffset < (FvLength - sizeof(EFI_FFS_FILE_HEADER))) {
|
||||
while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) {
|
||||
//
|
||||
// Get FileState which is the highest bit of the State
|
||||
//
|
||||
FileState = GetFileState (ErasePolarity, FfsFileHeader);
|
||||
|
||||
switch (FileState) {
|
||||
|
||||
case EFI_FILE_HEADER_INVALID:
|
||||
@ -200,40 +242,44 @@ Returns:
|
||||
|
||||
case EFI_FILE_DATA_VALID:
|
||||
case EFI_FILE_MARKED_FOR_UPDATE:
|
||||
if (CalculateHeaderChecksum (FfsFileHeader) == 0) {
|
||||
FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
|
||||
FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);
|
||||
if (Flag) {
|
||||
if ((FfsFileHeader->Type == EFI_FV_FILETYPE_PEIM) ||
|
||||
(FfsFileHeader->Type == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER)) {
|
||||
|
||||
*FileHeader = FfsFileHeader;
|
||||
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
if ((SearchType == FfsFileHeader->Type) ||
|
||||
(SearchType == EFI_FV_FILETYPE_ALL)) {
|
||||
|
||||
*FileHeader = FfsFileHeader;
|
||||
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
FileOffset += FileOccupiedSize;
|
||||
FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
|
||||
} else {
|
||||
if (CalculateHeaderChecksum (FfsFileHeader) != 0) {
|
||||
ASSERT (FALSE);
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
|
||||
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) ||
|
||||
(FfsFileHeader->Type == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER)) {
|
||||
|
||||
*FileHeader = FfsFileHeader;
|
||||
return EFI_SUCCESS;
|
||||
} else if (AprioriFile != NULL) {
|
||||
if (FfsFileHeader->Type == EFI_FV_FILETYPE_FREEFORM) {
|
||||
if (CompareGuid (&FfsFileHeader->Name, &gPeiAprioriFileNameGuid)) {
|
||||
*AprioriFile = FfsFileHeader;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ((SearchType == FfsFileHeader->Type) || (SearchType == EFI_FV_FILETYPE_ALL)) {
|
||||
*FileHeader = FfsFileHeader;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
FileOffset += FileOccupiedSize;
|
||||
FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
|
||||
break;
|
||||
|
||||
case EFI_FILE_DELETED:
|
||||
FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
|
||||
FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);
|
||||
FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8);
|
||||
FileOffset += FileOccupiedSize;
|
||||
FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
|
||||
break;
|
||||
@ -247,6 +293,206 @@ Returns:
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
VOID
|
||||
PeiInitializeFv (
|
||||
IN PEI_CORE_INSTANCE *PrivateData,
|
||||
IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Initialize PeiCore Fv List.
|
||||
|
||||
Arguments:
|
||||
PrivateData - Pointer to PEI_CORE_INSTANCE.
|
||||
SecCoreData - Pointer to EFI_SEC_PEI_HAND_OFF.
|
||||
|
||||
Returns:
|
||||
NONE
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
//
|
||||
// The BFV must be the first entry. The Core FV support is stateless
|
||||
// The AllFV list has a single entry per FV in PEI.
|
||||
// The Fv list only includes FV that PEIMs will be dispatched from and
|
||||
// its File System Format is PI 1.0 definition.
|
||||
//
|
||||
PrivateData->FvCount = 1;
|
||||
PrivateData->Fv[0].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase;
|
||||
|
||||
PrivateData->AllFvCount = 1;
|
||||
PrivateData->AllFv[0] = (EFI_PEI_FV_HANDLE)PrivateData->Fv[0].FvHeader;
|
||||
|
||||
|
||||
//
|
||||
// Post a call-back for the FvInfoPPI services to expose
|
||||
// additional Fvs to PeiCore.
|
||||
//
|
||||
Status = PeiServicesNotifyPpi (&mNotifyOnFvInfoList);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FirmwareVolmeInfoPpiNotifyCallback (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
|
||||
IN VOID *Ppi
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Process Firmware Volum Information once FvInfoPPI install.
|
||||
|
||||
Arguments:
|
||||
|
||||
PeiServices - General purpose services available to every PEIM.
|
||||
|
||||
Returns:
|
||||
|
||||
Status - EFI_SUCCESS if the interface could be successfully
|
||||
installed
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT8 FvCount;
|
||||
EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *Fv;
|
||||
PEI_CORE_INSTANCE *PrivateData;
|
||||
|
||||
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
|
||||
|
||||
if (PrivateData->FvCount >= PEI_CORE_MAX_FV_SUPPORTED) {
|
||||
ASSERT (FALSE);
|
||||
}
|
||||
|
||||
Fv = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *)Ppi;
|
||||
|
||||
if (CompareGuid (&Fv->FvFormat, &gEfiFirmwareFileSystem2Guid)) {
|
||||
for (FvCount = 0; FvCount < PrivateData->FvCount; FvCount ++) {
|
||||
if ((UINTN)PrivateData->Fv[FvCount].FvHeader == (UINTN)Fv->FvInfo) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
PrivateData->Fv[PrivateData->FvCount++].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Fv->FvInfo;
|
||||
BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) Fv->FvInfo, (UINT64) Fv->FvInfoSize);
|
||||
}
|
||||
|
||||
//
|
||||
// Allways add to the All list
|
||||
//
|
||||
PrivateData->AllFv[PrivateData->AllFvCount++] = (EFI_PEI_FV_HANDLE)Fv->FvInfo;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
PeiFfsProcessSection (
|
||||
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_SECTION_TYPE SectionType,
|
||||
IN EFI_COMMON_SECTION_HEADER *Section,
|
||||
IN UINTN SectionSize,
|
||||
OUT VOID **OutputBuffer,
|
||||
OUT UINTN *OutputSize,
|
||||
OUT UINT32 *Authentication
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Go through the file to search SectionType section,
|
||||
when meeting an encapsuled section, search recursively.
|
||||
|
||||
Arguments:
|
||||
PeiServices - Pointer to the PEI Core Services Table.
|
||||
SearchType - Filter to find only section of this type.
|
||||
Section - From where to search.
|
||||
SectionSize - The file size to search.
|
||||
OutputBuffer - Pointer to the section to search.
|
||||
OutputSize - The size of the section to search.
|
||||
Authentication - Authenticate the section.
|
||||
|
||||
Returns:
|
||||
EFI_STATUS
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
UINT32 SectionLength;
|
||||
UINT32 ParsedLength;
|
||||
EFI_GUID_DEFINED_SECTION *GuidSection;
|
||||
EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *GuidSectionPpi;
|
||||
EFI_COMPRESSION_SECTION *CompressionSection;
|
||||
EFI_PEI_DECOMPRESS_PPI *DecompressPpi;
|
||||
VOID *PpiOutput;
|
||||
UINTN PpiOutputSize;
|
||||
|
||||
*OutputBuffer = NULL;
|
||||
ParsedLength = 0;
|
||||
while (ParsedLength < SectionSize) {
|
||||
if (Section->Type == SectionType) {
|
||||
*OutputBuffer = (VOID *)(Section + 1);
|
||||
return EFI_SUCCESS;
|
||||
} else if (Section->Type == EFI_SECTION_GUID_DEFINED) {
|
||||
GuidSection = (EFI_GUID_DEFINED_SECTION *)Section;
|
||||
Status = PeiServicesLocatePpi (&GuidSection->SectionDefinitionGuid, 0, NULL, (VOID **) &GuidSectionPpi);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = GuidSectionPpi->ExtractSection (
|
||||
GuidSectionPpi,
|
||||
Section,
|
||||
&PpiOutput,
|
||||
&PpiOutputSize,
|
||||
Authentication
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
return PeiFfsProcessSection (
|
||||
PeiServices,
|
||||
SectionType,
|
||||
PpiOutput,
|
||||
PpiOutputSize,
|
||||
OutputBuffer,
|
||||
OutputSize,
|
||||
Authentication
|
||||
);
|
||||
}
|
||||
}
|
||||
} else if (Section->Type == EFI_SECTION_COMPRESSION) {
|
||||
CompressionSection = (EFI_COMPRESSION_SECTION *)Section;
|
||||
Status = PeiServicesLocatePpi (&gEfiPeiDecompressPpiGuid, 0, NULL, (VOID **) &DecompressPpi);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = DecompressPpi->Decompress (
|
||||
DecompressPpi,
|
||||
CompressionSection,
|
||||
&PpiOutput,
|
||||
&PpiOutputSize
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
return PeiFfsProcessSection (
|
||||
PeiServices, SectionType, PpiOutput, PpiOutputSize, OutputBuffer, OutputSize, Authentication
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
@ -275,46 +521,33 @@ Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT32 FileSize;
|
||||
EFI_COMMON_SECTION_HEADER *Section;
|
||||
UINT32 SectionLength;
|
||||
UINT32 ParsedLength;
|
||||
EFI_FFS_FILE_HEADER *FfsFileHeader;
|
||||
EFI_FFS_FILE_HEADER *FfsFileHeader;
|
||||
UINT32 FileSize;
|
||||
EFI_COMMON_SECTION_HEADER *Section;
|
||||
UINTN OutputSize;
|
||||
UINT32 AuthenticationStatus;
|
||||
|
||||
|
||||
FfsFileHeader = (EFI_FFS_FILE_HEADER *)(FileHandle);
|
||||
|
||||
FfsFileHeader = (EFI_FFS_FILE_HEADER *) FileHandle;
|
||||
|
||||
//
|
||||
// Size is 24 bits wide so mask upper 8 bits.
|
||||
// Does not include FfsFileHeader header size
|
||||
// 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);
|
||||
|
||||
*SectionData = NULL;
|
||||
ParsedLength = 0;
|
||||
while (ParsedLength < FileSize) {
|
||||
if (Section->Type == SectionType) {
|
||||
*SectionData = (VOID *)(Section + 1);
|
||||
FileSize -= sizeof (EFI_FFS_FILE_HEADER);
|
||||
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
//
|
||||
// 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 = GETOCCUPIEDSIZE (SectionLength, 4);
|
||||
ASSERT (SectionLength != 0);
|
||||
ParsedLength += SectionLength;
|
||||
Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);
|
||||
}
|
||||
|
||||
return EFI_NOT_FOUND;
|
||||
|
||||
return PeiFfsProcessSection (
|
||||
PeiServices,
|
||||
SectionType,
|
||||
Section,
|
||||
FileSize,
|
||||
SectionData,
|
||||
&OutputSize,
|
||||
&AuthenticationStatus
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -346,11 +579,12 @@ Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
return PeiFfsFindNextFileEx (
|
||||
0,
|
||||
FwVolHeader,
|
||||
PeimFileHeader,
|
||||
TRUE
|
||||
return PeiFindFileEx (
|
||||
(EFI_PEI_FV_HANDLE) FwVolHeader,
|
||||
NULL,
|
||||
EFI_FV_FILETYPE_PEIM,
|
||||
(EFI_PEI_FILE_HANDLE *)PeimFileHeader,
|
||||
NULL
|
||||
);
|
||||
}
|
||||
|
||||
@ -387,20 +621,10 @@ Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
|
||||
EFI_FFS_FILE_HEADER **FileHeader;
|
||||
|
||||
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)VolumeHandle;
|
||||
FileHeader = (EFI_FFS_FILE_HEADER **) FileHandle;
|
||||
|
||||
return PeiFfsFindNextFileEx (
|
||||
SearchType,
|
||||
FwVolHeader,
|
||||
FileHeader,
|
||||
FALSE
|
||||
);
|
||||
return PeiFindFileEx (VolumeHandle, NULL, SearchType, FileHandle, NULL);
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiFvFindNextVolume (
|
||||
@ -433,52 +657,162 @@ Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
PEI_CORE_INSTANCE *PrivateData;
|
||||
EFI_STATUS Status;
|
||||
EFI_PEI_FIND_FV_PPI *FindFvPpi;
|
||||
UINT8 LocalInstance;
|
||||
EFI_FIRMWARE_VOLUME_HEADER **FwVolHeader;
|
||||
PEI_CORE_INSTANCE *Private;
|
||||
|
||||
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER **) VolumeHandle;
|
||||
Private = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
|
||||
if (VolumeHandle == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
LocalInstance = (UINT8) Instance;
|
||||
|
||||
Status = EFI_SUCCESS;
|
||||
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
|
||||
|
||||
if (FwVolHeader == NULL) {
|
||||
|
||||
return EFI_INVALID_PARAMETER;
|
||||
if (Instance >= Private->AllFvCount) {
|
||||
VolumeHandle = NULL;
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (Instance == 0) {
|
||||
*FwVolHeader = PrivateData->DispatchData.BootFvAddress;
|
||||
*VolumeHandle = Private->AllFv[Instance];
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
return Status;
|
||||
} else {
|
||||
//
|
||||
// Locate all instances of FindFV
|
||||
// Alternately, could use FV HOBs, but the PPI is cleaner
|
||||
//
|
||||
Status = PeiServicesLocatePpi (
|
||||
&gEfiFindFvPpiGuid,
|
||||
0,
|
||||
NULL,
|
||||
(VOID **)&FindFvPpi
|
||||
);
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiFfsFindFileByName (
|
||||
IN CONST EFI_GUID *FileName,
|
||||
IN EFI_PEI_FV_HANDLE VolumeHandle,
|
||||
OUT EFI_PEI_FILE_HANDLE *FileHandle
|
||||
)
|
||||
/*++
|
||||
|
||||
if (Status != EFI_SUCCESS) {
|
||||
Status = EFI_NOT_FOUND;
|
||||
} else {
|
||||
Status = FindFvPpi->FindFv (
|
||||
FindFvPpi,
|
||||
(EFI_PEI_SERVICES **)PeiServices,
|
||||
&LocalInstance,
|
||||
FwVolHeader
|
||||
);
|
||||
Routine Description:
|
||||
|
||||
}
|
||||
Given the input VolumeHandle, search for the next matching name file.
|
||||
|
||||
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_STATUS Status;
|
||||
if ((VolumeHandle == NULL) || (FileName == NULL) || (FileHandle == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
Status = PeiFindFileEx (VolumeHandle, FileName, 0, FileHandle, NULL);
|
||||
if (Status == EFI_NOT_FOUND) {
|
||||
*FileHandle = NULL;
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiFfsGetFileInfo (
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
OUT EFI_FV_FILE_INFO *FileInfo
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Collect information of given file.
|
||||
|
||||
Arguments:
|
||||
FileHandle - The handle to file.
|
||||
FileInfo - Pointer to the file information.
|
||||
|
||||
Returns:
|
||||
EFI_STATUS
|
||||
|
||||
--*/
|
||||
{
|
||||
UINT8 FileState;
|
||||
UINT8 ErasePolarity;
|
||||
EFI_FFS_FILE_HEADER *FileHeader;
|
||||
EFI_PEI_FV_HANDLE VolumeHandle;
|
||||
|
||||
if ((FileHandle == NULL) || (FileInfo == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve the FirmwareVolume which the file resides in.
|
||||
//
|
||||
if (!PeiFileHandleToVolume(FileHandle, &VolumeHandle)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (((EFI_FIRMWARE_VOLUME_HEADER*)VolumeHandle)->Attributes & EFI_FVB_ERASE_POLARITY) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiFfsGetVolumeInfo (
|
||||
IN EFI_PEI_FV_HANDLE VolumeHandle,
|
||||
OUT EFI_FV_INFO *VolumeInfo
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Collect information of given Fv Volume.
|
||||
|
||||
Arguments:
|
||||
VolumeHandle - The handle to Fv Volume.
|
||||
VolumeInfo - The pointer to volume information.
|
||||
|
||||
Returns:
|
||||
EFI_STATUS
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
|
||||
EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExHeaderInfo;
|
||||
|
||||
if (VolumeInfo == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(VolumeHandle);
|
||||
VolumeInfo->FvAttributes = FwVolHeader->Attributes;
|
||||
VolumeInfo->FvStart = FwVolHeader;
|
||||
VolumeInfo->FvSize = FwVolHeader->FvLength;
|
||||
CopyMem (&VolumeInfo->FvFormat, &FwVolHeader->FileSystemGuid,sizeof(EFI_GUID));
|
||||
|
||||
if (FwVolHeader->ExtHeaderOffset != 0) {
|
||||
FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER*)(((UINT8 *)FwVolHeader) + FwVolHeader->ExtHeaderOffset);
|
||||
CopyMem (&VolumeInfo->FvName, &FwVolExHeaderInfo->FvName, sizeof(EFI_GUID));
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -21,13 +21,33 @@ Abstract:
|
||||
|
||||
#include <PeiMain.h>
|
||||
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
|
||||
|
||||
Arguments:
|
||||
|
||||
FileHandle - The handle to the PE/COFF file
|
||||
FileOffset - The offset, in bytes, into the file to read
|
||||
ReadSize - The number of bytes to read from the file starting at FileOffset
|
||||
Buffer - A pointer to the buffer to read the data into.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
|
||||
|
||||
--*/
|
||||
|
||||
EFI_STATUS
|
||||
PeiLoadImage (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_FFS_FILE_HEADER *PeimFileHeader,
|
||||
OUT VOID **EntryPoint
|
||||
PeiLoadImageLoadImage (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg, OPTIONAL
|
||||
OUT UINT64 *ImageSizeArg, OPTIONAL
|
||||
OUT EFI_PHYSICAL_ADDRESS *EntryPoint,
|
||||
OUT UINT32 *AuthenticationState
|
||||
)
|
||||
/*++
|
||||
|
||||
@ -37,9 +57,247 @@ Routine Description:
|
||||
|
||||
Arguments:
|
||||
|
||||
PeiServices - The PEI core services table.
|
||||
PeimFileHeader - Pointer to the FFS file header of the image.
|
||||
EntryPoint - Pointer to entry point of specified image file for output.
|
||||
PeiServices - The PEI core services table.
|
||||
FileHandle - Pointer to the FFS file header of the image.
|
||||
ImageAddressArg - Pointer to PE/TE image.
|
||||
ImageSizeArg - Size of PE/TE image.
|
||||
EntryPoint - Pointer to entry point of specified image file for output.
|
||||
AuthenticationState - Pointer to attestation authentication state of image.
|
||||
|
||||
Returns:
|
||||
|
||||
Status - EFI_SUCCESS - Image is successfully loaded.
|
||||
EFI_NOT_FOUND - Fail to locate necessary PPI
|
||||
Others - Fail to load file.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiLoadImageLoadImageWrapper (
|
||||
IN CONST EFI_PEI_LOAD_FILE_PPI *This,
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg, OPTIONAL
|
||||
OUT UINT64 *ImageSizeArg, OPTIONAL
|
||||
OUT EFI_PHYSICAL_ADDRESS *EntryPoint,
|
||||
OUT UINT32 *AuthenticationState
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
The wrapper function of PeiLoadImageLoadImage().
|
||||
|
||||
Arguments:
|
||||
|
||||
This - Pointer to EFI_PEI_LOAD_FILE_PPI.
|
||||
PeiServices - The PEI core services table.
|
||||
FileHandle - Pointer to the FFS file header of the image.
|
||||
ImageAddressArg - Pointer to PE/TE image.
|
||||
ImageSizeArg - Size of PE/TE image.
|
||||
EntryPoint - Pointer to entry point of specified image file for output.
|
||||
AuthenticationState - Pointer to attestation authentication state of image.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_STATUS.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
STATIC EFI_PEI_LOAD_FILE_PPI mPeiLoadImagePpi = {
|
||||
PeiLoadImageLoadImageWrapper
|
||||
};
|
||||
|
||||
|
||||
STATIC EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList = {
|
||||
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
|
||||
&gEfiPeiLoadFilePpiGuid,
|
||||
&mPeiLoadImagePpi
|
||||
};
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiImageRead (
|
||||
IN VOID *FileHandle,
|
||||
IN UINTN FileOffset,
|
||||
IN OUT UINTN *ReadSize,
|
||||
OUT VOID *Buffer
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
|
||||
|
||||
Arguments:
|
||||
|
||||
FileHandle - The handle to the PE/COFF file
|
||||
FileOffset - The offset, in bytes, into the file to read
|
||||
ReadSize - The number of bytes to read from the file starting at FileOffset
|
||||
Buffer - A pointer to the buffer to read the data into.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
|
||||
|
||||
--*/
|
||||
{
|
||||
CHAR8 *Destination8;
|
||||
CHAR8 *Source8;
|
||||
UINTN Length;
|
||||
|
||||
Destination8 = Buffer;
|
||||
Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);
|
||||
Length = *ReadSize;
|
||||
while (Length--) {
|
||||
*(Destination8++) = *(Source8++);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
GetImageReadFunction (
|
||||
IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Support routine to return the Image Read
|
||||
|
||||
Arguments:
|
||||
|
||||
PeiServices - PEI Services Table
|
||||
|
||||
ImageContext - The context of the image being loaded
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - If Image function location is found
|
||||
|
||||
--*/
|
||||
{
|
||||
VOID* MemoryBuffer;
|
||||
|
||||
MemoryBuffer = AllocatePages (0x400 / EFI_PAGE_SIZE + 1);
|
||||
ASSERT (MemoryBuffer != NULL);
|
||||
|
||||
CopyMem (MemoryBuffer, (CONST VOID *) (UINTN) PeiImageRead, 0x400);
|
||||
|
||||
ImageContext->ImageRead = (PE_COFF_LOADER_READ_FILE) (UINTN) MemoryBuffer;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
LoadAndRelocatePeCoffImage (
|
||||
IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *PeiEfiPeiPeCoffLoader,
|
||||
IN VOID *Pe32Data,
|
||||
OUT EFI_PHYSICAL_ADDRESS *ImageAddress,
|
||||
OUT UINT64 *ImageSize,
|
||||
OUT EFI_PHYSICAL_ADDRESS *EntryPoint
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Loads and relocates a PE/COFF image into memory.
|
||||
|
||||
Arguments:
|
||||
|
||||
PeiEfiPeiPeCoffLoader - Pointer to a PE COFF loader protocol
|
||||
|
||||
Pe32Data - The base address of the PE/COFF file that is to be loaded and relocated
|
||||
|
||||
ImageAddress - The base address of the relocated PE/COFF image
|
||||
|
||||
ImageSize - The size of the relocated PE/COFF image
|
||||
|
||||
EntryPoint - The entry point of the relocated PE/COFF image
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_SUCCESS - The file was loaded and relocated
|
||||
|
||||
EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
|
||||
|
||||
ASSERT (PeiEfiPeiPeCoffLoader != NULL);
|
||||
|
||||
ZeroMem (&ImageContext, sizeof (ImageContext));
|
||||
ImageContext.Handle = Pe32Data;
|
||||
Status = GetImageReadFunction (&ImageContext);
|
||||
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
Status = PeiEfiPeiPeCoffLoader->GetImageInfo (PeiEfiPeiPeCoffLoader, &ImageContext);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
//
|
||||
// Allocate Memory for the image
|
||||
//
|
||||
ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) AllocatePages (EFI_SIZE_TO_PAGES ((UINT32) ImageContext.ImageSize));
|
||||
ASSERT (ImageContext.ImageAddress != 0);
|
||||
|
||||
//
|
||||
// Load the image to our new buffer
|
||||
//
|
||||
Status = PeiEfiPeiPeCoffLoader->LoadImage (PeiEfiPeiPeCoffLoader, &ImageContext);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
//
|
||||
// Relocate the image in our new buffer
|
||||
//
|
||||
Status = PeiEfiPeiPeCoffLoader->RelocateImage (PeiEfiPeiPeCoffLoader, &ImageContext);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Flush the instruction cache so the image data is written before we execute it
|
||||
//
|
||||
InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
|
||||
|
||||
*ImageAddress = ImageContext.ImageAddress;
|
||||
*ImageSize = ImageContext.ImageSize;
|
||||
*EntryPoint = ImageContext.EntryPoint;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
PeiLoadImageLoadImage (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg, OPTIONAL
|
||||
OUT UINT64 *ImageSizeArg, OPTIONAL
|
||||
OUT EFI_PHYSICAL_ADDRESS *EntryPoint,
|
||||
OUT UINT32 *AuthenticationState
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Routine for loading file image.
|
||||
|
||||
Arguments:
|
||||
|
||||
PeiServices - The PEI core services table.
|
||||
FileHandle - Pointer to the FFS file header of the image.
|
||||
ImageAddressArg - Pointer to PE/TE image.
|
||||
ImageSizeArg - Size of PE/TE image.
|
||||
EntryPoint - Pointer to entry point of specified image file for output.
|
||||
AuthenticationState - Pointer to attestation authentication state of image.
|
||||
|
||||
Returns:
|
||||
|
||||
@ -51,55 +309,63 @@ Returns:
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
VOID *Pe32Data;
|
||||
EFI_PEI_FV_FILE_LOADER_PPI *FvLoadFilePpi;
|
||||
EFI_PHYSICAL_ADDRESS ImageAddress;
|
||||
UINT64 ImageSize;
|
||||
EFI_PHYSICAL_ADDRESS ImageEntryPoint;
|
||||
EFI_TE_IMAGE_HEADER *TEImageHeader;
|
||||
UINT16 Machine;
|
||||
PEI_CORE_INSTANCE *Private;
|
||||
VOID *EntryPointArg;
|
||||
|
||||
*EntryPoint = NULL;
|
||||
*EntryPoint = 0;
|
||||
TEImageHeader = NULL;
|
||||
ImageSize = 0;
|
||||
*AuthenticationState = 0;
|
||||
|
||||
//
|
||||
// Try to find a PE32 section.
|
||||
// Try to find a TE section.
|
||||
//
|
||||
Status = PeiServicesFfsFindSectionData (
|
||||
EFI_SECTION_PE32,
|
||||
PeimFileHeader,
|
||||
EFI_SECTION_TE,
|
||||
FileHandle,
|
||||
&Pe32Data
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
TEImageHeader = (EFI_TE_IMAGE_HEADER *)Pe32Data;
|
||||
}
|
||||
//
|
||||
// If we didn't find a PE32 section, try to find a TE section.
|
||||
//
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = PeiServicesFfsFindSectionData (
|
||||
EFI_SECTION_TE,
|
||||
PeimFileHeader,
|
||||
(VOID **) &TEImageHeader
|
||||
EFI_SECTION_PE32,
|
||||
FileHandle,
|
||||
&Pe32Data
|
||||
);
|
||||
if (EFI_ERROR (Status) || TEImageHeader == NULL) {
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// There was not a PE32 or a TE section, so assume that it's a Compressed section
|
||||
// and use the LoadFile
|
||||
// PEI core only carry the loader function fro TE and PE32 executables
|
||||
// If this two section does not exist, just return.
|
||||
//
|
||||
Status = PeiServicesLocatePpi (
|
||||
&gEfiPeiFvFileLoaderPpiGuid,
|
||||
0,
|
||||
NULL,
|
||||
(VOID **)&FvLoadFilePpi
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
Private = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
|
||||
|
||||
Status = FvLoadFilePpi->FvLoadFile (
|
||||
FvLoadFilePpi,
|
||||
PeimFileHeader,
|
||||
&ImageAddress,
|
||||
&ImageSize,
|
||||
&ImageEntryPoint
|
||||
);
|
||||
if (Private->PeiMemoryInstalled &&
|
||||
(Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {
|
||||
{
|
||||
//
|
||||
// If memory is installed, perform the shadow operations
|
||||
//
|
||||
Status = LoadAndRelocatePeCoffImage (
|
||||
Private->PeCoffLoader,
|
||||
Pe32Data,
|
||||
&ImageAddress,
|
||||
&ImageSize,
|
||||
&ImageEntryPoint
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_NOT_FOUND;
|
||||
@ -109,23 +375,28 @@ Returns:
|
||||
// Got the entry point from ImageEntryPoint and ImageStartAddress
|
||||
//
|
||||
Pe32Data = (VOID *) ((UINTN) ImageAddress);
|
||||
*EntryPoint = (VOID *) ((UINTN) ImageEntryPoint);
|
||||
} else {
|
||||
*EntryPoint = ImageEntryPoint;
|
||||
}
|
||||
} else {
|
||||
if (TEImageHeader != NULL) {
|
||||
//
|
||||
// Retrieve the entry point from the TE image header
|
||||
//
|
||||
ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) TEImageHeader;
|
||||
*EntryPoint = (VOID *)((UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) +
|
||||
ImageSize = 0;
|
||||
*EntryPoint = (EFI_PHYSICAL_ADDRESS)((UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) +
|
||||
TEImageHeader->AddressOfEntryPoint - TEImageHeader->StrippedSize);
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// Retrieve the entry point from the PE/COFF image header
|
||||
//
|
||||
ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) Pe32Data;
|
||||
Status = PeCoffLoaderGetEntryPoint (Pe32Data, EntryPoint);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_NOT_FOUND;
|
||||
} else {
|
||||
//
|
||||
// Retrieve the entry point from the PE/COFF image header
|
||||
//
|
||||
ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) Pe32Data;
|
||||
ImageSize = 0;
|
||||
Status = PeCoffLoaderGetEntryPoint (Pe32Data, &EntryPointArg);
|
||||
*EntryPoint = (EFI_PHYSICAL_ADDRESS) (UINTN) EntryPointArg;
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,6 +411,14 @@ Returns:
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (ImageAddressArg != NULL) {
|
||||
*ImageAddressArg = ImageAddress;
|
||||
}
|
||||
|
||||
if (ImageSizeArg != NULL) {
|
||||
*ImageSizeArg = ImageSize;
|
||||
}
|
||||
|
||||
//
|
||||
// Print debug message: Loading PEIM at 0x12345678 EntryPoint=0x12345688 Driver.efi
|
||||
//
|
||||
@ -264,4 +543,175 @@ Returns:
|
||||
DEBUG ((EFI_D_INFO | EFI_D_LOAD, "\n"));
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiLoadImageLoadImageWrapper (
|
||||
IN CONST EFI_PEI_LOAD_FILE_PPI *This,
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg, OPTIONAL
|
||||
OUT UINT64 *ImageSizeArg, OPTIONAL
|
||||
OUT EFI_PHYSICAL_ADDRESS *EntryPoint,
|
||||
OUT UINT32 *AuthenticationState
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
The wrapper function of PeiLoadImageLoadImage().
|
||||
|
||||
Arguments:
|
||||
|
||||
This - Pointer to EFI_PEI_LOAD_FILE_PPI.
|
||||
PeiServices - The PEI core services table.
|
||||
FileHandle - Pointer to the FFS file header of the image.
|
||||
ImageAddressArg - Pointer to PE/TE image.
|
||||
ImageSizeArg - Size of PE/TE image.
|
||||
EntryPoint - Pointer to entry point of specified image file for output.
|
||||
AuthenticationState - Pointer to attestation authentication state of image.
|
||||
|
||||
Returns:
|
||||
|
||||
EFI_STATUS.
|
||||
|
||||
--*/
|
||||
{
|
||||
return PeiLoadImageLoadImage (
|
||||
GetPeiServicesTablePointer (),
|
||||
FileHandle,
|
||||
ImageAddressArg,
|
||||
ImageSizeArg,
|
||||
EntryPoint,
|
||||
AuthenticationState
|
||||
);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
PeiLoadImage (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
OUT EFI_PHYSICAL_ADDRESS *EntryPoint,
|
||||
OUT UINT32 *AuthenticationState
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Routine for load image file.
|
||||
|
||||
Arguments:
|
||||
|
||||
PeiServices - The PEI core services table.
|
||||
FileHandle - Pointer to the FFS file header of the image.
|
||||
EntryPoint - Pointer to entry point of specified image file for output.
|
||||
AuthenticationState - Pointer to attestation authentication state of image.
|
||||
|
||||
Returns:
|
||||
|
||||
Status - EFI_SUCCESS - Image is successfully loaded.
|
||||
EFI_NOT_FOUND - Fail to locate necessary PPI
|
||||
Others - Fail to load file.
|
||||
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS PpiStatus;
|
||||
EFI_STATUS Status;
|
||||
UINTN Index;
|
||||
EFI_PEI_LOAD_FILE_PPI *LoadFile;
|
||||
EFI_PHYSICAL_ADDRESS ImageAddress;
|
||||
UINT64 ImageSize;
|
||||
|
||||
//
|
||||
// If any instances of PEI_LOAD_FILE_PPI are installed, they are called.
|
||||
// one at a time, until one reports EFI_SUCCESS.
|
||||
//
|
||||
Index = 0;
|
||||
do {
|
||||
PpiStatus = PeiServicesLocatePpi (
|
||||
&gEfiPeiLoadFilePpiGuid,
|
||||
Index,
|
||||
NULL,
|
||||
(VOID **)&LoadFile
|
||||
);
|
||||
if (!EFI_ERROR (PpiStatus)) {
|
||||
Status = LoadFile->LoadFile (
|
||||
LoadFile,
|
||||
FileHandle,
|
||||
&ImageAddress,
|
||||
&ImageSize,
|
||||
EntryPoint,
|
||||
AuthenticationState
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
Index++;
|
||||
} while (!EFI_ERROR (PpiStatus));
|
||||
|
||||
//
|
||||
// If no instances reports EFI_SUCCESS, then build-in support for
|
||||
// the PE32+/TE XIP image format is used.
|
||||
//
|
||||
Status = PeiLoadImageLoadImage (
|
||||
PeiServices,
|
||||
FileHandle,
|
||||
NULL,
|
||||
NULL,
|
||||
EntryPoint,
|
||||
AuthenticationState
|
||||
);
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
InitializeImageServices (
|
||||
IN PEI_CORE_INSTANCE *PrivateData,
|
||||
IN PEI_CORE_INSTANCE *OldCoreData
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Regitser PeCoffLoader to PeiCore PrivateData. And install
|
||||
Pei Load File PPI.
|
||||
|
||||
Arguments:
|
||||
|
||||
PrivateData - Pointer to PEI_CORE_INSTANCE.
|
||||
OldCoreData - Pointer to PEI_CORE_INSTANCE.
|
||||
|
||||
Returns:
|
||||
|
||||
NONE.
|
||||
|
||||
--*/
|
||||
{
|
||||
//
|
||||
// Always update PeCoffLoader pointer as PEI core itself may get
|
||||
// shadowed into memory
|
||||
//
|
||||
PrivateData->PeCoffLoader = GetPeCoffLoaderProtocol ();
|
||||
|
||||
if (OldCoreData == NULL) {
|
||||
//
|
||||
// The first time we are XIP (running from FLASH). We need to remember the
|
||||
// FLASH address so we can reinstall the memory version that runs faster
|
||||
//
|
||||
PrivateData->XipLoadFile = &gPpiLoadFilePpiList;
|
||||
PeiServicesInstallPpi (PrivateData->XipLoadFile);
|
||||
} else {
|
||||
//
|
||||
// 2nd time we are running from memory so replace the XIP version with the
|
||||
// new memory version.
|
||||
//
|
||||
PeiServicesReInstallPpi (PrivateData->XipLoadFile, &gPpiLoadFilePpiList);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -23,7 +23,7 @@ Abstract:
|
||||
|
||||
VOID
|
||||
InitializeMemoryServices (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN PEI_CORE_INSTANCE *PrivateData,
|
||||
IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
|
||||
IN PEI_CORE_INSTANCE *OldCoreData
|
||||
)
|
||||
@ -49,9 +49,6 @@ Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
PEI_CORE_INSTANCE *PrivateData;
|
||||
|
||||
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
|
||||
PrivateData->SwitchStackSignal = FALSE;
|
||||
|
||||
if (OldCoreData == NULL) {
|
||||
@ -64,6 +61,8 @@ Returns:
|
||||
DEBUG_CODE_BEGIN ();
|
||||
PrivateData->SizeOfCacheAsRam = SecCoreData->PeiTemporaryRamSize + SecCoreData->StackSize;
|
||||
PrivateData->MaxTopOfCarHeap = (VOID *) ((UINTN) PrivateData->BottomOfCarHeap + (UINTN) PrivateData->SizeOfCacheAsRam);
|
||||
PrivateData->StackBase = (EFI_PHYSICAL_ADDRESS) (UINTN) SecCoreData->StackBase;
|
||||
PrivateData->StackSize = (UINT64) SecCoreData->StackSize;
|
||||
DEBUG_CODE_END ();
|
||||
|
||||
PrivateData->HobList.Raw = PrivateData->BottomOfCarHeap;
|
||||
@ -73,23 +72,13 @@ Returns:
|
||||
(EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData->BottomOfCarHeap,
|
||||
(UINTN) SecCoreData->PeiTemporaryRamSize
|
||||
);
|
||||
//
|
||||
// Copy PeiServices from ROM to Cache in PrivateData
|
||||
//
|
||||
CopyMem (&(PrivateData->ServiceTableShadow), *PeiServices, sizeof (EFI_PEI_SERVICES));
|
||||
|
||||
//
|
||||
// Set PS to point to ServiceTableShadow in Cache
|
||||
//
|
||||
PrivateData->PS = &(PrivateData->ServiceTableShadow);
|
||||
} else {
|
||||
//
|
||||
// Set PS to point to ServiceTableShadow in Cache one time after the
|
||||
// stack switched to main memory
|
||||
//
|
||||
PrivateData->PS = &(PrivateData->ServiceTableShadow);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -29,11 +29,14 @@ Revision History
|
||||
#include <Guid/StatusCodeDataTypeId.h>
|
||||
#include <Ppi/DxeIpl.h>
|
||||
#include <Ppi/MemoryDiscovered.h>
|
||||
#include <Ppi/FindFv.h>
|
||||
#include <Ppi/StatusCode.h>
|
||||
#include <Ppi/Security.h>
|
||||
#include <Ppi/Reset.h>
|
||||
#include <Ppi/FvLoadFile.h>
|
||||
#include <Ppi/FirmwareVolume.h>
|
||||
#include <Ppi/FirmwareVolumeInfo.h>
|
||||
#include <Ppi/Decompress.h>
|
||||
#include <Ppi/GuidedSectionExtraction.h>
|
||||
#include <Ppi/LoadFile.h>
|
||||
#include <Ppi/Security2.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/PeiCoreEntryPoint.h>
|
||||
#include <Library/BaseLib.h>
|
||||
@ -43,11 +46,15 @@ Revision History
|
||||
#include <Library/ReportStatusCodeLib.h>
|
||||
#include <Library/PeCoffGetEntryPointLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
#include <Library/CacheMaintenanceLib.h>
|
||||
#include <Library/TimerLib.h>
|
||||
#include <Library/PeCoffLoaderLib.h>
|
||||
#include <IndustryStandard/PeImage.h>
|
||||
#include <Library/PeiServicesTablePointerLib.h>
|
||||
|
||||
extern EFI_GUID gEfiPeiCorePrivateGuid;
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Guid/FirmwareFileSystem2.h>
|
||||
#include <Guid/AprioriFileName.h>
|
||||
#include <Guid/PeiPeCoffLoader.h>
|
||||
|
||||
#define PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE 0xff
|
||||
|
||||
@ -94,18 +101,6 @@ typedef struct {
|
||||
BOOLEAN ScanFv;
|
||||
} PEI_CORE_FV_HANDLE;
|
||||
|
||||
typedef struct {
|
||||
UINT8 CurrentPeim;
|
||||
UINT8 CurrentFv;
|
||||
UINT32 DispatchedPeimBitMap;
|
||||
UINT32 PreviousPeimBitMap;
|
||||
EFI_FFS_FILE_HEADER *CurrentPeimAddress;
|
||||
EFI_FIRMWARE_VOLUME_HEADER *CurrentFvAddress;
|
||||
EFI_FIRMWARE_VOLUME_HEADER *BootFvAddress;
|
||||
EFI_PEI_FIND_FV_PPI *FindFv;
|
||||
} PEI_CORE_DISPATCH_DATA;
|
||||
|
||||
|
||||
//
|
||||
// Pei Core private data structure instance
|
||||
//
|
||||
@ -116,7 +111,6 @@ typedef struct{
|
||||
UINTN Signature;
|
||||
EFI_PEI_SERVICES *PS; // Point to ServiceTableShadow
|
||||
PEI_PPI_DATABASE PpiData;
|
||||
PEI_CORE_DISPATCH_DATA DispatchData;
|
||||
UINTN FvCount;
|
||||
PEI_CORE_FV_HANDLE Fv[PEI_CORE_MAX_FV_SUPPORTED];
|
||||
EFI_PEI_FILE_HANDLE CurrentFvFileHandles[PEI_CORE_MAX_PEIM_PER_FV];
|
||||
@ -134,10 +128,12 @@ typedef struct{
|
||||
VOID *BottomOfCarHeap;
|
||||
VOID *TopOfCarHeap;
|
||||
VOID *CpuIo;
|
||||
EFI_PEI_SECURITY_PPI *PrivateSecurityPpi;
|
||||
EFI_PEI_SECURITY2_PPI *PrivateSecurityPpi;
|
||||
EFI_PEI_SERVICES ServiceTableShadow;
|
||||
UINTN SizeOfCacheAsRam;
|
||||
VOID *MaxTopOfCarHeap;
|
||||
EFI_PEI_PPI_DESCRIPTOR *XipLoadFile;
|
||||
EFI_PEI_PE_COFF_LOADER_PROTOCOL *PeCoffLoader;
|
||||
} PEI_CORE_INSTANCE;
|
||||
|
||||
//
|
||||
@ -215,11 +211,10 @@ Returns:
|
||||
// Dispatcher support functions
|
||||
//
|
||||
|
||||
EFI_STATUS
|
||||
BOOLEAN
|
||||
PeimDispatchReadiness (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN VOID *DependencyExpression,
|
||||
IN OUT BOOLEAN *Runnable
|
||||
IN VOID *DependencyExpression
|
||||
)
|
||||
/*++
|
||||
|
||||
@ -255,11 +250,10 @@ Returns:
|
||||
;
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
VOID
|
||||
PeiDispatcher (
|
||||
IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
|
||||
IN PEI_CORE_INSTANCE *PrivateData,
|
||||
IN PEI_CORE_DISPATCH_DATA *DispatchData
|
||||
IN PEI_CORE_INSTANCE *PrivateData
|
||||
)
|
||||
|
||||
/*++
|
||||
@ -285,7 +279,7 @@ Returns:
|
||||
|
||||
VOID
|
||||
InitializeDispatcherData (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN PEI_CORE_INSTANCE *PrivateData,
|
||||
IN PEI_CORE_INSTANCE *OldCoreData,
|
||||
IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData
|
||||
)
|
||||
@ -390,8 +384,9 @@ Returns:
|
||||
|
||||
BOOLEAN
|
||||
DepexSatisfied (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN VOID *CurrentPeimAddress
|
||||
IN PEI_CORE_INSTANCE *Private,
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
IN UINTN PeimCount
|
||||
)
|
||||
/*++
|
||||
|
||||
@ -448,7 +443,7 @@ Returns:
|
||||
//
|
||||
VOID
|
||||
InitializePpiServices (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN PEI_CORE_INSTANCE *PrivateData,
|
||||
IN PEI_CORE_INSTANCE *OldCoreData
|
||||
)
|
||||
/*++
|
||||
@ -607,7 +602,7 @@ Returns:
|
||||
|
||||
VOID
|
||||
ProcessNotifyList (
|
||||
IN EFI_PEI_SERVICES **PeiServices
|
||||
IN PEI_CORE_INSTANCE *PrivateData
|
||||
)
|
||||
/*++
|
||||
|
||||
@ -626,7 +621,7 @@ Returns:
|
||||
|
||||
VOID
|
||||
DispatchNotify (
|
||||
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||
IN PEI_CORE_INSTANCE *PrivateData,
|
||||
IN UINTN NotifyType,
|
||||
IN INTN InstallStartIndex,
|
||||
IN INTN InstallStopIndex,
|
||||
@ -755,8 +750,9 @@ Returns:
|
||||
|
||||
EFI_STATUS
|
||||
VerifyPeim (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_FFS_FILE_HEADER *CurrentPeimAddress
|
||||
IN PEI_CORE_INSTANCE *PrivateData,
|
||||
IN EFI_PEI_FV_HANDLE VolumeHandle,
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle
|
||||
)
|
||||
/*++
|
||||
|
||||
@ -901,7 +897,7 @@ Returns:
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiFfsFindSectionData (
|
||||
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_SECTION_TYPE SectionType,
|
||||
IN EFI_PEI_FILE_HANDLE FfsFileHeader,
|
||||
IN OUT VOID **SectionData
|
||||
@ -964,7 +960,7 @@ Returns:
|
||||
//
|
||||
VOID
|
||||
InitializeMemoryServices (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN PEI_CORE_INSTANCE *PrivateData,
|
||||
IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
|
||||
IN PEI_CORE_INSTANCE *OldCoreData
|
||||
)
|
||||
@ -1082,8 +1078,9 @@ Returns:
|
||||
EFI_STATUS
|
||||
PeiLoadImage (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_FFS_FILE_HEADER *PeimFileHeader,
|
||||
OUT VOID **EntryPoint
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
OUT EFI_PHYSICAL_ADDRESS *EntryPoint,
|
||||
OUT UINT32 *AuthenticationState
|
||||
)
|
||||
/*++
|
||||
|
||||
@ -1149,7 +1146,7 @@ Returns:
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiResetSystem (
|
||||
IN EFI_PEI_SERVICES **PeiServices
|
||||
IN CONST EFI_PEI_SERVICES **PeiServices
|
||||
)
|
||||
/*++
|
||||
|
||||
@ -1171,6 +1168,148 @@ Returns:
|
||||
--*/
|
||||
;
|
||||
|
||||
VOID
|
||||
PeiInitializeFv (
|
||||
IN PEI_CORE_INSTANCE *PrivateData,
|
||||
IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Initialize PeiCore Fv List.
|
||||
|
||||
Arguments:
|
||||
PrivateData - Pointer to PEI_CORE_INSTANCE.
|
||||
SecCoreData - Pointer to EFI_SEC_PEI_HAND_OFF.
|
||||
|
||||
Returns:
|
||||
NONE
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FirmwareVolmeInfoPpiNotifyCallback (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
|
||||
IN VOID *Ppi
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Process Firmware Volum Information once FvInfoPPI install.
|
||||
|
||||
Arguments:
|
||||
|
||||
PeiServices - General purpose services available to every PEIM.
|
||||
|
||||
Returns:
|
||||
|
||||
Status - EFI_SUCCESS if the interface could be successfully
|
||||
installed
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiFfsFindFileByName (
|
||||
IN CONST EFI_GUID *FileName,
|
||||
IN EFI_PEI_FV_HANDLE VolumeHandle,
|
||||
OUT EFI_PEI_FILE_HANDLE *FileHandle
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Given the input VolumeHandle, search for the next matching name file.
|
||||
|
||||
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_STATUS
|
||||
EFIAPI
|
||||
PeiFfsGetFileInfo (
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
OUT EFI_FV_FILE_INFO *FileInfo
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Collect information of given file.
|
||||
|
||||
Arguments:
|
||||
FileHandle - The handle to file.
|
||||
FileInfo - Pointer to the file information.
|
||||
|
||||
Returns:
|
||||
EFI_STATUS
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiFfsGetVolumeInfo (
|
||||
IN EFI_PEI_FV_HANDLE VolumeHandle,
|
||||
OUT EFI_FV_INFO *VolumeInfo
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Collect information of given Fv Volume.
|
||||
|
||||
Arguments:
|
||||
VolumeHandle - The handle to Fv Volume.
|
||||
VolumeInfo - The pointer to volume information.
|
||||
|
||||
Returns:
|
||||
EFI_STATUS
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiRegisterForShadow (
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
This routine enable a PEIM to register itself to shadow when PEI Foundation
|
||||
discovery permanent memory.
|
||||
|
||||
Arguments:
|
||||
FileHandle - File handle of a PEIM.
|
||||
|
||||
Returns:
|
||||
EFI_NOT_FOUND - The file handle doesn't point to PEIM itself.
|
||||
EFI_ALREADY_STARTED - Indicate that the PEIM has been registered itself.
|
||||
EFI_SUCCESS - Successfully to register itself.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
|
||||
/**
|
||||
This routine enable a PEIM to register itself to shadow when PEI Foundation
|
||||
discovery permanent memory.
|
||||
@ -1221,4 +1360,60 @@ PeiSwitchStacks (
|
||||
IN VOID *NewBsp
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
PeiFindFileEx (
|
||||
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
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Given the input file pointer, search for the next matching file in the
|
||||
FFS volume as defined by SearchType. The search starts from FileHeader inside
|
||||
the Firmware Volume defined by FwVolHeader.
|
||||
|
||||
Arguments:
|
||||
PeiServices - Pointer to the PEI Core Services Table.
|
||||
SearchType - Filter to find only files of this type.
|
||||
Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
|
||||
FwVolHeader - Pointer to the FV header of the volume to search.
|
||||
This parameter must point to a valid FFS volume.
|
||||
FileHeader - Pointer to the current file from which to begin searching.
|
||||
This pointer will be updated upon return to reflect the file found.
|
||||
Flag - Indicator for if this is for PEI Dispath search
|
||||
|
||||
Returns:
|
||||
EFI_NOT_FOUND - No files matching the search criteria were found
|
||||
EFI_SUCCESS
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
VOID
|
||||
InitializeImageServices (
|
||||
IN PEI_CORE_INSTANCE *PrivateData,
|
||||
IN PEI_CORE_INSTANCE *OldCoreData
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
|
||||
Regitser PeCoffLoader to PeiCore PrivateData. And install
|
||||
Pei Load File PPI.
|
||||
|
||||
Arguments:
|
||||
|
||||
PrivateData - Pointer to PEI_CORE_INSTANCE.
|
||||
OldCoreData - Pointer to PEI_CORE_INSTANCE.
|
||||
|
||||
Returns:
|
||||
|
||||
NONE.
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
#endif
|
||||
|
@ -80,16 +80,27 @@
|
||||
BaseLib
|
||||
PeiCoreEntryPoint
|
||||
DebugLib
|
||||
MemoryAllocationLib
|
||||
CacheMaintenanceLib
|
||||
PeCoffLoaderLib
|
||||
PeCoffLib
|
||||
|
||||
[Guids]
|
||||
gEfiPeiCorePrivateGuid # PRIVATE
|
||||
gPeiAprioriFileNameGuid
|
||||
gEfiFirmwareFileSystem2Guid
|
||||
|
||||
|
||||
[Ppis]
|
||||
gEfiPeiSecurityPpiGuid # PPI_NOTIFY SOMETIMES_CONSUMED
|
||||
gEfiPeiStatusCodePpiGuid # PPI SOMETIMES_CONSUMED
|
||||
gEfiPeiResetPpiGuid # PPI SOMETIMES_CONSUMED
|
||||
gEfiDxeIplPpiGuid # PPI ALWAYS_CONSUMED
|
||||
gEfiPeiFvFileLoaderPpiGuid # PPI ALWAYS_CONSUMED
|
||||
gEfiFindFvPpiGuid # PPI ALWAYS_CONSUMED
|
||||
gEfiPeiMemoryDiscoveredPpiGuid # PPI ALWAYS_PRODUCED
|
||||
gEfiPeiDecompressPpiGuid
|
||||
gEfiPeiFirmwareVolumeInfoPpiGuid
|
||||
gEfiPeiLoadFilePpiGuid
|
||||
gEfiPeiSecurity2PpiGuid
|
||||
|
||||
[BuildOptions.common]
|
||||
MSFT:DEBUG_*_IA32_CC_FLAGS = /FAcs
|
||||
|
||||
|
@ -102,11 +102,6 @@
|
||||
<PpiNotifyCName>gEfiPeiSecurityPpiGuid</PpiNotifyCName>
|
||||
</PpiNotify>
|
||||
</PPIs>
|
||||
<Guids>
|
||||
<GuidCNames Usage="PRIVATE">
|
||||
<GuidCName>gEfiPeiCorePrivateGuid</GuidCName>
|
||||
</GuidCNames>
|
||||
</Guids>
|
||||
<Externs>
|
||||
<Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
|
||||
<Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
|
||||
|
@ -61,20 +61,21 @@ static EFI_PEI_SERVICES mPS = {
|
||||
PeiFfsFindNextFile,
|
||||
PeiFfsFindSectionData,
|
||||
|
||||
PeiInstallPeiMemory,
|
||||
PeiInstallPeiMemory,
|
||||
PeiAllocatePages,
|
||||
PeiAllocatePool,
|
||||
(EFI_PEI_COPY_MEM)CopyMem,
|
||||
(EFI_PEI_SET_MEM)SetMem,
|
||||
|
||||
PeiReportStatusCode,
|
||||
|
||||
PeiResetSystem,
|
||||
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
PeiFfsFindFileByName,
|
||||
PeiFfsGetFileInfo,
|
||||
PeiFfsGetVolumeInfo,
|
||||
PeiRegisterForShadow
|
||||
};
|
||||
|
||||
@ -82,7 +83,7 @@ EFI_STATUS
|
||||
EFIAPI
|
||||
PeiCore (
|
||||
IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
|
||||
IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList,
|
||||
IN CONST EFI_PEI_PPI_DESCRIPTOR *PpList,
|
||||
IN VOID *Data
|
||||
)
|
||||
/*++
|
||||
@ -117,9 +118,10 @@ Returns:
|
||||
PEI_CORE_INSTANCE PrivateData;
|
||||
EFI_STATUS Status;
|
||||
PEI_CORE_TEMP_POINTERS TempPtr;
|
||||
PEI_CORE_DISPATCH_DATA *DispatchData;
|
||||
UINT64 mTick;
|
||||
PEI_CORE_INSTANCE *OldCoreData;
|
||||
EFI_PEI_CPU_IO_PPI *CpuIo;
|
||||
EFI_PEI_PCI_CFG2_PPI *PciCfg;
|
||||
|
||||
mTick = 0;
|
||||
OldCoreData = (PEI_CORE_INSTANCE *) Data;
|
||||
@ -138,26 +140,31 @@ Returns:
|
||||
|
||||
if (OldCoreData != NULL) {
|
||||
CopyMem (&PrivateData, OldCoreData, sizeof (PEI_CORE_INSTANCE));
|
||||
|
||||
CpuIo = (VOID*)PrivateData.ServiceTableShadow.CpuIo;
|
||||
PciCfg = (VOID*)PrivateData.ServiceTableShadow.PciCfg;
|
||||
|
||||
CopyMem (&PrivateData.ServiceTableShadow, &mPS, sizeof (mPS));
|
||||
|
||||
PrivateData.ServiceTableShadow.CpuIo = CpuIo;
|
||||
PrivateData.ServiceTableShadow.PciCfg = PciCfg;
|
||||
} else {
|
||||
ZeroMem (&PrivateData, sizeof (PEI_CORE_INSTANCE));
|
||||
PrivateData.Signature = PEI_CORE_HANDLE_SIGNATURE;
|
||||
CopyMem (&PrivateData.ServiceTableShadow, &mPS, sizeof (mPS));
|
||||
}
|
||||
|
||||
PrivateData.Signature = PEI_CORE_HANDLE_SIGNATURE;
|
||||
PrivateData.PS = &mPS;
|
||||
PrivateData.PS = &PrivateData.ServiceTableShadow;
|
||||
|
||||
//
|
||||
// Initialize libraries that the PeiCore is linked against
|
||||
// BUGBUG: The FfsHeader is passed in as NULL. Do we look it up or remove it from the lib init?
|
||||
// BUGBUG: The FileHandle is passed in as NULL. Do we look it up or remove it from the lib init?
|
||||
//
|
||||
ProcessLibraryConstructorList (NULL, &PrivateData.PS);
|
||||
|
||||
InitializeMemoryServices (&PrivateData.PS, SecCoreData, OldCoreData);
|
||||
InitializeMemoryServices (&PrivateData, SecCoreData, OldCoreData);
|
||||
|
||||
InitializePpiServices (&PrivateData.PS, OldCoreData);
|
||||
|
||||
InitializeSecurityServices (&PrivateData.PS, OldCoreData);
|
||||
|
||||
InitializeDispatcherData (&PrivateData.PS, OldCoreData, SecCoreData);
|
||||
InitializePpiServices (&PrivateData, OldCoreData);
|
||||
|
||||
if (OldCoreData != NULL) {
|
||||
|
||||
@ -219,18 +226,25 @@ Returns:
|
||||
//
|
||||
// If SEC provided any PPI services to PEI, install them.
|
||||
//
|
||||
if (PpiList != NULL) {
|
||||
Status = PeiServicesInstallPpi (PpiList);
|
||||
if (PpList != NULL) {
|
||||
Status = PeiServicesInstallPpi (PpList);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
}
|
||||
|
||||
DispatchData = &PrivateData.DispatchData;
|
||||
InitializeSecurityServices (&PrivateData.PS, OldCoreData);
|
||||
|
||||
InitializeDispatcherData (&PrivateData, OldCoreData, SecCoreData);
|
||||
|
||||
//
|
||||
// Install Pei Load File PPI.
|
||||
//
|
||||
InitializeImageServices (&PrivateData, OldCoreData);
|
||||
|
||||
//
|
||||
// Call PEIM dispatcher
|
||||
//
|
||||
PeiDispatcher (SecCoreData, &PrivateData, DispatchData);
|
||||
PeiDispatcher (SecCoreData, &PrivateData);
|
||||
|
||||
//
|
||||
// Check if InstallPeiMemory service was called.
|
||||
|
@ -25,7 +25,7 @@ Revision History
|
||||
|
||||
VOID
|
||||
InitializePpiServices (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN PEI_CORE_INSTANCE *PrivateData,
|
||||
IN PEI_CORE_INSTANCE *OldCoreData
|
||||
)
|
||||
/*++
|
||||
@ -45,11 +45,7 @@ Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
PEI_CORE_INSTANCE *PrivateData;
|
||||
|
||||
if (OldCoreData == NULL) {
|
||||
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
|
||||
|
||||
PrivateData->PpiData.NotifyListEnd = MAX_PPI_DESCRIPTORS-1;
|
||||
PrivateData->PpiData.DispatchListEnd = MAX_PPI_DESCRIPTORS-1;
|
||||
PrivateData->PpiData.LastDispatchedNotify = MAX_PPI_DESCRIPTORS-1;
|
||||
@ -220,7 +216,7 @@ Returns:
|
||||
// Dispatch any callback level notifies for newly installed PPIs.
|
||||
//
|
||||
DispatchNotify (
|
||||
(CONST EFI_PEI_SERVICES **) PeiServices,
|
||||
PrivateData,
|
||||
EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
|
||||
LastCallbackInstall,
|
||||
PrivateData->PpiData.PpiListEnd,
|
||||
@ -298,7 +294,7 @@ Returns:
|
||||
// Dispatch any callback level notifies for the newly installed PPI.
|
||||
//
|
||||
DispatchNotify (
|
||||
(CONST EFI_PEI_SERVICES **) PeiServices,
|
||||
PrivateData,
|
||||
EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
|
||||
Index,
|
||||
Index+1,
|
||||
@ -496,7 +492,7 @@ Returns:
|
||||
// Dispatch any callback level notifies for all previously installed PPIs.
|
||||
//
|
||||
DispatchNotify (
|
||||
(CONST EFI_PEI_SERVICES **) PeiServices,
|
||||
PrivateData,
|
||||
EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
|
||||
0,
|
||||
PrivateData->PpiData.PpiListEnd,
|
||||
@ -511,7 +507,7 @@ Returns:
|
||||
|
||||
VOID
|
||||
ProcessNotifyList (
|
||||
IN EFI_PEI_SERVICES **PeiServices
|
||||
IN PEI_CORE_INSTANCE *PrivateData
|
||||
)
|
||||
/*++
|
||||
|
||||
@ -528,11 +524,7 @@ Returns:
|
||||
--*/
|
||||
|
||||
{
|
||||
PEI_CORE_INSTANCE *PrivateData;
|
||||
INTN TempValue;
|
||||
|
||||
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
|
||||
|
||||
|
||||
while (TRUE) {
|
||||
//
|
||||
@ -545,7 +537,7 @@ Returns:
|
||||
while (PrivateData->PpiData.LastDispatchedNotify != PrivateData->PpiData.DispatchListEnd) {
|
||||
TempValue = PrivateData->PpiData.DispatchListEnd;
|
||||
DispatchNotify (
|
||||
(CONST EFI_PEI_SERVICES **) PeiServices,
|
||||
PrivateData,
|
||||
EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,
|
||||
0,
|
||||
PrivateData->PpiData.LastDispatchedInstall,
|
||||
@ -566,7 +558,7 @@ Returns:
|
||||
while (PrivateData->PpiData.LastDispatchedInstall != PrivateData->PpiData.PpiListEnd) {
|
||||
TempValue = PrivateData->PpiData.PpiListEnd;
|
||||
DispatchNotify (
|
||||
(CONST EFI_PEI_SERVICES **) PeiServices,
|
||||
PrivateData,
|
||||
EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,
|
||||
PrivateData->PpiData.LastDispatchedInstall,
|
||||
PrivateData->PpiData.PpiListEnd,
|
||||
@ -585,7 +577,7 @@ Returns:
|
||||
|
||||
VOID
|
||||
DispatchNotify (
|
||||
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||
IN PEI_CORE_INSTANCE *PrivateData,
|
||||
IN UINTN NotifyType,
|
||||
IN INTN InstallStartIndex,
|
||||
IN INTN InstallStopIndex,
|
||||
@ -612,15 +604,12 @@ Returns: None
|
||||
--*/
|
||||
|
||||
{
|
||||
PEI_CORE_INSTANCE *PrivateData;
|
||||
INTN Index1;
|
||||
INTN Index2;
|
||||
EFI_GUID *SearchGuid;
|
||||
EFI_GUID *CheckGuid;
|
||||
EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor;
|
||||
|
||||
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
|
||||
|
||||
//
|
||||
// Remember that Installs moves up and Notifies moves down.
|
||||
//
|
||||
@ -645,7 +634,7 @@ Returns: None
|
||||
NotifyDescriptor->Notify
|
||||
));
|
||||
NotifyDescriptor->Notify (
|
||||
(EFI_PEI_SERVICES **)PeiServices,
|
||||
GetPeiServicesTablePointer (),
|
||||
NotifyDescriptor,
|
||||
(PrivateData->PpiData.PpiListPtrs[Index2].Ppi)->Ppi
|
||||
);
|
||||
|
@ -26,7 +26,7 @@ Revision History
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiResetSystem (
|
||||
IN EFI_PEI_SERVICES **PeiServices
|
||||
IN CONST EFI_PEI_SERVICES **PeiServices
|
||||
)
|
||||
/*++
|
||||
|
||||
|
@ -32,7 +32,7 @@ SecurityPpiNotifyCallback (
|
||||
|
||||
static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = {
|
||||
EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
|
||||
&gEfiPeiSecurityPpiGuid,
|
||||
&gEfiPeiSecurity2PpiGuid,
|
||||
SecurityPpiNotifyCallback
|
||||
};
|
||||
|
||||
@ -101,15 +101,16 @@ Returns:
|
||||
// If there isn't a security PPI installed, use the one from notification
|
||||
//
|
||||
if (PrivateData->PrivateSecurityPpi == NULL) {
|
||||
PrivateData->PrivateSecurityPpi = (EFI_PEI_SECURITY_PPI *)Ppi;
|
||||
PrivateData->PrivateSecurityPpi = (EFI_PEI_SECURITY2_PPI *)Ppi;
|
||||
}
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
VerifyPeim (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_FFS_FILE_HEADER *CurrentPeimAddress
|
||||
IN PEI_CORE_INSTANCE *PrivateData,
|
||||
IN EFI_PEI_FV_HANDLE VolumeHandle,
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle
|
||||
)
|
||||
/*++
|
||||
|
||||
@ -129,21 +130,15 @@ Returns:
|
||||
|
||||
--*/
|
||||
{
|
||||
PEI_CORE_INSTANCE *PrivateData;
|
||||
EFI_STATUS Status;
|
||||
UINT32 AuthenticationStatus;
|
||||
BOOLEAN StartCrisisRecovery;
|
||||
BOOLEAN DeferExection;
|
||||
|
||||
//
|
||||
// Set a default authentication state
|
||||
//
|
||||
AuthenticationStatus = 0;
|
||||
|
||||
//
|
||||
// get security PPI instance from PEI private data
|
||||
//
|
||||
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
|
||||
|
||||
if (PrivateData->PrivateSecurityPpi == NULL) {
|
||||
Status = EFI_NOT_FOUND;
|
||||
} else {
|
||||
@ -151,13 +146,14 @@ Returns:
|
||||
// Check to see if the image is OK
|
||||
//
|
||||
Status = PrivateData->PrivateSecurityPpi->AuthenticationState (
|
||||
PeiServices,
|
||||
(CONST EFI_PEI_SERVICES **) &PrivateData->PS,
|
||||
PrivateData->PrivateSecurityPpi,
|
||||
AuthenticationStatus,
|
||||
CurrentPeimAddress,
|
||||
&StartCrisisRecovery
|
||||
VolumeHandle,
|
||||
FileHandle,
|
||||
&DeferExection
|
||||
);
|
||||
if (StartCrisisRecovery) {
|
||||
if (DeferExection) {
|
||||
Status = EFI_SECURITY_VIOLATION;
|
||||
}
|
||||
}
|
||||
|
@ -62,7 +62,6 @@
|
||||
gEfiShellFileGuid = { 0xC57AD6B7, 0x0515, 0x40A8, { 0x9D, 0x21, 0x55, 0x16, 0x52, 0x85, 0x4E, 0x37 }}
|
||||
gEfiFlashMapHobGuid = { 0xB091E7D2, 0x05A0, 0x4198, { 0x94, 0xF0, 0x74, 0xB7, 0xB8, 0xC5, 0x54, 0x59 }}
|
||||
gEfiStandardErrorDeviceGuid = { 0xD3B36F2D, 0xD551, 0x11D4, { 0x9A, 0x46, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }}
|
||||
gEfiPeiCorePrivateGuid = { 0xd641a0f5, 0xcb7c, 0x4846, { 0xa3, 0x80, 0x1d, 0x01, 0xb4, 0xd9, 0xe3, 0xb9 }}
|
||||
|
||||
gEfiPeiPeCoffLoaderGuid = { 0xD8117CFF, 0x94A6, 0x11D4, { 0x9A, 0x3A, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }}
|
||||
|
||||
|
@ -71,6 +71,8 @@
|
||||
ReportStatusCodeLib|IntelFrameworkModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
|
||||
PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
|
||||
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
|
||||
PeCoffLoaderLib|MdeModulePkg/Library/PeiDxePeCoffLoaderLib/PeCoffLoaderLib.inf
|
||||
|
||||
|
||||
[LibraryClasses.common.PEIM]
|
||||
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
|
||||
|
@ -262,6 +262,30 @@ BuildFvHob (
|
||||
)
|
||||
;
|
||||
|
||||
/**
|
||||
Builds a EFI_HOB_TYPE_FV2 HOB.
|
||||
|
||||
This function builds a EFI_HOB_TYPE_FV2 HOB.
|
||||
It can only be invoked during PEI phase;
|
||||
for DXE phase, it will ASSERT() since PEI HOB is read-only for DXE phase.
|
||||
If there is no additional space for HOB creation, then ASSERT().
|
||||
|
||||
@param BaseAddress The base address of the Firmware Volume.
|
||||
@param Length The size of the Firmware Volume in bytes.
|
||||
@param FvName The name of the Firmware Volume.
|
||||
@param FileName The name of the file.
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
BuildFv2Hob (
|
||||
IN EFI_PHYSICAL_ADDRESS BaseAddress,
|
||||
IN UINT64 Length,
|
||||
IN CONST EFI_GUID *FvName,
|
||||
IN CONST EFI_GUID *FileName
|
||||
)
|
||||
;
|
||||
|
||||
/**
|
||||
Builds a Capsule Volume HOB.
|
||||
|
||||
|
30
MdePkg/Include/Library/PeiPiLib.h
Normal file
30
MdePkg/Include/Library/PeiPiLib.h
Normal file
@ -0,0 +1,30 @@
|
||||
/** @file
|
||||
MDE PI library functions and macros for PEI phase
|
||||
|
||||
Copyright (c) 2007, 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.
|
||||
|
||||
**/
|
||||
|
||||
#ifndef __PEI_PI_LIB_H__
|
||||
#define __PEI_PI_LIB_H__
|
||||
|
||||
#include <Pi/PiFirmwareFile.h>
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
PeiPiLibBuildPiFvInfoPpi (
|
||||
IN EFI_PHYSICAL_ADDRESS FvStart,
|
||||
IN UINT64 FvLength,
|
||||
IN EFI_GUID *ParentFvName,
|
||||
IN EFI_GUID *PraentFileName
|
||||
);
|
||||
|
||||
#endif
|
||||
|
@ -293,4 +293,35 @@ PeiServicesResetSystem (
|
||||
);
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiServicesFfsFindByName (
|
||||
IN CONST EFI_GUID *FileName,
|
||||
IN CONST EFI_PEI_FV_HANDLE VolumeHandle,
|
||||
OUT EFI_PEI_FILE_HANDLE *FileHandle
|
||||
);
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiServicesFfsGetFileInfo (
|
||||
IN CONST EFI_PEI_FILE_HANDLE FileHandle,
|
||||
OUT EFI_FV_FILE_INFO *FileInfo
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiServicesFfsGetVolumeInfo (
|
||||
IN EFI_PEI_FV_HANDLE VolumeHandle,
|
||||
OUT EFI_FV_INFO *VolumeInfo
|
||||
);
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiServicesRegisterForShadow (
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle
|
||||
);
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -30,5 +30,11 @@ GetPeiServicesTablePointer (
|
||||
VOID
|
||||
);
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
SetPeiServicesTablePointer (
|
||||
EFI_PEI_SERVICES ** PeiServicesTablePointer
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -75,6 +75,233 @@ GetSectionFromFvFile (
|
||||
)
|
||||
;
|
||||
|
||||
/**
|
||||
Identify the device handle from which the Image is loaded from. As this device handle is passed to
|
||||
GetSectionFromFv as the identifier for a Firmware Volume, an EFI_FIRMWARE_VOLUME2_PROTOCOL
|
||||
protocol instance should be located succesfully by calling gBS->HandleProtocol ().
|
||||
|
||||
This function locates the EFI_LOADED_IMAGE_PROTOCOL instance installed
|
||||
on ImageHandle. It then returns EFI_LOADED_IMAGE_PROTOCOL.DeviceHandle.
|
||||
|
||||
If ImageHandle is NULL, then ASSERT ();
|
||||
If failed to locate a EFI_LOADED_IMAGE_PROTOCOL on ImageHandle, then ASSERT ();
|
||||
|
||||
@param ImageHandle The firmware allocated handle for UEFI image.
|
||||
|
||||
@retval EFI_HANDLE The device handle from which the Image is loaded from.
|
||||
|
||||
**/
|
||||
|
||||
EFI_HANDLE
|
||||
EFIAPI
|
||||
ImageHandleToFvHandle (
|
||||
EFI_HANDLE ImageHandle
|
||||
)
|
||||
;
|
||||
|
||||
/**
|
||||
Allocate and fill a buffer from the Firmware Section identified by a Firmware File GUID name and a Firmware
|
||||
Section type and instance number from the any Firmware Volumes in the system.
|
||||
|
||||
The function will read the first Firmware Section found sepcifed by NameGuid and SectionType from the
|
||||
any Firmware Volume in the system.
|
||||
|
||||
The search order for Firmware Volumes in the system is determistic but abitrary if no new Firmware Volume is installed
|
||||
into the system. The search order for the section specified by SectionType within a Firmware File is defined by
|
||||
EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection (). Please check Section 2.4 of Volume 3: Platform Initialization
|
||||
Shared Architectural Elements for detailes.
|
||||
|
||||
If SectionType is EFI_SECTION_TE, EFI_SECTION_TE will be used as Firmware Section type to read Firmware Section
|
||||
data from the Firmware File. If no such section exists, EFI_SECTION_PE32 will be used as Firmware Section type to
|
||||
read Firmware Section data from the Firmware File. If no such section specified is found to match ,
|
||||
EFI_NOT_FOUND is returned.
|
||||
|
||||
The data and size is returned by Buffer and Size. The caller is responsible to free the Buffer allocated
|
||||
by this function. This function can only be called at TPL_NOTIFY and below.
|
||||
|
||||
If NameGuid is NULL, then ASSERT();
|
||||
If Buffer is NULL, then ASSERT();
|
||||
If Size is NULL, then ASSERT().
|
||||
|
||||
@param NameGuid The GUID name of a Firmware File.
|
||||
@param SectionType The Firmware Section type.
|
||||
@param Instance The instance number of Firmware Section to read from starting from 0.
|
||||
@param Buffer On output, Buffer contains the the data read from the section in the Firmware File found.
|
||||
@param Size On output, the size of Buffer.
|
||||
|
||||
@retval EFI_SUCCESS The image is found and data and size is returned.
|
||||
@retval EFI_NOT_FOUND The image specified by NameGuid and SectionType can't be found.
|
||||
@retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate the output data buffer or complete the operations.
|
||||
@retval EFI_DEVICE_ERROR A hardware error occurs during reading from the Firmware Volume.
|
||||
@retval EFI_ACCESS_DENIED The firmware volume containing the searched Firmware File is configured to disallow reads.
|
||||
|
||||
**/
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetSectionFromAnyFv (
|
||||
IN CONST EFI_GUID *NameGuid,
|
||||
IN EFI_SECTION_TYPE SectionType,
|
||||
IN UINTN Instance,
|
||||
OUT VOID **Buffer,
|
||||
OUT UINTN *Size
|
||||
)
|
||||
;
|
||||
|
||||
/**
|
||||
Allocate and fill a buffer from a Firmware Section identified by a Firmware File GUID name, a Firmware
|
||||
Section type and instance number from the specified Firmware Volume.
|
||||
|
||||
This functions first locate the EFI_FIRMWARE_VOLUME2_PROTOCOL protocol instance on FvHandle in order to
|
||||
carry out the Firmware Volume read operation. The function then reads the Firmware Section found sepcifed
|
||||
by NameGuid, SectionType and Instance.
|
||||
|
||||
The search order for the section specified by SectionType within a Firmware File is defined by
|
||||
EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection (). Please check Section 2.4 of Volume 3: Platform Initialization
|
||||
Shared Architectural Elements for detailes.
|
||||
|
||||
If SectionType is EFI_SECTION_TE, EFI_SECTION_TE will be used as Firmware Section type to read Firmware Section
|
||||
data from the Firmware File. If no such section exists, EFI_SECTION_PE32 will be used as Firmware Section type to
|
||||
read Firmware Section data from the Firmware File. If no such section specified is found to match ,
|
||||
EFI_NOT_FOUND is returned.
|
||||
|
||||
The data and size is returned by Buffer and Size. The caller is responsible to free the Buffer allocated
|
||||
by this function. This function can be only called at TPL_NOTIFY and below.
|
||||
|
||||
If FvHandle is NULL, then ASSERT ();
|
||||
If NameGuid is NULL, then ASSERT();
|
||||
If Buffer is NULL, then ASSERT();
|
||||
If Size is NULL, then ASSERT().
|
||||
|
||||
@param FvHandle The device handle that contains a instance of EFI_FIRMWARE_VOLUME2_PROTOCOL instance.
|
||||
@param NameGuid The GUID name of a Firmware File.
|
||||
@param SectionType The Firmware Section type.
|
||||
@param Instance The instance number of Firmware Section to read from starting from 0.
|
||||
@param Buffer On output, Buffer contains the the data read from the section in the Firmware File found.
|
||||
@param Size On output, the size of Buffer.
|
||||
|
||||
@retval EFI_SUCCESS The image is found and data and size is returned.
|
||||
@retval EFI_UNSUPPORTED FvHandle does not support EFI_FIRMWARE_VOLUME2_PROTOCOL.
|
||||
@retval EFI_NOT_FOUND The image specified by NameGuid and SectionType can't be found.
|
||||
@retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate the output data buffer or complete the operations.
|
||||
@retval EFI_DEVICE_ERROR A hardware error occurs during reading from the Firmware Volume.
|
||||
@retval EFI_ACCESS_DENIED The firmware volume containing the searched Firmware File is configured to disallow reads.
|
||||
|
||||
**/
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetSectionFromFv (
|
||||
IN EFI_HANDLE FvHandle,
|
||||
IN CONST EFI_GUID *NameGuid,
|
||||
IN EFI_SECTION_TYPE SectionType,
|
||||
IN UINTN Instance,
|
||||
OUT VOID **Buffer,
|
||||
OUT UINTN *Size
|
||||
)
|
||||
;
|
||||
|
||||
/**
|
||||
Allocate and fill a buffer from a Firmware Section identified by a Firmware File GUID name, a Firmware
|
||||
Section type and instance number from the same Firmware Volume with the caller's FFS.
|
||||
|
||||
This functions first locates the EFI_FIRMWARE_VOLUME2_PROTOCOL protocol instance for same Firmrware Volume
|
||||
which also contains the FFS of the caller in order to carry out the Firmware Volume read operation.
|
||||
The function then reads the Firmware Section found sepcifed by NameGuid, SectionType and Instance.
|
||||
|
||||
The search order for the section specified by SectionType within a Firmware File is defined by
|
||||
EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadSection (). Please check Section 2.4 of Volume 3: Platform Initialization
|
||||
Shared Architectural Elements for detailes.
|
||||
|
||||
If SectionType is EFI_SECTION_TE, EFI_SECTION_TE will be used as Firmware Section type to read Firmware Section
|
||||
data from the Firmware File. If no such section exists, EFI_SECTION_PE32 will be used as Firmware Section type to
|
||||
read Firmware Section data from the Firmware File. If no such section specified is found to match ,
|
||||
EFI_NOT_FOUND is returned.
|
||||
|
||||
The data and size is returned by Buffer and Size. The caller is responsible to free the Buffer allocated
|
||||
by this function. This function can be only called at TPL_NOTIFY and below.
|
||||
|
||||
If FvHandle is NULL, then ASSERT ();
|
||||
If NameGuid is NULL, then ASSERT();
|
||||
If Buffer is NULL, then ASSERT();
|
||||
If Size is NULL, then ASSERT().
|
||||
|
||||
@param NameGuid The GUID name of a Firmware File.
|
||||
@param SectionType The Firmware Section type.
|
||||
@param Instance The instance number of Firmware Section to read from starting from 0.
|
||||
@param Buffer On output, Buffer contains the the data read from the section in the Firmware File found.
|
||||
@param Size On output, the size of Buffer.
|
||||
|
||||
@retval EFI_SUCCESS The image is found and data and size is returned.
|
||||
@retval EFI_UNSUPPORTED FvHandle does not support EFI_FIRMWARE_VOLUME2_PROTOCOL.
|
||||
@retval EFI_NOT_FOUND The image specified by NameGuid and SectionType can't be found.
|
||||
@retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate the output data buffer or complete the operations.
|
||||
@retval EFI_DEVICE_ERROR A hardware error occurs during reading from the Firmware Volume.
|
||||
@retval EFI_ACCESS_DENIED The firmware volume containing the searched Firmware File is configured to disallow reads.
|
||||
|
||||
**/
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetSectionFromCurrentFv (
|
||||
IN CONST EFI_GUID *NameGuid,
|
||||
IN EFI_SECTION_TYPE SectionType,
|
||||
IN UINTN Instance,
|
||||
OUT VOID **Buffer,
|
||||
OUT UINTN *Size
|
||||
)
|
||||
;
|
||||
|
||||
|
||||
/**
|
||||
Allocate and fill a buffer from the first Firmware Section in the same Firmware File as the caller of this function.
|
||||
|
||||
The function will read the first Firmware Section found sepcifed by NameGuid and SectionType from the
|
||||
Firmware Volume specified by FvHandle. On this FvHandle, an EFI_FIRMWARE_VOLUME2_PROTOCOL protocol instance
|
||||
should be located succesfully in order to carry out the Firmware Volume operations.
|
||||
|
||||
The search order for the section type specified by SectionType in the Firmware File is using a depth-first
|
||||
and left-to-right algorithm through all sections. The first section found to match SectionType will be returned.
|
||||
|
||||
If SectionType is EFI_SECTION_PE32, EFI_SECTION_PE32 will be used as Firmware Section type
|
||||
to read Firmware Section data from the Firmware File. If no such section exists, the function will try
|
||||
to read a Firmware File named with NameGuid. If no such file exists, EFI_NOT_FOUND is returned.
|
||||
|
||||
If SectionType is EFI_SECTION_TE, EFI_SECTION_TE will be used as Firmware Section type to read Firmware Section
|
||||
data from the Firmware File. If no such section exists, EFI_SECTION_PE32 will be used as Firmware Section type to
|
||||
read Firmware Section data from the Firmware File. If no such section exists, the function will try to read a Firmware
|
||||
File named with NameGuid. If no such file exists, EFI_NOT_FOUND is returned.
|
||||
|
||||
The data and size is returned by Buffer and Size. The caller is responsible to free the Buffer allocated
|
||||
by this function. This function can only be called at TPL_NOTIFY and below.
|
||||
|
||||
If FvHandle is NULL and WithinImage is TRUE, then ASSERT ();
|
||||
If NameGuid is NULL, then ASSERT();
|
||||
If Buffer is NULL, then ASSERT();
|
||||
If Size is NULL, then ASSERT().
|
||||
|
||||
@param NameGuid The GUID name of a Firmware File.
|
||||
@param SectionType The Firmware Section type.
|
||||
@param Buffer On output, Buffer contains the the data read from the section in the Firmware File found.
|
||||
@param Size On output, the size of Buffer.
|
||||
|
||||
@retval EFI_SUCCESS The image is found and data and size is returned.
|
||||
@retval EFI_NOT_FOUND The image specified by NameGuid and SectionType can't be found.
|
||||
@retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate the output data buffer or complete the operations.
|
||||
@retval EFI_DEVICE_ERROR A hardware error occurs during reading from the Firmware Volume.
|
||||
@retval EFI_ACCESS_DENIED The firmware volume containing the searched Firmware File is configured to disallow reads.
|
||||
|
||||
**/
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetSectionFromCurrentFfs (
|
||||
IN EFI_SECTION_TYPE SectionType,
|
||||
IN UINTN Instance,
|
||||
OUT VOID **Buffer,
|
||||
OUT UINTN *Size
|
||||
)
|
||||
;
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -51,8 +51,8 @@ typedef struct _EFI_PEI_NOTIFY_DESCRIPTOR EFI_PEI_NOTIFY_DESCRIPTOR;
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_PEIM_ENTRY_POINT2)(
|
||||
IN EFI_PEI_FILE_HANDLE *FileHandle,
|
||||
IN EFI_PEI_SERVICES **PeiServices
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
IN CONST EFI_PEI_SERVICES **PeiServices
|
||||
);
|
||||
|
||||
/**
|
||||
@ -491,7 +491,7 @@ EFI_STATUS
|
||||
typedef
|
||||
EFI_STATUS
|
||||
(EFIAPI *EFI_PEI_RESET_SYSTEM) (
|
||||
IN EFI_PEI_SERVICES **PeiServices
|
||||
IN CONST EFI_PEI_SERVICES **PeiServices
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/UefiBootServicesTableLib.h>
|
||||
#include <Library/PiLib.h>
|
||||
#include <Protocol/FirmwareVolume2.h>
|
||||
#include <Protocol/LoadedImage.h>
|
||||
|
||||
@ -40,7 +41,7 @@
|
||||
**/
|
||||
STATIC
|
||||
EFI_STATUS
|
||||
GetImageFromFv (
|
||||
InternalGetImageFromFv (
|
||||
IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,
|
||||
IN CONST EFI_GUID *NameGuid,
|
||||
IN EFI_SECTION_TYPE SectionType,
|
||||
@ -193,7 +194,7 @@ GetSectionFromFvFile (
|
||||
(VOID **) &ImageFv
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = GetImageFromFv (ImageFv, NameGuid, SectionType, Buffer, Size);
|
||||
Status = InternalGetImageFromFv (ImageFv, NameGuid, SectionType, Buffer, Size);
|
||||
}
|
||||
}
|
||||
|
||||
@ -231,7 +232,7 @@ GetSectionFromFvFile (
|
||||
continue;
|
||||
}
|
||||
|
||||
Status = GetImageFromFv (Fv, NameGuid, SectionType, Buffer, Size);
|
||||
Status = InternalGetImageFromFv (Fv, NameGuid, SectionType, Buffer, Size);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
goto Done;
|
||||
@ -254,3 +255,216 @@ Done:
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_HANDLE
|
||||
EFIAPI
|
||||
ImageHandleToFvHandle (
|
||||
EFI_HANDLE ImageHandle
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
|
||||
|
||||
ASSERT (ImageHandle != NULL);
|
||||
|
||||
Status = gBS->HandleProtocol (
|
||||
(EFI_HANDLE *) ImageHandle,
|
||||
&gEfiLoadedImageProtocolGuid,
|
||||
(VOID **) &LoadedImage
|
||||
);
|
||||
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return LoadedImage->DeviceHandle;
|
||||
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetSectionFromAnyFv (
|
||||
IN CONST EFI_GUID *NameGuid,
|
||||
IN EFI_SECTION_TYPE SectionType,
|
||||
IN UINTN Instance,
|
||||
OUT VOID **Buffer,
|
||||
OUT UINTN *Size
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE *HandleBuffer;
|
||||
UINTN HandleCount;
|
||||
UINTN Index;
|
||||
EFI_HANDLE FvHandle;
|
||||
EFI_TPL OldTpl;
|
||||
|
||||
//
|
||||
// Search the FV that contain the caller's FFS first.
|
||||
// FV builder can choose to build FFS into the this FV
|
||||
// so that this implementation of GetSectionFromAnyFv
|
||||
// will locate the FFS faster.
|
||||
//
|
||||
FvHandle = ImageHandleToFvHandle (gImageHandle);
|
||||
Status = GetSectionFromFv (
|
||||
FvHandle,
|
||||
NameGuid,
|
||||
SectionType,
|
||||
Instance,
|
||||
Buffer,
|
||||
Size
|
||||
);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
|
||||
|
||||
HandleBuffer = NULL;
|
||||
Status = gBS->LocateHandleBuffer (
|
||||
ByProtocol,
|
||||
&gEfiFirmwareVolume2ProtocolGuid,
|
||||
NULL,
|
||||
&HandleCount,
|
||||
&HandleBuffer
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
goto Done;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < HandleCount; ++Index) {
|
||||
//
|
||||
// Skip the FV that contain the caller's FFS
|
||||
//
|
||||
if (HandleBuffer[Index] == FvHandle) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Status = GetSectionFromFv (
|
||||
HandleBuffer[Index],
|
||||
NameGuid,
|
||||
SectionType,
|
||||
Instance,
|
||||
Buffer,
|
||||
Size
|
||||
);
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
goto Done;
|
||||
}
|
||||
}
|
||||
|
||||
if (Index == HandleCount) {
|
||||
Status = EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
Done:
|
||||
|
||||
gBS->RestoreTPL (OldTpl);
|
||||
|
||||
if (HandleBuffer != NULL) {
|
||||
FreePool(HandleBuffer);
|
||||
}
|
||||
return Status;
|
||||
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetSectionFromFv (
|
||||
IN EFI_HANDLE FvHandle,
|
||||
IN CONST EFI_GUID *NameGuid,
|
||||
IN EFI_SECTION_TYPE SectionType,
|
||||
IN UINTN Instance,
|
||||
OUT VOID **Buffer,
|
||||
OUT UINTN *Size
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
|
||||
UINT32 AuthenticationStatus;
|
||||
|
||||
ASSERT (FvHandle != NULL);
|
||||
|
||||
Status = gBS->HandleProtocol (
|
||||
FvHandle,
|
||||
&gEfiFirmwareVolume2ProtocolGuid,
|
||||
(VOID **) &Fv
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// Read desired section content in NameGuid file
|
||||
//
|
||||
*Buffer = NULL;
|
||||
*Size = 0;
|
||||
Status = Fv->ReadSection (
|
||||
Fv,
|
||||
NameGuid,
|
||||
SectionType,
|
||||
0,
|
||||
Buffer,
|
||||
Size,
|
||||
&AuthenticationStatus
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status) && (SectionType == EFI_SECTION_TE)) {
|
||||
//
|
||||
// Try reading PE32 section, if the required section is TE type
|
||||
//
|
||||
*Buffer = NULL;
|
||||
*Size = 0;
|
||||
Status = Fv->ReadSection (
|
||||
Fv,
|
||||
NameGuid,
|
||||
EFI_SECTION_PE32,
|
||||
0,
|
||||
Buffer,
|
||||
Size,
|
||||
&AuthenticationStatus
|
||||
);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetSectionFromCurrentFv (
|
||||
IN CONST EFI_GUID *NameGuid,
|
||||
IN EFI_SECTION_TYPE SectionType,
|
||||
IN UINTN Instance,
|
||||
OUT VOID **Buffer,
|
||||
OUT UINTN *Size
|
||||
)
|
||||
{
|
||||
return GetSectionFromFv(
|
||||
ImageHandleToFvHandle(gImageHandle),
|
||||
NameGuid,
|
||||
SectionType,
|
||||
Instance,
|
||||
Buffer,
|
||||
Size
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
GetSectionFromCurrentFfs (
|
||||
IN EFI_SECTION_TYPE SectionType,
|
||||
IN UINTN Instance,
|
||||
OUT VOID **Buffer,
|
||||
OUT UINTN *Size
|
||||
)
|
||||
{
|
||||
return GetSectionFromFv(
|
||||
ImageHandleToFvHandle(gImageHandle),
|
||||
&gEfiCallerIdGuid,
|
||||
SectionType,
|
||||
Instance,
|
||||
Buffer,
|
||||
Size
|
||||
);
|
||||
}
|
||||
|
||||
|
67
MdePkg/Library/PeiPiLib/PeiPiLib.c
Normal file
67
MdePkg/Library/PeiPiLib/PeiPiLib.c
Normal file
@ -0,0 +1,67 @@
|
||||
/** @file
|
||||
MDE PI library functions and macros for PEI phase
|
||||
|
||||
Copyright (c) 2007, 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.
|
||||
|
||||
**/
|
||||
|
||||
#include <PiPei.h>
|
||||
#include <Ppi/FirmwareVolumeInfo.h>
|
||||
#include <Guid/FirmwareFileSystem2.h>
|
||||
|
||||
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/PeiServicesLib.h>
|
||||
#include <Library/PeiPiLib.h>
|
||||
|
||||
|
||||
STATIC CONST EFI_PEI_FIRMWARE_VOLUME_INFO_PPI mFvInfoPpiTemplate = {
|
||||
EFI_FIRMWARE_FILE_SYSTEM2_GUID,
|
||||
NULL,
|
||||
0, //FvInfoSize
|
||||
NULL, //ParentFvName
|
||||
NULL //ParentFileName;
|
||||
};
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
PeiPiLibBuildPiFvInfoPpi (
|
||||
IN EFI_PHYSICAL_ADDRESS FvStart,
|
||||
IN UINT64 FvLength,
|
||||
IN EFI_GUID *ParentFvName,
|
||||
IN EFI_GUID *ParentFileName
|
||||
) {
|
||||
|
||||
EFI_STATUS Status;
|
||||
EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *FvInfoPpi;
|
||||
EFI_PEI_PPI_DESCRIPTOR *FvInfoPpiDescriptor;
|
||||
|
||||
FvInfoPpi = AllocateCopyPool (sizeof (*FvInfoPpi), &mFvInfoPpiTemplate);
|
||||
ASSERT( FvInfoPpi != NULL);
|
||||
|
||||
FvInfoPpi->FvInfo = (VOID *) (UINTN) FvStart;
|
||||
FvInfoPpi->FvInfoSize = (UINT32) FvLength;
|
||||
FvInfoPpi->ParentFvName = ParentFvName;
|
||||
FvInfoPpi->ParentFileName = ParentFileName;
|
||||
|
||||
|
||||
FvInfoPpiDescriptor = AllocatePool (sizeof(EFI_PEI_PPI_DESCRIPTOR));
|
||||
ASSERT (FvInfoPpiDescriptor != NULL);
|
||||
|
||||
FvInfoPpiDescriptor->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
|
||||
FvInfoPpiDescriptor->Guid = &gEfiPeiFirmwareVolumeInfoPpiGuid;
|
||||
FvInfoPpiDescriptor->Ppi = (VOID *) FvInfoPpi;
|
||||
Status = PeiServicesInstallPpi (FvInfoPpiDescriptor);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
|
||||
}
|
||||
|
50
MdePkg/Library/PeiPiLib/PeiPiLib.inf
Normal file
50
MdePkg/Library/PeiPiLib/PeiPiLib.inf
Normal file
@ -0,0 +1,50 @@
|
||||
#/** @file
|
||||
# Component description file library instance for PiLib for PEI phase.
|
||||
#
|
||||
# Library to abstract utility functions that is related to PI Specification.
|
||||
#
|
||||
# Copyright (c) 2007, 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.
|
||||
#
|
||||
#
|
||||
#**/
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = PeiPiLib
|
||||
FILE_GUID = 6196FE81-4FA4-469a-B759-2C4DFE935B79
|
||||
MODULE_TYPE = PEIM
|
||||
VERSION_STRING = 1.0
|
||||
LIBRARY_CLASS = PiLib|PEIM
|
||||
EDK_RELEASE_VERSION = 0x00020000
|
||||
EFI_SPECIFICATION_VERSION = 0x00020000
|
||||
|
||||
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
|
||||
#
|
||||
|
||||
[Sources.common]
|
||||
PeiPiLib.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
|
||||
|
||||
[LibraryClasses]
|
||||
MemoryAllocationLib
|
||||
DebugLib
|
||||
|
||||
[Guids]
|
||||
|
||||
[Ppis]
|
||||
gEfiPeiFirmwareVolumeInfoPpiGuid
|
||||
|
||||
|
||||
|
@ -379,9 +379,58 @@ EFIAPI
|
||||
PeiServicesResetSystem (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
CONST EFI_PEI_SERVICES **PeiServices;
|
||||
|
||||
PeiServices = (CONST EFI_PEI_SERVICES **) GetPeiServicesTablePointer ();
|
||||
return (*PeiServices)->ResetSystem (PeiServices);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiServicesRegisterForShadow (
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle
|
||||
)
|
||||
{
|
||||
EFI_PEI_SERVICES **PeiServices;
|
||||
|
||||
PeiServices = GetPeiServicesTablePointer ();
|
||||
return (*PeiServices)->ResetSystem (PeiServices);
|
||||
return (*PeiServices)->RegisterForShadow (FileHandle);
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiServicesFfsGetFileInfo (
|
||||
IN CONST EFI_PEI_FILE_HANDLE FileHandle,
|
||||
OUT EFI_FV_FILE_INFO *FileInfo
|
||||
)
|
||||
{
|
||||
EFI_PEI_SERVICES **PeiServices;
|
||||
|
||||
PeiServices = GetPeiServicesTablePointer ();
|
||||
return (*PeiServices)->FfsGetFileInfo (FileHandle, FileInfo);
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiServicesFfsFindFileByName (
|
||||
IN CONST EFI_GUID *FileName,
|
||||
IN CONST EFI_PEI_FV_HANDLE VolumeHandle,
|
||||
OUT EFI_PEI_FILE_HANDLE *FileHandle
|
||||
)
|
||||
{
|
||||
return (*GetPeiServicesTablePointer())->FfsFindFileByName (FileName, VolumeHandle, FileHandle);
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiServicesFfsGetVolumeInfo (
|
||||
IN EFI_PEI_FV_HANDLE VolumeHandle,
|
||||
OUT EFI_FV_INFO *VolumeInfo
|
||||
)
|
||||
{
|
||||
return (*GetPeiServicesTablePointer())->FfsGetVolumeInfo (VolumeHandle, VolumeInfo);
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,15 @@
|
||||
|
||||
static EFI_PEI_SERVICES **gPeiServices;
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
SetPeiServicesTablePointer (
|
||||
EFI_PEI_SERVICES **PeiServices
|
||||
)
|
||||
{
|
||||
gPeiServices = PeiServices;
|
||||
}
|
||||
|
||||
/**
|
||||
The function returns the pointer to PEI services.
|
||||
|
||||
|
@ -22,6 +22,15 @@
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
SetPeiServicesTablePointer (
|
||||
IN EFI_PEI_SERVICES **PeiServices
|
||||
)
|
||||
{
|
||||
AsmWriteMm7 ((UINT64)(UINTN)PeiServices);
|
||||
}
|
||||
|
||||
/**
|
||||
The function returns the pointer to PeiServices.
|
||||
|
||||
|
@ -82,6 +82,7 @@
|
||||
MdePkg/Library/PeiMemoryLib/PeiMemoryLib.inf
|
||||
MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
|
||||
MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
|
||||
MdePkg/Library/PeiPiLib/PeiPiLib.inf
|
||||
MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf
|
||||
MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
|
||||
MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
|
||||
|
@ -21,35 +21,30 @@ Abstract:
|
||||
--*/
|
||||
|
||||
#include <PiPei.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Guid/PeiPeCoffLoader.h>
|
||||
#include <Library/PeCoffLoaderLib.h>
|
||||
#include <Library/PeCoffLoaderLib.h>
|
||||
#include <Library/PeiServicesLib.h>
|
||||
|
||||
|
||||
EFI_PEI_PE_COFF_LOADER_PROTOCOL *mPeiEfiPeiPeCoffLoader;
|
||||
EFI_PEI_PE_COFF_LOADER_PROTOCOL *mPeiEfiPeiPeCoffLoader = NULL;
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeCoffLoaderConstructor (
|
||||
IN EFI_FFS_FILE_HEADER *FfsHeader,
|
||||
IN EFI_PEI_SERVICES **PeiServices
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = (*PeiServices)->LocatePpi (
|
||||
PeiServices,
|
||||
&gEfiPeiPeCoffLoaderGuid,
|
||||
0,
|
||||
NULL,
|
||||
&mPeiEfiPeiPeCoffLoader
|
||||
);
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_PEI_PE_COFF_LOADER_PROTOCOL *
|
||||
EFIAPI
|
||||
GetPeCoffLoaderProtocol (
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
if (mPeiEfiPeiPeCoffLoader == NULL) {
|
||||
Status = PeiServicesLocatePpi(
|
||||
&gEfiPeiPeCoffLoaderGuid,
|
||||
0,
|
||||
NULL,
|
||||
(VOID **) &mPeiEfiPeiPeCoffLoader
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
}
|
||||
return mPeiEfiPeiPeCoffLoader;
|
||||
}
|
||||
|
@ -24,8 +24,6 @@
|
||||
EDK_RELEASE_VERSION = 0x00020000
|
||||
EFI_SPECIFICATION_VERSION = 0x00020000
|
||||
|
||||
CONSTRUCTOR = PeCoffLoaderConstructor
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
|
@ -145,6 +145,7 @@
|
||||
PeCoffGetEntryPointLib|Nt32Pkg/Library/Nt32PeiPeCoffGetEntryPointLib/Nt32PeiPeCoffGetEntryPointLib.inf
|
||||
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
|
||||
DebugLib|IntelFrameworkModulePkg/Library/PeiDxeDebugLibReportStatusCode/PeiDxeDebugLibReportStatusCode.inf
|
||||
PeCoffLoaderLib|Nt32Pkg/Library/Nt32PeCoffLoaderLib/Nt32PeCoffLoaderLib.inf
|
||||
|
||||
[LibraryClasses.common.DXE_RUNTIME_DRIVER]
|
||||
UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
|
||||
|
Loading…
x
Reference in New Issue
Block a user