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