/** @file
  Root Complex parser.

  Copyright (c) 2025, ARM Limited. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

  @par Reference(s):
  - linux/Documentation/devicetree/bindings/pci/host-generic-pci.yaml
**/

#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/FdtLib.h>
#include <IndustryStandard/IoRemappingTable.h>
#include "FdtHwInfoParser.h"
#include "CmObjectDescUtility.h"
#include "Arm/Iort/ArmIortParser.h"
#include "Arm/Iort/RootComplexParser.h"

#define IOMMU_MAP_CELL_COUNT  4

/** List of "compatible" property values for PciRootComplex nodes.

  Other "compatible" values are not supported by this module.
*/
STATIC CONST COMPATIBILITY_STR  RootComplexCompatibleStr[] = {
  { "pci-host-ecam-generic" }
};

/** PciRootComplex compatiblity information.
*/
STATIC CONST COMPATIBILITY_INFO  RootComplexCompatibleInfo = {
  ARRAY_SIZE (RootComplexCompatibleStr),
  RootComplexCompatibleStr
};

/** Determine the memory address size for the given root complex

  Determine the memory address size based on the dma-ranges property. If this
  property is not present then default to 32 bits.

  @param [in]  Fdt                Pointer to FDT
  @param [in]  RootComplexNode    Offset of root complex node
  @param [out] MemoryAddressSize  Location to store memory address size

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
STATIC
EFI_STATUS
RootComplexNodeGetMemoryAddressSize (
  IN  CONST VOID   *Fdt,
  IN  CONST INT32  RootComplexNode,
  OUT       UINT8  *MemoryAddressSize
  )
{
  CONST UINT32  *DmaRanges;
  INT32         ParentNode;
  INT32         DataSize;
  INT32         AddressCells;
  INT32         SizeCells;
  INT32         ParentAddressCells;
  INT32         Stride;
  INTN          DataOffset;
  INTN          SizeOffset;
  UINT64        DmaAddressEnd;
  UINT64        DmaAddress;
  UINT64        Size;

  DmaRanges = FdtGetProp (Fdt, RootComplexNode, "dma-ranges", &DataSize);
  if ((DmaRanges == NULL) || (DataSize <= 0)) {
    *MemoryAddressSize = 32;
    return 0;
  }

  AddressCells = FdtAddressCells (Fdt, RootComplexNode);
  if (AddressCells < 0) {
    ASSERT (AddressCells >= 0);
    return EFI_INVALID_PARAMETER;
  }

  SizeCells = FdtSizeCells (Fdt, RootComplexNode);
  if (SizeCells < 0) {
    ASSERT (SizeCells >= 0);
    return EFI_INVALID_PARAMETER;
  }

  // Find parent node with #address-cells
  ParentNode = FdtParentOffset (Fdt, RootComplexNode);
  if (ParentNode < 0) {
    ASSERT (ParentNode >= 0);
    return EFI_INVALID_PARAMETER;
  }

  ParentAddressCells = -1;

  do {
    ParentAddressCells = FdtAddressCells (Fdt, ParentNode);
    if (ParentAddressCells < 0) {
      ParentNode = FdtParentOffset (Fdt, ParentNode);
      if (ParentNode < 0) {
        ASSERT (ParentNode >= 0);
        return EFI_INVALID_PARAMETER;
      }
    }
  } while (ParentAddressCells < 0);

  Stride     = AddressCells + ParentAddressCells + SizeCells;
  SizeOffset = AddressCells + ParentAddressCells;
  if ((DataSize < Stride) || ((DataSize % Stride) != 0)) {
    ASSERT (DataSize >= Stride && (DataSize % Stride) == 0);
    return EFI_INVALID_PARAMETER;
  }

  DataOffset    = 0;
  DmaAddressEnd = 0;

  // Walk dma-ranges and find maximum DMA address
  while ((DataOffset + Stride) <= DataSize) {
    switch (AddressCells) {
      case 1:
        DmaAddress = Fdt32ToCpu (DmaRanges[DataOffset]);
        break;
      case 2:
        DmaAddress = Fdt64ToCpu (*(UINT64 *)&DmaRanges[DataOffset]);
        break;
      case 3:
        DmaAddress = Fdt64ToCpu (*(UINT64 *)&DmaRanges[DataOffset + 1]);
        break;
      default:
        ASSERT (0);
        return EFI_INVALID_PARAMETER;
    }

    switch (SizeCells) {
      case 1:
        Size = Fdt32ToCpu (DmaRanges[DataOffset + SizeOffset]);
        break;
      case 2:
        Size = Fdt64ToCpu (*(UINT64 *)&DmaRanges[DataOffset + SizeOffset]);
        break;
      default:
        ASSERT (0);
        return EFI_INVALID_PARAMETER;
    }

    if (DmaAddressEnd < (DmaAddress + Size)) {
      DmaAddressEnd = DmaAddress + Size;
    }

    DataOffset += Stride;
  }

  // Round up if required
  if (DmaAddressEnd & (DmaAddressEnd - 1)) {
    *MemoryAddressSize = HighBitSet64 (DmaAddressEnd) + 2;
  } else {
    *MemoryAddressSize = HighBitSet64 (DmaAddressEnd) + 1;
  }

  return EFI_SUCCESS;
}

/** Parse a PCI root complex node.

  @param [in]  FdtParserHandle    A handle to the parser instance.
  @param [in]  Fdt                Pointer to a Flattened Device Tree (Fdt).
  @param [in]  RootComplexNode    Offset of a root complex node.
  @param [in]  RootComplexInfo    The CM_ARM_ROOT_COMPLEX_NODE to populate.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_ABORTED             An error occurred.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
**/
STATIC
EFI_STATUS
EFIAPI
RootComplexNodeParser (
  IN  CONST FDT_HW_INFO_PARSER_HANDLE  FdtParserHandle,
  IN  CONST VOID                       *Fdt,
  IN        INT32                      RootComplexNode,
  IN        CM_ARM_ROOT_COMPLEX_NODE   *RootComplexInfo
  )
{
  EFI_STATUS         Status;
  CONST UINT32       *Data;
  INT32              DataSize;
  CM_ARM_ID_MAPPING  *IdMappings;
  INT32              MapIndex;

  if ((Fdt == NULL) || (RootComplexInfo == NULL)) {
    ASSERT ((Fdt != NULL) && (RootComplexInfo != NULL));
    return EFI_INVALID_PARAMETER;
  }

  /// Memory access properties : Cache coherent attributes
  /// Memory access properties : Memory access flags
  Data = FdtGetProp (Fdt, RootComplexNode, "dma-coherent", &DataSize);
  if ((Data != NULL) && (DataSize >= 0)) {
    RootComplexInfo->CacheCoherent     = EFI_ACPI_IORT_MEM_ACCESS_PROP_CCA;
    RootComplexInfo->MemoryAccessFlags = EFI_ACPI_IORT_MEM_ACCESS_FLAGS_CPM |
                                         EFI_ACPI_IORT_MEM_ACCESS_FLAGS_DACS;
  } else {
    RootComplexInfo->CacheCoherent     = 0;
    RootComplexInfo->MemoryAccessFlags = 0;
  }

  /// Memory access properties : Allocation hints
  RootComplexInfo->AllocationHints = 0;

  /// ATS attributes
  Data = FdtGetProp (Fdt, RootComplexNode, "ats-supported", &DataSize);
  if ((Data != NULL) && (DataSize >= 0)) {
    RootComplexInfo->AtsAttribute = EFI_ACPI_IORT_ROOT_COMPLEX_ATS_SUPPORTED;
  } else {
    RootComplexInfo->AtsAttribute = EFI_ACPI_IORT_ROOT_COMPLEX_ATS_UNSUPPORTED;
  }

  /// PCI segment number
  Data = FdtGetProp (Fdt, RootComplexNode, "linux,pci-domain", &DataSize);
  if (Data != NULL) {
    RootComplexInfo->PciSegmentNumber = *Data;
  }

  /// Memory address size limit
  Status = RootComplexNodeGetMemoryAddressSize (Fdt, RootComplexNode, &RootComplexInfo->MemoryAddressSize);
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    return Status;
  }

  /// PASID capabilities
  RootComplexInfo->PasidCapabilities = 0;

  /// Flags
  RootComplexInfo->Flags = 0;

  /// Unique identifier for this node.
  RootComplexInfo->Identifier = GetNextIortIdentifier ();

  Data = FdtGetProp (Fdt, RootComplexNode, "iommu-map", &DataSize);
  if (Data == NULL) {
    // Some guests (e.g. kvmtool) do not provide a SMMU, so the PCI node
    // in the DTB lacks an 'iommu-map'. In such cases set the Number of
    // ID mappings to 0.
    RootComplexInfo->IdMappingCount = 0;
  } else {
    if (((DataSize % (IOMMU_MAP_CELL_COUNT * sizeof (UINT32))) != 0)) {
      // If error or invalid number of cells (not multiple of IOMMU_MAP_CELL_COUNT).
      ASSERT ((DataSize % (IOMMU_MAP_CELL_COUNT * sizeof (UINT32))) == 0);
      return EFI_ABORTED;
    }

    DataSize /= IOMMU_MAP_CELL_COUNT * sizeof (UINT32);

    IdMappings = AllocateZeroPool (DataSize * sizeof (CM_ARM_ID_MAPPING));
    if (IdMappings == NULL) {
      ASSERT (IdMappings != NULL);
      return EFI_OUT_OF_RESOURCES;
    }

    for (MapIndex = 0; MapIndex < DataSize; MapIndex++) {
      IdMappings[MapIndex].InputBase            = Fdt32ToCpu (((UINT32 *)Data)[MapIndex * IOMMU_MAP_CELL_COUNT]);
      IdMappings[MapIndex].NumIds               = Fdt32ToCpu (((UINT32 *)Data)[MapIndex * IOMMU_MAP_CELL_COUNT + 3]);
      IdMappings[MapIndex].OutputBase           = Fdt32ToCpu (((UINT32 *)Data)[MapIndex * IOMMU_MAP_CELL_COUNT + 2]);
      IdMappings[MapIndex].OutputReferenceToken = CM_ABSTRACT_TOKEN_MAKE (
                                                    ETokenNameSpaceFdtHwInfo,
                                                    EFdtHwInfoIortObject,
                                                    Fdt32ToCpu (((UINT32 *)Data)[MapIndex * IOMMU_MAP_CELL_COUNT + 1])
                                                    );
    }

    // Add the CmObj to the Configuration Manager.
    Status = AddSingleCmObjArray (
               FdtParserHandle,
               CREATE_CM_ARM_OBJECT_ID (EArmObjIdMappingArray),
               IdMappings,
               sizeof (CM_ARM_ID_MAPPING) * DataSize,
               DataSize,
               &RootComplexInfo->IdMappingToken
               );
    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      FreePool (IdMappings);
      return Status;
    }

    /// Number of ID mappings
    RootComplexInfo->IdMappingCount = DataSize;
  }

  return EFI_SUCCESS;
}

/** CM_ARM_ROOT_COMPLEX_NODE parser function.

  The following structure is populated:
  typedef struct CmArmRootComplexNode {
    CM_OBJECT_TOKEN    Token;
    UINT32             IdMappingCount;          // {Populated}
    CM_OBJECT_TOKEN    IdMappingToken;          // {Populated}
    UINT32             CacheCoherent;           // {Populated}
    UINT8              AllocationHints;         // {default = 0}
    UINT8              MemoryAccessFlags;       // {Populated}
    UINT32             AtsAttribute;            // {Populated}
    UINT32             PciSegmentNumber;        // {Populated}
    UINT8              MemoryAddressSize;       // {Populated}
    UINT16             PasidCapabilities;       // {default = 0}
    UINT32             Flags;                   // {default = 0}
    UINT32             Identifier;              // {Populated}
  } CM_ARM_ROOT_COMPLEX_NODE;

  A parser parses a Device Tree to populate a specific CmObj type. None,
  one or many CmObj can be created by the parser.
  The created CmObj are then handed to the parser's caller through the
  HW_INFO_ADD_OBJECT interface.
  This can also be a dispatcher. I.e. a function that not parsing a
  Device Tree but calling other parsers.

  @param [in]  FdtParserHandle A handle to the parser instance.
  @param [in]  FdtBranch       When searching for DT node name, restrict
                               the search to this Device Tree branch.

  @retval EFI_SUCCESS             The function completed successfully.
  @retval EFI_ABORTED             An error occurred.
  @retval EFI_INVALID_PARAMETER   Invalid parameter.
  @retval EFI_NOT_FOUND           Not found.
  @retval EFI_UNSUPPORTED         Unsupported.
**/
EFI_STATUS
EFIAPI
ArmPciRootComplexParser (
  IN  CONST FDT_HW_INFO_PARSER_HANDLE  FdtParserHandle,
  IN        INT32                      FdtBranch
  )
{
  EFI_STATUS                Status;
  UINT32                    Index;
  INT32                     RootComplexNode;
  UINT32                    RootComplexNodeCount;
  CM_ARM_ROOT_COMPLEX_NODE  RootComplexInfo;
  VOID                      *Fdt;

  if (FdtParserHandle == NULL) {
    ASSERT (FdtParserHandle != NULL);
    return EFI_INVALID_PARAMETER;
  }

  Fdt    = FdtParserHandle->Fdt;
  Status = FdtCountCompatNodeInBranch (
             Fdt,
             FdtBranch,
             &RootComplexCompatibleInfo,
             &RootComplexNodeCount
             );
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    return Status;
  }

  if (RootComplexNodeCount == 0) {
    return EFI_NOT_FOUND;
  }

  // Parse each root complex node in the branch.
  RootComplexNode = FdtBranch;
  for (Index = 0; Index < RootComplexNodeCount; Index++) {
    ZeroMem (&RootComplexInfo, sizeof (CM_ARM_ROOT_COMPLEX_NODE));

    Status = FdtGetNextCompatNodeInBranch (
               Fdt,
               FdtBranch,
               &RootComplexCompatibleInfo,
               &RootComplexNode
               );
    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      if (Status == EFI_NOT_FOUND) {
        // Should have found the node.
        Status = EFI_ABORTED;
      }

      return Status;
    }

    Status = RootComplexNodeParser (FdtParserHandle, Fdt, RootComplexNode, &RootComplexInfo);
    if (EFI_ERROR (Status)) {
      if (Status != EFI_NOT_FOUND) {
        ASSERT_EFI_ERROR (Status);
      }

      return Status;
    }

    // Add the CmObj to the Configuration Manager.
    Status = AddSingleCmObj (
               FdtParserHandle,
               CREATE_CM_ARM_OBJECT_ID (EArmObjRootComplex),
               &RootComplexInfo,
               sizeof (CM_ARM_ROOT_COMPLEX_NODE),
               NULL
               );
    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      return Status;
    }
  } // for

  return Status;
}
