/** @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_ARM) || 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_ARM) || 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
    );
}
