REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4595 Fix build error when remove "-Wno-sometimes-uninitialized" option, Add variable "FspMultiPhaseApiOffset" initialization. Cc: Nate DeSimone <nathaniel.l.desimone@intel.com> Cc: Star Zeng <star.zeng@intel.com> Cc: Chasel Chiu <chasel.chiu@intel.com> Cc: Duggapu Chinni B <chinni.b.duggapu@intel.com> Cc: Ted Kuo <ted.kuo@intel.com> Cc: Susovan Mohapatra <susovan.mohapatra@intel.com> Cc: James Lu <james.lu@intel.com> Reviewed-by: Ashraf Ali S <ashraf.ali.s@intel.com> Reviewed-by: Chen Gang C <gang.c.chen@intel.com> Reviewed-by: Gua Guo <gua.guo@intel.com> Signed-off-by: Jason Hsu <jasonx.hsu@intel.com>
		
			
				
	
	
		
			375 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			375 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @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/FspWrapperPlatformMultiPhaseLib.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;
 | 
						|
  BOOLEAN                 IsVariableServiceRequest;
 | 
						|
  FSP_MULTI_PHASE_PARAMS  *FspMultiPhaseParamsPtr;
 | 
						|
 | 
						|
  FspMultiPhaseApiOffset   = 0;
 | 
						|
  FspMultiPhaseParamsPtr   = (FSP_MULTI_PHASE_PARAMS *)FspMultiPhaseParams;
 | 
						|
  IsVariableServiceRequest = FALSE;
 | 
						|
  if ((FspMultiPhaseParamsPtr->MultiPhaseAction == EnumMultiPhaseGetVariableRequestInfo) ||
 | 
						|
      (FspMultiPhaseParamsPtr->MultiPhaseAction == EnumMultiPhaseCompleteVariableRequest))
 | 
						|
  {
 | 
						|
    IsVariableServiceRequest = TRUE;
 | 
						|
  }
 | 
						|
 | 
						|
  if (ComponentIndex == FspMultiPhaseMemInitApiIndex) {
 | 
						|
    FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspmBaseAddress));
 | 
						|
    if (FspHeader == NULL) {
 | 
						|
      return EFI_DEVICE_ERROR;
 | 
						|
    } else if (FspHeader->SpecVersion < 0x24) {
 | 
						|
      return EFI_UNSUPPORTED;
 | 
						|
    }
 | 
						|
 | 
						|
    FspMultiPhaseApiOffset = FspHeader->FspMultiPhaseMemInitEntryOffset;
 | 
						|
  } else if (ComponentIndex == FspMultiPhaseSiInitApiIndex) {
 | 
						|
    FspHeader = (FSP_INFO_HEADER *)FspFindFspHeader (PcdGet32 (PcdFspsBaseAddress));
 | 
						|
    if (FspHeader == NULL) {
 | 
						|
      return EFI_DEVICE_ERROR;
 | 
						|
    } else if (FspHeader->SpecVersion < 0x22) {
 | 
						|
      return EFI_UNSUPPORTED;
 | 
						|
    } else if ((FspHeader->SpecVersion < 0x24) && (IsVariableServiceRequest == TRUE)) {
 | 
						|
      return EFI_UNSUPPORTED;
 | 
						|
    }
 | 
						|
 | 
						|
    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, out] 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,
 | 
						|
                            or FSP does not support VariableService
 | 
						|
  @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, out] FspHobListPtr        - Pointer to FSP HobList (valid after FSP-M completed)
 | 
						|
  @param[in]      ComponentIndex       - FSP Component which executing MultiPhase initialization.
 | 
						|
 | 
						|
  @retval EFI_UNSUPPORTED   Specific MultiPhase action was not supported.
 | 
						|
  @retval EFI_SUCCESS       MultiPhase action were completed successfully.
 | 
						|
 | 
						|
**/
 | 
						|
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;
 | 
						|
}
 |