/** @file
  OVMF support for QEMU system firmware flash device

  Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/MemEncryptSevLib.h>
#include <Library/PcdLib.h>

#include "QemuFlash.h"

#define WRITE_BYTE_CMD           0x10
#define BLOCK_ERASE_CMD          0x20
#define CLEAR_STATUS_CMD         0x50
#define READ_STATUS_CMD          0x70
#define READ_DEVID_CMD           0x90
#define BLOCK_ERASE_CONFIRM_CMD  0xd0
#define READ_ARRAY_CMD           0xff

#define CLEARED_ARRAY_STATUS  0x00

UINT8  *mFlashBase;

STATIC UINTN  mFdBlockSize  = 0;
STATIC UINTN  mFdBlockCount = 0;

STATIC
volatile UINT8 *
QemuFlashPtr (
  IN        EFI_LBA  Lba,
  IN        UINTN    Offset
  )
{
  return mFlashBase + ((UINTN)Lba * mFdBlockSize) + Offset;
}

/**
  Determines if the QEMU flash memory device is present.

  @retval FALSE   The QEMU flash device is not present.
  @retval TRUE    The QEMU flash device is present.

**/
STATIC
BOOLEAN
QemuFlashDetected (
  VOID
  )
{
  BOOLEAN         FlashDetected;
  volatile UINT8  *Ptr;

  UINTN  Offset;
  UINT8  OriginalUint8;
  UINT8  ProbeUint8;

  FlashDetected = FALSE;
  Ptr           = QemuFlashPtr (0, 0);

  for (Offset = 0; Offset < mFdBlockSize; Offset++) {
    Ptr        = QemuFlashPtr (0, Offset);
    ProbeUint8 = *Ptr;
    if ((ProbeUint8 != CLEAR_STATUS_CMD) &&
        (ProbeUint8 != READ_STATUS_CMD) &&
        (ProbeUint8 != CLEARED_ARRAY_STATUS))
    {
      break;
    }
  }

  if (Offset >= mFdBlockSize) {
    DEBUG ((DEBUG_INFO, "QEMU Flash: Failed to find probe location\n"));
    return FALSE;
  }

  DEBUG ((DEBUG_INFO, "QEMU Flash: Attempting flash detection at %p\n", Ptr));

  if (MemEncryptSevEsIsEnabled ()) {
    //
    // When SEV-ES is enabled, the check below can result in an infinite
    // loop with respect to a nested page fault. When the memslot is mapped
    // read-only, the nested page table entry is read-only. The check below
    // will cause a nested page fault that cannot be emulated, causing
    // the instruction to retried over and over. For SEV-ES, acknowledge that
    // the FD appears as ROM and not as FLASH, but report FLASH anyway because
    // FLASH behavior can be simulated using VMGEXIT.
    //
    DEBUG ((
      DEBUG_INFO,
      "QEMU Flash: SEV-ES enabled, assuming FD behaves as FLASH\n"
      ));
    return TRUE;
  }

  OriginalUint8 = *Ptr;
  *Ptr          = CLEAR_STATUS_CMD;
  ProbeUint8    = *Ptr;
  if ((OriginalUint8 != CLEAR_STATUS_CMD) &&
      (ProbeUint8 == CLEAR_STATUS_CMD))
  {
    DEBUG ((DEBUG_INFO, "QemuFlashDetected => FD behaves as RAM\n"));
    *Ptr = OriginalUint8;
  } else {
    *Ptr       = READ_STATUS_CMD;
    ProbeUint8 = *Ptr;
    if (ProbeUint8 == OriginalUint8) {
      DEBUG ((DEBUG_INFO, "QemuFlashDetected => FD behaves as ROM\n"));
    } else if (ProbeUint8 == READ_STATUS_CMD) {
      DEBUG ((DEBUG_INFO, "QemuFlashDetected => FD behaves as RAM\n"));
      *Ptr = OriginalUint8;
    } else if (ProbeUint8 == CLEARED_ARRAY_STATUS) {
      *Ptr       = WRITE_BYTE_CMD;
      *Ptr       = OriginalUint8;
      *Ptr       = READ_STATUS_CMD;
      ProbeUint8 = *Ptr;
      *Ptr       = READ_ARRAY_CMD;
      if (ProbeUint8 & 0x10 /* programming error */) {
        DEBUG ((DEBUG_INFO, "QemuFlashDetected => FD behaves as FLASH, write-protected\n"));
      } else {
        DEBUG ((DEBUG_INFO, "QemuFlashDetected => FD behaves as FLASH, writable\n"));
        FlashDetected = TRUE;
      }
    }
  }

  DEBUG ((
    DEBUG_INFO,
    "QemuFlashDetected => %a\n",
    FlashDetected ? "Yes" : "No"
    ));
  return FlashDetected;
}

/**
  Read from QEMU Flash

  @param[in] Lba      The starting logical block index to read from.
  @param[in] Offset   Offset into the block at which to begin reading.
  @param[in] NumBytes On input, indicates the requested read size. On
                      output, indicates the actual number of bytes read
  @param[in] Buffer   Pointer to the buffer to read into.

**/
EFI_STATUS
QemuFlashRead (
  IN        EFI_LBA  Lba,
  IN        UINTN    Offset,
  IN        UINTN    *NumBytes,
  IN        UINT8    *Buffer
  )
{
  UINT8  *Ptr;

  //
  // Only write to the first 64k. We don't bother saving the FTW Spare
  // block into the flash memory.
  //
  if (Lba >= mFdBlockCount) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Get flash address
  //
  Ptr = (UINT8 *)QemuFlashPtr (Lba, Offset);

  CopyMem (Buffer, Ptr, *NumBytes);

  return EFI_SUCCESS;
}

/**
  Write to QEMU Flash

  @param[in] Lba      The starting logical block index to write to.
  @param[in] Offset   Offset into the block at which to begin writing.
  @param[in] NumBytes On input, indicates the requested write size. On
                      output, indicates the actual number of bytes written
  @param[in] Buffer   Pointer to the data to write.

**/
EFI_STATUS
QemuFlashWrite (
  IN        EFI_LBA  Lba,
  IN        UINTN    Offset,
  IN        UINTN    *NumBytes,
  IN        UINT8    *Buffer
  )
{
  volatile UINT8  *Ptr;
  UINTN           Loop;

  //
  // Only write to the first 64k. We don't bother saving the FTW Spare
  // block into the flash memory.
  //
  if (Lba >= mFdBlockCount) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Program flash
  //
  Ptr = QemuFlashPtr (Lba, Offset);
  for (Loop = 0; Loop < *NumBytes; Loop++) {
    QemuFlashPtrWrite (Ptr, WRITE_BYTE_CMD);
    QemuFlashPtrWrite (Ptr, Buffer[Loop]);

    Ptr++;
  }

  //
  // Restore flash to read mode
  //
  if (*NumBytes > 0) {
    QemuFlashPtrWrite (Ptr - 1, READ_ARRAY_CMD);
  }

  return EFI_SUCCESS;
}

/**
  Erase a QEMU Flash block

  @param Lba    The logical block index to erase.

**/
EFI_STATUS
QemuFlashEraseBlock (
  IN   EFI_LBA  Lba
  )
{
  volatile UINT8  *Ptr;

  if (Lba >= mFdBlockCount) {
    return EFI_INVALID_PARAMETER;
  }

  Ptr = QemuFlashPtr (Lba, 0);
  QemuFlashPtrWrite (Ptr, BLOCK_ERASE_CMD);
  QemuFlashPtrWrite (Ptr, BLOCK_ERASE_CONFIRM_CMD);
  return EFI_SUCCESS;
}

/**
  Initializes QEMU flash memory support

  @retval EFI_WRITE_PROTECTED   The QEMU flash device is not present.
  @retval EFI_SUCCESS           The QEMU flash device is supported.

**/
EFI_STATUS
QemuFlashInitialize (
  VOID
  )
{
  mFlashBase   = (UINT8 *)(UINTN)PcdGet32 (PcdOvmfFdBaseAddress);
  mFdBlockSize = PcdGet32 (PcdOvmfFirmwareBlockSize);
  ASSERT (PcdGet32 (PcdOvmfFirmwareFdSize) % mFdBlockSize == 0);
  mFdBlockCount = PcdGet32 (PcdOvmfFirmwareFdSize) / mFdBlockSize;

  //
  // execute module specific hooks before probing the flash
  //
  QemuFlashBeforeProbe (
    (EFI_PHYSICAL_ADDRESS)(UINTN)mFlashBase,
    mFdBlockSize,
    mFdBlockCount
    );

  if (!QemuFlashDetected ()) {
    ASSERT (!FeaturePcdGet (PcdSmmSmramRequire));
    return EFI_WRITE_PROTECTED;
  }

  return EFI_SUCCESS;
}
