/** @file
  General purpose supporting routines for FAT recovery PEIM

Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>

SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "FatLitePeim.h"


#define CHAR_FAT_VALID  0x01


/**
  Converts a union code character to upper case.
  This functions converts a unicode character to upper case.
  If the input Letter is not a lower-cased letter,
  the original value is returned.

  @param  Letter            The input unicode character.

  @return The upper cased letter.

**/
CHAR16
ToUpper (
  IN CHAR16                    Letter
  )
{
  if ('a' <= Letter && Letter <= 'z') {
    Letter = (CHAR16) (Letter - 0x20);
  }

  return Letter;
}


/**
  Reads a block of data from the block device by calling
  underlying Block I/O service.

  @param  PrivateData       Global memory map for accessing global variables
  @param  BlockDeviceNo     The index for the block device number.
  @param  Lba               The logic block address to read data from.
  @param  BufferSize        The size of data in byte to read.
  @param  Buffer            The buffer of the

  @retval EFI_DEVICE_ERROR  The specified block device number exceeds the maximum
                            device number.
  @retval EFI_DEVICE_ERROR  The maximum address has exceeded the maximum address
                            of the block device.

**/
EFI_STATUS
FatReadBlock (
  IN  PEI_FAT_PRIVATE_DATA   *PrivateData,
  IN  UINTN                  BlockDeviceNo,
  IN  EFI_PEI_LBA            Lba,
  IN  UINTN                  BufferSize,
  OUT VOID                   *Buffer
  )
{
  EFI_STATUS            Status;
  PEI_FAT_BLOCK_DEVICE  *BlockDev;

  if (BlockDeviceNo > PEI_FAT_MAX_BLOCK_DEVICE - 1) {
    return EFI_DEVICE_ERROR;
  }

  Status    = EFI_SUCCESS;
  BlockDev  = &(PrivateData->BlockDevice[BlockDeviceNo]);

  if (BufferSize > MultU64x32 (BlockDev->LastBlock - Lba + 1, BlockDev->BlockSize)) {
    return EFI_DEVICE_ERROR;
  }

  if (!BlockDev->Logical) {
    //
    // Status = BlockDev->ReadFunc
    //  (PrivateData->PeiServices, BlockDev->PhysicalDevNo, Lba, BufferSize, Buffer);
    //
    if (BlockDev->BlockIo2 != NULL) {
      Status = BlockDev->BlockIo2->ReadBlocks (
                                    (EFI_PEI_SERVICES **) GetPeiServicesTablePointer (),
                                    BlockDev->BlockIo2,
                                    BlockDev->PhysicalDevNo,
                                    Lba,
                                    BufferSize,
                                    Buffer
                                    );
    } else {
      Status = BlockDev->BlockIo->ReadBlocks (
                                  (EFI_PEI_SERVICES **) GetPeiServicesTablePointer (),
                                  BlockDev->BlockIo,
                                  BlockDev->PhysicalDevNo,
                                  Lba,
                                  BufferSize,
                                  Buffer
                                  );
    }

  } else {
    Status = FatReadDisk (
              PrivateData,
              BlockDev->ParentDevNo,
              BlockDev->StartingPos + MultU64x32 (Lba, BlockDev->BlockSize),
              BufferSize,
              Buffer
              );
  }

  return Status;
}


/**
  Find a cache block designated to specific Block device and Lba.
  If not found, invalidate an oldest one and use it. (LRU cache)

  @param  PrivateData       the global memory map.
  @param  BlockDeviceNo     the Block device.
  @param  Lba               the Logical Block Address
  @param  CachePtr          Ptr to the starting address of the memory holding the
                            data;

  @retval EFI_SUCCESS       The function completed successfully.
  @retval EFI_DEVICE_ERROR  Something error while accessing media.

**/
EFI_STATUS
FatGetCacheBlock (
  IN  PEI_FAT_PRIVATE_DATA  *PrivateData,
  IN  UINTN                 BlockDeviceNo,
  IN  UINT64                Lba,
  OUT CHAR8                 **CachePtr
  )
{
  EFI_STATUS            Status;
  PEI_FAT_CACHE_BUFFER  *CacheBuffer;
  INTN                  Index;
  STATIC UINT8          Seed;

  Status      = EFI_SUCCESS;
  CacheBuffer = NULL;

  //
  // go through existing cache buffers
  //
  for (Index = 0; Index < PEI_FAT_CACHE_SIZE; Index++) {
    CacheBuffer = &(PrivateData->CacheBuffer[Index]);
    if (CacheBuffer->Valid && CacheBuffer->BlockDeviceNo == BlockDeviceNo && CacheBuffer->Lba == Lba) {
      break;
    }
  }

  if (Index < PEI_FAT_CACHE_SIZE) {
    *CachePtr = (CHAR8 *) CacheBuffer->Buffer;
    return EFI_SUCCESS;
  }
  //
  // We have to find an invalid cache buffer
  //
  for (Index = 0; Index < PEI_FAT_CACHE_SIZE; Index++) {
    if (!PrivateData->CacheBuffer[Index].Valid) {
      break;
    }
  }
  //
  // Use the cache buffer
  //
  if (Index == PEI_FAT_CACHE_SIZE) {
    Index = (Seed++) % PEI_FAT_CACHE_SIZE;
  }

  //
  // Current device ID should be less than maximum device ID.
  //
  if (BlockDeviceNo >= PEI_FAT_MAX_BLOCK_DEVICE) {
    return EFI_DEVICE_ERROR;
  }

  CacheBuffer                 = &(PrivateData->CacheBuffer[Index]);

  CacheBuffer->BlockDeviceNo  = BlockDeviceNo;
  CacheBuffer->Lba            = Lba;
  CacheBuffer->Size           = PrivateData->BlockDevice[BlockDeviceNo].BlockSize;

  //
  // Read in the data
  //
  Status = FatReadBlock (
            PrivateData,
            BlockDeviceNo,
            Lba,
            CacheBuffer->Size,
            CacheBuffer->Buffer
            );
  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  CacheBuffer->Valid  = TRUE;
  *CachePtr           = (CHAR8 *) CacheBuffer->Buffer;

  return Status;
}


/**
  Disk reading.

  @param  PrivateData       the global memory map;
  @param  BlockDeviceNo     the block device to read;
  @param  StartingAddress   the starting address.
  @param  Size              the amount of data to read.
  @param  Buffer            the buffer holding the data

  @retval EFI_SUCCESS       The function completed successfully.
  @retval EFI_DEVICE_ERROR  Something error.

**/
EFI_STATUS
FatReadDisk (
  IN  PEI_FAT_PRIVATE_DATA  *PrivateData,
  IN  UINTN                 BlockDeviceNo,
  IN  UINT64                StartingAddress,
  IN  UINTN                 Size,
  OUT VOID                  *Buffer
  )
{
  EFI_STATUS  Status;
  UINT32      BlockSize;
  CHAR8       *BufferPtr;
  CHAR8       *CachePtr;
  UINT32      Offset;
  UINT64      Lba;
  UINT64      OverRunLba;
  UINTN       Amount;

  Status    = EFI_SUCCESS;
  BufferPtr = Buffer;
  BlockSize = PrivateData->BlockDevice[BlockDeviceNo].BlockSize;

  //
  // Read underrun
  //
  Lba     = DivU64x32Remainder (StartingAddress, BlockSize, &Offset);
  Status  = FatGetCacheBlock (PrivateData, BlockDeviceNo, Lba, &CachePtr);
  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  Amount = Size < (BlockSize - Offset) ? Size : (BlockSize - Offset);
  CopyMem (BufferPtr, CachePtr + Offset, Amount);

  if (Size == Amount) {
    return EFI_SUCCESS;
  }

  Size -= Amount;
  BufferPtr += Amount;
  StartingAddress += Amount;
  Lba += 1;

  //
  // Read aligned parts
  //
  OverRunLba = Lba + DivU64x32Remainder (Size, BlockSize, &Offset);

  Size -= Offset;
  Status = FatReadBlock (PrivateData, BlockDeviceNo, Lba, Size, BufferPtr);
  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  BufferPtr += Size;

  //
  // Read overrun
  //
  if (Offset != 0) {
    Status = FatGetCacheBlock (PrivateData, BlockDeviceNo, OverRunLba, &CachePtr);
    if (EFI_ERROR (Status)) {
      return EFI_DEVICE_ERROR;
    }

    CopyMem (BufferPtr, CachePtr, Offset);
  }

  return Status;
}


/**
  This version is different from the version in Unicode collation
  protocol in that this version strips off trailing blanks.
  Converts an 8.3 FAT file name using an OEM character set
  to a Null-terminated Unicode string.
  Here does not expand DBCS FAT chars.

  @param  FatSize           The size of the string Fat in bytes.
  @param  Fat               A pointer to a Null-terminated string that contains
                            an 8.3 file name using an OEM character set.
  @param  Str               A pointer to a Null-terminated Unicode string. The
                            string must be allocated in advance to hold FatSize
                            Unicode characters

**/
VOID
EngFatToStr (
  IN UINTN                            FatSize,
  IN CHAR8                            *Fat,
  OUT CHAR16                          *Str
  )
{
  CHAR16  *String;

  String = Str;
  //
  // No DBCS issues, just expand and add null terminate to end of string
  //
  while (*Fat != 0 && FatSize != 0) {
    if (*Fat == ' ') {
      break;
    }
    *String = *Fat;
    String += 1;
    Fat += 1;
    FatSize -= 1;
  }

  *String = 0;
}


/**
  Performs a case-insensitive comparison of two Null-terminated Unicode strings.

  @param  PrivateData       Global memory map for accessing global variables
  @param  Str1              First string to perform case insensitive comparison.
  @param  Str2              Second string to perform case insensitive comparison.

**/
BOOLEAN
EngStriColl (
  IN  PEI_FAT_PRIVATE_DATA  *PrivateData,
  IN CHAR16                 *Str1,
  IN CHAR16                 *Str2
  )
{
  CHAR16  UpperS1;
  CHAR16  UpperS2;

  UpperS1 = ToUpper (*Str1);
  UpperS2 = ToUpper (*Str2);
  while (*Str1 != 0) {
    if (UpperS1 != UpperS2) {
      return FALSE;
    }

    Str1++;
    Str2++;
    UpperS1 = ToUpper (*Str1);
    UpperS2 = ToUpper (*Str2);
  }

  return (BOOLEAN) ((*Str2 != 0) ? FALSE : TRUE);
}
