From af1a266670d040d2f4083ff309d732d648afba2a Mon Sep 17 00:00:00 2001
From: Angelos Mouzakitis <a.mouzakitis@virtualopensystems.com>
Date: Tue, 10 Oct 2023 14:33:42 +0000
Subject: Add submodule dependency files

Change-Id: Iaf8d18082d3991dec7c0ebbea540f092188eb4ec
---
 roms/edk2/FatPkg/FatPei/FatLiteLib.c | 370 +++++++++++++++++++++++++++++++++++
 1 file changed, 370 insertions(+)
 create mode 100644 roms/edk2/FatPkg/FatPei/FatLiteLib.c

(limited to 'roms/edk2/FatPkg/FatPei/FatLiteLib.c')

diff --git a/roms/edk2/FatPkg/FatPei/FatLiteLib.c b/roms/edk2/FatPkg/FatPei/FatLiteLib.c
new file mode 100644
index 000000000..3d43e0b87
--- /dev/null
+++ b/roms/edk2/FatPkg/FatPei/FatLiteLib.c
@@ -0,0 +1,370 @@
+/** @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);
+}
-- 
cgit