summaryrefslogtreecommitdiffstats
path: root/IntelFsp2WrapperPkg/Library/FspWrapperMultiPhaseProcessLib/PeiFspWrapperMultiPhaseProcessLib.c
diff options
context:
space:
mode:
Diffstat (limited to 'IntelFsp2WrapperPkg/Library/FspWrapperMultiPhaseProcessLib/PeiFspWrapperMultiPhaseProcessLib.c')
-rw-r--r--IntelFsp2WrapperPkg/Library/FspWrapperMultiPhaseProcessLib/PeiFspWrapperMultiPhaseProcessLib.c355
1 files changed, 355 insertions, 0 deletions
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.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/FspWrapperApiLib.h>
+#include <Library/FspWrapperPlatformLib.h>
+#include <FspEas.h>
+#include <FspGlobalData.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Ppi/Variable.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/FspWrapperMultiPhaseProcessLib.h>
+
+/**
+ 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;
+}