edk2/IntelFsp2Pkg/FspNotifyPhase/FspNotifyPhasePeim.c
Hongbin1 Zhang d297c699c9 IntelFsp2Pkg: Add Fsp notify phase check
This change included following two changes:
1. Add Fsp notify phase check, it will hang
   if bootloader call FSP with wrong phase
2. Remove FspMode check, due to just API mode
   will run the code, no need to check

Signed-off-by: Hongbin1 Zhang <hongbin1.zhang@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Ted Kuo <ted.kuo@intel.com>
Cc: Ashraf Ali S <ashraf.ali.s@intel.com>
2025-06-13 03:14:20 +00:00

160 lines
4.0 KiB
C

/** @file
Source file for FSP notify phase PEI module
Copyright (c) 2016 - 2022, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "FspNotifyPhasePeim.h"
/**
This function waits for FSP notify.
@param This Entry point for DXE IPL PPI.
@param PeiServices General purpose services available to every PEIM.
@param HobList Address to the Pei HOB list.
@return EFI_SUCCESS This function never returns.
**/
EFI_STATUS
EFIAPI
WaitForNotify (
IN CONST EFI_DXE_IPL_PPI *This,
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_HOB_POINTERS HobList
);
CONST EFI_DXE_IPL_PPI mDxeIplPpi = {
WaitForNotify
};
CONST EFI_PEI_PPI_DESCRIPTOR mInstallDxeIplPpi = {
EFI_PEI_PPI_DESCRIPTOR_PPI,
&gEfiDxeIplPpiGuid,
(VOID *)&mDxeIplPpi
};
CONST EFI_PEI_PPI_DESCRIPTOR gEndOfPeiSignalPpi = {
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gEfiEndOfPeiSignalPpiGuid,
NULL
};
CONST EFI_PEI_PPI_DESCRIPTOR gFspReadyForNotifyPhasePpi = {
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gFspReadyForNotifyPhasePpiGuid,
NULL
};
/**
This function waits for FSP notify.
@param This Entry point for DXE IPL PPI.
@param PeiServices General purpose services available to every PEIM.
@param HobList Address to the Pei HOB list.
@return EFI_SUCCESS This function never returns.
**/
EFI_STATUS
EFIAPI
WaitForNotify (
IN CONST EFI_DXE_IPL_PPI *This,
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_HOB_POINTERS HobList
)
{
EFI_STATUS Status;
DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP HOB is located at 0x%08X\n", HobList));
//
// End of PEI phase signal
//
Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi);
ASSERT_EFI_ERROR (Status);
//
// Give control back to BootLoader after FspSiliconInit
//
DEBUG ((DEBUG_INFO | DEBUG_INIT, "FSP is waiting for NOTIFY\n"));
FspSiliconInitDone2 (EFI_SUCCESS);
//
// Fsp notify phase check
//
DEBUG ((DEBUG_INFO | DEBUG_INIT, "Fsp Notify Phase called ...\n"));
ASSERT (GetFspApiCallingIndex () == NotifyPhaseApiIndex);
while (GetFspApiCallingIndex () != NotifyPhaseApiIndex) {
SetFspApiReturnStatus (EFI_UNSUPPORTED);
Pei2LoaderSwitchStack ();
}
//
// BootLoader called FSP again through NotifyPhase
//
FspWaitForNotify ();
//
// Should not come here
//
while (TRUE) {
DEBUG ((DEBUG_ERROR, "No FSP API should be called after FSP is DONE!\n"));
SetFspApiReturnStatus (EFI_UNSUPPORTED);
Pei2LoaderSwitchStack ();
}
return EFI_SUCCESS;
}
/**
FSP notify phase PEI module entry point
@param[in] FileHandle Not used.
@param[in] PeiServices General purpose services available to every PEIM.
@retval EFI_SUCCESS The function completes successfully
@retval EFI_OUT_OF_RESOURCES Insufficient resources to create database
**/
EFI_STATUS
EFIAPI
FspNotifyPhasePeimEntryPoint (
IN EFI_PEI_FILE_HANDLE FileHandle,
IN CONST EFI_PEI_SERVICES **PeiServices
)
{
EFI_STATUS Status;
VOID *OldDxeIplPpi;
EFI_PEI_PPI_DESCRIPTOR *OldDescriptor;
DEBUG ((DEBUG_INFO | DEBUG_INIT, "The entry of FspNotificationPeim\n"));
if (GetFspGlobalDataPointer ()->FspMode == FSP_IN_API_MODE) {
//
// Locate old DXE IPL PPI
//
Status = PeiServicesLocatePpi (
&gEfiDxeIplPpiGuid,
0,
&OldDescriptor,
&OldDxeIplPpi
);
ASSERT_EFI_ERROR (Status);
//
// Re-install the DXE IPL PPI to wait for notify
//
Status = PeiServicesReInstallPpi (OldDescriptor, &mInstallDxeIplPpi);
ASSERT_EFI_ERROR (Status);
} else {
Status = PeiServicesInstallPpi (&gFspReadyForNotifyPhasePpi);
ASSERT_EFI_ERROR (Status);
}
return EFI_SUCCESS;
}