/** @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>
#include <Library/BaseMemoryLib.h>
#include <Library/HobLib.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;
  VOID                                              *GuidHob;
  VOID                                              *HobData;

  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;
    }
  }

  //
  // Refresh FspHobList pointer stored in HOB.
  //
  GuidHob = GetFirstGuidHob (&gFspHobGuid);
  ASSERT (GuidHob != NULL);
  if (GuidHob != NULL) {
    HobData = GET_GUID_HOB_DATA (GuidHob);
    CopyMem (HobData, FspHobListPtr, sizeof (*FspHobListPtr));
  }

  //
  // 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;
  VOID                                         *GuidHob;
  VOID                                         *HobData;

  //
  // 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);

    //
    // Refresh FspHobList pointer stored in HOB.
    //
    GuidHob = GetFirstGuidHob (&gFspHobGuid);
    ASSERT (GuidHob != NULL);
    if (GuidHob != NULL) {
      HobData = GET_GUID_HOB_DATA (GuidHob);
      CopyMem (HobData, FspHobListPtr, sizeof (*FspHobListPtr));
    }

    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;
}
