/** @file
  SPCR table parser

  Copyright (c) 2016 - 2024, Arm Limited. All rights reserved.
  SPDX-License-Identifier: BSD-2-Clause-Patent

  @par Reference(s):
    - Microsoft Serial Port Console Redirection Table
      Specification - Version 1.03 - August 10, 2015.
**/

#include <IndustryStandard/Acpi.h>
#include <IndustryStandard/SerialPortConsoleRedirectionTable.h>
#include <Library/UefiLib.h>
#include "AcpiParser.h"
#include "AcpiTableParser.h"

// Local variables
STATIC ACPI_DESCRIPTION_HEADER_INFO  AcpiHdrInfo;

STATIC UINT16  *NamespaceStringLength;
STATIC UINT16  *NamespaceStringOffset;

/**
  This function validates the Interrupt Type.

  @param [in] Ptr     Pointer to the start of the field data.
  @param [in] Length  Length of the field.
  @param [in] Context Pointer to context specific information e.g. this
                      could be a pointer to the ACPI table header.
**/
STATIC
VOID
EFIAPI
ValidateInterruptType (
  IN UINT8   *Ptr,
  IN UINT32  Length,
  IN VOID    *Context
  )
{
 #if defined (MDE_CPU_AARCH64)
  UINT8  InterruptType;

  InterruptType = *Ptr;

  if (InterruptType !=
      EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERRUPT_TYPE_GIC)
  {
    IncrementErrorCount ();
    Print (
      L"\nERROR: InterruptType = %d. This must be 8 on ARM Platforms",
      InterruptType
      );
  }

 #endif
}

/**
  This function validates the Irq.

  @param [in] Ptr     Pointer to the start of the field data.
  @param [in] Length  Length of the field.
  @param [in] Context Pointer to context specific information e.g. this
                      could be a pointer to the ACPI table header.
**/
STATIC
VOID
EFIAPI
ValidateIrq (
  IN UINT8   *Ptr,
  IN UINT32  Length,
  IN VOID    *Context
  )
{
 #if defined (MDE_CPU_AARCH64)
  UINT8  Irq;

  Irq = *Ptr;

  if (Irq != 0) {
    IncrementErrorCount ();
    Print (
      L"\nERROR: Irq = %d. This must be zero on ARM Platforms\n",
      Irq
      );
  }

 #endif
}

/**
  This function validates the NameSpace string length.

  @param [in] Ptr     Pointer to the start of the buffer.
  @param [in] Length  Length of the field.
  @param [in] Context Pointer to context specific information e.g. this
                      could be a pointer to the ACPI table header.
**/
STATIC
VOID
EFIAPI
ValidateNameSpaceStrLen (
  IN UINT8   *Ptr,
  IN UINT32  Length,
  IN VOID    *Context
  )
{
  UINT16  NameSpaceStrLen;

  NameSpaceStrLen = *(UINT16 *)Ptr;

  if (NameSpaceStrLen < 2) {
    IncrementErrorCount ();
    Print (
      L"\nERROR: NamespaceString Length = %d. If no Namespace device exists, " \
      L"NamespaceString[] must contain a period '.'",
      NameSpaceStrLen
      );
  }
}

/**
  An ACPI_PARSER array describing the ACPI SPCR Table.
**/
STATIC CONST ACPI_PARSER  SpcrParser[] = {
  PARSE_ACPI_HEADER (&AcpiHdrInfo),
  { L"Interface Type",             1,   36, L"%d",       NULL,       NULL,                            NULL,                    NULL },
  { L"Reserved",                   3,   37, L"%x %x %x", Dump3Chars, NULL,                            NULL,                    NULL },
  { L"Base Address",               12,  40, NULL,        DumpGas,    NULL,                            NULL,                    NULL },
  { L"Interrupt Type",             1,   52, L"%d",       NULL,       NULL,                            ValidateInterruptType,   NULL },
  { L"IRQ",                        1,   53, L"%d",       NULL,       NULL,                            ValidateIrq,             NULL },
  { L"Global System Interrupt",    4,   54, L"0x%x",     NULL,       NULL,                            NULL,                    NULL },
  { L"Baud Rate",                  1,   58, L"%d",       NULL,       NULL,                            NULL,                    NULL },
  { L"Parity",                     1,   59, L"%d",       NULL,       NULL,                            NULL,                    NULL },
  { L"Stop Bits",                  1,   60, L"%d",       NULL,       NULL,                            NULL,                    NULL },
  { L"Flow Control",               1,   61, L"0x%x",     NULL,       NULL,                            NULL,                    NULL },
  { L"Terminal Type",              1,   62, L"%d",       NULL,       NULL,                            NULL,                    NULL },
  { L"Reserved",                   1,   63, L"%x",       NULL,       NULL,                            NULL,                    NULL },

  { L"PCI Device ID",              2,   64, L"0x%x",     NULL,       NULL,                            NULL,                    NULL },
  { L"PCI Vendor ID",              2,   66, L"0x%x",     NULL,       NULL,                            NULL,                    NULL },
  { L"PCI Bus Number",             1,   68, L"0x%x",     NULL,       NULL,                            NULL,                    NULL },
  { L"PCI Device Number",          1,   69, L"0x%x",     NULL,       NULL,                            NULL,                    NULL },
  { L"PCI Function Number",        1,   70, L"0x%x",     NULL,       NULL,                            NULL,                    NULL },
  { L"PCI Flags",                  4,   71, L"0x%x",     NULL,       NULL,                            NULL,                    NULL },
  { L"PCI Segment",                1,   75, L"0x%x",     NULL,       NULL,                            NULL,                    NULL },
  { L"UART Clock Frequency",       4,   76, L"%d",       NULL,       NULL,                            NULL,                    NULL },
  { L"Precise Baud Rate",          4,   80, L"%d",       NULL,       NULL,                            NULL,                    NULL },
  { L"Namespace String Length",    2,   84, L"%x",       NULL,       (VOID **)&NamespaceStringLength, ValidateNameSpaceStrLen, NULL },
  { L"Namespace String Offset",    2,   86, L"%x",       NULL,       (VOID **)&NamespaceStringOffset, NULL,                    NULL }
};

/**
  This function parses the ACPI SPCR table.
  When trace is enabled this function parses the SPCR table and
  traces the ACPI table fields.

  This function also performs validations of the ACPI table fields.

  @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
ParseAcpiSpcr (
  IN BOOLEAN  Trace,
  IN UINT8    *Ptr,
  IN UINT32   AcpiTableLength,
  IN UINT8    AcpiTableRevision
  )
{
  UINT16  Index;
  UINT16  Offset;

  if (!Trace) {
    return;
  }

  // Dump the SPCR
  ParseAcpi (
    TRUE,
    0,
    "SPCR",
    Ptr,
    AcpiTableLength,
    PARSER_PARAMS (SpcrParser)
    );

  if (*AcpiHdrInfo.Revision >= EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION_4) {
    if ((*NamespaceStringOffset >= AcpiTableLength) ||
        ((UINT32)(*NamespaceStringOffset + *NamespaceStringLength) > AcpiTableLength))
    {
      IncrementErrorCount ();
      Print (
        L"ERROR: Invalid Namespace String. AcpiTableLength = %d, NamespaceStringOffset = %d, NamespaceStringLength = %d\n",
        AcpiTableLength,
        *NamespaceStringOffset,
        *NamespaceStringLength
        );
      return;
    }

    Index  = 0;
    Offset = *NamespaceStringOffset;
    PrintFieldName (4, L"Namespace String");
    while ((Index++ < *NamespaceStringLength) &&
           ((UINT32)Offset < AcpiTableLength))
    {
      Print (L"%c", *(Ptr + Offset));
      Offset++;
    }
  }
}
