diff --git a/IntelFsp2WrapperPkg/Include/Library/FspWrapperMultiPhaseProcessLib.h b/IntelFsp2WrapperPkg/Include/Library/FspWrapperMultiPhaseProcessLib.h new file mode 100644 index 0000000000..65a5db233f --- /dev/null +++ b/IntelFsp2WrapperPkg/Include/Library/FspWrapperMultiPhaseProcessLib.h @@ -0,0 +1,62 @@ +/** @file + Provide FSP wrapper MultiPhase handling functions. + + Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __FSP_WRAPPER_MULTI_PHASE_PROCESS_LIB_H__ +#define __FSP_WRAPPER_MULTI_PHASE_PROCESS_LIB_H__ + +/** + FSP Wrapper Platform MultiPhase Handler + + @param[in] FspHobListPtr - Pointer to FSP HobList (valid after FSP-M completed) + @param[in] ComponentIndex - FSP Component which executing MultiPhase initialization. + @param[in] PhaseIndex - Indicates current execution phase of FSP MultiPhase initialization. + + @retval EFI_STATUS Always return EFI_SUCCESS + +**/ +VOID +EFIAPI +FspWrapperPlatformMultiPhaseHandler ( + IN OUT VOID **FspHobListPtr, + IN UINT8 ComponentIndex, + IN UINT32 PhaseIndex + ); + +/** + FSP Wrapper Variable Request Handler + + @param[in] FspHobListPtr - Pointer to FSP HobList (valid after FSP-M completed) + @param[in] ComponentIndex - FSP Component which executing MultiPhase initialization. + + @retval EFI_UNSUPPORTED FSP Wrapper cannot support the specific variable request + @retval EFI_STATUS Return FSP returned status + +**/EFI_STATUS +EFIAPI +FspWrapperVariableRequestHandler ( + IN OUT VOID **FspHobListPtr, + IN UINT8 ComponentIndex + ); + +/** + FSP Wrapper MultiPhase Handler + + @param[in] FspHobListPtr - Pointer to FSP HobList (valid after FSP-M completed) + @param[in] ComponentIndex - FSP Component which executing MultiPhase initialization. + + @retval EFI_STATUS Always return EFI_SUCCESS + +**/ +EFI_STATUS +EFIAPI +FspWrapperMultiPhaseHandler ( + IN OUT VOID **FspHobListPtr, + IN UINT8 ComponentIndex + ); + +#endif diff --git a/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec b/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec index c43b0c2267..d96037b63b 100644 --- a/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec +++ b/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec @@ -1,7 +1,7 @@ ## @file # Provides drivers and definitions to support fsp in EDKII bios. # -# Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.
+# Copyright (c) 2014 - 2022, Intel Corporation. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -28,6 +28,14 @@ ## @libraryclass Provide FSP TPM measurement related function. FspMeasurementLib|Include/Library/FspMeasurementLib.h + + ## @libraryclass Provide MultiPhase handling related functions. + FspWrapperMultiPhaseProcessLib|Include/Library/FspWrapperMultiPhaseProcessLib.h + + ## @libraryclass Provide MultiPhase platform actions related functions. + FspWrapperPlatformMultiPhaseLib|Include/Library/FspWrapperMultiPhaseProcessLib.h + + [Guids] # # GUID defined in package diff --git a/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc b/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc index 21e089000e..79a5c7f13d 100644 --- a/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc +++ b/IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dsc @@ -1,7 +1,7 @@ ## @file # Provides drivers and definitions to support fsp in EDKII bios. # -# Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.
+# Copyright (c) 2014 - 2022, Intel Corporation. All rights reserved.
# SPDX-License-Identifier: BSD-2-Clause-Patent # ## @@ -48,6 +48,8 @@ FspWrapperApiLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf FspWrapperApiTestLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperApiTestLibNull/BaseFspWrapperApiTestLibNull.inf FspMeasurementLib|IntelFsp2WrapperPkg/Library/BaseFspMeasurementLib/BaseFspMeasurementLib.inf + FspWrapperPlatformMultiPhaseLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformMultiPhaseLibSample/BaseFspWrapperPlatformMultiPhaseLibSample.inf + FspWrapperMultiPhaseProcessLib|IntelFsp2WrapperPkg/Library/FspWrapperMultiPhaseProcessLib/FspWrapperMultiPhaseProcessLib.inf # FSP platform sample FspWrapperPlatformLib|IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/BaseFspWrapperPlatformLibSample.inf @@ -91,6 +93,8 @@ IntelFsp2WrapperPkg/Library/BaseFspWrapperApiLib/BaseFspWrapperApiLib.inf IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformLibSample/BaseFspWrapperPlatformLibSample.inf IntelFsp2WrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf + IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformMultiPhaseLibSample/BaseFspWrapperPlatformMultiPhaseLibSample.inf + IntelFsp2WrapperPkg/Library/FspWrapperMultiPhaseProcessLib/FspWrapperMultiPhaseProcessLib.inf [PcdsFixedAtBuild.common] gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x1f diff --git a/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformMultiPhaseLibSample/BaseFspWrapperPlatformMultiPhaseLibSample.inf b/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformMultiPhaseLibSample/BaseFspWrapperPlatformMultiPhaseLibSample.inf new file mode 100644 index 0000000000..607ad41a23 --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformMultiPhaseLibSample/BaseFspWrapperPlatformMultiPhaseLibSample.inf @@ -0,0 +1,37 @@ +## @file +# FSP Wrapper to handle platform specific actions for +# FSP MultiPhase (SeparatePhase) Initialization. +# +# Copyright (c) 2022, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BaseFspWrapperPlatformMultiPhaseLibSample + FILE_GUID = DB63E5AA-21C6-40BB-879A-CD1762C8427B + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = FspWrapperPlatformMultiPhaseLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + FspWrapperPlatformMultiPhaseLibSample.c + +[Packages] + MdePkg/MdePkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec + +[LibraryClasses] + DebugLib + BaseLib + PcdLib + PeiServicesLib diff --git a/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformMultiPhaseLibSample/FspWrapperPlatformMultiPhaseLibSample.c b/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformMultiPhaseLibSample/FspWrapperPlatformMultiPhaseLibSample.c new file mode 100644 index 0000000000..b4bc3d8b07 --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/BaseFspWrapperPlatformMultiPhaseLibSample/FspWrapperPlatformMultiPhaseLibSample.c @@ -0,0 +1,50 @@ +/** @file + FSP Wrapper to handle platform specific actions for + FSP MultiPhase (SeparatePhase) Initialization. + + Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include + +/** + FSP Wrapper Platform MultiPhase Handler + + @param[in] FspHobListPtr - Pointer to FSP HobList (valid after FSP-M completed) + @param[in] ComponentIndex - FSP Component which executing MultiPhase initialization. + @param[in] PhaseIndex - Indicates current execution phase of FSP MultiPhase initialization. + + @retval EFI_STATUS Always return EFI_SUCCESS + +**/ +VOID +EFIAPI +FspWrapperPlatformMultiPhaseHandler ( + IN OUT VOID **FspHobListPtr, + IN UINT8 ComponentIndex, + IN UINT32 PhaseIndex + ) +{ + /* Example platform actions as below + switch (ComponentIndex) { + case FspMultiPhaseMemInitApiIndex: + switch (PhaseIndex) { + case 1: + PlatformAction1 (); + break; + } + break; + case FspMultiPhaseSiInitApiIndex: + switch (PhaseIndex) { + case 1: + PlatformAction2 (); + break; + } + break; + } + */ +} diff --git a/IntelFsp2WrapperPkg/Library/FspWrapperMultiPhaseProcessLib/FspWrapperMultiPhaseProcessLib.inf b/IntelFsp2WrapperPkg/Library/FspWrapperMultiPhaseProcessLib/FspWrapperMultiPhaseProcessLib.inf new file mode 100644 index 0000000000..e76a7465f2 --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/FspWrapperMultiPhaseProcessLib/FspWrapperMultiPhaseProcessLib.inf @@ -0,0 +1,48 @@ +## @file +# FSP wrapper to handle FSP MultiPhase (SeparatePhase) Initialization. +# +# Copyright (c) 2022, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = FspWrapperMultiPhaseProcessLib + FILE_GUID = 11E657B7-C3D8-405B-94C5-516840E67B75 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = FspWrapperMultiPhaseProcessLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 +# + +[Sources] + PeiFspWrapperMultiPhaseProcessLib.c + +[Packages] + MdePkg/MdePkg.dec + IntelFsp2Pkg/IntelFsp2Pkg.dec + IntelFsp2WrapperPkg/IntelFsp2WrapperPkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseMemoryLib + DebugLib + BaseLib + PcdLib + FspWrapperPlatformLib + PeiServicesLib + FspWrapperPlatformMultiPhaseLib + +[Ppis] + gEfiPeiReadOnlyVariable2PpiGuid + gEdkiiPeiVariablePpiGuid + +[Pcd] + gIntelFsp2WrapperTokenSpaceGuid.PcdFspmBaseAddress ## CONSUMES + gIntelFsp2WrapperTokenSpaceGuid.PcdFspsBaseAddress ## CONSUMES diff --git a/IntelFsp2WrapperPkg/Library/FspWrapperMultiPhaseProcessLib/PeiFspWrapperMultiPhaseProcessLib.c b/IntelFsp2WrapperPkg/Library/FspWrapperMultiPhaseProcessLib/PeiFspWrapperMultiPhaseProcessLib.c new file mode 100644 index 0000000000..3ddc07690a --- /dev/null +++ b/IntelFsp2WrapperPkg/Library/FspWrapperMultiPhaseProcessLib/PeiFspWrapperMultiPhaseProcessLib.c @@ -0,0 +1,355 @@ +/** @file + Support FSP Wrapper MultiPhase process. + + Copyright (c) 2022, Intel Corporation. All rights reserved.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + Execute 32-bit FSP API entry code. + + @param[in] Function The 32bit code entry to be executed. + @param[in] Param1 The first parameter to pass to 32bit code. + @param[in] Param2 The second parameter to pass to 32bit code. + + @return EFI_STATUS. +**/ +EFI_STATUS +Execute32BitCode ( + IN UINT64 Function, + IN UINT64 Param1, + IN UINT64 Param2 + ); + +/** + Execute 64-bit FSP API entry code. + + @param[in] Function The 64bit code entry to be executed. + @param[in] Param1 The first parameter to pass to 64bit code. + @param[in] Param2 The second parameter to pass to 64bit code. + + @return EFI_STATUS. +**/ +EFI_STATUS +Execute64BitCode ( + IN UINT64 Function, + IN UINT64 Param1, + IN UINT64 Param2 + ); + +/** + Call FspsMultiPhase API. + + @param[in] FspsMultiPhaseParams - Parameters for MultiPhase API. + @param[in] FspHobListPtr - Pointer to FSP HobList (valid after FSP-M completed) + @param[in] ComponentIndex - FSP Component which executing MultiPhase initialization. + + @return EFI_UNSUPPORTED - the requested FspsMultiPhase API is not supported. + @return EFI_DEVICE_ERROR - the FSP header was not found. + @return EFI status returned by FspsMultiPhase API. +**/ +EFI_STATUS +EFIAPI +CallFspMultiPhaseEntry ( + IN VOID *FspMultiPhaseParams, + IN OUT VOID **FspHobListPtr, + IN UINT8 ComponentIndex + ) +{ + FSP_INFO_HEADER *FspHeader; + // + // FSP_MULTI_PHASE_INIT and FSP_MULTI_PHASE_SI_INIT API functions having same prototype. + // + UINTN FspMultiPhaseApiEntry; + UINTN FspMultiPhaseApiOffset; + EFI_STATUS Status; + BOOLEAN InterruptState; + + if (ComponentIndex == FspMultiPhaseMemInitApiIndex) { + FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress)); + if (FspHeader == NULL) { + return EFI_DEVICE_ERROR; + } + + FspMultiPhaseApiOffset = FspHeader->FspMultiPhaseMemInitEntryOffset; + } else if (ComponentIndex == FspMultiPhaseSiInitApiIndex) { + FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress)); + if (FspHeader == NULL) { + return EFI_DEVICE_ERROR; + } + + FspMultiPhaseApiOffset = FspHeader->FspMultiPhaseSiInitEntryOffset; + } + + if (FspMultiPhaseApiOffset == 0) { + return EFI_UNSUPPORTED; + } + + FspMultiPhaseApiEntry = FspHeader->ImageBase + FspMultiPhaseApiOffset; + InterruptState = SaveAndDisableInterrupts (); + if ((FspHeader->ImageAttribute & BIT2) == 0) { + // BIT2: IMAGE_ATTRIBUTE_64BIT_MODE_SUPPORT + Status = Execute32BitCode ((UINTN)FspMultiPhaseApiEntry, (UINTN)FspMultiPhaseParams, (UINTN)NULL); + } else { + Status = Execute64BitCode ((UINTN)FspMultiPhaseApiEntry, (UINTN)FspMultiPhaseParams, (UINTN)NULL); + } + + SetInterruptState (InterruptState); + + DEBUG ((DEBUG_ERROR, "CallFspMultiPhaseEntry return Status %r \n", Status)); + + return Status; +} + +/** + FSP Wrapper Variable Request Handler + + @param[in] FspHobListPtr - Pointer to FSP HobList (valid after FSP-M completed) + @param[in] ComponentIndex - FSP Component which executing MultiPhase initialization. + + @retval EFI_UNSUPPORTED FSP Wrapper cannot support the specific variable request + @retval EFI_STATUS Return FSP returned status + +**/ +EFI_STATUS +EFIAPI +FspWrapperVariableRequestHandler ( + IN OUT VOID **FspHobListPtr, + IN UINT8 ComponentIndex + ) +{ + EFI_STATUS Status; + FSP_MULTI_PHASE_PARAMS FspMultiPhaseParams; + FSP_MULTI_PHASE_VARIABLE_REQUEST_INFO_PARAMS *FspVariableRequestParams; + EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariablePpi; + EDKII_PEI_VARIABLE_PPI *VariablePpi; + BOOLEAN WriteVariableSupport; + FSP_MULTI_PHASE_COMPLETE_VARIABLE_REQUEST_PARAMS CompleteVariableRequestParams; + + WriteVariableSupport = TRUE; + Status = PeiServicesLocatePpi ( + &gEdkiiPeiVariablePpiGuid, + 0, + NULL, + (VOID **)&VariablePpi + ); + if (EFI_ERROR (Status)) { + WriteVariableSupport = FALSE; + Status = PeiServicesLocatePpi ( + &gEfiPeiReadOnlyVariable2PpiGuid, + 0, + NULL, + (VOID **)&ReadOnlyVariablePpi + ); + ASSERT_EFI_ERROR (Status); + if (EFI_ERROR (Status)) { + return EFI_UNSUPPORTED; + } + } + + Status = FSP_STATUS_VARIABLE_REQUEST; + while (Status == FSP_STATUS_VARIABLE_REQUEST) { + // + // Get the variable request information from FSP. + // + FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseGetVariableRequestInfo; + FspMultiPhaseParams.PhaseIndex = 0; + Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex); + ASSERT_EFI_ERROR (Status); + // + // FSP should output this pointer for variable request information. + // + FspVariableRequestParams = (FSP_MULTI_PHASE_VARIABLE_REQUEST_INFO_PARAMS *)FspMultiPhaseParams.MultiPhaseParamPtr; + switch (FspVariableRequestParams->VariableRequest) { + case EnumFspVariableRequestGetVariable: + if (WriteVariableSupport) { + Status = VariablePpi->GetVariable ( + VariablePpi, + FspVariableRequestParams->VariableName, + FspVariableRequestParams->VariableGuid, + FspVariableRequestParams->Attributes, + (UINTN *)FspVariableRequestParams->DataSize, + FspVariableRequestParams->Data + ); + } else { + Status = ReadOnlyVariablePpi->GetVariable ( + ReadOnlyVariablePpi, + FspVariableRequestParams->VariableName, + FspVariableRequestParams->VariableGuid, + FspVariableRequestParams->Attributes, + (UINTN *)FspVariableRequestParams->DataSize, + FspVariableRequestParams->Data + ); + } + + CompleteVariableRequestParams.VariableRequestStatus = Status; + FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams; + FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest; + Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex); + break; + + case EnumFspVariableRequestSetVariable: + if (WriteVariableSupport) { + Status = VariablePpi->SetVariable ( + VariablePpi, + FspVariableRequestParams->VariableName, + FspVariableRequestParams->VariableGuid, + *FspVariableRequestParams->Attributes, + (UINTN)*FspVariableRequestParams->DataSize, + FspVariableRequestParams->Data + ); + } else { + Status = EFI_UNSUPPORTED; + } + + CompleteVariableRequestParams.VariableRequestStatus = Status; + FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams; + FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest; + Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex); + break; + + case EnumFspVariableRequestGetNextVariableName: + if (WriteVariableSupport) { + Status = VariablePpi->GetNextVariableName ( + VariablePpi, + (UINTN *)FspVariableRequestParams->VariableNameSize, + FspVariableRequestParams->VariableName, + FspVariableRequestParams->VariableGuid + ); + } else { + Status = ReadOnlyVariablePpi->NextVariableName ( + ReadOnlyVariablePpi, + (UINTN *)FspVariableRequestParams->VariableNameSize, + FspVariableRequestParams->VariableName, + FspVariableRequestParams->VariableGuid + ); + } + + CompleteVariableRequestParams.VariableRequestStatus = Status; + FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams; + FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest; + Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex); + break; + + case EnumFspVariableRequestQueryVariableInfo: + if (WriteVariableSupport) { + Status = VariablePpi->QueryVariableInfo ( + VariablePpi, + *FspVariableRequestParams->Attributes, + FspVariableRequestParams->MaximumVariableStorageSize, + FspVariableRequestParams->RemainingVariableStorageSize, + FspVariableRequestParams->MaximumVariableSize + ); + } else { + Status = EFI_UNSUPPORTED; + } + + CompleteVariableRequestParams.VariableRequestStatus = Status; + FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&CompleteVariableRequestParams; + FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseCompleteVariableRequest; + Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex); + break; + + default: + DEBUG ((DEBUG_ERROR, "Unknown VariableRequest type!\n")); + Status = EFI_UNSUPPORTED; + break; + } + } + + // + // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status + // + if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) { + DEBUG ((DEBUG_INFO, "FspMultiPhaseApi-0x%x requested reset %r\n", ComponentIndex, Status)); + CallFspWrapperResetSystem ((UINTN)Status); + } + + return Status; +} + +/** + FSP Wrapper MultiPhase Handler + + @param[in] FspHobListPtr - Pointer to FSP HobList (valid after FSP-M completed) + @param[in] ComponentIndex - FSP Component which executing MultiPhase initialization. + + @retval EFI_STATUS Always return EFI_SUCCESS + +**/ +EFI_STATUS +EFIAPI +FspWrapperMultiPhaseHandler ( + IN OUT VOID **FspHobListPtr, + IN UINT8 ComponentIndex + ) +{ + EFI_STATUS Status; + FSP_MULTI_PHASE_PARAMS FspMultiPhaseParams; + FSP_MULTI_PHASE_GET_NUMBER_OF_PHASES_PARAMS FspMultiPhaseGetNumber; + UINT32 Index; + UINT32 NumOfPhases; + + // + // Query FSP for the number of phases supported. + // + FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseGetNumberOfPhases; + FspMultiPhaseParams.PhaseIndex = 0; + FspMultiPhaseParams.MultiPhaseParamPtr = (VOID *)&FspMultiPhaseGetNumber; + Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex); + if (Status == EFI_UNSUPPORTED) { + // + // MultiPhase API was not supported + // + return Status; + } else { + ASSERT_EFI_ERROR (Status); + } + + NumOfPhases = FspMultiPhaseGetNumber.NumberOfPhases; + + for (Index = 1; Index <= NumOfPhases; Index++) { + DEBUG ((DEBUG_ERROR, "MultiPhase Index/NumOfPhases = %d of %d\n", Index, NumOfPhases)); + // + // Platform actions can be added in below function for each component and phase before returning control back to FSP. + // + FspWrapperPlatformMultiPhaseHandler (FspHobListPtr, ComponentIndex, Index); + + FspMultiPhaseParams.MultiPhaseAction = EnumMultiPhaseExecutePhase; + FspMultiPhaseParams.PhaseIndex = Index; + FspMultiPhaseParams.MultiPhaseParamPtr = NULL; + Status = CallFspMultiPhaseEntry (&FspMultiPhaseParams, FspHobListPtr, ComponentIndex); + + if (Status == FSP_STATUS_VARIABLE_REQUEST) { + // + // call to Variable request handler + // + FspWrapperVariableRequestHandler (FspHobListPtr, ComponentIndex); + } + + // + // Reset the system if FSP API returned FSP_STATUS_RESET_REQUIRED status + // + if ((Status >= FSP_STATUS_RESET_REQUIRED_COLD) && (Status <= FSP_STATUS_RESET_REQUIRED_8)) { + DEBUG ((DEBUG_INFO, "FspMultiPhaseApi-0x%x requested reset %r\n", ComponentIndex, Status)); + CallFspWrapperResetSystem ((UINTN)Status); + } + + ASSERT_EFI_ERROR (Status); + } + + return EFI_SUCCESS; +}