/** @file
  General purpose supporting routines for FAT recovery PEIM

Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>

This program and the accompanying materials are licensed and made available
under the terms and conditions of the BSD License which accompanies this
distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#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);
}
