/** @file
  SMM SwDispatch2 Protocol.

  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent



**/

#include "PchSmiDispatchSmm.h"

typedef struct {
  UINT8   EosBitOffset;
  UINT8   ApmBitOffset;
  UINT32  SmiEosAddr;
  UINT32  SmiApmStsAddr;
} SMM_PCH_REGISTER;

SMM_PCH_REGISTER       mSmiPchReg;

EFI_SMM_CPU_PROTOCOL   *mSmmCpuProtocol;
LIST_ENTRY             mSmmSwDispatch2Queue = INITIALIZE_LIST_HEAD_VARIABLE (mSmmSwDispatch2Queue);

/**
  Find SmmSwDispatch2Context by SwSmiInputValue.

  @param[in] SwSmiInputValue      The value to indentify the SmmSwDispatch2 context

  @return Pointer to EFI_SMM_SW_DISPATCH2_CONTEXT context
**/
EFI_SMM_SW_DISPATCH2_CONTEXT *
FindContextBySwSmiInputValue (
  IN UINTN                              SwSmiInputValue
  )
{
  LIST_ENTRY                            *Node;
  EFI_SMM_SW_DISPATCH2_CONTEXT          *Dispatch2Context;

  Node = mSmmSwDispatch2Queue.ForwardLink;
  for (; Node != &mSmmSwDispatch2Queue; Node = Node->ForwardLink) {
    Dispatch2Context = BASE_CR (Node, EFI_SMM_SW_DISPATCH2_CONTEXT, Link);
    if (Dispatch2Context->SwSmiInputValue == SwSmiInputValue) {
      return Dispatch2Context;
    }
  }
  return NULL;
}

/**
  Find SmmSwDispatch2Context by DispatchHandle.

  @param DispatchHandle    The handle to indentify the SmmSwDispatch2 context

  @return Pointer to EFI_SMM_SW_DISPATCH2_CONTEXT context
**/
EFI_SMM_SW_DISPATCH2_CONTEXT *
FindContextByDispatchHandle (
  IN EFI_HANDLE                         DispatchHandle
  )
{
  LIST_ENTRY                            *Node;
  EFI_SMM_SW_DISPATCH2_CONTEXT          *Dispatch2Context;

  Node = mSmmSwDispatch2Queue.ForwardLink;
  for (; Node != &mSmmSwDispatch2Queue; Node = Node->ForwardLink) {
    Dispatch2Context = BASE_CR (Node, EFI_SMM_SW_DISPATCH2_CONTEXT, Link);
    if (Dispatch2Context->DispatchHandle == DispatchHandle) {
      return Dispatch2Context;
    }
  }
  return NULL;
}

/**
  Dispatch registered SMM handlers

  @param  DispatchHandle  The unique handle assigned to this handler by SmiHandlerRegister().
  @param  RegisterContext Points to an optional handler context which was specified when the handler was registered.
  @param  CommBuffer      A pointer to a collection of data in memory that will
                          be conveyed from a non-SMM environment into an SMM environment.
  @param  CommBufferSize  The size of the CommBuffer.

  @return Status Code

**/
EFI_STATUS
SmmSwDispatcher (
  IN     EFI_HANDLE               DispatchHandle,
  IN     CONST VOID               *RegisterContext,
  IN OUT VOID                     *CommBuffer,
  IN OUT UINTN                    *CommBufferSize
  )
{
  EFI_STATUS                      Status;
  EFI_SMM_SW_CONTEXT              SwContext;
  UINTN                           Index;
  EFI_SMM_SW_DISPATCH2_CONTEXT    *Context;
  EFI_SMM_HANDLER_ENTRY_POINT2    DispatchFunction;
  EFI_SMM_SW_REGISTER_CONTEXT     DispatchContext;
  UINTN                           Size;
  EFI_SMM_SAVE_STATE_IO_INFO      IoInfo;

  //
  // Construct new context
  //
  SwContext.SwSmiCpuIndex = 0;
  SwContext.CommandPort   = IoRead8 (SMM_CONTROL_PORT);
  SwContext.DataPort      = IoRead8 (SMM_DATA_PORT);

  //
  // Try to find which CPU trigger SWSMI
  //
  for (Index = 0; Index < gSmst->NumberOfCpus; Index++) {
    Status = mSmmCpuProtocol->ReadSaveState (
                                mSmmCpuProtocol,
                                sizeof(IoInfo),
                                EFI_SMM_SAVE_STATE_REGISTER_IO,
                                Index,
                                &IoInfo
                                );
    if (EFI_ERROR (Status)) {
      continue;
    }
    if (IoInfo.IoPort == SMM_CONTROL_PORT) {
      //
      // Great! Find it.
      //
      SwContext.SwSmiCpuIndex = Index;
      DEBUG ((DEBUG_VERBOSE, "CPU index = 0x%x/0x%x\n", Index, gSmst->NumberOfCpus));
      break;
    }
  }

  if (SwContext.CommandPort == 0) {
    DEBUG ((DEBUG_VERBOSE, "NOT SW SMI\n"));
    Status = EFI_SUCCESS;
    goto End;
  }

  //
  // Search context
  //
  Context = FindContextBySwSmiInputValue (SwContext.CommandPort);
  if (Context == NULL) {
    DEBUG ((DEBUG_INFO, "No handler for SMI value 0x%x\n", SwContext.CommandPort));
    Status = EFI_SUCCESS;
    goto End;
  }
  DEBUG ((DEBUG_VERBOSE, "Prepare to call handler for 0x%x\n", SwContext.CommandPort));

  //
  // Dispatch
  //
  DispatchContext.SwSmiInputValue = SwContext.CommandPort;
  Size = sizeof(SwContext);
  DispatchFunction = (EFI_SMM_HANDLER_ENTRY_POINT2)Context->DispatchFunction;
  Status = DispatchFunction (DispatchHandle, &DispatchContext, &SwContext, &Size);

End:
  //
  // Clear SMI APM status
  //
  IoOr32 (mSmiPchReg.SmiApmStsAddr, 1 << mSmiPchReg.ApmBitOffset);


  //
  // Set EOS bit
  //
  IoOr32 (mSmiPchReg.SmiEosAddr, 1 << mSmiPchReg.EosBitOffset);

  return Status;
}


/**
Check the SwSmiInputValue is already used

@param[in]  SwSmiInputValue      To indentify the SmmSwDispatch2 context

@retval EFI_SUCCESS              SwSmiInputValue could be used.
@retval EFI_INVALID_PARAMETER    SwSmiInputValue is already be used.

**/
EFI_STATUS
SmiInputValueCheck (
  IN UINTN                              SwSmiInputValue
  )
{
  LIST_ENTRY                            *Node;
  EFI_SMM_SW_DISPATCH2_CONTEXT          *Dispatch2Context;

  Node = mSmmSwDispatch2Queue.ForwardLink;
  for (; Node != &mSmmSwDispatch2Queue; Node = Node->ForwardLink) {
    Dispatch2Context = BASE_CR (Node, EFI_SMM_SW_DISPATCH2_CONTEXT, Link);
    if (Dispatch2Context->SwSmiInputValue == SwSmiInputValue) {
      return EFI_INVALID_PARAMETER;
    }
  }

  return EFI_SUCCESS;
}


/**
  Register a child SMI source dispatch function for the specified software SMI.

  This service registers a function (DispatchFunction) which will be called when the software
  SMI source specified by RegContext->SwSmiCpuIndex is detected. On return, DispatchHandle
  contains a unique handle which may be used later to unregister the function using UnRegister().

  @param[in]  This               Pointer to the EFI_SMM_SW_DISPATCH2_PROTOCOL instance.
  @param[in]  DispatchFunction   Function to register for handler when the specified software
                                 SMI is generated.
  @param[in, out]  RegContext    Pointer to the dispatch function's context.
                                 The caller fills this context in before calling
                                 the register function to indicate to the register
                                 function which Software SMI input value the
                                 dispatch function should be invoked for.
  @param[out] DispatchHandle     Handle generated by the dispatcher to track the
                                 function instance.

  @retval EFI_SUCCESS            The dispatch function has been successfully
                                 registered and the SMI source has been enabled.
  @retval EFI_DEVICE_ERROR       The SW driver was unable to enable the SMI source.
  @retval EFI_INVALID_PARAMETER  RegisterContext is invalid. The SW SMI input value
                                 is not within valid range.
  @retval EFI_OUT_OF_RESOURCES   There is not enough memory (system or SMM) to manage this
                                 child.
  @retval EFI_OUT_OF_RESOURCES   A unique software SMI value could not be assigned
                                 for this dispatch.
**/
EFI_STATUS
EFIAPI
SmmSwDispatch2Register (
  IN  CONST EFI_SMM_SW_DISPATCH2_PROTOCOL  *This,
  IN        EFI_SMM_HANDLER_ENTRY_POINT2   DispatchFunction,
  IN  OUT   EFI_SMM_SW_REGISTER_CONTEXT    *RegContext,
  OUT       EFI_HANDLE                     *DispatchHandle
  )
{
  EFI_STATUS                                Status;
  UINTN                                     Index;
  EFI_SMM_SW_DISPATCH2_CONTEXT             *Context;

  if (RegContext->SwSmiInputValue == (UINTN)-1) {
    //
    // If SwSmiInputValue is set to (UINTN) -1 then a unique value
    // will be assigned and returned in the structure.
    //
    Status = EFI_NOT_FOUND;
    for (Index = 1; Index < MAXIMUM_SWI_VALUE; Index++) {
      Status = SmiInputValueCheck (Index);
      if (!EFI_ERROR (Status)) {
        RegContext->SwSmiInputValue = Index;
        break;
      }
    }
    if (RegContext->SwSmiInputValue == (UINTN)-1) {
      return EFI_OUT_OF_RESOURCES;
    }
  }

  if ((RegContext->SwSmiInputValue > MAXIMUM_SWI_VALUE) || (RegContext->SwSmiInputValue == 0)) {
    DEBUG ((DEBUG_ERROR, "ERROR: SMI value range (1 ~ 0x%x)\n", MAXIMUM_SWI_VALUE));
    return EFI_INVALID_PARAMETER;
  }

  //
  // Register
  //
  Status = gSmst->SmmAllocatePool (EfiRuntimeServicesData, sizeof(*Context), (VOID **)&Context);
  ASSERT_EFI_ERROR (Status);
  if (EFI_ERROR (Status)) {
    return EFI_OUT_OF_RESOURCES;
  }

  *DispatchHandle  = (EFI_HANDLE )Context;
  Context->Signature        = SMI_SW_HANDLER_SIGNATURE;
  Context->SwSmiInputValue  = RegContext->SwSmiInputValue;
  Context->DispatchFunction = (UINTN)DispatchFunction;
  Context->DispatchHandle   = *DispatchHandle;
  InsertTailList (&mSmmSwDispatch2Queue, &Context->Link);

  return Status;
}


/**
  Unregister a child SMI source dispatch function for the specified software SMI.

  This service removes the handler associated with DispatchHandle so that it will no longer be
  called in response to a software SMI.

  @param[in] This                Pointer to the EFI_SMM_SW_DISPATCH2_PROTOCOL instance.
  @param[in] DispatchHandle      Handle of dispatch function to deregister.

  @retval EFI_SUCCESS            The dispatch function has been successfully unregistered.
  @retval EFI_INVALID_PARAMETER  The DispatchHandle was not valid.
**/
EFI_STATUS
EFIAPI
SmmSwDispatch2UnRegister (
  IN CONST EFI_SMM_SW_DISPATCH2_PROTOCOL  *This,
  IN       EFI_HANDLE                     DispatchHandle
  )
{
  EFI_SMM_SW_DISPATCH2_CONTEXT            *Context;

  //
  // Unregister
  //
  Context = FindContextByDispatchHandle (DispatchHandle);
  ASSERT (Context != NULL);
  if (Context != NULL) {
    RemoveEntryList (&Context->Link);
    gSmst->SmmFreePool (Context);
  }

  return EFI_SUCCESS;
}


EFI_SMM_SW_DISPATCH2_PROTOCOL gSmmSwDispatch2 = {
  SmmSwDispatch2Register,
  SmmSwDispatch2UnRegister,
  MAXIMUM_SWI_VALUE
};


/**
  Get specified SMI register based on given register ID

  @param[in]  SmmRegister  SMI related register array from bootloader
  @param[in]  Id           The register ID to get.

  @retval NULL             The register is not found or the format is not expected.
  @return smi register

**/
PLD_GENERIC_REGISTER *
GetSmmCtrlRegById (
  IN PLD_SMM_REGISTERS    *SmmRegister,
  IN UINT32               Id
  )
{
  UINT32                  Index;
  PLD_GENERIC_REGISTER    *PldReg;

  PldReg = NULL;
  for (Index = 0; Index < SmmRegister->Count; Index++) {
    if (SmmRegister->Registers[Index].Id == Id) {
      PldReg = &SmmRegister->Registers[Index];
      break;
    }
  }

  if (PldReg == NULL) {
    DEBUG ((DEBUG_INFO, "Register %d not found.\n", Id));
    return NULL;
  }

  //
  // Checking the register if it is expected.
  //
  if ((PldReg->Address.AccessSize       != EFI_ACPI_3_0_DWORD) ||
      (PldReg->Address.Address          == 0) ||
      (PldReg->Address.RegisterBitWidth != 1) ||
      (PldReg->Address.AddressSpaceId   != EFI_ACPI_3_0_SYSTEM_IO) ||
      (PldReg->Value != 1)) {
    DEBUG ((DEBUG_INFO, "Unexpected SMM register.\n"));
    DEBUG ((DEBUG_INFO, "AddressSpaceId= 0x%x\n", PldReg->Address.AddressSpaceId));
    DEBUG ((DEBUG_INFO, "RegBitWidth   = 0x%x\n", PldReg->Address.RegisterBitWidth));
    DEBUG ((DEBUG_INFO, "RegBitOffset  = 0x%x\n", PldReg->Address.RegisterBitOffset));
    DEBUG ((DEBUG_INFO, "AccessSize    = 0x%x\n", PldReg->Address.AccessSize));
    DEBUG ((DEBUG_INFO, "Address       = 0x%lx\n",PldReg->Address.Address ));
    return NULL;
  }

  return PldReg;
}


/**
  Entry Point for this driver.

  @param[in] ImageHandle  Image handle of this driver.
  @param[in] SystemTable  A Pointer to the EFI System Table.

  @retval EFI_SUCCESS  The entry point is executed successfully.
  @retval other        Some error occurred when executing this entry point.
**/
EFI_STATUS
EFIAPI
PchSmiDispatchEntryPoint (
  IN EFI_HANDLE            ImageHandle,
  IN EFI_SYSTEM_TABLE      *SystemTable
  )
{
  EFI_STATUS               Status;
  EFI_HANDLE               DispatchHandle;
  EFI_HOB_GUID_TYPE       *GuidHob;
  PLD_SMM_REGISTERS       *SmmRegister;
  PLD_GENERIC_REGISTER    *SmiEosReg;
  PLD_GENERIC_REGISTER    *SmiApmStsReg;

  GuidHob = GetFirstGuidHob (&gSmmRegisterInfoGuid);
  if (GuidHob == NULL) {
    return EFI_UNSUPPORTED;
  }

  SmmRegister = (PLD_SMM_REGISTERS *) GET_GUID_HOB_DATA(GuidHob);
  SmiEosReg = GetSmmCtrlRegById (SmmRegister, REGISTER_ID_SMI_EOS);
  if (SmiEosReg == NULL) {
    DEBUG ((DEBUG_ERROR, "SMI EOS reg not found.\n"));
    return EFI_NOT_FOUND;
  }
  mSmiPchReg.SmiEosAddr   = (UINT32)SmiEosReg->Address.Address;
  mSmiPchReg.EosBitOffset = SmiEosReg->Address.RegisterBitOffset;

  SmiApmStsReg = GetSmmCtrlRegById (SmmRegister, REGISTER_ID_SMI_APM_STS);
  if (SmiApmStsReg == NULL) {
    DEBUG ((DEBUG_ERROR, "SMI APM status reg not found.\n"));
    return EFI_NOT_FOUND;
  }
  mSmiPchReg.SmiApmStsAddr = (UINT32)SmiApmStsReg->Address.Address;
  mSmiPchReg.ApmBitOffset  = SmiApmStsReg->Address.RegisterBitOffset;

  //
  // Locate PI SMM CPU protocol
  //
  Status = gSmst->SmmLocateProtocol (&gEfiSmmCpuProtocolGuid, NULL, (VOID **)&mSmmCpuProtocol);
  ASSERT_EFI_ERROR (Status);

  //
  // Register a SMM handler to handle subsequent SW SMIs.
  //
  Status = gSmst->SmiHandlerRegister ((EFI_MM_HANDLER_ENTRY_POINT)SmmSwDispatcher, NULL, &DispatchHandle);
  ASSERT_EFI_ERROR (Status);

  //
  // Publish PI SMM SwDispatch2 Protocol
  //
  ImageHandle = NULL;
  Status = gSmst->SmmInstallProtocolInterface (
                    &ImageHandle,
                    &gEfiSmmSwDispatch2ProtocolGuid,
                    EFI_NATIVE_INTERFACE,
                    &gSmmSwDispatch2
                    );
  ASSERT_EFI_ERROR (Status);

  return Status;
}

