diff options
Diffstat (limited to 'ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c')
| -rw-r--r-- | ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c | 1884 |
1 files changed, 942 insertions, 942 deletions
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c index eac9286176..63269b270d 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c @@ -1,942 +1,942 @@ -/** @file
- ACPI parser
-
- Copyright (c) 2016 - 2021, 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.
-**/
-VOID
-EFIAPI
-Dump3Chars (
- IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
- )
-{
- 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.
-**/
-VOID
-EFIAPI
-Dump4Chars (
- IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
- )
-{
- 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.
-**/
-VOID
-EFIAPI
-Dump6Chars (
- IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
- )
-{
- 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.
-**/
-VOID
-EFIAPI
-Dump8Chars (
- IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
- )
-{
- 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.
-**/
-VOID
-EFIAPI
-Dump12Chars (
- IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
- )
-{
- 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 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);
- } 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].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.
-**/
-VOID
-EFIAPI
-DumpGas (
- IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
- )
-{
- 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);
- } 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].Context);
- }
-
- Print (L"\n");
- } // if (Trace)
-
- Offset += Parser[Index].Length;
- } // for
-
- // Decrement the Indent
- gIndent -= Indent;
- return Offset;
-}
+/** @file + ACPI parser + + Copyright (c) 2016 - 2021, 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. +**/ +VOID +EFIAPI +Dump3Chars ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + 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. +**/ +VOID +EFIAPI +Dump4Chars ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + 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. +**/ +VOID +EFIAPI +Dump6Chars ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + 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. +**/ +VOID +EFIAPI +Dump8Chars ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + 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. +**/ +VOID +EFIAPI +Dump12Chars ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + 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 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); + } 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].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. +**/ +VOID +EFIAPI +DumpGas ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + 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); + } 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].Context); + } + + Print (L"\n"); + } // if (Trace) + + Offset += Parser[Index].Length; + } // for + + // Decrement the Indent + gIndent -= Indent; + return Offset; +} |
