/** @file
  Flash Device Library based on SPI Flash library.

Copyright (c) 2018 - 2021, Intel Corporation. All rights reserved. <BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <PiDxe.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/SpiFlashLib.h>

/**
  Initialize spi flash device.

  @retval EFI_SUCCESS              The tested spi flash device is supported.
  @retval EFI_UNSUPPORTED          The tested spi flash device is not supported.

**/
EFI_STATUS
EFIAPI
LibFvbFlashDeviceInit (
  VOID
  )
{
  return SpiConstructor ();
}

/**
  Read NumBytes bytes of data from the address specified by
  PAddress into Buffer.

  @param[in]      PAddress      The starting physical address of the read.
  @param[in,out]  NumBytes      On input, the number of bytes to read. On output, the number
                                of bytes actually read.
  @param[out]     Buffer        The destination data buffer for the read.

  @retval         EFI_SUCCESS.      Opertion is successful.
  @retval         EFI_DEVICE_ERROR  If there is any device errors.

**/
EFI_STATUS
EFIAPI
LibFvbFlashDeviceRead (
  IN      UINTN  PAddress,
  IN  OUT UINTN  *NumBytes,
  OUT UINT8      *Buffer
  )
{
  EFI_STATUS  Status;
  UINT32      ByteCount;
  UINT32      RgnSize;
  UINT32      AddrOffset;

  Status = SpiGetRegionAddress (FlashRegionBios, NULL, &RgnSize);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  // BIOS region offset can be calculated by (PAddress - (0x100000000 - RgnSize))
  // which equal (PAddress + RgnSize) here.
  AddrOffset = (UINT32)((UINT32)PAddress + RgnSize);
  ByteCount  = (UINT32)*NumBytes;
  return SpiFlashRead (FlashRegionBios, AddrOffset, ByteCount, Buffer);
}

/**
  Write NumBytes bytes of data from Buffer to the address specified by
  PAddresss.

  @param[in]      PAddress        The starting physical address of the write.
  @param[in,out]  NumBytes        On input, the number of bytes to write. On output,
                                  the actual number of bytes written.
  @param[in]      Buffer          The source data buffer for the write.

  @retval         EFI_SUCCESS.      Opertion is successful.
  @retval         EFI_DEVICE_ERROR  If there is any device errors.

**/
EFI_STATUS
EFIAPI
LibFvbFlashDeviceWrite (
  IN        UINTN  PAddress,
  IN OUT    UINTN  *NumBytes,
  IN        UINT8  *Buffer
  )
{
  EFI_STATUS  Status;
  UINT32      ByteCount;
  UINT32      RgnSize;
  UINT32      AddrOffset;

  Status = SpiGetRegionAddress (FlashRegionBios, NULL, &RgnSize);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  // BIOS region offset can be calculated by (PAddress - (0x100000000 - RgnSize))
  // which equal (PAddress + RgnSize) here.
  AddrOffset = (UINT32)((UINT32)PAddress + RgnSize);
  ByteCount  = (UINT32)*NumBytes;
  return SpiFlashWrite (FlashRegionBios, AddrOffset, ByteCount, Buffer);
}

/**
  Erase the block starting at PAddress.

  @param[in]  PAddress        The starting physical address of the block to be erased.
                              This library assume that caller garantee that the PAddress
                              is at the starting address of this block.
  @param[in]  LbaLength       The length of the logical block to be erased.

  @retval     EFI_SUCCESS.      Opertion is successful.
  @retval     EFI_DEVICE_ERROR  If there is any device errors.

**/
EFI_STATUS
EFIAPI
LibFvbFlashDeviceBlockErase (
  IN    UINTN  PAddress,
  IN    UINTN  LbaLength
  )
{
  EFI_STATUS  Status;
  UINT32      RgnSize;
  UINT32      AddrOffset;

  Status = SpiGetRegionAddress (FlashRegionBios, NULL, &RgnSize);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  // BIOS region offset can be calculated by (PAddress - (0x100000000 - RgnSize))
  // which equal (PAddress + RgnSize) here.
  AddrOffset = (UINT32)((UINT32)PAddress + RgnSize);
  return SpiFlashErase (FlashRegionBios, AddrOffset, (UINT32)LbaLength);
}

/**
  Lock or unlock the block starting at PAddress.

  @param[in]  PAddress        The starting physical address of region to be (un)locked.
  @param[in]  LbaLength       The length of the logical block to be erased.
  @param[in]  Lock            TRUE to lock. FALSE to unlock.

  @retval     EFI_SUCCESS.      Opertion is successful.
  @retval     EFI_DEVICE_ERROR  If there is any device errors.

**/
EFI_STATUS
EFIAPI
LibFvbFlashDeviceBlockLock (
  IN    UINTN    PAddress,
  IN    UINTN    LbaLength,
  IN    BOOLEAN  Lock
  )
{
  return EFI_SUCCESS;
}
