/** @file

  Stateful and implicitly initialized fw_cfg library implementation.

  Copyright (C) 2013, Red Hat, Inc.
  Copyright (c) 2011 - 2013, Intel Corporation. All rights reserved.<BR>
  Copyright (c) 2017, Advanced Micro Devices. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <Uefi.h>

#include <Protocol/IoMmu.h>

#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/IoLib.h>
#include <Library/DebugLib.h>
#include <Library/QemuFwCfgLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/MemEncryptTdxLib.h>
#include <Library/MemEncryptSevLib.h>

#include "QemuFwCfgLibInternal.h"

STATIC BOOLEAN  mQemuFwCfgSupported = FALSE;
STATIC BOOLEAN  mQemuFwCfgDmaSupported;

STATIC EDKII_IOMMU_PROTOCOL  *mIoMmuProtocol;

/**
  Returns a boolean indicating if the firmware configuration interface
  is available or not.

  This function may change fw_cfg state.

  @retval    TRUE   The interface is available
  @retval    FALSE  The interface is not available

**/
BOOLEAN
EFIAPI
QemuFwCfgIsAvailable (
  VOID
  )
{
  return InternalQemuFwCfgIsAvailable ();
}

RETURN_STATUS
EFIAPI
QemuFwCfgInitialize (
  VOID
  )
{
  UINT32  Signature;
  UINT32  Revision;

  //
  // Enable the access routines while probing to see if it is supported.
  // For probing we always use the IO Port (IoReadFifo8()) access method.
  //
  mQemuFwCfgSupported    = TRUE;
  mQemuFwCfgDmaSupported = FALSE;

  QemuFwCfgSelectItem (QemuFwCfgItemSignature);
  Signature = QemuFwCfgRead32 ();
  DEBUG ((DEBUG_INFO, "FW CFG Signature: 0x%x\n", Signature));
  QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion);
  Revision = QemuFwCfgRead32 ();
  DEBUG ((DEBUG_INFO, "FW CFG Revision: 0x%x\n", Revision));
  if ((Signature != SIGNATURE_32 ('Q', 'E', 'M', 'U')) ||
      (Revision < 1)
      )
  {
    DEBUG ((DEBUG_INFO, "QemuFwCfg interface not supported.\n"));
    mQemuFwCfgSupported = FALSE;
    return RETURN_SUCCESS;
  }

  if ((Revision & FW_CFG_F_DMA) == 0) {
    DEBUG ((DEBUG_INFO, "QemuFwCfg interface (IO Port) is supported.\n"));
  } else {
    mQemuFwCfgDmaSupported = TRUE;
    DEBUG ((DEBUG_INFO, "QemuFwCfg interface (DMA) is supported.\n"));
  }

  if (mQemuFwCfgDmaSupported && (MemEncryptSevIsEnabled () || (MemEncryptTdxIsEnabled ()))) {
    EFI_STATUS  Status;

    //
    // IoMmuDxe driver must have installed the IOMMU protocol. If we are not
    // able to locate the protocol then something must have gone wrong.
    //
    Status = gBS->LocateProtocol (
                    &gEdkiiIoMmuProtocolGuid,
                    NULL,
                    (VOID **)&mIoMmuProtocol
                    );
    if (EFI_ERROR (Status)) {
      DEBUG ((
        DEBUG_ERROR,
        "QemuFwCfgDma %a:%a Failed to locate IOMMU protocol.\n",
        gEfiCallerBaseName,
        __FUNCTION__
        ));
      ASSERT (FALSE);
      CpuDeadLoop ();
    }
  }

  return RETURN_SUCCESS;
}

/**
  Returns a boolean indicating if the firmware configuration interface is
  available for library-internal purposes.

  This function never changes fw_cfg state.

  @retval    TRUE   The interface is available internally.
  @retval    FALSE  The interface is not available internally.
**/
BOOLEAN
InternalQemuFwCfgIsAvailable (
  VOID
  )
{
  return mQemuFwCfgSupported;
}

/**
  Returns a boolean indicating whether QEMU provides the DMA-like access method
  for fw_cfg.

  @retval    TRUE   The DMA-like access method is available.
  @retval    FALSE  The DMA-like access method is unavailable.
**/
BOOLEAN
InternalQemuFwCfgDmaIsAvailable (
  VOID
  )
{
  return mQemuFwCfgDmaSupported;
}

/**
  Function is used for allocating a bi-directional FW_CFG_DMA_ACCESS used
  between Host and device to exchange the information. The buffer must be free'd
  using FreeFwCfgDmaAccessBuffer ().

**/
STATIC
VOID
AllocFwCfgDmaAccessBuffer (
  OUT   VOID  **Access,
  OUT   VOID  **MapInfo
  )
{
  UINTN                 Size;
  UINTN                 NumPages;
  EFI_STATUS            Status;
  VOID                  *HostAddress;
  EFI_PHYSICAL_ADDRESS  DmaAddress;
  VOID                  *Mapping;

  Size     = sizeof (FW_CFG_DMA_ACCESS);
  NumPages = EFI_SIZE_TO_PAGES (Size);

  //
  // As per UEFI spec, in order to map a host address with
  // BusMasterCommonBuffer64, the buffer must be allocated using the IOMMU
  // AllocateBuffer()
  //
  Status = mIoMmuProtocol->AllocateBuffer (
                             mIoMmuProtocol,
                             AllocateAnyPages,
                             EfiBootServicesData,
                             NumPages,
                             &HostAddress,
                             EDKII_IOMMU_ATTRIBUTE_DUAL_ADDRESS_CYCLE
                             );
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_ERROR,
      "%a:%a failed to allocate FW_CFG_DMA_ACCESS\n",
      gEfiCallerBaseName,
      __FUNCTION__
      ));
    ASSERT (FALSE);
    CpuDeadLoop ();
  }

  //
  // Avoid exposing stale data even temporarily: zero the area before mapping
  // it.
  //
  ZeroMem (HostAddress, Size);

  //
  // Map the host buffer with BusMasterCommonBuffer64
  //
  Status = mIoMmuProtocol->Map (
                             mIoMmuProtocol,
                             EdkiiIoMmuOperationBusMasterCommonBuffer64,
                             HostAddress,
                             &Size,
                             &DmaAddress,
                             &Mapping
                             );
  if (EFI_ERROR (Status)) {
    mIoMmuProtocol->FreeBuffer (mIoMmuProtocol, NumPages, HostAddress);
    DEBUG ((
      DEBUG_ERROR,
      "%a:%a failed to Map() FW_CFG_DMA_ACCESS\n",
      gEfiCallerBaseName,
      __FUNCTION__
      ));
    ASSERT (FALSE);
    CpuDeadLoop ();
  }

  if (Size < sizeof (FW_CFG_DMA_ACCESS)) {
    mIoMmuProtocol->Unmap (mIoMmuProtocol, Mapping);
    mIoMmuProtocol->FreeBuffer (mIoMmuProtocol, NumPages, HostAddress);
    DEBUG ((
      DEBUG_ERROR,
      "%a:%a failed to Map() - requested 0x%Lx got 0x%Lx\n",
      gEfiCallerBaseName,
      __FUNCTION__,
      (UINT64)sizeof (FW_CFG_DMA_ACCESS),
      (UINT64)Size
      ));
    ASSERT (FALSE);
    CpuDeadLoop ();
  }

  *Access  = HostAddress;
  *MapInfo = Mapping;
}

/**
  Function is to used for freeing the Access buffer allocated using
  AllocFwCfgDmaAccessBuffer()

**/
STATIC
VOID
FreeFwCfgDmaAccessBuffer (
  IN  VOID  *Access,
  IN  VOID  *Mapping
  )
{
  UINTN       NumPages;
  EFI_STATUS  Status;

  NumPages = EFI_SIZE_TO_PAGES (sizeof (FW_CFG_DMA_ACCESS));

  Status = mIoMmuProtocol->Unmap (mIoMmuProtocol, Mapping);
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_ERROR,
      "%a:%a failed to UnMap() Mapping 0x%Lx\n",
      gEfiCallerBaseName,
      __FUNCTION__,
      (UINT64)(UINTN)Mapping
      ));
    ASSERT (FALSE);
    CpuDeadLoop ();
  }

  Status = mIoMmuProtocol->FreeBuffer (mIoMmuProtocol, NumPages, Access);
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_ERROR,
      "%a:%a failed to Free() 0x%Lx\n",
      gEfiCallerBaseName,
      __FUNCTION__,
      (UINT64)(UINTN)Access
      ));
    ASSERT (FALSE);
    CpuDeadLoop ();
  }
}

/**
  Function is used for mapping host address to device address. The buffer must
  be unmapped with UnmapDmaDataBuffer ().

**/
STATIC
VOID
MapFwCfgDmaDataBuffer (
  IN  BOOLEAN               IsWrite,
  IN  VOID                  *HostAddress,
  IN  UINT32                Size,
  OUT EFI_PHYSICAL_ADDRESS  *DeviceAddress,
  OUT VOID                  **MapInfo
  )
{
  EFI_STATUS            Status;
  UINTN                 NumberOfBytes;
  VOID                  *Mapping;
  EFI_PHYSICAL_ADDRESS  PhysicalAddress;

  NumberOfBytes = Size;
  Status        = mIoMmuProtocol->Map (
                                    mIoMmuProtocol,
                                    (IsWrite ?
                                     EdkiiIoMmuOperationBusMasterRead64 :
                                     EdkiiIoMmuOperationBusMasterWrite64),
                                    HostAddress,
                                    &NumberOfBytes,
                                    &PhysicalAddress,
                                    &Mapping
                                    );
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_ERROR,
      "%a:%a failed to Map() Address 0x%Lx Size 0x%Lx\n",
      gEfiCallerBaseName,
      __FUNCTION__,
      (UINT64)(UINTN)HostAddress,
      (UINT64)Size
      ));
    ASSERT (FALSE);
    CpuDeadLoop ();
  }

  if (NumberOfBytes < Size) {
    mIoMmuProtocol->Unmap (mIoMmuProtocol, Mapping);
    DEBUG ((
      DEBUG_ERROR,
      "%a:%a failed to Map() - requested 0x%x got 0x%Lx\n",
      gEfiCallerBaseName,
      __FUNCTION__,
      Size,
      (UINT64)NumberOfBytes
      ));
    ASSERT (FALSE);
    CpuDeadLoop ();
  }

  *DeviceAddress = PhysicalAddress;
  *MapInfo       = Mapping;
}

STATIC
VOID
UnmapFwCfgDmaDataBuffer (
  IN  VOID  *Mapping
  )
{
  EFI_STATUS  Status;

  Status = mIoMmuProtocol->Unmap (mIoMmuProtocol, Mapping);
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_ERROR,
      "%a:%a failed to UnMap() Mapping 0x%Lx\n",
      gEfiCallerBaseName,
      __FUNCTION__,
      (UINT64)(UINTN)Mapping
      ));
    ASSERT (FALSE);
    CpuDeadLoop ();
  }
}

/**
  Transfer an array of bytes, or skip a number of bytes, using the DMA
  interface.

  @param[in]     Size     Size in bytes to transfer or skip.

  @param[in,out] Buffer   Buffer to read data into or write data from. Ignored,
                          and may be NULL, if Size is zero, or Control is
                          FW_CFG_DMA_CTL_SKIP.

  @param[in]     Control  One of the following:
                          FW_CFG_DMA_CTL_WRITE - write to fw_cfg from Buffer.
                          FW_CFG_DMA_CTL_READ  - read from fw_cfg into Buffer.
                          FW_CFG_DMA_CTL_SKIP  - skip bytes in fw_cfg.
**/
VOID
InternalQemuFwCfgDmaBytes (
  IN     UINT32  Size,
  IN OUT VOID    *Buffer OPTIONAL,
  IN     UINT32  Control
  )
{
  volatile FW_CFG_DMA_ACCESS  LocalAccess;
  volatile FW_CFG_DMA_ACCESS  *Access;
  UINT32                      AccessHigh, AccessLow;
  UINT32                      Status;
  VOID                        *AccessMapping, *DataMapping;
  VOID                        *DataBuffer;

  ASSERT (
    Control == FW_CFG_DMA_CTL_WRITE || Control == FW_CFG_DMA_CTL_READ ||
    Control == FW_CFG_DMA_CTL_SKIP
    );

  if (Size == 0) {
    return;
  }

  Access        = &LocalAccess;
  AccessMapping = NULL;
  DataMapping   = NULL;
  DataBuffer    = Buffer;

  //
  // When SEV or TDX is enabled, map Buffer to DMA address before issuing the DMA
  // request
  //
  if (MemEncryptSevIsEnabled () || MemEncryptTdxIsEnabled ()) {
    VOID                  *AccessBuffer;
    EFI_PHYSICAL_ADDRESS  DataBufferAddress;

    //
    // Allocate DMA Access buffer
    //
    AllocFwCfgDmaAccessBuffer (&AccessBuffer, &AccessMapping);

    Access = AccessBuffer;

    //
    // Map actual data buffer
    //
    if (Control != FW_CFG_DMA_CTL_SKIP) {
      MapFwCfgDmaDataBuffer (
        Control == FW_CFG_DMA_CTL_WRITE,
        Buffer,
        Size,
        &DataBufferAddress,
        &DataMapping
        );

      DataBuffer = (VOID *)(UINTN)DataBufferAddress;
    }
  }

  Access->Control = SwapBytes32 (Control);
  Access->Length  = SwapBytes32 (Size);
  Access->Address = SwapBytes64 ((UINTN)DataBuffer);

  //
  // Delimit the transfer from (a) modifications to Access, (b) in case of a
  // write, from writes to Buffer by the caller.
  //
  MemoryFence ();

  //
  // Start the transfer.
  //
  AccessHigh = (UINT32)RShiftU64 ((UINTN)Access, 32);
  AccessLow  = (UINT32)(UINTN)Access;
  IoWrite32 (FW_CFG_IO_DMA_ADDRESS, SwapBytes32 (AccessHigh));
  IoWrite32 (FW_CFG_IO_DMA_ADDRESS + 4, SwapBytes32 (AccessLow));

  //
  // Don't look at Access.Control before starting the transfer.
  //
  MemoryFence ();

  //
  // Wait for the transfer to complete.
  //
  do {
    Status = SwapBytes32 (Access->Control);
    ASSERT ((Status & FW_CFG_DMA_CTL_ERROR) == 0);
  } while (Status != 0);

  //
  // After a read, the caller will want to use Buffer.
  //
  MemoryFence ();

  //
  // If Access buffer was dynamically allocated then free it.
  //
  if (AccessMapping != NULL) {
    FreeFwCfgDmaAccessBuffer ((VOID *)Access, AccessMapping);
  }

  //
  // If DataBuffer was mapped then unmap it.
  //
  if (DataMapping != NULL) {
    UnmapFwCfgDmaDataBuffer (DataMapping);
  }
}
