/** @file
  SLIT table parser

  Copyright (c) 2016 - 2019, ARM Limited. All rights reserved.
  SPDX-License-Identifier: BSD-2-Clause-Patent

  @par Reference(s):
    - ACPI 6.2 Specification - Errata A, September 2017
**/

#include <IndustryStandard/Acpi.h>
#include <Library/PrintLib.h>
#include <Library/UefiLib.h>
#include "AcpiParser.h"
#include "AcpiTableParser.h"

// Local Variables
STATIC CONST UINT64* SlitSystemLocalityCount;
STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;

/**
  An ACPI_PARSER array describing the ACPI SLIT table.
**/
STATIC CONST ACPI_PARSER SlitParser[] = {
  PARSE_ACPI_HEADER (&AcpiHdrInfo),
  {L"Number of System Localities", 8, 36, L"0x%lx", NULL,
   (VOID**)&SlitSystemLocalityCount, NULL, NULL}
};

/**
  Macro to get the value of a System Locality
**/
#define SLIT_ELEMENT(Ptr, i, j) *(Ptr + (i * LocalityCount) + j)

/**
  This function parses the ACPI SLIT table.
  When trace is enabled this function parses the SLIT table and
  traces the ACPI table fields.

  This function also validates System Localities for the following:
    - Diagonal elements have a normalized value of 10
    - Relative distance from System Locality at i*N+j is same as
      j*N+i

  @param [in] Trace              If TRUE, trace the ACPI fields.
  @param [in] Ptr                Pointer to the start of the buffer.
  @param [in] AcpiTableLength    Length of the ACPI table.
  @param [in] AcpiTableRevision  Revision of the ACPI table.
**/
VOID
EFIAPI
ParseAcpiSlit (
  IN BOOLEAN Trace,
  IN UINT8*  Ptr,
  IN UINT32  AcpiTableLength,
  IN UINT8   AcpiTableRevision
  )
{
  UINT32 Offset;
  UINT32 Count;
  UINT32 Index;
  UINT32 LocalityCount;
  UINT8* LocalityPtr;
  CHAR16 Buffer[80];  // Used for AsciiName param of ParseAcpi

  if (!Trace) {
    return;
  }

  Offset = ParseAcpi (
             TRUE,
             0,
             "SLIT",
             Ptr,
             AcpiTableLength,
             PARSER_PARAMS (SlitParser)
             );

  // Check if the values used to control the parsing logic have been
  // successfully read.
  if (SlitSystemLocalityCount == NULL) {
    IncrementErrorCount ();
    Print (
      L"ERROR: Insufficient table length. AcpiTableLength = %d.\n",
      AcpiTableLength
      );
    return;
  }

  /*
    Despite the 'Number of System Localities' being a 64-bit field in SLIT,
    the maximum number of localities that can be represented in SLIT is limited
    by the 'Length' field of the ACPI table.

    Since the ACPI table length field is 32-bit wide. The maximum number of
    localities that can be represented in SLIT can be calculated as:

    MaxLocality = sqrt (MAX_UINT32 - sizeof (EFI_ACPI_6_3_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER))
                = 65535
                = MAX_UINT16
  */
  if (*SlitSystemLocalityCount > MAX_UINT16) {
    IncrementErrorCount ();
    Print (
      L"ERROR: The Number of System Localities provided can't be represented " \
        L"in the SLIT table. SlitSystemLocalityCount = %ld. " \
        L"MaxLocalityCountAllowed = %d.\n",
      *SlitSystemLocalityCount,
      MAX_UINT16
      );
    return;
  }

  LocalityCount = (UINT32)*SlitSystemLocalityCount;

  // Make sure system localities fit in the table buffer provided
  if (Offset + (LocalityCount * LocalityCount) > AcpiTableLength) {
    IncrementErrorCount ();
    Print (
      L"ERROR: Invalid Number of System Localities. " \
        L"SlitSystemLocalityCount = %ld. AcpiTableLength = %d.\n",
      *SlitSystemLocalityCount,
      AcpiTableLength
      );
    return;
  }

  LocalityPtr = Ptr + Offset;

  // We only print the Localities if the count is less than 16
  // If the locality count is more than 16 then refer to the
  // raw data dump.
  if (LocalityCount < 16) {
    UnicodeSPrint (
      Buffer,
      sizeof (Buffer),
      L"Entry[0x%lx][0x%lx]",
      LocalityCount,
      LocalityCount
      );
    PrintFieldName (0, Buffer);
    Print (L"\n");
    Print (L"       ");
    for (Index = 0; Index < LocalityCount; Index++) {
      Print (L" (%3d) ", Index);
    }
    Print (L"\n");
    for (Count = 0; Count< LocalityCount; Count++) {
      Print (L" (%3d) ", Count);
      for (Index = 0; Index < LocalityCount; Index++) {
        Print (L"  %3d  ", SLIT_ELEMENT (LocalityPtr, Count, Index));
      }
      Print (L"\n");
    }
  }

  // Validate
  for (Count = 0; Count < LocalityCount; Count++) {
    for (Index = 0; Index < LocalityCount; Index++) {
      // Element[x][x] must be equal to 10
      if ((Count == Index) && (SLIT_ELEMENT (LocalityPtr, Count,Index) != 10)) {
        IncrementErrorCount ();
        Print (
          L"ERROR: Diagonal Element[0x%lx][0x%lx] (%3d)."
            L" Normalized Value is not 10\n",
          Count,
          Index,
          SLIT_ELEMENT (LocalityPtr, Count, Index)
          );
      }
      // Element[i][j] must be equal to Element[j][i]
      if (SLIT_ELEMENT (LocalityPtr, Count, Index) !=
          SLIT_ELEMENT (LocalityPtr, Index, Count)) {
        IncrementErrorCount ();
        Print (
          L"ERROR: Relative distances for Element[0x%lx][0x%lx] (%3d) and \n"
           L"Element[0x%lx][0x%lx] (%3d) do not match.\n",
          Count,
          Index,
          SLIT_ELEMENT (LocalityPtr, Count, Index),
          Index,
          Count,
          SLIT_ELEMENT (LocalityPtr, Index, Count)
          );
      }
    }
  }
}
