/** @file
  SLIT Table Generator

  Copyright (C) 2025 Advanced Micro Devices, Inc. All rights reserved.

  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Protocol/AcpiTable.h>

// Module specific include files.
#include <AcpiTableGenerator.h>
#include <ConfigurationManagerObject.h>
#include <ConfigurationManagerHelper.h>
#include <Library/TableHelperLib.h>
#include <Protocol/ConfigurationManagerProtocol.h>
#include <Library/CmObjHelperLib.h>

#define SLIT_DISTANCE_NORMALIZED   10
#define SLIT_DISTANCE_UNREACHABLE  0xFF

/** Structure to hold domain relation information.
 */
typedef struct {
  UINT32    DomainIdSrc;
  UINT32    DomainIdDst;
  UINT64    Relation;
} DOMAIN_RELATION_INFO;

/** Standard SLIT Generator

Requirements:
  The following Configuration Manager Object(s) are required by
  this Generator:
  - EArchCommonObjSystemLocalityInfo
  - EArchCommonObjProximityDomainRelationInfo
  - EArchCommonObjProximityDomainInfo
*/

/** Retrieve the System locality information. */
GET_OBJECT_LIST (
  EObjNameSpaceArchCommon,
  EArchCommonObjSystemLocalityInfo,
  CM_ARCH_COMMON_SYSTEM_LOCALITY_INFO
  );

/** Retrieve the Proximity Domain relation information. */
GET_OBJECT_LIST (
  EObjNameSpaceArchCommon,
  EArchCommonObjProximityDomainRelationInfo,
  CM_ARCH_COMMON_PROXIMITY_DOMAIN_RELATION_INFO
  );

/** Retrieve the System Locality domain information.

  This function fetches the System Locality data from the
  Configuration Manager.

  The caller is responsible for freeing the memory allocated for
  the System Locality data, i.e., SlitDomainRelationInfo.

  @param [in]  CfgMgrProtocol         Pointer to the Configuration Manager Protocol.
  @param [out] SlitDomainRelationInfoCount  Pointer to the count of System Locality
                                            domain information entries.
  @param [out] SlitDomainRelationInfo Pointer to the System Locality domain information.

  @retval EFI_SUCCESS           Successfully retrieved the System Locality domain information.
  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
  @retval retval                Errors returned by the Configuration Manager Protocol.
**/
STATIC
EFI_STATUS
EFIAPI
GetProximityDomainInfo (
  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST  CfgMgrProtocol,
  OUT UINT32                                              *SlitDomainRelationInfoCount,
  OUT DOMAIN_RELATION_INFO                                **SlitDomainRelationInfo
  )
{
  CM_ARCH_COMMON_PROXIMITY_DOMAIN_RELATION_INFO  *DomainRelationInfo;
  CM_ARCH_COMMON_SYSTEM_LOCALITY_INFO            *SystemLocalityInfo;
  DOMAIN_RELATION_INFO                           *RelationInfo;
  EFI_STATUS                                     Status;
  UINT32                                         DomainIdFirst;
  UINT32                                         DomainIdSecond;
  UINT32                                         DomainRelationInfoCount;
  UINT32                                         Index;

  if ((CfgMgrProtocol == NULL) ||
      (SlitDomainRelationInfoCount == NULL) ||
      (SlitDomainRelationInfo == NULL))
  {
    return EFI_INVALID_PARAMETER;
  }

  Status = GetEArchCommonObjSystemLocalityInfo (
             CfgMgrProtocol,
             CM_NULL_TOKEN,
             &SystemLocalityInfo,
             NULL
             );

  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_ERROR,
      "ERROR: SLIT: Failed to retrieve SLIT information. Status = %r\n",
      Status
      ));
    return Status;
  }

  if (SystemLocalityInfo == NULL) {
    DEBUG ((
      DEBUG_ERROR,
      "ERROR: SLIT: No SLIT information provided by configuration manager.\n"
      ));
    return EFI_NOT_FOUND;
  }

  Status = GetEArchCommonObjProximityDomainRelationInfo (
             CfgMgrProtocol,
             SystemLocalityInfo->RelativeDistanceArray,
             &DomainRelationInfo,
             &DomainRelationInfoCount
             );
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_ERROR,
      "ERROR: SLIT: Failed to get domain relation info. Status = %r\n",
      Status
      ));
    return Status;
  }

  if ((DomainRelationInfo == NULL) || (DomainRelationInfoCount == 0)) {
    DEBUG ((
      DEBUG_ERROR,
      "ERROR: SLIT: No domain relation info from config manager.\n"
      ));
    return EFI_NOT_FOUND;
  }

  RelationInfo = AllocateZeroPool (
                   sizeof (DOMAIN_RELATION_INFO) * DomainRelationInfoCount
                   );
  if (RelationInfo == NULL) {
    DEBUG ((
      DEBUG_ERROR,
      "ERROR: SLIT: Failed to allocate memory for SLIT relation info.\n"
      ));
    return EFI_OUT_OF_RESOURCES;
  }

  for (Index = 0; Index < DomainRelationInfoCount; Index++) {
    if ((DomainRelationInfo[Index].Relation < SLIT_DISTANCE_NORMALIZED) ||
        (DomainRelationInfo[Index].Relation > SLIT_DISTANCE_UNREACHABLE))
    {
      DEBUG ((
        DEBUG_ERROR,
        "ERROR: SLIT: Invalid relation value %d\n",
        DomainRelationInfo[Index].Relation
        ));
      FreePool (RelationInfo);
      return EFI_INVALID_PARAMETER;
    }

    Status = GetProximityDomainId (
               CfgMgrProtocol,
               0,
               DomainRelationInfo[Index].FirstDomainToken,
               &DomainIdFirst
               );
    if (EFI_ERROR (Status)) {
      DEBUG ((
        DEBUG_ERROR,
        "ERROR: SLIT: Failed to retrieve First Domain ID. Status = %r\n",
        Status
        ));
      FreePool (RelationInfo);
      return Status;
    }

    Status = GetProximityDomainId (
               CfgMgrProtocol,
               0,
               DomainRelationInfo[Index].SecondDomainToken,
               &DomainIdSecond
               );
    if (EFI_ERROR (Status)) {
      DEBUG ((
        DEBUG_ERROR,
        "ERROR: SLIT: Failed to retrieve Second Domain ID. Status = %r\n",
        Status
        ));
      FreePool (RelationInfo);
      return Status;
    }

    if (DomainIdFirst == DomainIdSecond) {
      if (DomainRelationInfo[Index].Relation != SLIT_DISTANCE_NORMALIZED) {
        DEBUG ((
          DEBUG_ERROR,
          "ERROR: SLIT: Invalid relation value %d for same domain ID %d\n",
          DomainRelationInfo[Index].Relation,
          DomainIdFirst
          ));
        FreePool (RelationInfo);
        return EFI_INVALID_PARAMETER;
      }
    }

    RelationInfo[Index].DomainIdSrc = DomainIdFirst;
    RelationInfo[Index].DomainIdDst = DomainIdSecond;
    RelationInfo[Index].Relation    = DomainRelationInfo[Index].Relation;
  }

  *SlitDomainRelationInfoCount = DomainRelationInfoCount;
  *SlitDomainRelationInfo      = RelationInfo;
  return EFI_SUCCESS;
}

/** Get the number of System Localities.

  This function calculates the number of System Localities based on
  the maximum locality ID found in the SLIT domain relation information.

  @param [in]  SlitDomainRelationInfo       Pointer to the SLIT domain relation information.
  @param [in]  SlitDomainRelationInfoCount  The count of SLIT domain relation information entries.
  @param [out] NumberOfSystemLocalities    Pointer to the number of System Localities.

  @retval EFI_SUCCESS           Successfully retrieved the number of System Localities.
  @retval EFI_INVALID_PARAMETER One or more parameters are invalid
**/
STATIC
EFI_STATUS
EFIAPI
GetNumberOfSystemLocalities (
  IN DOMAIN_RELATION_INFO  *SlitDomainRelationInfo,
  IN UINT32                SlitDomainRelationInfoCount,
  OUT UINT32               *NumberOfSystemLocalities
  )
{
  UINT32  Index;
  UINT32  MaxLocality;

  if ((SlitDomainRelationInfo == NULL) ||
      (NumberOfSystemLocalities == NULL) ||
      (SlitDomainRelationInfoCount == 0))
  {
    return EFI_INVALID_PARAMETER;
  }

  MaxLocality = 0;
  for (Index = 0; Index < SlitDomainRelationInfoCount; Index++) {
    MaxLocality = MAX (
                    MaxLocality,
                    MAX (
                      SlitDomainRelationInfo[Index].DomainIdSrc,
                      SlitDomainRelationInfo[Index].DomainIdDst
                      )
                    );
  }

  *NumberOfSystemLocalities = MaxLocality + 1;
  return EFI_SUCCESS;
}

/** Get the SLIT entry.

  This function constructs the SLIT entry based on the SLIT domain relation
  information and the number of System Localities.

  @param [in]  SlitDomainRelationInfo       Pointer to the SLIT domain relation information.
  @param [in]  SlitDomainRelationInfoCount  The count of SLIT domain relation information entries.
  @param [in]  NumberOfSystemLocalities     The number of System Localities.
  @param [in, out] SlitEntry                Pointer to the SLIT entry.

  @retval EFI_SUCCESS           Successfully retrieved the SLIT entry.
  @retval EFI_INVALID_PARAMETER One or more parameters are invalid.
**/
STATIC
EFI_STATUS
EFIAPI
GetSlitEntry (
  IN DOMAIN_RELATION_INFO  *SlitDomainRelationInfo,
  IN UINT32                SlitDomainRelationInfoCount,
  IN UINT32                NumberOfSystemLocalities,
  IN OUT UINT8             *SlitEntry
  )
{
  UINT32  Index;
  UINT32  LocalitySrc;
  UINT32  LocalityDst;
  UINT32  SrcIndex;
  UINT32  DstIndex;

  if ((SlitDomainRelationInfo == NULL) ||
      (SlitEntry == NULL) ||
      (NumberOfSystemLocalities == 0) ||
      (SlitDomainRelationInfoCount == 0))
  {
    return EFI_INVALID_PARAMETER;
  }

  SetMem (
    SlitEntry,
    sizeof (UINT8) * NumberOfSystemLocalities * NumberOfSystemLocalities,
    SLIT_DISTANCE_UNREACHABLE
    );
  for (Index = 0; Index < NumberOfSystemLocalities; Index++) {
    SlitEntry[(Index * NumberOfSystemLocalities) + Index] = SLIT_DISTANCE_NORMALIZED;
  }

  for (Index = 0; Index < SlitDomainRelationInfoCount; Index++) {
    LocalitySrc = SlitDomainRelationInfo[Index].DomainIdSrc;
    LocalityDst = SlitDomainRelationInfo[Index].DomainIdDst;
    SrcIndex    = (LocalitySrc * NumberOfSystemLocalities) + LocalityDst;
    DstIndex    = (LocalityDst * NumberOfSystemLocalities) + LocalitySrc;

    /// compare with default normalized
    if (SlitDomainRelationInfo[Index].Relation == SLIT_DISTANCE_NORMALIZED) {
      if ((SlitEntry[SrcIndex] != SLIT_DISTANCE_NORMALIZED) ||
          (SlitEntry[DstIndex] != SLIT_DISTANCE_NORMALIZED))
      {
        DEBUG ((
          DEBUG_ERROR,
          "ERROR: SLIT: Invalid normalized value Src[%d] = %d, Dst[%d] = %d.\n",
          SrcIndex,
          SlitEntry[SrcIndex],
          DstIndex,
          SlitEntry[DstIndex]
          ));
        return EFI_INVALID_PARAMETER;
      }

      continue;
    }

    /// Compare with default unreachable and symmetric value
    if (SlitDomainRelationInfo[Index].Relation == SLIT_DISTANCE_UNREACHABLE) {
      if ((SlitEntry[SrcIndex] != SLIT_DISTANCE_UNREACHABLE) ||
          (SlitEntry[DstIndex] != SLIT_DISTANCE_UNREACHABLE))
      {
        DEBUG ((
          DEBUG_ERROR,
          "ERROR: SLIT: Invalid unreachable value Src[%d] = %d, Dst[%d] = %d\n",
          SrcIndex,
          SlitEntry[SrcIndex],
          DstIndex,
          SlitEntry[DstIndex]
          ));
        return EFI_INVALID_PARAMETER;
      }

      continue;
    }

    if ((SlitEntry[SrcIndex] != SLIT_DISTANCE_UNREACHABLE) &&
        (SlitEntry[SrcIndex] != SlitDomainRelationInfo[Index].Relation))
    {
      DEBUG ((
        DEBUG_ERROR,
        "ERROR: SLIT: Invalid existing value %d for Src %d Dst %d\n",
        SlitEntry[SrcIndex],
        LocalitySrc,
        LocalityDst
        ));
      return EFI_INVALID_PARAMETER;
    }

    SlitEntry[SrcIndex] = (SlitDomainRelationInfo[Index].Relation & MAX_UINT8);

    if ((SlitEntry[DstIndex] != SLIT_DISTANCE_UNREACHABLE) &&
        (SlitEntry[DstIndex] != SlitDomainRelationInfo[Index].Relation))
    {
      DEBUG ((
        DEBUG_ERROR,
        "ERROR: SLIT: Invalid existing value %d for Dst %d Src %d\n",
        SlitEntry[DstIndex],
        LocalityDst,
        LocalitySrc
        ));
      return EFI_INVALID_PARAMETER;
    }

    SlitEntry[DstIndex] = (SlitDomainRelationInfo[Index].Relation & MAX_UINT8);
  }

  return EFI_SUCCESS;
}

/** Construct the SLIT ACPI table.

  This function invokes the Configuration Manager protocol interface
  to get the required hardware information for generating the ACPI
  table.

  If this function allocates any resources then they must be freed
  in the FreeXXXXTableResources function.

  @param [in]  This           Pointer to the table generator.
  @param [in]  AcpiTableInfo  Pointer to the ACPI Table Info.
  @param [in]  CfgMgrProtocol Pointer to the Configuration Manager
                                Protocol Interface.
  @param [out] Table          Pointer to the constructed ACPI Table.

  @retval EFI_SUCCESS           Table generated successfully.
  @retval EFI_INVALID_PARAMETER A parameter is invalid.
  @retval EFI_NOT_FOUND         The required object was not found.
  @retval EFI_BAD_BUFFER_SIZE   The size returned by the Configuration
                                Manager is less than the Object size for the
                                requested object.
**/
STATIC
EFI_STATUS
EFIAPI
BuildSlitTable (
  IN  CONST ACPI_TABLE_GENERATOR                  *CONST  This,
  IN  CONST CM_STD_OBJ_ACPI_TABLE_INFO            *CONST  AcpiTableInfo,
  IN  CONST EDKII_CONFIGURATION_MANAGER_PROTOCOL  *CONST  CfgMgrProtocol,
  OUT       EFI_ACPI_DESCRIPTION_HEADER          **CONST  Table
  )
{
  DOMAIN_RELATION_INFO  *SlitDomainRelationInfo;
  EFI_STATUS            Status;
  UINT32                NumberOfSystemLocalities;
  UINT32                SlitDomainRelationInfoCount;
  UINT8                 *SlitEntry;

  EFI_ACPI_6_5_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER  *AcpiSlitTable;

  ASSERT (This != NULL);
  ASSERT (AcpiTableInfo != NULL);
  ASSERT (CfgMgrProtocol != NULL);
  ASSERT (Table != NULL);
  ASSERT (AcpiTableInfo->TableGeneratorId == This->GeneratorID);
  ASSERT (AcpiTableInfo->AcpiTableSignature == This->AcpiTableSignature);

  if ((AcpiTableInfo->AcpiTableRevision < This->MinAcpiTableRevision) ||
      (AcpiTableInfo->AcpiTableRevision > This->AcpiTableRevision))
  {
    DEBUG ((
      DEBUG_ERROR,
      "ERROR: SLIT: Requested table revision = %d, is not supported."
      "Supported table revision: Minimum = %d, Maximum = %d\n",
      AcpiTableInfo->AcpiTableRevision,
      This->MinAcpiTableRevision,
      This->AcpiTableRevision
      ));
    return EFI_INVALID_PARAMETER;
  }

  *Table = NULL;

  Status = GetProximityDomainInfo (
             CfgMgrProtocol,
             &SlitDomainRelationInfoCount,
             &SlitDomainRelationInfo
             );
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_ERROR,
      "ERROR: SLIT: Failed to get domain info. Status = %r\n",
      Status
      ));
    return Status;
  }

  Status = GetNumberOfSystemLocalities (
             SlitDomainRelationInfo,
             SlitDomainRelationInfoCount,
             &NumberOfSystemLocalities
             );
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_ERROR,
      "ERROR: SLIT: Failed to get NumberOfSystemLocalities. Status = %r\n",
      Status
      ));
    FreePool (SlitDomainRelationInfo);
    return Status;
  }

  AcpiSlitTable = AllocateZeroPool (
                    sizeof (EFI_ACPI_6_5_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER) +
                    (sizeof (UINT8) * NumberOfSystemLocalities * NumberOfSystemLocalities)
                    );
  if (AcpiSlitTable == NULL) {
    DEBUG ((
      DEBUG_ERROR,
      "ERROR: SLIT: Failed to allocate memory for SLIT table.\n"
      ));
    FreePool (SlitDomainRelationInfo);
    return EFI_OUT_OF_RESOURCES;
  }

  AcpiSlitTable->NumberOfSystemLocalities = NumberOfSystemLocalities;

  SlitEntry = (UINT8 *)AcpiSlitTable;
  SlitEntry = SlitEntry + sizeof (EFI_ACPI_6_5_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER);

  Status = GetSlitEntry (
             SlitDomainRelationInfo,
             SlitDomainRelationInfoCount,
             NumberOfSystemLocalities,
             SlitEntry
             );
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_ERROR,
      "ERROR: SLIT: Failed to get SLIT entry. Status = %r\n",
      Status
      ));
    FreePool (AcpiSlitTable);
    FreePool (SlitDomainRelationInfo);
    return Status;
  }

  FreePool (SlitDomainRelationInfo);
  Status = AddAcpiHeader (
             CfgMgrProtocol,
             This,
             (EFI_ACPI_DESCRIPTION_HEADER *)AcpiSlitTable,
             AcpiTableInfo,
             (sizeof (EFI_ACPI_6_5_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER) +
              (sizeof (UINT8) * NumberOfSystemLocalities * NumberOfSystemLocalities))
             );
  if (EFI_ERROR (Status)) {
    DEBUG ((
      DEBUG_ERROR,
      "ERROR: SLIT: Failed to add ACPI header. Status = %r\n",
      Status
      ));
    FreePool (AcpiSlitTable);
    return Status;
  }

  *Table = (EFI_ACPI_DESCRIPTION_HEADER *)AcpiSlitTable;
  return Status;
}

/** This macro defines the SLIT Table Generator revision.
*/
#define SLIT_GENERATOR_REVISION  CREATE_REVISION (1, 0)

/** The interface for the SLIT Table Generator.
*/
STATIC
CONST
ACPI_TABLE_GENERATOR  SpmiGenerator = {
  // Generator ID
  CREATE_STD_ACPI_TABLE_GEN_ID (EStdAcpiTableIdSlit),
  // Generator Description
  L"ACPI.STD.SLIT.GENERATOR",
  // ACPI Table Signature
  EFI_ACPI_6_5_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE,
  // ACPI Table Revision supported by this Generator
  EFI_ACPI_6_5_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_REVISION,
  // Minimum supported ACPI Table Revision
  EFI_ACPI_6_5_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_REVISION,
  // Creator ID
  TABLE_GENERATOR_CREATOR_ID,
  // Creator Revision
  SLIT_GENERATOR_REVISION,
  // Build Table function
  BuildSlitTable,
  // Free Resource function
  NULL,
  // Extended build function not needed
  NULL,
  // Extended build function not implemented by the generator.
  // Hence extended free resource function is not required.
  NULL
};

/** Register the Generator with the ACPI Table Factory.

  @param [in]  ImageHandle  The handle to the image.
  @param [in]  SystemTable  Pointer to the System Table.

  @retval EFI_SUCCESS           The Generator is registered.
  @retval EFI_INVALID_PARAMETER A parameter is invalid.
  @retval EFI_ALREADY_STARTED   The Generator for the Table ID
                                is already registered.
**/
EFI_STATUS
EFIAPI
AcpiSlitLibConstructor (
  IN  EFI_HANDLE        ImageHandle,
  IN  EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  Status = RegisterAcpiTableGenerator (&SpmiGenerator);
  DEBUG ((DEBUG_INFO, "SLIT: Register Generator. Status = %r\n", Status));
  ASSERT_EFI_ERROR (Status);
  return Status;
}

/** Deregister the Generator from the ACPI Table Factory.

  @param [in]  ImageHandle  The handle to the image.
  @param [in]  SystemTable  Pointer to the System Table.

  @retval EFI_SUCCESS           The Generator is deregistered.
  @retval EFI_INVALID_PARAMETER A parameter is invalid.
  @retval EFI_NOT_FOUND         The Generator is not registered.
**/
EFI_STATUS
EFIAPI
AcpiSlitLibDestructor (
  IN  EFI_HANDLE        ImageHandle,
  IN  EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  Status = DeregisterAcpiTableGenerator (&SpmiGenerator);
  DEBUG ((DEBUG_INFO, "SLIT: Deregister Generator. Status = %r\n", Status));
  ASSERT_EFI_ERROR (Status);
  return Status;
}
