MdeModulePkg PeiCore: Recheck SwitchStackSignal after ProcessNotifyList()
in case PeiInstallPeiMemory() is done in a callback with EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH, and the callback is registered on a PPI that is installed in the last PEIM. At the case, PeiCore SwitchStack code will be not being invoked. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Star Zeng <star.zeng@intel.com> Reviewed-by: Liming Gao <liming.gao@intel.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18305 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
a60a462e53
commit
bfb685da6f
|
@ -627,52 +627,39 @@ PeiCoreEntry (
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Conduct PEIM dispatch.
|
Check SwitchStackSignal and switch stack if SwitchStackSignal is TRUE.
|
||||||
|
|
||||||
@param SecCoreData Points to a data structure containing information about the PEI core's operating
|
@param[in] SecCoreData Points to a data structure containing information about the PEI core's operating
|
||||||
environment, such as the size and location of temporary RAM, the stack location and
|
environment, such as the size and location of temporary RAM, the stack location and
|
||||||
the BFV location.
|
the BFV location.
|
||||||
@param Private Pointer to the private data passed in from caller
|
@param[in] Private Pointer to the private data passed in from caller.
|
||||||
|
|
||||||
**/
|
**/
|
||||||
VOID
|
VOID
|
||||||
PeiDispatcher (
|
PeiCheckAndSwitchStack (
|
||||||
IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
|
IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
|
||||||
IN PEI_CORE_INSTANCE *Private
|
IN PEI_CORE_INSTANCE *Private
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
VOID *LoadFixPeiCodeBegin;
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
UINT32 Index1;
|
|
||||||
UINT32 Index2;
|
|
||||||
CONST EFI_PEI_SERVICES **PeiServices;
|
CONST EFI_PEI_SERVICES **PeiServices;
|
||||||
EFI_PEI_FILE_HANDLE PeimFileHandle;
|
|
||||||
UINTN FvCount;
|
|
||||||
UINTN PeimCount;
|
|
||||||
UINT32 AuthenticationState;
|
|
||||||
EFI_PHYSICAL_ADDRESS EntryPoint;
|
|
||||||
EFI_PEIM_ENTRY_POINT2 PeimEntryPoint;
|
|
||||||
UINTN SaveCurrentPeimCount;
|
|
||||||
UINTN SaveCurrentFvCount;
|
|
||||||
EFI_PEI_FILE_HANDLE SaveCurrentFileHandle;
|
|
||||||
EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI *TemporaryRamSupportPpi;
|
|
||||||
UINT64 NewStackSize;
|
UINT64 NewStackSize;
|
||||||
UINTN HeapTemporaryRamSize;
|
|
||||||
EFI_PHYSICAL_ADDRESS BaseOfNewHeap;
|
|
||||||
EFI_PHYSICAL_ADDRESS TopOfNewStack;
|
|
||||||
EFI_PHYSICAL_ADDRESS TopOfOldStack;
|
EFI_PHYSICAL_ADDRESS TopOfOldStack;
|
||||||
|
EFI_PHYSICAL_ADDRESS TopOfNewStack;
|
||||||
|
UINTN StackOffset;
|
||||||
|
BOOLEAN StackOffsetPositive;
|
||||||
EFI_PHYSICAL_ADDRESS TemporaryRamBase;
|
EFI_PHYSICAL_ADDRESS TemporaryRamBase;
|
||||||
UINTN TemporaryRamSize;
|
UINTN TemporaryRamSize;
|
||||||
UINTN TemporaryStackSize;
|
UINTN TemporaryStackSize;
|
||||||
VOID *TemporaryStackBase;
|
VOID *TemporaryStackBase;
|
||||||
UINTN PeiTemporaryRamSize;
|
UINTN PeiTemporaryRamSize;
|
||||||
VOID *PeiTemporaryRamBase;
|
VOID *PeiTemporaryRamBase;
|
||||||
UINTN StackOffset;
|
EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI *TemporaryRamSupportPpi;
|
||||||
BOOLEAN StackOffsetPositive;
|
EFI_PHYSICAL_ADDRESS BaseOfNewHeap;
|
||||||
EFI_PHYSICAL_ADDRESS HoleMemBase;
|
EFI_PHYSICAL_ADDRESS HoleMemBase;
|
||||||
UINTN HoleMemSize;
|
UINTN HoleMemSize;
|
||||||
EFI_FV_FILE_INFO FvFileInfo;
|
UINTN HeapTemporaryRamSize;
|
||||||
PEI_CORE_FV_HANDLE *CoreFvHandle;
|
|
||||||
VOID *LoadFixPeiCodeBegin;
|
|
||||||
EFI_PHYSICAL_ADDRESS TempBase1;
|
EFI_PHYSICAL_ADDRESS TempBase1;
|
||||||
UINTN TempSize1;
|
UINTN TempSize1;
|
||||||
EFI_PHYSICAL_ADDRESS TempBase2;
|
EFI_PHYSICAL_ADDRESS TempBase2;
|
||||||
|
@ -680,178 +667,6 @@ PeiDispatcher (
|
||||||
UINTN Index;
|
UINTN Index;
|
||||||
|
|
||||||
PeiServices = (CONST EFI_PEI_SERVICES **) &Private->Ps;
|
PeiServices = (CONST EFI_PEI_SERVICES **) &Private->Ps;
|
||||||
PeimEntryPoint = NULL;
|
|
||||||
PeimFileHandle = NULL;
|
|
||||||
EntryPoint = 0;
|
|
||||||
|
|
||||||
if ((Private->PeiMemoryInstalled) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME || PcdGetBool (PcdShadowPeimOnS3Boot))) {
|
|
||||||
//
|
|
||||||
// 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;
|
|
||||||
SaveCurrentFvCount = Private->CurrentPeimFvCount;
|
|
||||||
SaveCurrentFileHandle = Private->CurrentFileHandle;
|
|
||||||
|
|
||||||
for (Index1 = 0; Index1 <= SaveCurrentFvCount; Index1++) {
|
|
||||||
for (Index2 = 0; (Index2 < PcdGet32 (PcdPeiCoreMaxPeimPerFv)) && (Private->Fv[Index1].FvFileHandles[Index2] != NULL); Index2++) {
|
|
||||||
if (Private->Fv[Index1].PeimState[Index2] == PEIM_STATE_REGISITER_FOR_SHADOW) {
|
|
||||||
PeimFileHandle = Private->Fv[Index1].FvFileHandles[Index2];
|
|
||||||
Private->CurrentFileHandle = PeimFileHandle;
|
|
||||||
Private->CurrentPeimFvCount = Index1;
|
|
||||||
Private->CurrentPeimCount = Index2;
|
|
||||||
Status = PeiLoadImage (
|
|
||||||
(CONST EFI_PEI_SERVICES **) &Private->Ps,
|
|
||||||
PeimFileHandle,
|
|
||||||
PEIM_STATE_REGISITER_FOR_SHADOW,
|
|
||||||
&EntryPoint,
|
|
||||||
&AuthenticationState
|
|
||||||
);
|
|
||||||
if (Status == EFI_SUCCESS) {
|
|
||||||
//
|
|
||||||
// PEIM_STATE_REGISITER_FOR_SHADOW move to PEIM_STATE_DONE
|
|
||||||
//
|
|
||||||
Private->Fv[Index1].PeimState[Index2]++;
|
|
||||||
//
|
|
||||||
// Call the PEIM entry point
|
|
||||||
//
|
|
||||||
PeimEntryPoint = (EFI_PEIM_ENTRY_POINT2)(UINTN)EntryPoint;
|
|
||||||
|
|
||||||
PERF_START (PeimFileHandle, "PEIM", NULL, 0);
|
|
||||||
PeimEntryPoint(PeimFileHandle, (const EFI_PEI_SERVICES **) &Private->Ps);
|
|
||||||
PERF_END (PeimFileHandle, "PEIM", NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Process the Notify list and dispatch any notifies for
|
|
||||||
// newly installed PPIs.
|
|
||||||
//
|
|
||||||
ProcessNotifyList (Private);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Private->CurrentFileHandle = SaveCurrentFileHandle;
|
|
||||||
Private->CurrentPeimFvCount = SaveCurrentFvCount;
|
|
||||||
Private->CurrentPeimCount = SaveCurrentPeimCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// This is the main dispatch loop. It will search known FVs for PEIMs and
|
|
||||||
// attempt to dispatch them. If any PEIM gets dispatched through a single
|
|
||||||
// pass of the dispatcher, it will start over from the Bfv again to see
|
|
||||||
// if any new PEIMs dependencies got satisfied. With a well ordered
|
|
||||||
// FV where PEIMs are found in the order their dependencies are also
|
|
||||||
// satisfied, this dipatcher should run only once.
|
|
||||||
//
|
|
||||||
do {
|
|
||||||
//
|
|
||||||
// In case that reenter PeiCore happens, the last pass record is still available.
|
|
||||||
//
|
|
||||||
if (!Private->PeimDispatcherReenter) {
|
|
||||||
Private->PeimNeedingDispatch = FALSE;
|
|
||||||
Private->PeimDispatchOnThisPass = FALSE;
|
|
||||||
} else {
|
|
||||||
Private->PeimDispatcherReenter = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (FvCount = Private->CurrentPeimFvCount; FvCount < Private->FvCount; FvCount++) {
|
|
||||||
CoreFvHandle = FindNextCoreFvHandle (Private, FvCount);
|
|
||||||
ASSERT (CoreFvHandle != NULL);
|
|
||||||
|
|
||||||
//
|
|
||||||
// If the FV has corresponding EFI_PEI_FIRMWARE_VOLUME_PPI instance, then dispatch it.
|
|
||||||
//
|
|
||||||
if (CoreFvHandle->FvPpi == NULL) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Private->CurrentPeimFvCount = FvCount;
|
|
||||||
|
|
||||||
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, CoreFvHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Start to dispatch all modules within the current Fv.
|
|
||||||
//
|
|
||||||
for (PeimCount = Private->CurrentPeimCount;
|
|
||||||
(PeimCount < PcdGet32 (PcdPeiCoreMaxPeimPerFv)) && (Private->CurrentFvFileHandles[PeimCount] != NULL);
|
|
||||||
PeimCount++) {
|
|
||||||
Private->CurrentPeimCount = PeimCount;
|
|
||||||
PeimFileHandle = Private->CurrentFileHandle = Private->CurrentFvFileHandles[PeimCount];
|
|
||||||
|
|
||||||
if (Private->Fv[FvCount].PeimState[PeimCount] == PEIM_STATE_NOT_DISPATCHED) {
|
|
||||||
if (!DepexSatisfied (Private, PeimFileHandle, PeimCount)) {
|
|
||||||
Private->PeimNeedingDispatch = TRUE;
|
|
||||||
} else {
|
|
||||||
Status = CoreFvHandle->FvPpi->GetFileInfo (CoreFvHandle->FvPpi, PeimFileHandle, &FvFileInfo);
|
|
||||||
ASSERT_EFI_ERROR (Status);
|
|
||||||
if (FvFileInfo.FileType == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {
|
|
||||||
//
|
|
||||||
// For Fv type file, Produce new FV PPI and FV hob
|
|
||||||
//
|
|
||||||
Status = ProcessFvFile (Private, &Private->Fv[FvCount], PeimFileHandle);
|
|
||||||
if (Status == EFI_SUCCESS) {
|
|
||||||
//
|
|
||||||
// PEIM_STATE_NOT_DISPATCHED move to PEIM_STATE_DISPATCHED
|
|
||||||
//
|
|
||||||
Private->Fv[FvCount].PeimState[PeimCount]++;
|
|
||||||
Private->PeimDispatchOnThisPass = TRUE;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//
|
|
||||||
// For PEIM driver, Load its entry point
|
|
||||||
//
|
|
||||||
Status = PeiLoadImage (
|
|
||||||
PeiServices,
|
|
||||||
PeimFileHandle,
|
|
||||||
PEIM_STATE_NOT_DISPATCHED,
|
|
||||||
&EntryPoint,
|
|
||||||
&AuthenticationState
|
|
||||||
);
|
|
||||||
if (Status == EFI_SUCCESS) {
|
|
||||||
//
|
|
||||||
// The PEIM has its dependencies satisfied, and its entry point
|
|
||||||
// has been found, so invoke it.
|
|
||||||
//
|
|
||||||
PERF_START (PeimFileHandle, "PEIM", NULL, 0);
|
|
||||||
|
|
||||||
REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
|
|
||||||
EFI_PROGRESS_CODE,
|
|
||||||
(EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_BEGIN),
|
|
||||||
(VOID *)(&PeimFileHandle),
|
|
||||||
sizeof (PeimFileHandle)
|
|
||||||
);
|
|
||||||
|
|
||||||
Status = VerifyPeim (Private, CoreFvHandle->FvHandle, PeimFileHandle, AuthenticationState);
|
|
||||||
if (Status != EFI_SECURITY_VIOLATION) {
|
|
||||||
//
|
|
||||||
// PEIM_STATE_NOT_DISPATCHED move to PEIM_STATE_DISPATCHED
|
|
||||||
//
|
|
||||||
Private->Fv[FvCount].PeimState[PeimCount]++;
|
|
||||||
//
|
|
||||||
// Call the PEIM entry point for PEIM driver
|
|
||||||
//
|
|
||||||
PeimEntryPoint = (EFI_PEIM_ENTRY_POINT2)(UINTN)EntryPoint;
|
|
||||||
PeimEntryPoint (PeimFileHandle, (const EFI_PEI_SERVICES **) PeiServices);
|
|
||||||
Private->PeimDispatchOnThisPass = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
|
|
||||||
EFI_PROGRESS_CODE,
|
|
||||||
(EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_END),
|
|
||||||
(VOID *)(&PeimFileHandle),
|
|
||||||
sizeof (PeimFileHandle)
|
|
||||||
);
|
|
||||||
PERF_END (PeimFileHandle, "PEIM", NULL, 0);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Private->SwitchStackSignal) {
|
if (Private->SwitchStackSignal) {
|
||||||
//
|
//
|
||||||
|
@ -1094,12 +909,227 @@ PeiDispatcher (
|
||||||
//
|
//
|
||||||
ASSERT (FALSE);
|
ASSERT (FALSE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Conduct PEIM dispatch.
|
||||||
|
|
||||||
|
@param SecCoreData Points to a data structure containing information about the PEI core's operating
|
||||||
|
environment, such as the size and location of temporary RAM, the stack location and
|
||||||
|
the BFV location.
|
||||||
|
@param Private Pointer to the private data passed in from caller
|
||||||
|
|
||||||
|
**/
|
||||||
|
VOID
|
||||||
|
PeiDispatcher (
|
||||||
|
IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
|
||||||
|
IN PEI_CORE_INSTANCE *Private
|
||||||
|
)
|
||||||
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINT32 Index1;
|
||||||
|
UINT32 Index2;
|
||||||
|
CONST EFI_PEI_SERVICES **PeiServices;
|
||||||
|
EFI_PEI_FILE_HANDLE PeimFileHandle;
|
||||||
|
UINTN FvCount;
|
||||||
|
UINTN PeimCount;
|
||||||
|
UINT32 AuthenticationState;
|
||||||
|
EFI_PHYSICAL_ADDRESS EntryPoint;
|
||||||
|
EFI_PEIM_ENTRY_POINT2 PeimEntryPoint;
|
||||||
|
UINTN SaveCurrentPeimCount;
|
||||||
|
UINTN SaveCurrentFvCount;
|
||||||
|
EFI_PEI_FILE_HANDLE SaveCurrentFileHandle;
|
||||||
|
EFI_FV_FILE_INFO FvFileInfo;
|
||||||
|
PEI_CORE_FV_HANDLE *CoreFvHandle;
|
||||||
|
|
||||||
|
PeiServices = (CONST EFI_PEI_SERVICES **) &Private->Ps;
|
||||||
|
PeimEntryPoint = NULL;
|
||||||
|
PeimFileHandle = NULL;
|
||||||
|
EntryPoint = 0;
|
||||||
|
|
||||||
|
if ((Private->PeiMemoryInstalled) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME || PcdGetBool (PcdShadowPeimOnS3Boot))) {
|
||||||
|
//
|
||||||
|
// 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;
|
||||||
|
SaveCurrentFvCount = Private->CurrentPeimFvCount;
|
||||||
|
SaveCurrentFileHandle = Private->CurrentFileHandle;
|
||||||
|
|
||||||
|
for (Index1 = 0; Index1 <= SaveCurrentFvCount; Index1++) {
|
||||||
|
for (Index2 = 0; (Index2 < PcdGet32 (PcdPeiCoreMaxPeimPerFv)) && (Private->Fv[Index1].FvFileHandles[Index2] != NULL); Index2++) {
|
||||||
|
if (Private->Fv[Index1].PeimState[Index2] == PEIM_STATE_REGISITER_FOR_SHADOW) {
|
||||||
|
PeimFileHandle = Private->Fv[Index1].FvFileHandles[Index2];
|
||||||
|
Private->CurrentFileHandle = PeimFileHandle;
|
||||||
|
Private->CurrentPeimFvCount = Index1;
|
||||||
|
Private->CurrentPeimCount = Index2;
|
||||||
|
Status = PeiLoadImage (
|
||||||
|
(CONST EFI_PEI_SERVICES **) &Private->Ps,
|
||||||
|
PeimFileHandle,
|
||||||
|
PEIM_STATE_REGISITER_FOR_SHADOW,
|
||||||
|
&EntryPoint,
|
||||||
|
&AuthenticationState
|
||||||
|
);
|
||||||
|
if (Status == EFI_SUCCESS) {
|
||||||
|
//
|
||||||
|
// PEIM_STATE_REGISITER_FOR_SHADOW move to PEIM_STATE_DONE
|
||||||
|
//
|
||||||
|
Private->Fv[Index1].PeimState[Index2]++;
|
||||||
|
//
|
||||||
|
// Call the PEIM entry point
|
||||||
|
//
|
||||||
|
PeimEntryPoint = (EFI_PEIM_ENTRY_POINT2)(UINTN)EntryPoint;
|
||||||
|
|
||||||
|
PERF_START (PeimFileHandle, "PEIM", NULL, 0);
|
||||||
|
PeimEntryPoint(PeimFileHandle, (const EFI_PEI_SERVICES **) &Private->Ps);
|
||||||
|
PERF_END (PeimFileHandle, "PEIM", NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Process the Notify list and dispatch any notifies for
|
// Process the Notify list and dispatch any notifies for
|
||||||
// newly installed PPIs.
|
// newly installed PPIs.
|
||||||
//
|
//
|
||||||
ProcessNotifyList (Private);
|
ProcessNotifyList (Private);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Private->CurrentFileHandle = SaveCurrentFileHandle;
|
||||||
|
Private->CurrentPeimFvCount = SaveCurrentFvCount;
|
||||||
|
Private->CurrentPeimCount = SaveCurrentPeimCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// This is the main dispatch loop. It will search known FVs for PEIMs and
|
||||||
|
// attempt to dispatch them. If any PEIM gets dispatched through a single
|
||||||
|
// pass of the dispatcher, it will start over from the Bfv again to see
|
||||||
|
// if any new PEIMs dependencies got satisfied. With a well ordered
|
||||||
|
// FV where PEIMs are found in the order their dependencies are also
|
||||||
|
// satisfied, this dipatcher should run only once.
|
||||||
|
//
|
||||||
|
do {
|
||||||
|
//
|
||||||
|
// In case that reenter PeiCore happens, the last pass record is still available.
|
||||||
|
//
|
||||||
|
if (!Private->PeimDispatcherReenter) {
|
||||||
|
Private->PeimNeedingDispatch = FALSE;
|
||||||
|
Private->PeimDispatchOnThisPass = FALSE;
|
||||||
|
} else {
|
||||||
|
Private->PeimDispatcherReenter = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (FvCount = Private->CurrentPeimFvCount; FvCount < Private->FvCount; FvCount++) {
|
||||||
|
CoreFvHandle = FindNextCoreFvHandle (Private, FvCount);
|
||||||
|
ASSERT (CoreFvHandle != NULL);
|
||||||
|
|
||||||
|
//
|
||||||
|
// If the FV has corresponding EFI_PEI_FIRMWARE_VOLUME_PPI instance, then dispatch it.
|
||||||
|
//
|
||||||
|
if (CoreFvHandle->FvPpi == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Private->CurrentPeimFvCount = FvCount;
|
||||||
|
|
||||||
|
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, CoreFvHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Start to dispatch all modules within the current Fv.
|
||||||
|
//
|
||||||
|
for (PeimCount = Private->CurrentPeimCount;
|
||||||
|
(PeimCount < PcdGet32 (PcdPeiCoreMaxPeimPerFv)) && (Private->CurrentFvFileHandles[PeimCount] != NULL);
|
||||||
|
PeimCount++) {
|
||||||
|
Private->CurrentPeimCount = PeimCount;
|
||||||
|
PeimFileHandle = Private->CurrentFileHandle = Private->CurrentFvFileHandles[PeimCount];
|
||||||
|
|
||||||
|
if (Private->Fv[FvCount].PeimState[PeimCount] == PEIM_STATE_NOT_DISPATCHED) {
|
||||||
|
if (!DepexSatisfied (Private, PeimFileHandle, PeimCount)) {
|
||||||
|
Private->PeimNeedingDispatch = TRUE;
|
||||||
|
} else {
|
||||||
|
Status = CoreFvHandle->FvPpi->GetFileInfo (CoreFvHandle->FvPpi, PeimFileHandle, &FvFileInfo);
|
||||||
|
ASSERT_EFI_ERROR (Status);
|
||||||
|
if (FvFileInfo.FileType == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {
|
||||||
|
//
|
||||||
|
// For Fv type file, Produce new FV PPI and FV hob
|
||||||
|
//
|
||||||
|
Status = ProcessFvFile (Private, &Private->Fv[FvCount], PeimFileHandle);
|
||||||
|
if (Status == EFI_SUCCESS) {
|
||||||
|
//
|
||||||
|
// PEIM_STATE_NOT_DISPATCHED move to PEIM_STATE_DISPATCHED
|
||||||
|
//
|
||||||
|
Private->Fv[FvCount].PeimState[PeimCount]++;
|
||||||
|
Private->PeimDispatchOnThisPass = TRUE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// For PEIM driver, Load its entry point
|
||||||
|
//
|
||||||
|
Status = PeiLoadImage (
|
||||||
|
PeiServices,
|
||||||
|
PeimFileHandle,
|
||||||
|
PEIM_STATE_NOT_DISPATCHED,
|
||||||
|
&EntryPoint,
|
||||||
|
&AuthenticationState
|
||||||
|
);
|
||||||
|
if (Status == EFI_SUCCESS) {
|
||||||
|
//
|
||||||
|
// The PEIM has its dependencies satisfied, and its entry point
|
||||||
|
// has been found, so invoke it.
|
||||||
|
//
|
||||||
|
PERF_START (PeimFileHandle, "PEIM", NULL, 0);
|
||||||
|
|
||||||
|
REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
|
||||||
|
EFI_PROGRESS_CODE,
|
||||||
|
(EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_BEGIN),
|
||||||
|
(VOID *)(&PeimFileHandle),
|
||||||
|
sizeof (PeimFileHandle)
|
||||||
|
);
|
||||||
|
|
||||||
|
Status = VerifyPeim (Private, CoreFvHandle->FvHandle, PeimFileHandle, AuthenticationState);
|
||||||
|
if (Status != EFI_SECURITY_VIOLATION) {
|
||||||
|
//
|
||||||
|
// PEIM_STATE_NOT_DISPATCHED move to PEIM_STATE_DISPATCHED
|
||||||
|
//
|
||||||
|
Private->Fv[FvCount].PeimState[PeimCount]++;
|
||||||
|
//
|
||||||
|
// Call the PEIM entry point for PEIM driver
|
||||||
|
//
|
||||||
|
PeimEntryPoint = (EFI_PEIM_ENTRY_POINT2)(UINTN)EntryPoint;
|
||||||
|
PeimEntryPoint (PeimFileHandle, (const EFI_PEI_SERVICES **) PeiServices);
|
||||||
|
Private->PeimDispatchOnThisPass = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
|
||||||
|
EFI_PROGRESS_CODE,
|
||||||
|
(EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_END),
|
||||||
|
(VOID *)(&PeimFileHandle),
|
||||||
|
sizeof (PeimFileHandle)
|
||||||
|
);
|
||||||
|
PERF_END (PeimFileHandle, "PEIM", NULL, 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PeiCheckAndSwitchStack (SecCoreData, Private);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Process the Notify list and dispatch any notifies for
|
||||||
|
// newly installed PPIs.
|
||||||
|
//
|
||||||
|
ProcessNotifyList (Private);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Recheck SwitchStackSignal after ProcessNotifyList()
|
||||||
|
// in case PeiInstallPeiMemory() is done in a callback with
|
||||||
|
// EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH.
|
||||||
|
//
|
||||||
|
PeiCheckAndSwitchStack (SecCoreData, Private);
|
||||||
|
|
||||||
if ((Private->PeiMemoryInstalled) && (Private->Fv[FvCount].PeimState[PeimCount] == PEIM_STATE_REGISITER_FOR_SHADOW) && \
|
if ((Private->PeiMemoryInstalled) && (Private->Fv[FvCount].PeimState[PeimCount] == PEIM_STATE_REGISITER_FOR_SHADOW) && \
|
||||||
(Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME || PcdGetBool (PcdShadowPeimOnS3Boot))) {
|
(Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME || PcdGetBool (PcdShadowPeimOnS3Boot))) {
|
||||||
|
|
Loading…
Reference in New Issue