/** @file
  FAT recovery PEIM entry point, Ppi Functions and FAT Api functions.

Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>

SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "FatLitePeim.h"

PEI_FAT_PRIVATE_DATA  *mPrivateData = NULL;

/**
  BlockIo installation notification function. Find out all the current BlockIO
  PPIs in the system and add them into private data. Assume there is

  @param  PeiServices             General purpose services available to every
                                  PEIM.
  @param  NotifyDescriptor        The typedef structure of the notification
                                  descriptor. Not used in this function.
  @param  Ppi                     The typedef structure of the PPI descriptor.
                                  Not used in this function.

  @retval EFI_SUCCESS             The function completed successfully.

**/
EFI_STATUS
EFIAPI
BlockIoNotifyEntry (
  IN EFI_PEI_SERVICES           **PeiServices,
  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
  IN VOID                       *Ppi
  );

/**
  Discover all the block I/O devices to find the FAT volume.

  @param  PrivateData             Global memory map for accessing global
                                  variables.
  @param  BlockIo2                Boolean to show whether using BlockIo2 or BlockIo

  @retval EFI_SUCCESS             The function completed successfully.

**/
EFI_STATUS
UpdateBlocksAndVolumes (
  IN OUT PEI_FAT_PRIVATE_DATA  *PrivateData,
  IN     BOOLEAN               BlockIo2
  )
{
  EFI_STATUS                      Status;
  EFI_PEI_PPI_DESCRIPTOR          *TempPpiDescriptor;
  UINTN                           BlockIoPpiInstance;
  EFI_PEI_RECOVERY_BLOCK_IO_PPI   *BlockIoPpi;
  EFI_PEI_RECOVERY_BLOCK_IO2_PPI  *BlockIo2Ppi;
  UINTN                           NumberBlockDevices;
  UINTN                           Index;
  EFI_PEI_BLOCK_IO_MEDIA          Media;
  EFI_PEI_BLOCK_IO2_MEDIA         Media2;
  PEI_FAT_VOLUME                  Volume;
  EFI_PEI_SERVICES                **PeiServices;

  PeiServices = (EFI_PEI_SERVICES **)GetPeiServicesTablePointer ();
  BlockIo2Ppi = NULL;
  BlockIoPpi  = NULL;
  //
  // Clean up caches
  //
  for (Index = 0; Index < PEI_FAT_CACHE_SIZE; Index++) {
    PrivateData->CacheBuffer[Index].Valid = FALSE;
  }

  PrivateData->BlockDeviceCount = 0;

  //
  // Find out all Block Io Ppi instances within the system
  // Assuming all device Block Io Peims are dispatched already
  //
  for (BlockIoPpiInstance = 0; BlockIoPpiInstance < PEI_FAT_MAX_BLOCK_IO_PPI; BlockIoPpiInstance++) {
    if (BlockIo2) {
      Status = PeiServicesLocatePpi (
                 &gEfiPeiVirtualBlockIo2PpiGuid,
                 BlockIoPpiInstance,
                 &TempPpiDescriptor,
                 (VOID **)&BlockIo2Ppi
                 );
    } else {
      Status = PeiServicesLocatePpi (
                 &gEfiPeiVirtualBlockIoPpiGuid,
                 BlockIoPpiInstance,
                 &TempPpiDescriptor,
                 (VOID **)&BlockIoPpi
                 );
    }

    if (EFI_ERROR (Status)) {
      //
      // Done with all Block Io Ppis
      //
      break;
    }

    if (BlockIo2) {
      Status = BlockIo2Ppi->GetNumberOfBlockDevices (
                              PeiServices,
                              BlockIo2Ppi,
                              &NumberBlockDevices
                              );
    } else {
      Status = BlockIoPpi->GetNumberOfBlockDevices (
                             PeiServices,
                             BlockIoPpi,
                             &NumberBlockDevices
                             );
    }

    if (EFI_ERROR (Status)) {
      continue;
    }

    for (Index = 1; Index <= NumberBlockDevices && PrivateData->BlockDeviceCount < PEI_FAT_MAX_BLOCK_DEVICE; Index++) {
      if (BlockIo2) {
        Status = BlockIo2Ppi->GetBlockDeviceMediaInfo (
                                PeiServices,
                                BlockIo2Ppi,
                                Index,
                                &Media2
                                );
        if (EFI_ERROR (Status) || !Media2.MediaPresent) {
          continue;
        }

        PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockIo2      = BlockIo2Ppi;
        PrivateData->BlockDevice[PrivateData->BlockDeviceCount].InterfaceType = Media2.InterfaceType;
        PrivateData->BlockDevice[PrivateData->BlockDeviceCount].LastBlock     = Media2.LastBlock;
        PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockSize     = Media2.BlockSize;
      } else {
        Status = BlockIoPpi->GetBlockDeviceMediaInfo (
                               PeiServices,
                               BlockIoPpi,
                               Index,
                               &Media
                               );
        if (EFI_ERROR (Status) || !Media.MediaPresent) {
          continue;
        }

        PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockIo   = BlockIoPpi;
        PrivateData->BlockDevice[PrivateData->BlockDeviceCount].DevType   = Media.DeviceType;
        PrivateData->BlockDevice[PrivateData->BlockDeviceCount].LastBlock = Media.LastBlock;
        PrivateData->BlockDevice[PrivateData->BlockDeviceCount].BlockSize = (UINT32)Media.BlockSize;
      }

      PrivateData->BlockDevice[PrivateData->BlockDeviceCount].IoAlign = 0;
      //
      // Not used here
      //
      PrivateData->BlockDevice[PrivateData->BlockDeviceCount].Logical          = FALSE;
      PrivateData->BlockDevice[PrivateData->BlockDeviceCount].PartitionChecked = FALSE;

      PrivateData->BlockDevice[PrivateData->BlockDeviceCount].PhysicalDevNo = (UINT8)Index;
      PrivateData->BlockDeviceCount++;
    }
  }

  //
  // Find out all logical devices
  //
  FatFindPartitions (PrivateData);

  //
  // Build up file system volume array
  //
  PrivateData->VolumeCount = 0;
  for (Index = 0; Index < PrivateData->BlockDeviceCount; Index++) {
    Volume.BlockDeviceNo = Index;
    Status               = FatGetBpbInfo (PrivateData, &Volume);
    if (Status == EFI_SUCCESS) {
      //
      // Add the detected volume to the volume array
      //
      CopyMem (
        (UINT8 *)&(PrivateData->Volume[PrivateData->VolumeCount]),
        (UINT8 *)&Volume,
        sizeof (PEI_FAT_VOLUME)
        );
      PrivateData->VolumeCount += 1;
      if (PrivateData->VolumeCount >= PEI_FAT_MAX_VOLUME) {
        break;
      }
    }
  }

  return EFI_SUCCESS;
}

/**
  BlockIo installation notification function. Find out all the current BlockIO
  PPIs in the system and add them into private data. Assume there is

  @param  PeiServices             General purpose services available to every
                                  PEIM.
  @param  NotifyDescriptor        The typedef structure of the notification
                                  descriptor. Not used in this function.
  @param  Ppi                     The typedef structure of the PPI descriptor.
                                  Not used in this function.

  @retval EFI_SUCCESS             The function completed successfully.

**/
EFI_STATUS
EFIAPI
BlockIoNotifyEntry (
  IN EFI_PEI_SERVICES           **PeiServices,
  IN EFI_PEI_NOTIFY_DESCRIPTOR  *NotifyDescriptor,
  IN VOID                       *Ppi
  )
{
  if (CompareGuid (NotifyDescriptor->Guid, &gEfiPeiVirtualBlockIo2PpiGuid)) {
    UpdateBlocksAndVolumes (mPrivateData, TRUE);
  } else {
    UpdateBlocksAndVolumes (mPrivateData, FALSE);
  }

  return EFI_SUCCESS;
}

/**
  Installs the Device Recovery Module PPI, Initialize BlockIo Ppi
  installation notification

  @param  FileHandle              Handle of the file being invoked. Type
                                  EFI_PEI_FILE_HANDLE is defined in
                                  FfsFindNextFile().
  @param  PeiServices             Describes the list of possible PEI Services.

  @retval EFI_SUCCESS             The entry point was executed successfully.
  @retval EFI_OUT_OF_RESOURCES    There is no enough memory to complete the
                                  operations.

**/
EFI_STATUS
EFIAPI
FatPeimEntry (
  IN EFI_PEI_FILE_HANDLE     FileHandle,
  IN CONST EFI_PEI_SERVICES  **PeiServices
  )
{
  EFI_STATUS            Status;
  EFI_PHYSICAL_ADDRESS  Address;
  PEI_FAT_PRIVATE_DATA  *PrivateData;

  Status = PeiServicesRegisterForShadow (FileHandle);
  if (!EFI_ERROR (Status)) {
    return Status;
  }

  Status = PeiServicesAllocatePages (
             EfiBootServicesCode,
             (sizeof (PEI_FAT_PRIVATE_DATA) - 1) / PEI_FAT_MEMORY_PAGE_SIZE + 1,
             &Address
             );
  if (EFI_ERROR (Status)) {
    return EFI_OUT_OF_RESOURCES;
  }

  PrivateData = (PEI_FAT_PRIVATE_DATA *)(UINTN)Address;

  //
  // Initialize Private Data (to zero, as is required by subsequent operations)
  //
  ZeroMem ((UINT8 *)PrivateData, sizeof (PEI_FAT_PRIVATE_DATA));

  PrivateData->Signature = PEI_FAT_PRIVATE_DATA_SIGNATURE;

  //
  // Installs Ppi
  //
  PrivateData->DeviceRecoveryPpi.GetNumberRecoveryCapsules = GetNumberRecoveryCapsules;
  PrivateData->DeviceRecoveryPpi.GetRecoveryCapsuleInfo    = GetRecoveryCapsuleInfo;
  PrivateData->DeviceRecoveryPpi.LoadRecoveryCapsule       = LoadRecoveryCapsule;

  PrivateData->PpiDescriptor.Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
  PrivateData->PpiDescriptor.Guid  = &gEfiPeiDeviceRecoveryModulePpiGuid;
  PrivateData->PpiDescriptor.Ppi   = &PrivateData->DeviceRecoveryPpi;

  Status = PeiServicesInstallPpi (&PrivateData->PpiDescriptor);
  if (EFI_ERROR (Status)) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Other initializations
  //
  PrivateData->BlockDeviceCount = 0;

  UpdateBlocksAndVolumes (PrivateData, TRUE);
  UpdateBlocksAndVolumes (PrivateData, FALSE);

  //
  // PrivateData is allocated now, set it to the module variable
  //
  mPrivateData = PrivateData;

  //
  // Installs Block Io Ppi notification function
  //
  PrivateData->NotifyDescriptor[0].Flags =
    (
     EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
    );
  PrivateData->NotifyDescriptor[0].Guid   = &gEfiPeiVirtualBlockIoPpiGuid;
  PrivateData->NotifyDescriptor[0].Notify = BlockIoNotifyEntry;
  PrivateData->NotifyDescriptor[1].Flags  =
    (
     EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK |
     EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
    );
  PrivateData->NotifyDescriptor[1].Guid   = &gEfiPeiVirtualBlockIo2PpiGuid;
  PrivateData->NotifyDescriptor[1].Notify = BlockIoNotifyEntry;
  return PeiServicesNotifyPpi (&PrivateData->NotifyDescriptor[0]);
}

/**
  Returns the number of DXE capsules residing on the device.

  This function searches for DXE capsules from the associated device and returns
  the number and maximum size in bytes of the capsules discovered. Entry 1 is
  assumed to be the highest load priority and entry N is assumed to be the lowest
  priority.

  @param[in]  PeiServices              General-purpose services that are available
                                       to every PEIM
  @param[in]  This                     Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI
                                       instance.
  @param[out] NumberRecoveryCapsules   Pointer to a caller-allocated UINTN. On
                                       output, *NumberRecoveryCapsules contains
                                       the number of recovery capsule images
                                       available for retrieval from this PEIM
                                       instance.

  @retval EFI_SUCCESS        One or more capsules were discovered.
  @retval EFI_DEVICE_ERROR   A device error occurred.
  @retval EFI_NOT_FOUND      A recovery DXE capsule cannot be found.

**/
EFI_STATUS
EFIAPI
GetNumberRecoveryCapsules (
  IN EFI_PEI_SERVICES                    **PeiServices,
  IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI  *This,
  OUT UINTN                              *NumberRecoveryCapsules
  )
{
  EFI_STATUS            Status;
  PEI_FAT_PRIVATE_DATA  *PrivateData;
  UINTN                 Index;
  UINTN                 RecoveryCapsuleCount;
  PEI_FILE_HANDLE       Handle;

  PrivateData = PEI_FAT_PRIVATE_DATA_FROM_THIS (This);

  //
  // Search each volume in the root directory for the Recovery capsule
  //
  RecoveryCapsuleCount = 0;
  for (Index = 0; Index < PrivateData->VolumeCount; Index++) {
    Status = FindRecoveryFile (PrivateData, Index, (CHAR16 *)PcdGetPtr (PcdRecoveryFileName), &Handle);
    if (EFI_ERROR (Status)) {
      continue;
    }

    RecoveryCapsuleCount++;
  }

  *NumberRecoveryCapsules = RecoveryCapsuleCount;

  if (*NumberRecoveryCapsules == 0) {
    return EFI_NOT_FOUND;
  }

  return EFI_SUCCESS;
}

/**
  Returns the size and type of the requested recovery capsule.

  This function gets the size and type of the capsule specified by CapsuleInstance.

  @param[in]  PeiServices       General-purpose services that are available to every PEIM
  @param[in]  This              Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI
                                instance.
  @param[in]  CapsuleInstance   Specifies for which capsule instance to retrieve
                                the information.  This parameter must be between
                                one and the value returned by GetNumberRecoveryCapsules()
                                in NumberRecoveryCapsules.
  @param[out] Size              A pointer to a caller-allocated UINTN in which
                                the size of the requested recovery module is
                                returned.
  @param[out] CapsuleType       A pointer to a caller-allocated EFI_GUID in which
                                the type of the requested recovery capsule is
                                returned.  The semantic meaning of the value
                                returned is defined by the implementation.

  @retval EFI_SUCCESS        One or more capsules were discovered.
  @retval EFI_DEVICE_ERROR   A device error occurred.
  @retval EFI_NOT_FOUND      A recovery DXE capsule cannot be found.

**/
EFI_STATUS
EFIAPI
GetRecoveryCapsuleInfo (
  IN  EFI_PEI_SERVICES                    **PeiServices,
  IN  EFI_PEI_DEVICE_RECOVERY_MODULE_PPI  *This,
  IN  UINTN                               CapsuleInstance,
  OUT UINTN                               *Size,
  OUT EFI_GUID                            *CapsuleType
  )
{
  EFI_STATUS            Status;
  PEI_FAT_PRIVATE_DATA  *PrivateData;
  UINTN                 Index;
  UINTN                 BlockDeviceNo;
  UINTN                 RecoveryCapsuleCount;
  PEI_FILE_HANDLE       Handle;
  UINTN                 NumberRecoveryCapsules;

  Status = GetNumberRecoveryCapsules (PeiServices, This, &NumberRecoveryCapsules);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  if ((CapsuleInstance == 0) || (CapsuleInstance > NumberRecoveryCapsules)) {
    return EFI_NOT_FOUND;
  }

  PrivateData = PEI_FAT_PRIVATE_DATA_FROM_THIS (This);

  //
  // Search each volume in the root directory for the Recovery capsule
  //
  RecoveryCapsuleCount = 0;
  for (Index = 0; Index < PrivateData->VolumeCount; Index++) {
    Status = FindRecoveryFile (PrivateData, Index, (CHAR16 *)PcdGetPtr (PcdRecoveryFileName), &Handle);

    if (EFI_ERROR (Status)) {
      continue;
    }

    if (CapsuleInstance - 1 == RecoveryCapsuleCount) {
      //
      // Get file size
      //
      *Size = (UINTN)(((PEI_FAT_FILE *)Handle)->FileSize);

      //
      // Find corresponding physical block device
      //
      BlockDeviceNo = PrivateData->Volume[Index].BlockDeviceNo;
      while (BlockDeviceNo < PrivateData->BlockDeviceCount && PrivateData->BlockDevice[BlockDeviceNo].Logical) {
        BlockDeviceNo = PrivateData->BlockDevice[BlockDeviceNo].ParentDevNo;
      }

      //
      // Fill in the Capsule Type GUID according to the block device type
      //
      if (BlockDeviceNo < PrivateData->BlockDeviceCount) {
        if (PrivateData->BlockDevice[BlockDeviceNo].BlockIo2 != NULL) {
          switch (PrivateData->BlockDevice[BlockDeviceNo].InterfaceType) {
            case MSG_ATAPI_DP:
              CopyGuid (CapsuleType, &gRecoveryOnFatIdeDiskGuid);
              break;

            case MSG_USB_DP:
              CopyGuid (CapsuleType, &gRecoveryOnFatUsbDiskGuid);
              break;

            case MSG_NVME_NAMESPACE_DP:
              CopyGuid (CapsuleType, &gRecoveryOnFatNvmeDiskGuid);
              break;

            default:
              break;
          }
        }

        if (PrivateData->BlockDevice[BlockDeviceNo].BlockIo != NULL) {
          switch (PrivateData->BlockDevice[BlockDeviceNo].DevType) {
            case LegacyFloppy:
              CopyGuid (CapsuleType, &gRecoveryOnFatFloppyDiskGuid);
              break;

            case IdeCDROM:
            case IdeLS120:
              CopyGuid (CapsuleType, &gRecoveryOnFatIdeDiskGuid);
              break;

            case UsbMassStorage:
              CopyGuid (CapsuleType, &gRecoveryOnFatUsbDiskGuid);
              break;

            default:
              break;
          }
        }
      }

      return EFI_SUCCESS;
    }

    RecoveryCapsuleCount++;
  }

  return EFI_NOT_FOUND;
}

/**
  Loads a DXE capsule from some media into memory.

  This function, by whatever mechanism, retrieves a DXE capsule from some device
  and loads it into memory. Note that the published interface is device neutral.

  @param[in]     PeiServices       General-purpose services that are available
                                   to every PEIM
  @param[in]     This              Indicates the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI
                                   instance.
  @param[in]     CapsuleInstance   Specifies which capsule instance to retrieve.
  @param[out]    Buffer            Specifies a caller-allocated buffer in which
                                   the requested recovery capsule will be returned.

  @retval EFI_SUCCESS        The capsule was loaded correctly.
  @retval EFI_DEVICE_ERROR   A device error occurred.
  @retval EFI_NOT_FOUND      A requested recovery DXE capsule cannot be found.

**/
EFI_STATUS
EFIAPI
LoadRecoveryCapsule (
  IN EFI_PEI_SERVICES                    **PeiServices,
  IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI  *This,
  IN UINTN                               CapsuleInstance,
  OUT VOID                               *Buffer
  )
{
  EFI_STATUS            Status;
  PEI_FAT_PRIVATE_DATA  *PrivateData;
  UINTN                 Index;
  UINTN                 RecoveryCapsuleCount;
  PEI_FILE_HANDLE       Handle;
  UINTN                 NumberRecoveryCapsules;

  Status = GetNumberRecoveryCapsules (PeiServices, This, &NumberRecoveryCapsules);

  if (EFI_ERROR (Status)) {
    return Status;
  }

  if ((CapsuleInstance == 0) || (CapsuleInstance > NumberRecoveryCapsules)) {
    return EFI_NOT_FOUND;
  }

  PrivateData = PEI_FAT_PRIVATE_DATA_FROM_THIS (This);

  //
  // Search each volume in the root directory for the Recovery capsule
  //
  RecoveryCapsuleCount = 0;
  for (Index = 0; Index < PrivateData->VolumeCount; Index++) {
    Status = FindRecoveryFile (PrivateData, Index, (CHAR16 *)PcdGetPtr (PcdRecoveryFileName), &Handle);
    if (EFI_ERROR (Status)) {
      continue;
    }

    if (CapsuleInstance - 1 == RecoveryCapsuleCount) {
      Status = FatReadFile (
                 PrivateData,
                 Handle,
                 (UINTN)(((PEI_FAT_FILE *)Handle)->FileSize),
                 Buffer
                 );
      return Status;
    }

    RecoveryCapsuleCount++;
  }

  return EFI_NOT_FOUND;
}

/**
  Finds the recovery file on a FAT volume.
  This function finds the recovery file named FileName on a specified FAT volume and returns
  its FileHandle pointer.

  @param  PrivateData             Global memory map for accessing global
                                  variables.
  @param  VolumeIndex             The index of the volume.
  @param  FileName                The recovery file name to find.
  @param  Handle                  The output file handle.

  @retval EFI_DEVICE_ERROR        Some error occurred when operating the FAT
                                  volume.
  @retval EFI_NOT_FOUND           The recovery file was not found.
  @retval EFI_SUCCESS             The recovery file was successfully found on the
                                  FAT volume.

**/
EFI_STATUS
FindRecoveryFile (
  IN  PEI_FAT_PRIVATE_DATA  *PrivateData,
  IN  UINTN                 VolumeIndex,
  IN  CHAR16                *FileName,
  OUT PEI_FILE_HANDLE       *Handle
  )
{
  EFI_STATUS    Status;
  PEI_FAT_FILE  Parent;
  PEI_FAT_FILE  *File;

  File = &PrivateData->File;

  //
  // VolumeIndex must be less than PEI_FAT_MAX_VOLUME because PrivateData->VolumeCount
  // cannot be larger than PEI_FAT_MAX_VOLUME when detecting recovery volume.
  //
  ASSERT (VolumeIndex < PEI_FAT_MAX_VOLUME);

  //
  // Construct root directory file
  //
  ZeroMem (&Parent, sizeof (PEI_FAT_FILE));
  Parent.IsFixedRootDir  = (BOOLEAN)((PrivateData->Volume[VolumeIndex].FatType == Fat32) ? FALSE : TRUE);
  Parent.Attributes      = FAT_ATTR_DIRECTORY;
  Parent.CurrentPos      = 0;
  Parent.CurrentCluster  = Parent.IsFixedRootDir ? 0 : PrivateData->Volume[VolumeIndex].RootDirCluster;
  Parent.StartingCluster = Parent.CurrentCluster;
  Parent.Volume          = &PrivateData->Volume[VolumeIndex];

  Status = FatSetFilePos (PrivateData, &Parent, 0);
  if (EFI_ERROR (Status)) {
    return EFI_DEVICE_ERROR;
  }

  //
  // Search for recovery capsule in root directory
  //
  Status = FatReadNextDirectoryEntry (PrivateData, &Parent, File);
  while (Status == EFI_SUCCESS) {
    //
    // Compare whether the file name is recovery file name.
    //
    if (EngStriColl (PrivateData, FileName, File->FileName)) {
      break;
    }

    Status = FatReadNextDirectoryEntry (PrivateData, &Parent, File);
  }

  if (EFI_ERROR (Status)) {
    return EFI_NOT_FOUND;
  }

  //
  // Get the recovery file, set its file position to 0.
  //
  if (File->StartingCluster != 0) {
    Status = FatSetFilePos (PrivateData, File, 0);
  }

  *Handle = File;

  return EFI_SUCCESS;
}
