/** @file
  ACPI parser

  Copyright (c) 2016 - 2024, Arm Limited. All rights reserved.
  Copyright (c) 2022, AMD Incorporated. All rights reserved.
  SPDX-License-Identifier: BSD-2-Clause-Patent
**/

#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/BaseMemoryLib.h>
#include "AcpiParser.h"
#include "AcpiView.h"
#include "AcpiViewConfig.h"

STATIC UINT32  gIndent;
STATIC UINT32  mTableErrorCount;
STATIC UINT32  mTableWarningCount;

STATIC ACPI_DESCRIPTION_HEADER_INFO  AcpiHdrInfo;

/**
  An ACPI_PARSER array describing the ACPI header.
**/
STATIC CONST ACPI_PARSER  AcpiHeaderParser[] = {
  PARSE_ACPI_HEADER (&AcpiHdrInfo)
};

/**
  This function resets the ACPI table error counter to Zero.
**/
VOID
ResetErrorCount (
  VOID
  )
{
  mTableErrorCount = 0;
}

/**
  This function returns the ACPI table error count.

  @retval Returns the count of errors detected in the ACPI tables.
**/
UINT32
GetErrorCount (
  VOID
  )
{
  return mTableErrorCount;
}

/**
  This function resets the ACPI table warning counter to Zero.
**/
VOID
ResetWarningCount (
  VOID
  )
{
  mTableWarningCount = 0;
}

/**
  This function returns the ACPI table warning count.

  @retval Returns the count of warning detected in the ACPI tables.
**/
UINT32
GetWarningCount (
  VOID
  )
{
  return mTableWarningCount;
}

/**
  This function increments the ACPI table error counter.
**/
VOID
EFIAPI
IncrementErrorCount (
  VOID
  )
{
  mTableErrorCount++;
}

/**
  This function increments the ACPI table warning counter.
**/
VOID
EFIAPI
IncrementWarningCount (
  VOID
  )
{
  mTableWarningCount++;
}

/**
  This function verifies the ACPI table checksum.

  This function verifies the checksum for the ACPI table and optionally
  prints the status.

  @param [in] Log     If TRUE log the status of the checksum.
  @param [in] Ptr     Pointer to the start of the table buffer.
  @param [in] Length  The length of the buffer.

  @retval TRUE        The checksum is OK.
  @retval FALSE       The checksum failed.
**/
BOOLEAN
EFIAPI
VerifyChecksum (
  IN BOOLEAN  Log,
  IN UINT8    *Ptr,
  IN UINT32   Length
  )
{
  UINTN  ByteCount;
  UINT8  Checksum;
  UINTN  OriginalAttribute;

  //
  // set local variables to suppress incorrect compiler/analyzer warnings
  //
  OriginalAttribute = 0;
  ByteCount         = 0;
  Checksum          = 0;

  while (ByteCount < Length) {
    Checksum += *(Ptr++);
    ByteCount++;
  }

  if (Log) {
    OriginalAttribute = gST->ConOut->Mode->Attribute;
    if (Checksum == 0) {
      if (GetColourHighlighting ()) {
        gST->ConOut->SetAttribute (
                       gST->ConOut,
                       EFI_TEXT_ATTR (
                         EFI_GREEN,
                         ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)
                         )
                       );
      }

      Print (L"Table Checksum : OK\n\n");
    } else {
      IncrementErrorCount ();
      if (GetColourHighlighting ()) {
        gST->ConOut->SetAttribute (
                       gST->ConOut,
                       EFI_TEXT_ATTR (
                         EFI_RED,
                         ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)
                         )
                       );
      }

      Print (L"Table Checksum : FAILED (0x%X)\n\n", Checksum);
    }

    if (GetColourHighlighting ()) {
      gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);
    }
  }

  return (Checksum == 0);
}

/**
  This function performs a raw data dump of the ACPI table.

  @param [in] Ptr     Pointer to the start of the table buffer.
  @param [in] Length  The length of the buffer.
**/
VOID
EFIAPI
DumpRaw (
  IN UINT8   *Ptr,
  IN UINT32  Length
  )
{
  UINTN  ByteCount;
  UINTN  PartLineChars;
  UINTN  AsciiBufferIndex;
  CHAR8  AsciiBuffer[17];

  ByteCount        = 0;
  AsciiBufferIndex = 0;

  Print (L"Address  : 0x%p\n", Ptr);
  Print (L"Length   : %d\n", Length);

  while (ByteCount < Length) {
    if ((ByteCount & 0x0F) == 0) {
      AsciiBuffer[AsciiBufferIndex] = '\0';
      Print (L"  %a\n%08X : ", AsciiBuffer, ByteCount);
      AsciiBufferIndex = 0;
    } else if ((ByteCount & 0x07) == 0) {
      Print (L"- ");
    }

    if ((*Ptr >= ' ') && (*Ptr < 0x7F)) {
      AsciiBuffer[AsciiBufferIndex++] = *Ptr;
    } else {
      AsciiBuffer[AsciiBufferIndex++] = '.';
    }

    Print (L"%02X ", *Ptr++);

    ByteCount++;
  }

  // Justify the final line using spaces before printing
  // the ASCII data.
  PartLineChars = (Length & 0x0F);
  if (PartLineChars != 0) {
    PartLineChars = 48 - (PartLineChars * 3);
    if ((Length & 0x0F) <= 8) {
      PartLineChars += 2;
    }

    while (PartLineChars > 0) {
      Print (L" ");
      PartLineChars--;
    }
  }

  // Print ASCII data for the final line.
  AsciiBuffer[AsciiBufferIndex] = '\0';
  Print (L"  %a\n\n", AsciiBuffer);
}

/**
  This function traces 1 byte of data as specified in the format string.

  @param [in] Format  The format string for tracing the data.
  @param [in] Ptr     Pointer to the start of the buffer.
**/
VOID
EFIAPI
DumpUint8 (
  IN CONST CHAR16  *Format,
  IN UINT8         *Ptr
  )
{
  Print (Format, *Ptr);
}

/**
  This function traces 2 bytes of data as specified in the format string.

  @param [in] Format  The format string for tracing the data.
  @param [in] Ptr     Pointer to the start of the buffer.
**/
VOID
EFIAPI
DumpUint16 (
  IN CONST CHAR16  *Format,
  IN UINT8         *Ptr
  )
{
  Print (Format, *(UINT16 *)Ptr);
}

/**
  This function traces 4 bytes of data as specified in the format string.

  @param [in] Format  The format string for tracing the data.
  @param [in] Ptr     Pointer to the start of the buffer.
**/
VOID
EFIAPI
DumpUint32 (
  IN CONST CHAR16  *Format,
  IN UINT8         *Ptr
  )
{
  Print (Format, *(UINT32 *)Ptr);
}

/**
  This function traces 8 bytes of data as specified by the format string.

  @param [in] Format  The format string for tracing the data.
  @param [in] Ptr     Pointer to the start of the buffer.
**/
VOID
EFIAPI
DumpUint64 (
  IN CONST CHAR16  *Format,
  IN UINT8         *Ptr
  )
{
  // Some fields are not aligned and this causes alignment faults
  // on ARM platforms if the compiler generates LDRD instructions.
  // Perform word access so that LDRD instructions are not generated.
  UINT64  Val;

  Val = *(UINT32 *)(Ptr + sizeof (UINT32));

  Val  = LShiftU64 (Val, 32);
  Val |= (UINT64)*(UINT32 *)Ptr;

  Print (Format, Val);
}

/**
  This function traces 3 characters which can be optionally
  formated using the format string if specified.

  If no format string is specified the Format must be NULL.

  @param [in] Format  Optional format string for tracing the data.
  @param [in] Ptr     Pointer to the start of the buffer.
  @param [in] Length  Length of the field.
**/
VOID
EFIAPI
Dump3Chars (
  IN CONST CHAR16  *Format OPTIONAL,
  IN UINT8         *Ptr,
  IN UINT32        Length
  )
{
  Print (
    (Format != NULL) ? Format : L"%c%c%c",
    Ptr[0],
    Ptr[1],
    Ptr[2]
    );
}

/**
  This function traces 4 characters which can be optionally
  formated using the format string if specified.

  If no format string is specified the Format must be NULL.

  @param [in] Format  Optional format string for tracing the data.
  @param [in] Ptr     Pointer to the start of the buffer.
  @param [in] Length  Length of the field.
**/
VOID
EFIAPI
Dump4Chars (
  IN CONST CHAR16  *Format OPTIONAL,
  IN UINT8         *Ptr,
  IN UINT32        Length
  )
{
  Print (
    (Format != NULL) ? Format : L"%c%c%c%c",
    Ptr[0],
    Ptr[1],
    Ptr[2],
    Ptr[3]
    );
}

/**
  This function traces 6 characters which can be optionally
  formated using the format string if specified.

  If no format string is specified the Format must be NULL.

  @param [in] Format  Optional format string for tracing the data.
  @param [in] Ptr     Pointer to the start of the buffer.
  @param [in] Length  Length of the field.
**/
VOID
EFIAPI
Dump6Chars (
  IN CONST CHAR16  *Format OPTIONAL,
  IN UINT8         *Ptr,
  IN UINT32        Length
  )
{
  Print (
    (Format != NULL) ? Format : L"%c%c%c%c%c%c",
    Ptr[0],
    Ptr[1],
    Ptr[2],
    Ptr[3],
    Ptr[4],
    Ptr[5]
    );
}

/**
  This function traces 8 characters which can be optionally
  formated using the format string if specified.

  If no format string is specified the Format must be NULL.

  @param [in] Format  Optional format string for tracing the data.
  @param [in] Ptr     Pointer to the start of the buffer.
  @param [in] Length  Length of the field.
**/
VOID
EFIAPI
Dump8Chars (
  IN CONST CHAR16  *Format OPTIONAL,
  IN UINT8         *Ptr,
  IN UINT32        Length
  )
{
  Print (
    (Format != NULL) ? Format : L"%c%c%c%c%c%c%c%c",
    Ptr[0],
    Ptr[1],
    Ptr[2],
    Ptr[3],
    Ptr[4],
    Ptr[5],
    Ptr[6],
    Ptr[7]
    );
}

/**
  This function traces 12 characters which can be optionally
  formated using the format string if specified.

  If no format string is specified the Format must be NULL.

  @param [in] Format  Optional format string for tracing the data.
  @param [in] Ptr     Pointer to the start of the buffer.
  @param [in] Length  Length of the field.
**/
VOID
EFIAPI
Dump12Chars (
  IN CONST CHAR16  *Format OPTIONAL,
  IN       UINT8   *Ptr,
  IN UINT32        Length
  )
{
  Print (
    (Format != NULL) ? Format : L"%c%c%c%c%c%c%c%c%c%c%c%c",
    Ptr[0],
    Ptr[1],
    Ptr[2],
    Ptr[3],
    Ptr[4],
    Ptr[5],
    Ptr[6],
    Ptr[7],
    Ptr[8],
    Ptr[9],
    Ptr[10],
    Ptr[11]
    );
}

/**
  This function traces 16 characters which can be optionally
  formated using the format string if specified.

  If no format string is specified the Format must be NULL.

  @param [in] Format  Optional format string for tracing the data.
  @param [in] Ptr     Pointer to the start of the buffer.
  @param [in] Length  Length of the field.
**/
VOID
EFIAPI
Dump16Chars (
  IN CONST CHAR16  *Format OPTIONAL,
  IN UINT8         *Ptr,
  IN UINT32        Length
  )
{
  Print (
    (Format != NULL) ? Format : L"%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
    Ptr[0],
    Ptr[1],
    Ptr[2],
    Ptr[3],
    Ptr[4],
    Ptr[5],
    Ptr[6],
    Ptr[7],
    Ptr[8],
    Ptr[9],
    Ptr[10],
    Ptr[11],
    Ptr[12],
    Ptr[13],
    Ptr[14],
    Ptr[15]
    );
}

/**
  This function traces reserved fields up to 8 bytes in length.

  Format string is ignored by this function as the reserved field is printed
  byte by byte with intermittent spacing <eg: 0 0 0 0>. Use DumpxChars for any
  other use case.
  @param [in] Format  Optional format string for tracing the data.
  @param [in] Ptr     Pointer to the start of the buffer.
  @param [in] Length  Length of the field.
**/
VOID
EFIAPI
DumpReserved (
  IN CONST CHAR16  *Format OPTIONAL,
  IN UINT8         *Ptr,
  IN UINT32        Length
  )
{
  switch (Length) {
    case 8:
      Print (
        L"%u %u %u %u %u %u %u %u",
        Ptr[0],
        Ptr[1],
        Ptr[2],
        Ptr[3],
        Ptr[4],
        Ptr[5],
        Ptr[6],
        Ptr[7]
        );
      break;
    case 7:
      Print (
        L"%u %u %u %u %u %u %u",
        Ptr[0],
        Ptr[1],
        Ptr[2],
        Ptr[3],
        Ptr[4],
        Ptr[5],
        Ptr[6]
        );
      break;
    case 6:
      Print (
        L"%u %u %u %u %u %u",
        Ptr[0],
        Ptr[1],
        Ptr[2],
        Ptr[3],
        Ptr[4],
        Ptr[5]
        );
      break;
    case 5:
      Print (
        L"%u %u %u %u %u",
        Ptr[0],
        Ptr[1],
        Ptr[2],
        Ptr[3],
        Ptr[4]
        );
      break;
    case 4:
      Print (
        L"%u %u %u %u",
        Ptr[0],
        Ptr[1],
        Ptr[2],
        Ptr[3]
        );
      break;
    case 3:
      Print (
        L"%u %u %u",
        Ptr[0],
        Ptr[1],
        Ptr[2]
        );
      break;
    case 2:
      Print (
        L"%u %u",
        Ptr[0],
        Ptr[1]
        );
      break;
    case 1:
      Print (
        L"%u",
        Ptr[0]
        );
      break;
    default:
      return;
  }
}

/**
  This function traces reserved fields up to 64 bits in length.

  Format string is ignored by this function as the reserved field is printed
  byte by byte with intermittent spacing. eg: <0 0 0 0>. When the field length
  isn't a multiple of 8, the number of bytes are "ceil"-ed by one. eg for 27
  bits <0 0 0 0>

  @param [in] Format  Optional format string for tracing the data.
  @param [in] Ptr     Pointer to the start of the buffer.
  @param [in] Length  Length of the field as number of bits.
**/
VOID
EFIAPI
DumpReservedBits (
  IN CONST CHAR16  *Format OPTIONAL,
  IN UINT8         *Ptr,
  IN UINT32        Length
  )
{
  UINT32  ByteLength;

  ByteLength = (Length + 7) >> 3;
  DumpReserved (Format, Ptr, ByteLength);
}

/**
  This function validates reserved fields to check if they are 0.

  @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.
**/
VOID
EFIAPI
ValidateReserved (
  IN UINT8   *Ptr,
  IN UINT32  Length,
  IN VOID    *Context
  )
{
  while (Length > 0) {
    if (Ptr[Length - 1] != 0) {
      IncrementErrorCount ();
      Print (L"\nERROR : Reserved field must be 0\n");
      break;
    }

    Length--;
  }
}

/**
  This function validates bit-length reserved fields to check if they are 0.

  @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.
**/
VOID
EFIAPI
ValidateReservedBits (
  IN UINT8   *Ptr,
  IN UINT32  Length,
  IN VOID    *Context
  )
{
  UINT32  ByteLength;

  ByteLength = (Length + 7) >> 3;
  ValidateReserved (Ptr, ByteLength, Context);
}

/**
  This function indents and prints the ACPI table Field Name.

  @param [in] Indent      Number of spaces to add to the global table indent.
                          The global table indent is 0 by default; however
                          this value is updated on entry to the ParseAcpi()
                          by adding the indent value provided to ParseAcpi()
                          and restored back on exit.
                          Therefore the total indent in the output is
                          dependent on from where this function is called.
  @param [in] FieldName   Pointer to the Field Name.
**/
VOID
EFIAPI
PrintFieldName (
  IN UINT32        Indent,
  IN CONST CHAR16  *FieldName
  )
{
  Print (
    L"%*a%-*s : ",
    gIndent + Indent,
    "",
    (OUTPUT_FIELD_COLUMN_WIDTH - gIndent - Indent),
    FieldName
    );
}

/**
  This function is used to parse an ACPI table buffer.

  The ACPI table buffer is parsed using the ACPI table parser information
  specified by a pointer to an array of ACPI_PARSER elements. This parser
  function iterates through each item on the ACPI_PARSER array and logs the
  ACPI table fields.

  This function can optionally be used to parse ACPI tables and fetch specific
  field values. The ItemPtr member of the ACPI_PARSER structure (where used)
  is updated by this parser function to point to the selected field data
  (e.g. useful for variable length nested fields).

  @param [in] Trace        Trace the ACPI fields TRUE else only parse the
                           table.
  @param [in] Indent       Number of spaces to indent the output.
  @param [in] AsciiName    Optional pointer to an ASCII string that describes
                           the table being parsed.
  @param [in] Ptr          Pointer to the start of the buffer.
  @param [in] Length       Length of the buffer pointed by Ptr.
  @param [in] Parser       Pointer to an array of ACPI_PARSER structure that
                           describes the table being parsed.
  @param [in] ParserItems  Number of items in the ACPI_PARSER array.

  @retval Number of bytes parsed.
**/
UINT32
EFIAPI
ParseAcpi (
  IN BOOLEAN            Trace,
  IN UINT32             Indent,
  IN CONST CHAR8        *AsciiName OPTIONAL,
  IN UINT8              *Ptr,
  IN UINT32             Length,
  IN CONST ACPI_PARSER  *Parser,
  IN UINT32             ParserItems
  )
{
  UINT32   Index;
  UINT32   Offset;
  BOOLEAN  HighLight;
  UINTN    OriginalAttribute;

  //
  // set local variables to suppress incorrect compiler/analyzer warnings
  //
  OriginalAttribute = 0;
  Offset            = 0;

  // Increment the Indent
  gIndent += Indent;

  if (Trace && (AsciiName != NULL)) {
    HighLight = GetColourHighlighting ();

    if (HighLight) {
      OriginalAttribute = gST->ConOut->Mode->Attribute;
      gST->ConOut->SetAttribute (
                     gST->ConOut,
                     EFI_TEXT_ATTR (
                       EFI_YELLOW,
                       ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)
                       )
                     );
    }

    Print (
      L"%*a%-*a :\n",
      gIndent,
      "",
      (OUTPUT_FIELD_COLUMN_WIDTH - gIndent),
      AsciiName
      );
    if (HighLight) {
      gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);
    }
  }

  for (Index = 0; Index < ParserItems; Index++) {
    if ((Offset + Parser[Index].Length) > Length) {
      // For fields outside the buffer length provided, reset any pointers
      // which were supposed to be updated by this function call
      if (Parser[Index].ItemPtr != NULL) {
        *Parser[Index].ItemPtr = NULL;
      }

      // We don't parse past the end of the max length specified
      continue;
    }

    if (GetConsistencyChecking () &&
        (Offset != Parser[Index].Offset))
    {
      IncrementErrorCount ();
      Print (
        L"\nERROR: %a: Offset Mismatch for %s\n"
        L"CurrentOffset = %d FieldOffset = %d\n",
        AsciiName,
        Parser[Index].NameStr,
        Offset,
        Parser[Index].Offset
        );
    }

    if (Trace) {
      // if there is a Formatter function let the function handle
      // the printing else if a Format is specified in the table use
      // the Format for printing
      PrintFieldName (2, Parser[Index].NameStr);
      if (Parser[Index].PrintFormatter != NULL) {
        Parser[Index].PrintFormatter (Parser[Index].Format, Ptr, Parser[Index].Length);
      } else if (Parser[Index].Format != NULL) {
        switch (Parser[Index].Length) {
          case 1:
            DumpUint8 (Parser[Index].Format, Ptr);
            break;
          case 2:
            DumpUint16 (Parser[Index].Format, Ptr);
            break;
          case 4:
            DumpUint32 (Parser[Index].Format, Ptr);
            break;
          case 8:
            DumpUint64 (Parser[Index].Format, Ptr);
            break;
          default:
            Print (
              L"\nERROR: %a: CANNOT PARSE THIS FIELD, Field Length = %d\n",
              AsciiName,
              Parser[Index].Length
              );
        } // switch
      }

      // Validating only makes sense if we are tracing
      // the parsed table entries, to report by table name.
      if (GetConsistencyChecking () &&
          (Parser[Index].FieldValidator != NULL))
      {
        Parser[Index].FieldValidator (
                        Ptr,
                        Parser[Index].Length,
                        Parser[Index].Context
                        );
      }

      Print (L"\n");
    } // if (Trace)

    if (Parser[Index].ItemPtr != NULL) {
      *Parser[Index].ItemPtr = (VOID *)Ptr;
    }

    Ptr    += Parser[Index].Length;
    Offset += Parser[Index].Length;
  } // for

  // Decrement the Indent
  gIndent -= Indent;
  return Offset;
}

/**
  An array describing the ACPI Generic Address Structure.
  The GasParser array is used by the ParseAcpi function to parse and/or trace
  the GAS structure.
**/
STATIC CONST ACPI_PARSER  GasParser[] = {
  { L"Address Space ID",    1, 0, L"0x%x",  NULL, NULL, NULL, NULL },
  { L"Register Bit Width",  1, 1, L"0x%x",  NULL, NULL, NULL, NULL },
  { L"Register Bit Offset", 1, 2, L"0x%x",  NULL, NULL, NULL, NULL },
  { L"Access Size",         1, 3, L"0x%x",  NULL, NULL, NULL, NULL },
  { L"Address",             8, 4, L"0x%lx", NULL, NULL, NULL, NULL }
};

/**
  This function indents and traces the GAS structure as described by the GasParser.

  @param [in] Ptr     Pointer to the start of the buffer.
  @param [in] Indent  Number of spaces to indent the output.
  @param [in] Length  Length of the GAS structure buffer.

  @retval Number of bytes parsed.
**/
UINT32
EFIAPI
DumpGasStruct (
  IN UINT8   *Ptr,
  IN UINT32  Indent,
  IN UINT32  Length
  )
{
  Print (L"\n");
  return ParseAcpi (
           TRUE,
           Indent,
           NULL,
           Ptr,
           Length,
           PARSER_PARAMS (GasParser)
           );
}

/**
  This function traces the GAS structure as described by the GasParser.

  @param [in] Format  Optional format string for tracing the data.
  @param [in] Ptr     Pointer to the start of the buffer.
  @param [in] Length  Length of the field.
**/
VOID
EFIAPI
DumpGas (
  IN CONST CHAR16  *Format OPTIONAL,
  IN UINT8         *Ptr,
  IN UINT32        Length
  )
{
  DumpGasStruct (Ptr, 2, sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE));
}

/**
  This function traces the ACPI header as described by the AcpiHeaderParser.

  @param [in] Ptr          Pointer to the start of the buffer.

  @retval Number of bytes parsed.
**/
UINT32
EFIAPI
DumpAcpiHeader (
  IN UINT8  *Ptr
  )
{
  return ParseAcpi (
           TRUE,
           0,
           "ACPI Table Header",
           Ptr,
           sizeof (EFI_ACPI_DESCRIPTION_HEADER),
           PARSER_PARAMS (AcpiHeaderParser)
           );
}

/**
  This function parses the ACPI header as described by the AcpiHeaderParser.

  This function optionally returns the signature, length and revision of the
  ACPI table.

  @param [in]  Ptr        Pointer to the start of the buffer.
  @param [out] Signature  Gets location of the ACPI table signature.
  @param [out] Length     Gets location of the length of the ACPI table.
  @param [out] Revision   Gets location of the revision of the ACPI table.

  @retval Number of bytes parsed.
**/
UINT32
EFIAPI
ParseAcpiHeader (
  IN  UINT8         *Ptr,
  OUT CONST UINT32  **Signature,
  OUT CONST UINT32  **Length,
  OUT CONST UINT8   **Revision
  )
{
  UINT32  BytesParsed;

  BytesParsed = ParseAcpi (
                  FALSE,
                  0,
                  NULL,
                  Ptr,
                  sizeof (EFI_ACPI_DESCRIPTION_HEADER),
                  PARSER_PARAMS (AcpiHeaderParser)
                  );

  *Signature = AcpiHdrInfo.Signature;
  *Length    = AcpiHdrInfo.Length;
  *Revision  = AcpiHdrInfo.Revision;

  return BytesParsed;
}

/**
  This function is used to parse an ACPI table bitfield buffer.

  The ACPI table buffer is parsed using the ACPI table parser information
  specified by a pointer to an array of ACPI_PARSER elements. This parser
  function iterates through each item on the ACPI_PARSER array and logs the ACPI table bitfields.

  This function can optionally be used to parse ACPI tables and fetch specific
  field values. The ItemPtr member of the ACPI_PARSER structure (where used)
  is updated by this parser function to point to the selected field data
  (e.g. useful for variable length nested fields).

  ItemPtr member of ACPI_PARSER is not supported with this function.

  @param [in] Trace        Trace the ACPI fields TRUE else only parse the
                           table.
  @param [in] Indent       Number of spaces to indent the output.
  @param [in] AsciiName    Optional pointer to an ASCII string that describes
                           the table being parsed.
  @param [in] Ptr          Pointer to the start of the buffer.
  @param [in] Length       Length in bytes of the buffer pointed by Ptr.
  @param [in] Parser       Pointer to an array of ACPI_PARSER structure that
                           describes the table being parsed.
  @param [in] ParserItems  Number of items in the ACPI_PARSER array.

  @retval Number of bits parsed.
**/
UINT32
EFIAPI
ParseAcpiBitFields (
  IN BOOLEAN            Trace,
  IN UINT32             Indent,
  IN CONST CHAR8        *AsciiName OPTIONAL,
  IN UINT8              *Ptr,
  IN UINT32             Length,
  IN CONST ACPI_PARSER  *Parser,
  IN UINT32             ParserItems
  )
{
  UINT32   Index;
  UINT32   Offset;
  BOOLEAN  HighLight;
  UINTN    OriginalAttribute;

  UINT64  Data;
  UINT64  BitsData;

  if ((Length == 0) || (Length > 8)) {
    IncrementErrorCount ();
    Print (
      L"\nERROR: Bitfield Length(%d) is zero or exceeding the 64 bit limit.\n",
      Length
      );
    return 0;
  }

  //
  // set local variables to suppress incorrect compiler/analyzer warnings
  //
  OriginalAttribute = 0;
  Offset            = 0;

  // Increment the Indent
  gIndent += Indent;

  CopyMem ((VOID *)&BitsData, (VOID *)Ptr, Length);
  if (Trace && (AsciiName != NULL)) {
    HighLight = GetColourHighlighting ();

    if (HighLight) {
      OriginalAttribute = gST->ConOut->Mode->Attribute;
      gST->ConOut->SetAttribute (
                     gST->ConOut,
                     EFI_TEXT_ATTR (
                       EFI_YELLOW,
                       ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)
                       )
                     );
    }

    Print (
      L"%*a%-*a :\n",
      gIndent,
      "",
      (OUTPUT_FIELD_COLUMN_WIDTH - gIndent),
      AsciiName
      );
    if (HighLight) {
      gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);
    }
  }

  for (Index = 0; Index < ParserItems; Index++) {
    if ((Offset + Parser[Index].Length) > (Length * 8)) {
      // For fields outside the buffer length provided, reset any pointers
      // which were supposed to be updated by this function call
      if (Parser[Index].ItemPtr != NULL) {
        *Parser[Index].ItemPtr = NULL;
      }

      // We don't parse past the end of the max length specified
      continue;
    }

    if (Parser[Index].Length == 0) {
      IncrementErrorCount ();
      // don't parse the bitfield whose length is zero
      Print (
        L"\nERROR: %a: Cannot parse this field, Field Length = %d\n",
        Parser[Index].Length
        );
      continue;
    }

    if (GetConsistencyChecking () &&
        (Offset != Parser[Index].Offset))
    {
      IncrementErrorCount ();
      Print (
        L"\nERROR: %a: Offset Mismatch for %s\n"
        L"CurrentOffset = %d FieldOffset = %d\n",
        AsciiName,
        Parser[Index].NameStr,
        Offset,
        Parser[Index].Offset
        );
    }

    // extract Bitfield data for the current item
    Data = RShiftU64 (BitsData, Parser[Index].Offset) & ~(LShiftU64 (~0ULL, Parser[Index].Length));

    if (Trace) {
      // if there is a Formatter function let the function handle
      // the printing else if a Format is specified in the table use
      // the Format for printing
      PrintFieldName (2, Parser[Index].NameStr);
      if (Parser[Index].PrintFormatter != NULL) {
        Parser[Index].PrintFormatter (Parser[Index].Format, (UINT8 *)&Data, Parser[Index].Length);
      } else if (Parser[Index].Format != NULL) {
        // convert bit length to byte length
        switch ((Parser[Index].Length + 7) >> 3) {
          // print the data depends on byte size
          case 1:
            DumpUint8 (Parser[Index].Format, (UINT8 *)&Data);
            break;
          case 2:
            DumpUint16 (Parser[Index].Format, (UINT8 *)&Data);
            break;
          case 3:
          case 4:
            DumpUint32 (Parser[Index].Format, (UINT8 *)&Data);
            break;
          case 5:
          case 6:
          case 7:
          case 8:
            DumpUint64 (Parser[Index].Format, (UINT8 *)&Data);
            break;
          default:
            Print (
              L"\nERROR: %a: CANNOT PARSE THIS FIELD, Field Length = %d\n",
              AsciiName,
              Parser[Index].Length
              );
        } // switch
      }

      // Validating only makes sense if we are tracing
      // the parsed table entries, to report by table name.
      if (GetConsistencyChecking () &&
          (Parser[Index].FieldValidator != NULL))
      {
        Parser[Index].FieldValidator (
                        (UINT8 *)&Data,
                        Parser[Index].Length,
                        Parser[Index].Context
                        );
      }

      Print (L"\n");
    } // if (Trace)

    Offset += Parser[Index].Length;
  } // for

  // Decrement the Indent
  gIndent -= Indent;
  return Offset;
}
