/** @file
  ACPI table parser

  Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
  SPDX-License-Identifier: BSD-2-Clause-Patent

  @par Glossary:
    - Sbbr or SBBR   - Server Base Boot Requirements

  @par Reference(s):
    - Arm Server Base Boot Requirements 1.2, September 2019
**/

#include <Uefi.h>
#include <IndustryStandard/Acpi.h>
#include <Library/UefiLib.h>
#include "AcpiParser.h"
#include "AcpiTableParser.h"
#include "AcpiView.h"
#include "AcpiViewConfig.h"

#if defined (MDE_CPU_AARCH64)
  #include "Arm/SbbrValidator.h"
#endif

/**
  A list of registered ACPI table parsers.
**/
STATIC ACPI_TABLE_PARSER  mTableParserList[MAX_ACPI_TABLE_PARSERS];

/**
  Register the ACPI table Parser

  This function registers the ACPI table parser.

  @param [in] Signature   The ACPI table signature.
  @param [in] ParserProc  The ACPI table parser.

  @retval EFI_SUCCESS           The parser is registered.
  @retval EFI_INVALID_PARAMETER A parameter is invalid.
  @retval EFI_ALREADY_STARTED   The parser for the Table
                                was already registered.
  @retval EFI_OUT_OF_RESOURCES  No space to register the
                                parser.
**/
EFI_STATUS
EFIAPI
RegisterParser (
  IN  UINT32                 Signature,
  IN  PARSE_ACPI_TABLE_PROC  ParserProc
  )
{
  UINT32  Index;

  if ((ParserProc == NULL) || (Signature == ACPI_PARSER_SIGNATURE_NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  // Search if a parser is already installed
  for (Index = 0;
       Index < (sizeof (mTableParserList) / sizeof (mTableParserList[0]));
       Index++)
  {
    if (Signature == mTableParserList[Index].Signature) {
      if (mTableParserList[Index].Parser != NULL) {
        return EFI_ALREADY_STARTED;
      }
    }
  }

  // Find the first free slot and register the parser
  for (Index = 0;
       Index < (sizeof (mTableParserList) / sizeof (mTableParserList[0]));
       Index++)
  {
    if (mTableParserList[Index].Signature == ACPI_PARSER_SIGNATURE_NULL) {
      mTableParserList[Index].Signature = Signature;
      mTableParserList[Index].Parser    = ParserProc;
      return EFI_SUCCESS;
    }
  }

  // No free slot found
  return EFI_OUT_OF_RESOURCES;
}

/**
  Deregister the ACPI table Parser

  This function deregisters the ACPI table parser.

  @param [in] Signature   The ACPI table signature.

  @retval EFI_SUCCESS           The parser was deregistered.
  @retval EFI_INVALID_PARAMETER A parameter is invalid.
  @retval EFI_NOT_FOUND         A registered parser was not found.
**/
EFI_STATUS
EFIAPI
DeregisterParser (
  IN  UINT32  Signature
  )
{
  UINT32  Index;

  if (Signature == ACPI_PARSER_SIGNATURE_NULL) {
    return EFI_INVALID_PARAMETER;
  }

  for (Index = 0;
       Index < (sizeof (mTableParserList) / sizeof (mTableParserList[0]));
       Index++)
  {
    if (Signature == mTableParserList[Index].Signature) {
      mTableParserList[Index].Signature = ACPI_PARSER_SIGNATURE_NULL;
      mTableParserList[Index].Parser    = NULL;
      return EFI_SUCCESS;
    }
  }

  // No matching registered parser found.
  return EFI_NOT_FOUND;
}

/**
  Get the ACPI table Parser

  This function returns the ACPI table parser proc from the list of
  registered parsers.

  @param [in]  Signature   The ACPI table signature.
  @param [out] ParserProc  Pointer to a ACPI table parser proc.

  @retval EFI_SUCCESS           The parser was returned successfully.
  @retval EFI_INVALID_PARAMETER A parameter is invalid.
  @retval EFI_NOT_FOUND         A registered parser was not found.
**/
EFI_STATUS
EFIAPI
GetParser (
  IN  UINT32                 Signature,
  OUT PARSE_ACPI_TABLE_PROC  *ParserProc
  )
{
  UINT32  Index;

  if ((ParserProc == NULL) || (Signature == ACPI_PARSER_SIGNATURE_NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  for (Index = 0;
       Index < (sizeof (mTableParserList) / sizeof (mTableParserList[0]));
       Index++)
  {
    if (Signature == mTableParserList[Index].Signature) {
      *ParserProc = mTableParserList[Index].Parser;
      return EFI_SUCCESS;
    }
  }

  // No matching registered parser found.
  return EFI_NOT_FOUND;
}

/**
  This function processes the ACPI tables.
  This function calls ProcessTableReportOptions() to list the ACPI
  tables, perform binary dump of the tables and determine if the
  ACPI fields should be traced.

  This function also invokes the parser for the ACPI tables.

  This function also performs a RAW dump of the ACPI table including
  the unknown/unparsed ACPI tables and validates the checksum.

  @param [in] Ptr                Pointer to the start of the ACPI
                                 table data buffer.
**/
VOID
EFIAPI
ProcessAcpiTable (
  IN UINT8  *Ptr
  )
{
  EFI_STATUS             Status;
  BOOLEAN                Trace;
  CONST UINT32           *AcpiTableSignature;
  CONST UINT32           *AcpiTableLength;
  CONST UINT8            *AcpiTableRevision;
  CONST UINT8            *SignaturePtr;
  PARSE_ACPI_TABLE_PROC  ParserProc;

  ParseAcpiHeader (
    Ptr,
    &AcpiTableSignature,
    &AcpiTableLength,
    &AcpiTableRevision
    );

  Trace = ProcessTableReportOptions (
            *AcpiTableSignature,
            Ptr,
            *AcpiTableLength
            );

  if (Trace) {
    DumpRaw (Ptr, *AcpiTableLength);

    // Do not process the ACPI table any further if the table length read
    // is invalid. The ACPI table should at least contain the table header.
    if (*AcpiTableLength < sizeof (EFI_ACPI_DESCRIPTION_HEADER)) {
      SignaturePtr = (CONST UINT8 *)AcpiTableSignature;
      IncrementErrorCount ();
      Print (
        L"ERROR: Invalid %c%c%c%c table length. Length = %d\n",
        SignaturePtr[0],
        SignaturePtr[1],
        SignaturePtr[2],
        SignaturePtr[3],
        *AcpiTableLength
        );
      return;
    }

    if (GetConsistencyChecking ()) {
      VerifyChecksum (TRUE, Ptr, *AcpiTableLength);
    }
  }

 #if defined (MDE_CPU_AARCH64)
  if (GetMandatoryTableValidate ()) {
    ArmSbbrIncrementTableCount (*AcpiTableSignature);
  }

 #endif

  Status = GetParser (*AcpiTableSignature, &ParserProc);
  if (EFI_ERROR (Status)) {
    // No registered parser found, do default handling.
    if (Trace) {
      DumpAcpiHeader (Ptr);
    }

    return;
  }

  ParserProc (
    Trace,
    Ptr,
    *AcpiTableLength,
    *AcpiTableRevision
    );
}
