/** @file
  UfsPciHcPei driver is used to provide platform-dependent info, mainly UFS host controller
  MMIO base, to upper layer UFS drivers.

  Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "UfsPciHcPei.h"

EDKII_UFS_HOST_CONTROLLER_PPI  mUfsHostControllerPpi = { GetUfsHcMmioBar };

EFI_PEI_PPI_DESCRIPTOR  mPpiList = {
  (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
  &gEdkiiPeiUfsHostControllerPpiGuid,
  &mUfsHostControllerPpi
};

/**
  Get the MMIO base address of UFS host controller.

  @param[in]  This               The protocol instance pointer.
  @param[in]  ControllerId       The ID of the UFS host controller.
  @param[out] MmioBar            Pointer to the UFS host controller MMIO base address.

  @retval EFI_SUCCESS            The operation succeeds.
  @retval EFI_INVALID_PARAMETER  The parameters are invalid.

**/
EFI_STATUS
EFIAPI
GetUfsHcMmioBar (
  IN     EDKII_UFS_HOST_CONTROLLER_PPI  *This,
  IN     UINT8                          ControllerId,
  OUT UINTN                             *MmioBar
  )
{
  UFS_HC_PEI_PRIVATE_DATA  *Private;

  if ((This == NULL) || (MmioBar == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Private = UFS_HC_PEI_PRIVATE_DATA_FROM_THIS (This);

  if (ControllerId >= Private->TotalUfsHcs) {
    return EFI_INVALID_PARAMETER;
  }

  *MmioBar = (UINTN)Private->UfsHcPciAddr[ControllerId];

  return EFI_SUCCESS;
}

/**
  The user code starts with this function.

  @param  FileHandle             Handle of the file being invoked.
  @param  PeiServices            Describes the list of possible PEI Services.

  @retval EFI_SUCCESS            The driver is successfully initialized.
  @retval Others                 Can't initialize the driver.

**/
EFI_STATUS
EFIAPI
InitializeUfsHcPeim (
  IN EFI_PEI_FILE_HANDLE     FileHandle,
  IN CONST EFI_PEI_SERVICES  **PeiServices
  )
{
  EFI_BOOT_MODE            BootMode;
  EFI_STATUS               Status;
  UINT16                   Bus;
  UINT16                   Device;
  UINT16                   Function;
  UINT32                   Size;
  UINT64                   MmioSize;
  UINT32                   BarAddr;
  UINT8                    SubClass;
  UINT8                    BaseClass;
  UFS_HC_PEI_PRIVATE_DATA  *Private;

  //
  // Shadow this PEIM to run from memory
  //
  if (!EFI_ERROR (PeiServicesRegisterForShadow (FileHandle))) {
    return EFI_SUCCESS;
  }

  Status = PeiServicesGetBootMode (&BootMode);
  ///
  /// We do not export this in S3 boot path, because it is only for recovery.
  ///
  if (BootMode == BOOT_ON_S3_RESUME) {
    return EFI_SUCCESS;
  }

  Private = (UFS_HC_PEI_PRIVATE_DATA *)AllocateZeroPool (sizeof (UFS_HC_PEI_PRIVATE_DATA));
  if (Private == NULL) {
    DEBUG ((DEBUG_ERROR, "Failed to allocate memory for UFS_HC_PEI_PRIVATE_DATA! \n"));
    return EFI_OUT_OF_RESOURCES;
  }

  Private->Signature            = UFS_HC_PEI_SIGNATURE;
  Private->UfsHostControllerPpi = mUfsHostControllerPpi;
  Private->PpiList              = mPpiList;
  Private->PpiList.Ppi          = &Private->UfsHostControllerPpi;

  BarAddr = PcdGet32 (PcdUfsPciHostControllerMmioBase);
  for (Bus = 0; Bus < 256; Bus++) {
    for (Device = 0; Device < 32; Device++) {
      for (Function = 0; Function < 8; Function++) {
        SubClass  = PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x0A));
        BaseClass = PciRead8 (PCI_LIB_ADDRESS (Bus, Device, Function, 0x0B));

        if ((SubClass == 0x09) && (BaseClass == PCI_CLASS_MASS_STORAGE)) {
          //
          // Get the Ufs Pci host controller's MMIO region size.
          //
          PciAnd16 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_COMMAND_OFFSET), (UINT16) ~(EFI_PCI_COMMAND_BUS_MASTER | EFI_PCI_COMMAND_MEMORY_SPACE));
          PciWrite32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET), 0xFFFFFFFF);
          Size = PciRead32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET));

          switch (Size & 0x07) {
            case 0x0:
              //
              // Memory space: anywhere in 32 bit address space
              //
              MmioSize = (~(Size & 0xFFFFFFF0)) + 1;
              break;
            case 0x4:
              //
              // Memory space: anywhere in 64 bit address space
              //
              MmioSize = Size & 0xFFFFFFF0;
              PciWrite32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 4), 0xFFFFFFFF);
              Size = PciRead32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 4));

              //
              // Fix the length to support some specific 64 bit BAR
              //
              Size |= ((UINT32)(-1) << HighBitSet32 (Size));

              //
              // Calculate the size of 64bit bar
              //
              MmioSize |= LShiftU64 ((UINT64)Size, 32);
              MmioSize  = (~(MmioSize)) + 1;

              //
              // Clean the high 32bits of this 64bit BAR to 0 as we only allow a 32bit BAR.
              //
              PciWrite32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET + 4), 0);
              break;
            default:
              //
              // Unknown BAR type
              //
              ASSERT (FALSE);
              continue;
          }

          //
          // Assign resource to the Ufs Pci host controller's MMIO BAR.
          // Enable the Ufs Pci host controller by setting BME and MSE bits of PCI_CMD register.
          //
          PciWrite32 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_BASE_ADDRESSREG_OFFSET), BarAddr);
          PciOr16 (PCI_LIB_ADDRESS (Bus, Device, Function, PCI_COMMAND_OFFSET), (EFI_PCI_COMMAND_BUS_MASTER | EFI_PCI_COMMAND_MEMORY_SPACE));
          //
          // Record the allocated Mmio base address.
          //
          Private->UfsHcPciAddr[Private->TotalUfsHcs] = BarAddr;
          Private->TotalUfsHcs++;
          BarAddr += (UINT32)MmioSize;
          ASSERT (Private->TotalUfsHcs < MAX_UFS_HCS);
        }
      }
    }
  }

  ///
  /// Install Ufs Host Controller PPI
  ///
  Status = PeiServicesInstallPpi (&Private->PpiList);

  ASSERT_EFI_ERROR (Status);
  return Status;
}
