summaryrefslogtreecommitdiffstats
path: root/ShellPkg/Library
diff options
context:
space:
mode:
Diffstat (limited to 'ShellPkg/Library')
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c662
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h759
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.c215
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h126
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c601
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.h103
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Bgrt/BgrtParser.c69
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c242
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dsdt/DsdtParser.c47
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c261
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Gtdt/GtdtParser.c293
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c700
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c313
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Mcfg/McfgParser.c94
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rsdp/RsdpParser.c169
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Slit/SlitParser.c142
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Spcr/SpcrParser.c168
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Srat/SratParser.c330
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Ssdt/SsdtParser.c47
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Xsdt/XsdtParser.c153
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c167
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.h32
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf74
-rw-r--r--ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni127
24 files changed, 5894 insertions, 0 deletions
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c
new file mode 100644
index 0000000000..318f386fda
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c
@@ -0,0 +1,662 @@
+/**
+ ACPI parser
+
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#include <Uefi.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include "AcpiParser.h"
+#include "AcpiView.h"
+
+STATIC UINT32 gIndent;
+STATIC UINT32 mTableErrorCount;
+STATIC UINT32 mTableWarningCount;
+
+/** 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 = 0;
+ UINT8 Checksum = 0;
+ UINTN OriginalAttribute;
+
+ 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"\n\nTable 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"\n\nTable 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 = 0;
+ UINTN PartLineChars;
+ UINTN AsciiBufferIndex = 0;
+ CHAR8 AsciiBuffer[17];
+
+ 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", 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 = *(UINT32*)(Ptr + sizeof (UINT32));
+ Val <<= 32;
+ Val |= *(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 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 = 0;
+
+ // Increment the Indent
+ gIndent += Indent;
+
+ if (Trace && (AsciiName != NULL)){
+ BOOLEAN HighLight = GetColourHighlighting ();
+ UINTN OriginalAttribute;
+
+ 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) {
+ // We don't parse past the end of the max length specified
+ break;
+ }
+
+ if (Offset != Parser[Index].Offset) {
+ IncrementErrorCount ();
+ Print (
+ L"\nERROR: %a: Offset Mismatch for %s\n"
+ "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 (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"Address 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.
+*/
+VOID
+EFIAPI
+DumpGasStruct (
+ IN UINT8* Ptr,
+ IN UINT32 Indent
+ )
+{
+ Print (L"\n");
+ ParseAcpi (
+ TRUE,
+ Indent,
+ NULL,
+ Ptr,
+ GAS_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);
+}
+
+/** 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
+ )
+{
+ ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
+ ACPI_PARSER AcpiHeaderParser[] = {
+ PARSE_ACPI_HEADER (&AcpiHdrInfo)
+ };
+
+ return ParseAcpi (
+ TRUE,
+ 0,
+ "ACPI Table Header",
+ Ptr,
+ ACPI_DESCRIPTION_HEADER_LENGTH,
+ 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;
+ ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
+ ACPI_PARSER AcpiHeaderParser[] = {
+ PARSE_ACPI_HEADER (&AcpiHdrInfo)
+ };
+
+ BytesParsed = ParseAcpi (
+ FALSE,
+ 0,
+ NULL,
+ Ptr,
+ ACPI_DESCRIPTION_HEADER_LENGTH,
+ PARSER_PARAMS (AcpiHeaderParser)
+ );
+
+ *Signature = AcpiHdrInfo.Signature;
+ *Length = AcpiHdrInfo.Length;
+ *Revision = AcpiHdrInfo.Revision;
+
+ return BytesParsed;
+}
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
new file mode 100644
index 0000000000..4dadd4d104
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h
@@ -0,0 +1,759 @@
+/**
+ Header file for ACPI parser
+
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#ifndef ACPIPARSER_H_
+#define ACPIPARSER_H_
+
+#define OUTPUT_FIELD_COLUMN_WIDTH 36
+
+/// The RSDP table signature is "RSD PTR " (8 bytes)
+/// However The signature for ACPI tables is 4 bytes.
+/// To work around this oddity define a signature type
+/// that allows us to process the log options.
+#define RSDP_TABLE_INFO SIGNATURE_32('R', 'S', 'D', 'P')
+
+/** This function increments the ACPI table error counter.
+*/
+VOID
+EFIAPI
+IncrementErrorCount (
+ VOID
+ );
+
+/** This function increments the ACPI table warning counter.
+*/
+VOID
+EFIAPI
+IncrementWarningCount (
+ VOID
+ );
+
+/** 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
+ );
+
+/** 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
+ );
+
+/** This function traces 1 byte of datum 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
+ );
+
+/** 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
+ );
+
+/** 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
+ );
+
+/** 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
+ );
+
+/** 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
+ );
+
+/** 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
+ );
+
+/** 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
+ );
+
+/** 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
+ );
+
+/** 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
+);
+
+/** This function pointer is the template for customizing the trace output
+
+ @param [in] Format Format string for tracing the data as specified by
+ the 'Format' member of ACPI_PARSER.
+ @param [in] Ptr Pointer to the start of the buffer.
+*/
+typedef VOID (EFIAPI *FNPTR_PRINT_FORMATTER)(CONST CHAR16* Format, UINT8* Ptr);
+
+/** This function pointer is the template for validating an ACPI table field.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Context Pointer to context specific information as specified by
+ the 'Context' member of the ACPI_PARSER.
+ e.g. this could be a pointer to the ACPI table header.
+*/
+typedef VOID (EFIAPI *FNPTR_FIELD_VALIDATOR)(UINT8* Ptr, VOID* Context);
+
+/** The ACPI_PARSER structure describes the fields of an ACPI table and
+ provides means for the parser to interpret and trace appropriately.
+
+ The first three members are populated based on information present in
+ in the ACPI table specifications. The remaining members describe how
+ the parser should report the field information, validate the field data
+ and/or update an external pointer to the field (ItemPtr).
+
+ ParseAcpi() uses the format string specified by 'Format' for tracing
+ the field data. If the field is more complex and requires additional
+ processing for formatting and representation a print formatter function
+ can be specified in 'PrintFormatter'.
+ The PrintFormatter function may choose to use the format string
+ specified by 'Format' or use its own internal format string.
+
+ The 'Format' and 'PrintFormatter' members allow flexibility for
+ representing the field data.
+*/
+typedef struct AcpiParser {
+
+ /// String describing the ACPI table field
+ /// (Field column from ACPI table spec)
+ CONST CHAR16* NameStr;
+
+ /// The length of the field.
+ /// (Byte Length column from ACPI table spec)
+ UINT32 Length;
+
+ /// The offset of the field from the start of the table.
+ /// (Byte Offset column from ACPI table spec)
+ UINT32 Offset;
+
+ /// Optional Print() style format string for tracing the data. If not
+ /// used this must be set to NULL.
+ CONST CHAR16* Format;
+
+ /// Optional pointer to a print formatter function which
+ /// is typically used to trace complex field information.
+ /// If not used this must be set to NULL.
+ /// The Format string is passed to the PrintFormatter function
+ /// but may be ignored by the implementation code.
+ FNPTR_PRINT_FORMATTER PrintFormatter;
+
+ /// Optional pointer which may be set to request the parser to update
+ /// a pointer to the field data. If unused this must be set to NULL.
+ VOID** ItemPtr;
+
+ /// Optional pointer to a field validator function.
+ /// The function should directly report any appropriate error or warning
+ /// and invoke the appropriate counter update function.
+ /// If not used this parameter must be set to NULL.
+ FNPTR_FIELD_VALIDATOR FieldValidator;
+
+ /// Optional pointer to context specific information,
+ /// which the Field Validator function can use to determine
+ /// additional information about the ACPI table and make
+ /// decisions about the field being validated.
+ /// e.g. this could be a pointer to the ACPI table header
+ VOID* Context;
+} ACPI_PARSER;
+
+/** A structure used to store the pointers to the members of the
+ ACPI description header structure that was parsed.
+*/
+typedef struct AcpiDescriptionHeaderInfo {
+ /// ACPI table signature
+ UINT32* Signature;
+ /// Length of the ACPI table
+ UINT32* Length;
+ /// Revision
+ UINT8* Revision;
+ /// Checksum
+ UINT8* Checksum;
+ /// OEM Id - length is 6 bytes
+ UINT8* OemId;
+ /// OEM table Id
+ UINT64* OemTableId;
+ /// OEM revision Id
+ UINT32* OemRevision;
+ /// Creator Id
+ UINT32* CreatorId;
+ /// Creator revision
+ UINT32* CreatorRevision;
+} ACPI_DESCRIPTION_HEADER_INFO;
+
+/** 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
+);
+
+/** This is a helper macro to pass parameters to the Parser functions.
+
+ @param [in] Parser The name of the ACPI_PARSER array describing the
+ ACPI table fields.
+*/
+#define PARSER_PARAMS(Parser) Parser, sizeof (Parser) / sizeof (Parser[0])
+
+/** This is a helper macro for describing the ACPI header fields.
+
+ @param [out] Info Pointer to retrieve the ACPI table header information.
+*/
+#define PARSE_ACPI_HEADER(Info) \
+ { L"Signature", 4, 0, NULL, Dump4Chars, \
+ (VOID**)&(Info)->Signature , NULL, NULL }, \
+ { L"Length", 4, 4, L"%d", NULL, \
+ (VOID**)&(Info)->Length, NULL, NULL }, \
+ { L"Revision", 1, 8, L"%d", NULL, \
+ (VOID**)&(Info)->Revision, NULL, NULL }, \
+ { L"Checksum", 1, 9, L"0x%X", NULL, \
+ (VOID**)&(Info)->Checksum, NULL, NULL }, \
+ { L"Oem ID", 6, 10, NULL, Dump6Chars, \
+ (VOID**)&(Info)->OemId, NULL, NULL }, \
+ { L"Oem Table ID", 8, 16, NULL, Dump8Chars, \
+ (VOID**)&(Info)->OemTableId, NULL, NULL }, \
+ { L"Oem Revision", 4, 24, L"0x%X", NULL, \
+ (VOID**)&(Info)->OemRevision, NULL, NULL }, \
+ { L"Creator ID", 4, 28, NULL, Dump4Chars, \
+ (VOID**)&(Info)->CreatorId, NULL, NULL }, \
+ { L"Creator Revision", 4, 32, L"0x%X", NULL, \
+ (VOID**)&(Info)->CreatorRevision, NULL, NULL }
+
+/** Length of the ACPI GAS structure.
+
+ NOTE: This might normally be defined as
+ sizeof (EFI_ACPI_6_2_GENERIC_ADDRESS_STRUCTURE).
+ However, we deliberately minimise any reference to the EDK2 ACPI
+ headers in an attempt to provide cross checking.
+*/
+#define GAS_LENGTH 12
+
+/** Length of the ACPI Header structure.
+
+ NOTE: This might normally be defined as
+ sizeof (EFI_ACPI_DESCRIPTION_HEADER).
+ However, we deliberately minimise any reference to the EDK2 ACPI
+ headers in an attempt to provide cross checking.
+*/
+#define ACPI_DESCRIPTION_HEADER_LENGTH 36
+
+/** 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.
+*/
+VOID
+EFIAPI
+DumpGasStruct (
+ IN UINT8* Ptr,
+ IN UINT32 Indent
+ );
+
+/** 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
+ );
+
+/** 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
+ );
+
+/** 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
+ );
+
+/** This function parses the ACPI BGRT table.
+ When trace is enabled this function parses the BGRT table and
+ traces the ACPI table fields.
+
+ This function also performs validation of the ACPI table fields.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiBgrt (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ );
+
+/** This function parses the ACPI DBG2 table.
+ When trace is enabled this function parses the DBG2 table and
+ traces the ACPI table fields.
+
+ This function also performs validation of the ACPI table fields.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiDbg2 (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ );
+
+/** This function parses the ACPI DSDT table.
+ When trace is enabled this function parses the DSDT table and
+ traces the ACPI table fields.
+ For the DSDT table only the ACPI header fields are parsed and
+ traced.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiDsdt (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ );
+
+/** This function parses the ACPI FADT table.
+ This function parses the FADT table and optionally traces the ACPI
+ table fields.
+
+ This function also performs validation of the ACPI table fields.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiFadt (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ );
+
+/** This function parses the ACPI GTDT table.
+ When trace is enabled this function parses the GTDT table and
+ traces the ACPI table fields.
+
+ This function also parses the following platform timer structures:
+ - GT Block timer
+ - Watchdog timer
+
+ This function also performs validation of the ACPI table fields.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiGtdt (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ );
+
+/** This function parses the ACPI IORT table.
+ When trace is enabled this function parses the IORT table and
+ traces the ACPI fields.
+
+ This function also parses the following nodes:
+ - ITS Group
+ - Named Component
+ - Root Complex
+ - SMMUv1/2
+ - SMMUv3
+ - PMCG
+
+ This function also performs validation of the ACPI table fields.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiIort (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ );
+
+/** This function parses the ACPI MADT table.
+ When trace is enabled this function parses the MADT table and
+ traces the ACPI table fields.
+
+ This function currently parses the following Interrupt Controller
+ Structures:
+ - GICC
+ - GICD
+ - GIC MSI Frame
+ - GICR
+ - GIC ITS
+
+ This function also performs validation of the ACPI table fields.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiMadt (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ );
+
+/** This function parses the ACPI MCFG table.
+ When trace is enabled this function parses the MCFG table and
+ traces the ACPI table fields.
+
+ This function also performs validation of the ACPI table fields.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiMcfg (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ );
+
+/** This function parses the ACPI RSDP table.
+
+ This function invokes the parser for the XSDT table.
+ * Note - This function does not support parsing of RSDT table.
+
+ This function also performs a RAW dump of the ACPI table and
+ validates the checksum.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiRsdp (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ );
+
+/** This function parses the ACPI SLIT table.
+ When trace is enabled this function parses the SLIT table and
+ traces the ACPI table fields.
+
+ This function also validates System Localities for the following:
+ - Diagonal elements have a normalized value of 10
+ - Relative distance from System Locality at i*N+j is same as
+ j*N+i
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiSlit (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ );
+
+/** This function parses the ACPI SPCR table.
+ When trace is enabled this function parses the SPCR table and
+ traces the ACPI table fields.
+
+ This function also performs validations of the ACPI table fields.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiSpcr (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ );
+
+/** This function parses the ACPI SRAT table.
+ When trace is enabled this function parses the SRAT table and
+ traces the ACPI table fields.
+
+ This function parses the following Resource Allocation Structures:
+ - Processor Local APIC/SAPIC Affinity Structure
+ - Memory Affinity Structure
+ - Processor Local x2APIC Affinity Structure
+ - GICC Affinity Structure
+
+ This function also performs validation of the ACPI table fields.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiSrat (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ );
+
+/** This function parses the ACPI SSDT table.
+ When trace is enabled this function parses the SSDT table and
+ traces the ACPI table fields.
+ For the SSDT table only the ACPI header fields are
+ parsed and traced.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiSsdt (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ );
+
+/** This function parses the ACPI XSDT table
+ and optionally traces the ACPI table fields.
+
+ This function also performs validation of the XSDT table.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiXsdt (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ );
+
+#endif // ACPIPARSER_H_
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.c
new file mode 100644
index 0000000000..14a8b14411
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.c
@@ -0,0 +1,215 @@
+/**
+ ACPI table parser
+
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#include <Uefi.h>
+#include <IndustryStandard/Acpi.h>
+#include <Library/UefiLib.h>
+#include "AcpiParser.h"
+#include "AcpiTableParser.h"
+#include "AcpiView.h"
+
+/** A list of registered ACPI table parsers.
+*/
+STATIC ACPI_TABLE_PARSER mTableParserList[MAX_ACPI_TABLE_PARSERS];
+
+/** Register the ACPI table Parser
+
+ This function registers the ACPI table parser.
+
+ @param [in] Signature The ACPI table signature.
+ @param [in] ParserProc The ACPI table parser.
+
+ @retval EFI_SUCCESS The parser is registered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_ALREADY_STARTED The parser for the Table
+ was already registered.
+ @retval EFI_OUT_OF_RESOURCES No space to register the
+ parser.
+*/
+EFI_STATUS
+EFIAPI
+RegisterParser (
+ IN UINT32 Signature,
+ IN PARSE_ACPI_TABLE_PROC ParserProc
+ )
+{
+ UINT32 index;
+
+ if ((ParserProc == NULL) || (Signature == ACPI_PARSER_SIGNATURE_NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Search if a parser is already installed
+ for (index = 0;
+ index < (sizeof (mTableParserList) / sizeof (mTableParserList[0]));
+ index++)
+ {
+ if (Signature == mTableParserList[index].Signature) {
+ if (mTableParserList[index].Parser != NULL) {
+ return EFI_ALREADY_STARTED;
+ }
+ }
+ }
+
+ // Find the first free slot and register the parser
+ for (index = 0;
+ index < (sizeof (mTableParserList) / sizeof (mTableParserList[0]));
+ index++)
+ {
+ if (mTableParserList[index].Signature == ACPI_PARSER_SIGNATURE_NULL) {
+ mTableParserList[index].Signature = Signature;
+ mTableParserList[index].Parser = ParserProc;
+ return EFI_SUCCESS;
+ }
+ }
+
+ // No free slot found
+ return EFI_OUT_OF_RESOURCES;
+}
+
+/** Deregister the ACPI table Parser
+
+ This function deregisters the ACPI table parser.
+
+ @param [in] Signature The ACPI table signature.
+
+ @retval EFI_SUCCESS The parser was deregistered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND A registered parser was not found.
+*/
+EFI_STATUS
+EFIAPI
+DeregisterParser (
+ IN UINT32 Signature
+ )
+{
+ UINT32 index;
+
+ if (Signature == ACPI_PARSER_SIGNATURE_NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for (index = 0;
+ index < (sizeof (mTableParserList) / sizeof (mTableParserList[0]));
+ index++)
+ {
+ if (Signature == mTableParserList[index].Signature) {
+ mTableParserList[index].Signature = ACPI_PARSER_SIGNATURE_NULL;
+ mTableParserList[index].Parser = NULL;
+ return EFI_SUCCESS;
+ }
+ }
+
+ // No matching registered parser found.
+ return EFI_NOT_FOUND;
+}
+
+/** Get the ACPI table Parser
+
+ This function returns the ACPI table parser proc from the list of
+ registered parsers.
+
+ @param [in] Signature The ACPI table signature.
+ @param [out] ParserProc Pointer to a ACPI table parser proc.
+
+ @retval EFI_SUCCESS The parser was returned successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND A registered parser was not found.
+*/
+EFI_STATUS
+EFIAPI
+GetParser (
+ IN UINT32 Signature,
+ OUT PARSE_ACPI_TABLE_PROC * ParserProc
+ )
+{
+ UINT32 index;
+
+ if ((ParserProc == NULL) || (Signature == ACPI_PARSER_SIGNATURE_NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for (index = 0;
+ index < (sizeof (mTableParserList) / sizeof (mTableParserList[0]));
+ index++)
+ {
+ if (Signature == mTableParserList[index].Signature) {
+ *ParserProc = mTableParserList[index].Parser;
+ return EFI_SUCCESS;
+ }
+ }
+
+ // No matching registered parser found.
+ return EFI_NOT_FOUND;
+}
+
+/** This function processes the ACPI tables.
+ This function calls ProcessTableReportOptions() to list the ACPI
+ tables, perform binary dump of the tables and determine if the
+ ACPI fields should be traced.
+
+ This function also invokes the parser for the ACPI tables.
+
+ This function also performs a RAW dump of the ACPI table including
+ the unknown/unparsed ACPI tables and validates the checksum.
+
+ @param [in] Ptr Pointer to the start of the ACPI
+ table data buffer.
+*/
+VOID
+EFIAPI
+ProcessAcpiTable (
+ IN UINT8* Ptr
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN Trace;
+ CONST UINT32* AcpiTableSignature;
+ CONST UINT32* AcpiTableLength;
+ CONST UINT8* AcpiTableRevision;
+ PARSE_ACPI_TABLE_PROC ParserProc;
+
+ ParseAcpiHeader (
+ Ptr,
+ &AcpiTableSignature,
+ &AcpiTableLength,
+ &AcpiTableRevision
+ );
+
+ Trace = ProcessTableReportOptions (
+ *AcpiTableSignature,
+ Ptr,
+ *AcpiTableLength
+ );
+
+ if (Trace) {
+ DumpRaw (Ptr, *AcpiTableLength);
+ VerifyChecksum (TRUE, Ptr, *AcpiTableLength);
+ }
+
+ Status = GetParser (*AcpiTableSignature, &ParserProc);
+ if (EFI_ERROR (Status)) {
+ // No registered parser found, do default handling.
+ if (Trace) {
+ DumpAcpiHeader (Ptr);
+ }
+ return;
+ }
+
+ ParserProc (
+ Trace,
+ Ptr,
+ *AcpiTableLength,
+ *AcpiTableRevision
+ );
+}
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
new file mode 100644
index 0000000000..a69d56da6c
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h
@@ -0,0 +1,126 @@
+/**
+ Header file for ACPI table parser
+
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#ifndef ACPITABLEPARSER_H_
+#define ACPITABLEPARSER_H_
+
+/** The maximum number of ACPI table parsers.
+*/
+#define MAX_ACPI_TABLE_PARSERS 16
+
+/** An invalid/NULL signature value.
+*/
+#define ACPI_PARSER_SIGNATURE_NULL 0
+
+/** A function that parses the ACPI table.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+typedef
+VOID
+(EFIAPI * PARSE_ACPI_TABLE_PROC) (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ );
+
+/** The ACPI table parser information
+*/
+typedef struct AcpiTableParser {
+ /// ACPI table signature
+ UINT32 Signature;
+
+ /// The ACPI table parser function.
+ PARSE_ACPI_TABLE_PROC Parser;
+} ACPI_TABLE_PARSER;
+
+/** Register the ACPI table Parser
+
+ This function registers the ACPI table parser.
+
+ @param [in] Signature The ACPI table signature.
+ @param [in] ParserProc The ACPI table parser.
+
+ @retval EFI_SUCCESS The parser is registered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_ALREADY_STARTED The parser for the Table
+ was already registered.
+ @retval EFI_OUT_OF_RESOURCES No space to register the
+ parser.
+*/
+EFI_STATUS
+EFIAPI
+RegisterParser (
+ IN UINT32 Signature,
+ IN PARSE_ACPI_TABLE_PROC ParserProc
+);
+
+/** Deregister the ACPI table Parser
+
+ This function deregisters the ACPI table parser.
+
+ @param [in] Signature The ACPI table signature.
+
+ @retval EFI_SUCCESS The parser was deregistered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND A registered parser was not found.
+*/
+EFI_STATUS
+EFIAPI
+DeregisterParser (
+ IN UINT32 Signature
+);
+
+/** This function processes the ACPI tables.
+ This function calls ProcessTableReportOptions() to list the ACPI
+ tables, perform binary dump of the tables and determine if the
+ ACPI fields should be traced.
+
+ This function also invokes the parser for the ACPI tables.
+
+ This function also performs a RAW dump of the ACPI table including
+ the unknown/unparsed ACPI tables and validates the checksum.
+
+ @param [in] Ptr Pointer to the start of the ACPI
+ table data buffer.
+*/
+VOID
+EFIAPI
+ProcessAcpiTable (
+ IN UINT8* Ptr
+ );
+
+/** Get the ACPI table Parser
+
+ This function returns the ACPI table parser proc from the list of
+ registered parsers.
+
+ @param [in] Signature The ACPI table signature.
+ @param [out] ParserProc Pointer to a ACPI table parser proc.
+
+ @retval EFI_SUCCESS The parser was returned successfully.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_NOT_FOUND A registered parser was not found.
+*/
+EFI_STATUS
+EFIAPI
+GetParser (
+ IN UINT32 Signature,
+ OUT PARSE_ACPI_TABLE_PROC * ParserProc
+ );
+
+#endif // ACPITABLEPARSER_H_
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c
new file mode 100644
index 0000000000..3bb142538c
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c
@@ -0,0 +1,601 @@
+/**
+
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#include <Library/PrintLib.h>
+#include <Library/UefiLib.h>
+#include <Library/ShellLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include "AcpiParser.h"
+#include "AcpiTableParser.h"
+#include "AcpiView.h"
+#include "UefiShellAcpiViewCommandLib.h"
+
+EFI_HII_HANDLE gShellAcpiViewHiiHandle = NULL;
+
+// Report variables
+STATIC UINT32 mSelectedAcpiTable;
+STATIC CONST CHAR16* mSelectedAcpiTableName;
+STATIC BOOLEAN mSelectedAcpiTableFound;
+STATIC EREPORT_OPTION mReportType;
+STATIC UINT32 mTableCount;
+STATIC UINT32 mBinTableCount;
+STATIC BOOLEAN mVerbose;
+STATIC BOOLEAN mConsistencyCheck;
+STATIC BOOLEAN mColourHighlighting;
+
+/** An array of acpiview command line parameters.
+*/
+STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
+ {L"/?", TypeFlag},
+ {L"-c", TypeFlag},
+ {L"-d", TypeFlag},
+ {L"-h", TypeValue},
+ {L"-l", TypeFlag},
+ {L"-s", TypeValue},
+ {L"-v", TypeFlag},
+ {NULL, TypeMax}
+};
+
+/** This function returns the colour highlighting status.
+
+ @retval TRUE if colour highlighting is enabled.
+*/
+BOOLEAN
+GetColourHighlighting (
+ VOID
+ )
+{
+ return mColourHighlighting;
+}
+
+/** This function sets the colour highlighting status.
+
+*/
+VOID
+SetColourHighlighting (
+ BOOLEAN Highlight
+ )
+{
+ mColourHighlighting = Highlight;
+}
+
+/** This function returns the report options.
+
+ @retval Returns the report option.
+*/
+STATIC
+EREPORT_OPTION
+GetReportOption (
+ VOID
+ )
+{
+ return mReportType;
+}
+
+/** This function returns the selected ACPI table.
+
+ @retval Returns signature of the selected ACPI table.
+*/
+STATIC
+UINT32
+GetSelectedAcpiTable (
+ VOID
+ )
+{
+ return mSelectedAcpiTable;
+}
+
+/** This function dumps the ACPI table to a file.
+ @param [in] Ptr Pointer to the ACPI table data.
+ @param [in] Length The length of the ACPI table.
+
+ @retval TRUE Success.
+ @retval FALSE Failure.
+*/
+STATIC
+BOOLEAN
+DumpAcpiTableToFile (
+ IN CONST UINT8* Ptr,
+ IN CONST UINTN Length
+ )
+{
+ EFI_STATUS Status;
+ CHAR16 FileNameBuffer[MAX_FILE_NAME_LEN];
+ SHELL_FILE_HANDLE DumpFileHandle = NULL;
+ UINTN TransferBytes = Length;
+
+ UnicodeSPrint (
+ FileNameBuffer,
+ sizeof (FileNameBuffer),
+ L".\\%s%04d.bin",
+ mSelectedAcpiTableName,
+ mBinTableCount++
+ );
+
+ Status = ShellOpenFileByName (
+ FileNameBuffer,
+ &DumpFileHandle,
+ EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE,
+ 0
+ );
+ if (EFI_ERROR (Status)) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_READONLY_MEDIA),
+ gShellAcpiViewHiiHandle,
+ L"acpiview"
+ );
+ return FALSE;
+ }
+
+ Print (L"Dumping ACPI table to : %s ... ", FileNameBuffer);
+
+ Status = ShellWriteFile (
+ DumpFileHandle,
+ &TransferBytes,
+ (VOID*)Ptr
+ );
+ if (EFI_ERROR (Status)) {
+ Print (L"ERROR: Failed to dump table to binary file.\n");
+ TransferBytes = 0;
+ } else {
+ Print (L"DONE.\n");
+ }
+
+ ShellCloseFile (&DumpFileHandle);
+ return (Length == TransferBytes);
+}
+
+/** This function processes the table reporting options for the ACPI table.
+
+ @param [in] Signature The ACPI table Signature.
+ @param [in] TablePtr Pointer to the ACPI table data.
+ @param [in] Length The length fo the ACPI table.
+
+ @retval Returns TRUE if the ACPI table should be traced.
+*/
+BOOLEAN
+ProcessTableReportOptions (
+ IN CONST UINT32 Signature,
+ IN CONST UINT8* TablePtr,
+ IN CONST UINT32 Length
+ )
+{
+ UINTN OriginalAttribute;
+ UINT8* SignaturePtr = (UINT8*)(UINTN)&Signature;
+ BOOLEAN Log = FALSE;
+ BOOLEAN HighLight = GetColourHighlighting ();
+ switch (GetReportOption ()) {
+ case EREPORT_ALL:
+ Log = TRUE;
+ break;
+ case EREPORT_SELECTED:
+ if (Signature == GetSelectedAcpiTable ()) {
+ Log = TRUE;
+ mSelectedAcpiTableFound = TRUE;
+ }
+ break;
+ case EREPORT_TABLE_LIST:
+ if (mTableCount == 0) {
+ if (HighLight) {
+ OriginalAttribute = gST->ConOut->Mode->Attribute;
+ gST->ConOut->SetAttribute (
+ gST->ConOut,
+ EFI_TEXT_ATTR(EFI_CYAN,
+ ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))
+ );
+ }
+ Print (L"\nInstalled Table(s):\n");
+ if (HighLight) {
+ gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);
+ }
+ }
+ Print (
+ L"\t%4d. %c%c%c%c\n",
+ ++mTableCount,
+ SignaturePtr[0],
+ SignaturePtr[1],
+ SignaturePtr[2],
+ SignaturePtr[3]
+ );
+ break;
+ case EREPORT_DUMP_BIN_FILE:
+ if (Signature == GetSelectedAcpiTable ()) {
+ mSelectedAcpiTableFound = TRUE;
+ DumpAcpiTableToFile (TablePtr, Length);
+ }
+ break;
+ case EREPORT_MAX:
+ // We should never be here.
+ // This case is only present to prevent compiler warning.
+ break;
+ } // switch
+
+ if (Log) {
+ if (HighLight) {
+ OriginalAttribute = gST->ConOut->Mode->Attribute;
+ gST->ConOut->SetAttribute (
+ gST->ConOut,
+ EFI_TEXT_ATTR(EFI_LIGHTBLUE,
+ ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4))
+ );
+ }
+ Print (
+ L"\n\n --------------- %c%c%c%c Table --------------- \n\n",
+ SignaturePtr[0],
+ SignaturePtr[1],
+ SignaturePtr[2],
+ SignaturePtr[3]
+ );
+ if (HighLight) {
+ gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);
+ }
+ }
+
+ return Log;
+}
+
+/** This function converts a string to ACPI table signature.
+
+ @param [in] Str Pointer to the string to be converted to the
+ ACPI table signature.
+
+ @retval The ACPI table signature.
+*/
+STATIC
+UINT32
+ConvertStrToAcpiSignature (
+ IN CONST CHAR16* Str
+ )
+{
+ UINT8 Index = 0;
+ CHAR8 Ptr[4];
+
+ // Convert to Upper case and convert to ASCII
+ while ((Index < 4) && (Str[Index] != 0)) {
+ if (Str[Index] >= L'a' && Str[Index] <= L'z') {
+ Ptr[Index] = (CHAR8)(Str[Index] - (L'a' - L'A'));
+ } else {
+ Ptr[Index] = (CHAR8)Str[Index];
+ }
+ Index++;
+ }
+ return *(UINT32*)Ptr;
+}
+
+/** This function iterates the configuration table entries in the
+ system table, retrieves the RSDP pointer and starts parsing
+ the ACPI tables.
+
+ @param [in] SystemTable Pointer to the EFI system table.
+
+ @retval Returns EFI_NOT_FOUND if the RSDP pointer is not found.
+ Returns EFI_UNSUPPORTED if the RSDP version is less than 2.
+ Returns EFI_SUCCESS if successful.
+*/
+STATIC
+EFI_STATUS
+EFIAPI
+AcpiView (
+ IN EFI_SYSTEM_TABLE* SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ EFI_CONFIGURATION_TABLE* EfiConfigurationTable;
+ BOOLEAN FoundAcpiTable;
+ UINTN OriginalAttribute;
+ UINTN PrintAttribute;
+ EREPORT_OPTION ReportOption;
+ UINT8* RsdpPtr;
+ UINT32 RsdpLength;
+ UINT8 RsdpRevision;
+ PARSE_ACPI_TABLE_PROC RsdpParserProc;
+ BOOLEAN Trace;
+
+ // Search the table for an entry that matches the ACPI Table Guid
+ FoundAcpiTable = FALSE;
+ for (Index = 0; Index < SystemTable->NumberOfTableEntries; Index++) {
+ if (CompareGuid (&gEfiAcpiTableGuid,
+ &(SystemTable->ConfigurationTable[Index].VendorGuid))) {
+ EfiConfigurationTable = &SystemTable->ConfigurationTable[Index];
+ FoundAcpiTable = TRUE;
+ break;
+ }
+ }
+
+ if (FoundAcpiTable) {
+ RsdpPtr = (UINT8*)EfiConfigurationTable->VendorTable;
+
+ // The RSDP revision is 1 byte starting at offset 15
+ RsdpRevision = *(RsdpPtr + RSDP_REVISION_OFFSET);
+
+ if (RsdpRevision < 2) {
+ Print (
+ L"ERROR: RSDP version less than 2 is not supported.\n"
+ );
+ return EFI_UNSUPPORTED;
+ }
+
+ // The RSDP length is 4 bytes starting at offset 20
+ RsdpLength = *(UINT32*)(RsdpPtr + RSDP_LENGTH_OFFSET);
+
+ Trace = ProcessTableReportOptions (RSDP_TABLE_INFO, RsdpPtr, RsdpLength);
+
+ Status = GetParser (RSDP_TABLE_INFO, &RsdpParserProc);
+ if (EFI_ERROR (Status)) {
+ Print (
+ L"ERROR: No registered parser found for RSDP.\n"
+ );
+ return Status;
+ }
+
+ RsdpParserProc (
+ Trace,
+ RsdpPtr,
+ RsdpLength,
+ RsdpRevision
+ );
+
+ } else {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Failed to find ACPI Table Guid in System Configuration Table.\n"
+ );
+ return EFI_NOT_FOUND;
+ }
+
+ ReportOption = GetReportOption ();
+ if (EREPORT_TABLE_LIST != ReportOption) {
+ if (((EREPORT_SELECTED == ReportOption) ||
+ (EREPORT_DUMP_BIN_FILE == ReportOption)) &&
+ (!mSelectedAcpiTableFound)) {
+ Print (L"\nRequested ACPI Table not found.\n");
+ } else if (EREPORT_DUMP_BIN_FILE != ReportOption) {
+ OriginalAttribute = gST->ConOut->Mode->Attribute;
+
+ Print (L"\nTable Statistics:\n");
+
+ if (GetColourHighlighting ()) {
+ PrintAttribute = (GetErrorCount () > 0) ?
+ EFI_TEXT_ATTR (
+ EFI_RED,
+ ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)
+ ) :
+ OriginalAttribute;
+ gST->ConOut->SetAttribute (gST->ConOut, PrintAttribute);
+ }
+ Print (L"\t%d Error(s)\n", GetErrorCount ());
+
+ if (GetColourHighlighting ()) {
+ PrintAttribute = (GetWarningCount () > 0) ?
+ EFI_TEXT_ATTR (
+ EFI_RED,
+ ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)
+ ) :
+ OriginalAttribute;
+
+ gST->ConOut->SetAttribute (gST->ConOut, PrintAttribute);
+ }
+ Print (L"\t%d Warning(s)\n", GetWarningCount ());
+
+ if (GetColourHighlighting ()) {
+ gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);
+ }
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Function for 'acpiview' command.
+
+ @param[in] ImageHandle Handle to the Image (NULL if Internal).
+ @param[in] SystemTable Pointer to the System Table (NULL if Internal).
+*/
+SHELL_STATUS
+EFIAPI
+ShellCommandRunAcpiView (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE* SystemTable
+ )
+{
+ EFI_STATUS Status;
+ SHELL_STATUS ShellStatus = SHELL_SUCCESS;
+ LIST_ENTRY* Package = NULL;
+ CHAR16* ProblemParam;
+ CONST CHAR16* Temp;
+ CHAR8 ColourOption[8];
+ SHELL_FILE_HANDLE TmpDumpFileHandle = NULL;
+
+ // Set Defaults
+ mReportType = EREPORT_ALL;
+ mTableCount = 0;
+ mBinTableCount = 0;
+ mSelectedAcpiTable = 0;
+ mSelectedAcpiTableName = NULL;
+ mSelectedAcpiTableFound = FALSE;
+ mVerbose = TRUE;
+ mConsistencyCheck = TRUE;
+
+ // Reset The error/warning counters
+ ResetErrorCount ();
+ ResetWarningCount ();
+
+ Status = ShellCommandLineParse (ParamList, &Package, &ProblemParam, TRUE);
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_VOLUME_CORRUPTED && ProblemParam != NULL) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_PROBLEM),
+ gShellAcpiViewHiiHandle,
+ L"acpiview",
+ ProblemParam
+ );
+ FreePool (ProblemParam);
+ } else {
+ Print (L"acpiview: Error processing input parameter(s)\n");
+ }
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ if (ShellCommandLineGetCount (Package) > 1) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_TOO_MANY),
+ gShellAcpiViewHiiHandle,
+ L"acpiview"
+ );
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else if (ShellCommandLineGetFlag (Package, L"-?")) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GET_HELP_ACPIVIEW),
+ gShellAcpiViewHiiHandle,
+ L"acpiview"
+ );
+ } else if (ShellCommandLineGetFlag (Package, L"-s") &&
+ ShellCommandLineGetValue (Package, L"-s") == NULL) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_NO_VALUE),
+ gShellAcpiViewHiiHandle,
+ L"acpiview",
+ L"-s"
+ );
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else if ((ShellCommandLineGetFlag (Package, L"-s") &&
+ ShellCommandLineGetFlag (Package, L"-l"))) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_TOO_MANY),
+ gShellAcpiViewHiiHandle,
+ L"acpiview"
+ );
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else if (ShellCommandLineGetFlag (Package, L"-h") &&
+ ShellCommandLineGetValue (Package, L"-h") == NULL) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_NO_VALUE),
+ gShellAcpiViewHiiHandle,
+ L"acpiview",
+ L"-h"
+ );
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else if (ShellCommandLineGetFlag (Package, L"-d") &&
+ !ShellCommandLineGetFlag (Package, L"-s")) {
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_MISSING_OPTION),
+ gShellAcpiViewHiiHandle,
+ L"acpiview",
+ L"-s",
+ L"-d"
+ );
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ } else {
+ // Check if the colour option is set
+ Temp = ShellCommandLineGetValue (Package, L"-h");
+ if (Temp != NULL) {
+ UnicodeStrToAsciiStrS (Temp, ColourOption, sizeof (ColourOption));
+ if ((AsciiStriCmp (ColourOption, "ON") == 0) ||
+ (AsciiStriCmp (ColourOption, "TRUE") == 0)) {
+ SetColourHighlighting (TRUE);
+ } else if ((AsciiStriCmp (ColourOption, "OFF") == 0) ||
+ (AsciiStriCmp (ColourOption, "FALSE") == 0)) {
+ SetColourHighlighting (FALSE);
+ }
+ }
+
+ if (ShellCommandLineGetFlag (Package, L"-l")) {
+ mReportType = EREPORT_TABLE_LIST;
+ } else {
+ mSelectedAcpiTableName = ShellCommandLineGetValue (Package, L"-s");
+ if (mSelectedAcpiTableName != NULL) {
+ mSelectedAcpiTable = (UINT32)ConvertStrToAcpiSignature (
+ mSelectedAcpiTableName
+ );
+ mReportType = EREPORT_SELECTED;
+
+ if (ShellCommandLineGetFlag (Package, L"-d")) {
+ // Create a temporary file to check if the media is writable.
+ CHAR16 FileNameBuffer[MAX_FILE_NAME_LEN];
+ mReportType = EREPORT_DUMP_BIN_FILE;
+
+ UnicodeSPrint (
+ FileNameBuffer,
+ sizeof (FileNameBuffer),
+ L".\\%s%04d.tmp",
+ mSelectedAcpiTableName,
+ mBinTableCount
+ );
+
+ Status = ShellOpenFileByName (
+ FileNameBuffer,
+ &TmpDumpFileHandle,
+ EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE |
+ EFI_FILE_MODE_CREATE,
+ 0
+ );
+
+ if (EFI_ERROR (Status)) {
+ ShellStatus = SHELL_INVALID_PARAMETER;
+ TmpDumpFileHandle = NULL;
+ ShellPrintHiiEx (
+ -1,
+ -1,
+ NULL,
+ STRING_TOKEN (STR_GEN_READONLY_MEDIA),
+ gShellAcpiViewHiiHandle,
+ L"acpiview"
+ );
+ goto Done;
+ }
+ // Delete Temporary file.
+ ShellDeleteFile (&TmpDumpFileHandle);
+ } // -d
+ } // -s
+ }
+
+ // Parse ACPI Table information
+ Status = AcpiView (SystemTable);
+ if (EFI_ERROR (Status)) {
+ ShellStatus = SHELL_NOT_FOUND;
+ }
+ }
+ }
+
+Done:
+ if (Package != NULL) {
+ ShellCommandLineFreeVarList (Package);
+ }
+ return ShellStatus;
+}
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.h
new file mode 100644
index 0000000000..03561ea816
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.h
@@ -0,0 +1,103 @@
+/**
+ Header file for AcpiView
+
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#ifndef ACPIVIEW_H_
+#define ACPIVIEW_H_
+
+/** A macro to define the max file name length
+*/
+#define MAX_FILE_NAME_LEN 128
+
+/** Offset to the RSDP revision from the start of the RSDP
+*/
+#define RSDP_REVISION_OFFSET 15
+
+/** Offset to the RSDP length from the start of the RSDP
+*/
+#define RSDP_LENGTH_OFFSET 20
+
+/** The EREPORT_OPTION enum describes ACPI table Reporting options.
+*/
+typedef enum ReportOption {
+ EREPORT_ALL, ///< Report All tables.
+ EREPORT_SELECTED, ///< Report Selected table.
+ EREPORT_TABLE_LIST, ///< Report List of tables.
+ EREPORT_DUMP_BIN_FILE, ///< Dump selected table to a file.
+ EREPORT_MAX
+} EREPORT_OPTION;
+
+/** This function resets the ACPI table error counter to Zero.
+*/
+VOID
+ResetErrorCount (
+ VOID
+ );
+
+/** This function returns the ACPI table error count.
+
+ @retval Returns the count of errors detected in the ACPI tables.
+*/
+UINT32
+GetErrorCount (
+ VOID
+ );
+
+/** This function resets the ACPI table warning counter to Zero.
+*/
+VOID
+ResetWarningCount (
+ VOID
+ );
+
+/** This function returns the ACPI table warning count.
+
+ @retval Returns the count of warning detected in the ACPI tables.
+*/
+UINT32
+GetWarningCount (
+ VOID
+ );
+
+/** This function returns the colour highlighting status.
+
+ @retval TRUE if colour highlighting is enabled.
+*/
+BOOLEAN
+GetColourHighlighting (
+ VOID
+ );
+
+/** This function sets the colour highlighting status.
+
+*/
+VOID
+SetColourHighlighting (
+ BOOLEAN Highlight
+ );
+
+/** This function processes the table reporting options for the ACPI table.
+
+ @param [in] Signature The ACPI table Signature.
+ @param [in] TablePtr Pointer to the ACPI table data.
+ @param [in] Length The length fo the ACPI table.
+
+ @retval Returns TRUE if the ACPI table should be traced.
+*/
+BOOLEAN
+ProcessTableReportOptions (
+ IN CONST UINT32 Signature,
+ IN CONST UINT8* TablePtr,
+ IN CONST UINT32 Length
+ );
+
+#endif // ACPIVIEW_H_
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Bgrt/BgrtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Bgrt/BgrtParser.c
new file mode 100644
index 0000000000..0b3f9a7901
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Bgrt/BgrtParser.c
@@ -0,0 +1,69 @@
+/**
+ BGRT table parser
+
+ Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Reference(s):
+ - ACPI 6.2 Specification - Errata A, September 2017
+**/
+
+#include <IndustryStandard/Acpi.h>
+#include <Library/UefiLib.h>
+#include "AcpiParser.h"
+#include "AcpiTableParser.h"
+
+// Local variables
+STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
+
+/** An ACPI_PARSER array describing the ACPI BDRT Table.
+*/
+STATIC CONST ACPI_PARSER BgrtParser[] = {
+ PARSE_ACPI_HEADER (&AcpiHdrInfo),
+ {L"Version", 2, 36, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Status", 1, 38, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Image Type", 1, 39, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Image Address", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL},
+ {L"Image Offset X", 4, 48, L"%d", NULL, NULL, NULL, NULL},
+ {L"Image Offset Y", 4, 52, L"%d", NULL, NULL, NULL, NULL}
+};
+
+/** This function parses the ACPI BGRT table.
+ When trace is enabled this function parses the BGRT table and
+ traces the ACPI table fields.
+
+ This function also performs validation of the ACPI table fields.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiBgrt (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ )
+{
+ if (!Trace) {
+ return;
+ }
+
+ ParseAcpi (
+ Trace,
+ 0,
+ "BGRT",
+ Ptr,
+ AcpiTableLength,
+ PARSER_PARAMS (BgrtParser)
+ );
+}
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c
new file mode 100644
index 0000000000..f70a1328cc
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c
@@ -0,0 +1,242 @@
+/**
+ DBG2 table parser
+
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Reference(s):
+ - Microsoft Debug Port Table 2 (DBG2) Specification - December 10, 2015.
+**/
+
+#include <IndustryStandard/DebugPort2Table.h>
+#include <Library/UefiLib.h>
+#include "AcpiParser.h"
+#include "AcpiTableParser.h"
+
+// Local variables pointing to the table fields
+STATIC CONST UINT32* OffsetDbgDeviceInfo;
+STATIC CONST UINT32* NumberDbgDeviceInfo;
+STATIC CONST UINT16* DbgDevInfoLen;
+STATIC CONST UINT8* GasCount;
+STATIC CONST UINT16* NameSpaceStringLength;
+STATIC CONST UINT16* NameSpaceStringOffset;
+STATIC CONST UINT16* OEMDataLength;
+STATIC CONST UINT16* OEMDataOffset;
+STATIC CONST UINT16* BaseAddrRegOffset;
+STATIC CONST UINT16* AddrSizeOffset;
+STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
+
+/** This function Validates the NameSpace string length.
+
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+*/
+STATIC
+VOID
+EFIAPI
+ValidateNameSpaceStrLen (
+ IN UINT8* Ptr,
+ IN VOID* Context
+ );
+
+/** This function parses the debug device information structure.
+
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [out] Length Pointer in which the length of the debug
+ device information is returned.
+*/
+STATIC
+VOID
+EFIAPI
+DumpDbgDeviceInfo (
+ IN UINT8* Ptr,
+ OUT UINT32* Length
+ );
+
+/// An ACPI_PARSER array describing the ACPI DBG2 table.
+STATIC CONST ACPI_PARSER Dbg2Parser[] = {
+ PARSE_ACPI_HEADER (&AcpiHdrInfo),
+ {L"OffsetDbgDeviceInfo", 4, 36, L"0x%x", NULL,
+ (VOID**)&OffsetDbgDeviceInfo, NULL, NULL},
+ {L"NumberDbgDeviceInfo", 4, 40, L"%d", NULL,
+ (VOID**)&NumberDbgDeviceInfo, NULL, NULL}
+};
+
+/// An ACPI_PARSER array describing the debug device information.
+STATIC CONST ACPI_PARSER DbgDevInfoParser[] = {
+ {L"Revision", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Length", 2, 1, L"%d", NULL, (VOID**)&DbgDevInfoLen, NULL, NULL},
+
+ {L"Generic Address Registers Count", 1, 3, L"0x%x", NULL,
+ (VOID**)&GasCount, NULL, NULL},
+ {L"NameSpace String Length", 2, 4, L"%d", NULL,
+ (VOID**)&NameSpaceStringLength, ValidateNameSpaceStrLen, NULL},
+ {L"NameSpace String Offset", 2, 6, L"0x%x", NULL,
+ (VOID**)&NameSpaceStringOffset, NULL, NULL},
+ {L"OEM Data Length", 2, 8, L"%d", NULL, (VOID**)&OEMDataLength,
+ NULL, NULL},
+ {L"OEM Data Offset", 2, 10, L"0x%x", NULL, (VOID**)&OEMDataOffset,
+ NULL, NULL},
+
+ {L"Port Type", 2, 12, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Port SubType", 2, 14, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Reserved", 2, 16, L"%x", NULL, NULL, NULL, NULL},
+
+ {L"Base Address Register Offset", 2, 18, L"0x%x", NULL,
+ (VOID**)&BaseAddrRegOffset, NULL, NULL},
+ {L"Address Size Offset", 2, 20, L"0x%x", NULL,
+ (VOID**)&AddrSizeOffset, NULL, NULL}
+};
+
+/** This function validates the NameSpace string length.
+
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+*/
+STATIC
+VOID
+EFIAPI
+ValidateNameSpaceStrLen (
+ IN UINT8* Ptr,
+ IN VOID* Context
+ )
+{
+ UINT16 NameSpaceStrLen = *(UINT16*)Ptr;
+ if (NameSpaceStrLen < 2) {
+ IncrementErrorCount ();
+ Print (
+ L"\nERROR: NamespaceString Length = %d. If no Namespace device exists,\n"
+ " then NamespaceString[] must contain a period '.'",
+ NameSpaceStrLen
+ );
+ }
+}
+
+/** This function parses the debug device information structure.
+
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [out] Ptr Pointer in which the length of the debug
+ device information is returned.
+*/
+STATIC
+VOID
+EFIAPI
+DumpDbgDeviceInfo (
+ IN UINT8* Ptr,
+ OUT UINT32* Length
+ )
+{
+ UINT16 Index;
+ UINT8* DataPtr;
+ UINT32* AddrSize;
+
+ // Parse the debug device info to get the Length
+ ParseAcpi (
+ FALSE,
+ 0,
+ "Debug Device Info",
+ Ptr,
+ 3, // Length is 2 bytes starting at offset 1
+ PARSER_PARAMS (DbgDevInfoParser)
+ );
+
+ ParseAcpi (
+ TRUE,
+ 2,
+ "Debug Device Info",
+ Ptr,
+ *DbgDevInfoLen,
+ PARSER_PARAMS (DbgDevInfoParser)
+ );
+
+ // GAS and Address Size
+ Index = 0;
+ DataPtr = Ptr + (*BaseAddrRegOffset);
+ AddrSize = (UINT32*)(Ptr + (*AddrSizeOffset));
+ while (Index < (*GasCount)) {
+ PrintFieldName (4, L"BaseAddressRegister");
+ DumpGasStruct (DataPtr, 4);
+ PrintFieldName (4, L"Address Size");
+ Print (L"0x%x\n", AddrSize[Index]);
+ DataPtr += GAS_LENGTH;
+ Index++;
+ }
+
+ // NameSpace String
+ Index = 0;
+ DataPtr = Ptr + (*NameSpaceStringOffset);
+ PrintFieldName (4, L"NameSpace String");
+ while (Index < (*NameSpaceStringLength)) {
+ Print (L"%c", DataPtr[Index++]);
+ }
+ Print (L"\n");
+
+ // OEM Data
+ Index = 0;
+ DataPtr = Ptr + (*OEMDataOffset);
+ PrintFieldName (4, L"OEM Data");
+ while (Index < (*OEMDataLength)) {
+ Print (L"%x ", DataPtr[Index++]);
+ if ((Index & 7) == 0) {
+ Print (L"\n%-*s ", OUTPUT_FIELD_COLUMN_WIDTH, L"");
+ }
+ }
+
+ *Length = *DbgDevInfoLen;
+}
+
+/** This function parses the ACPI DBG2 table.
+ When trace is enabled this function parses the DBG2 table and
+ traces the ACPI table fields.
+
+ This function also performs validation of the ACPI table fields.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiDbg2 (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ )
+{
+ UINT32 Offset;
+ UINT32 DbgDeviceInfoLength;
+ UINT8* DevInfoPtr;
+
+ if (!Trace) {
+ return;
+ }
+
+ Offset = ParseAcpi (
+ TRUE,
+ 0,
+ "DBG2",
+ Ptr,
+ AcpiTableLength,
+ PARSER_PARAMS (Dbg2Parser)
+ );
+ DevInfoPtr = Ptr + Offset;
+
+ while (Offset < AcpiTableLength) {
+ DumpDbgDeviceInfo (
+ DevInfoPtr,
+ &DbgDeviceInfoLength
+ );
+ Offset += DbgDeviceInfoLength;
+ DevInfoPtr += DbgDeviceInfoLength;
+ }
+}
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dsdt/DsdtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dsdt/DsdtParser.c
new file mode 100644
index 0000000000..ef459a1209
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dsdt/DsdtParser.c
@@ -0,0 +1,47 @@
+/**
+ DSDT table parser
+
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Reference(s):
+ - ACPI 6.2 Specification - Errata A, September 2017
+**/
+
+#include <IndustryStandard/Acpi.h>
+#include <Library/UefiLib.h>
+#include "AcpiParser.h"
+#include "AcpiTableParser.h"
+
+/** This function parses the ACPI DSDT table.
+ When trace is enabled this function parses the DSDT table and
+ traces the ACPI table fields.
+ For the DSDT table only the ACPI header fields are parsed and
+ traced.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiDsdt (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ )
+{
+ if (!Trace) {
+ return;
+ }
+
+ DumpAcpiHeader (Ptr);
+}
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c
new file mode 100644
index 0000000000..fdccb2ac3b
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c
@@ -0,0 +1,261 @@
+/**
+ FADT table parser
+
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Reference(s):
+ - ACPI 6.2 Specification - Errata A, September 2017
+**/
+
+#include <IndustryStandard/Acpi.h>
+#include <Library/UefiLib.h>
+#include "AcpiParser.h"
+#include "AcpiTableParser.h"
+
+// Local variables
+STATIC CONST UINT32* DsdtAddress;
+STATIC CONST UINT64* X_DsdtAddress;
+STATIC CONST UINT8* FadtMinorRevision;
+STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
+
+/** A macro defining the Hardware reduced ACPI flag
+*/
+#define HW_REDUCED_ACPI BIT20
+
+// Forward declarations
+CONST ACPI_DESCRIPTION_HEADER_INFO* CONST
+EFIAPI
+GetAcpiXsdtHeaderInfo (
+ VOID
+);
+
+STATIC
+VOID
+EFIAPI
+ValidateFirmwareCtrl (
+ IN UINT8* Ptr,
+ IN VOID* Context
+);
+
+STATIC
+VOID
+EFIAPI
+ValidateXFirmwareCtrl (
+ IN UINT8* Ptr,
+ IN VOID* Context
+);
+
+STATIC
+VOID
+EFIAPI
+ValidateFlags (
+ IN UINT8* Ptr,
+ IN VOID* Context
+);
+
+/** An ACPI_PARSER array describing the ACPI FADT Table.
+*/
+STATIC CONST ACPI_PARSER FadtParser[] = {
+ PARSE_ACPI_HEADER (&AcpiHdrInfo),
+ {L"FIRMWARE_CTRL", 4, 36, L"0x%x", NULL, NULL, ValidateFirmwareCtrl, NULL},
+ {L"DSDT", 4, 40, L"0x%x", NULL, (VOID**)&DsdtAddress, NULL, NULL},
+ {L"Reserved", 1, 44, L"%x", NULL, NULL, NULL, NULL},
+ {L"Preferred_PM_Profile", 1, 45, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"SCI_INT", 2, 46, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"SMI_CMD", 4, 48, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"ACPI_ENABLE", 1, 52, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"ACPI_DISABLE", 1, 53, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"S4BIOS_REQ", 1, 54, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"PSTATE_CNT", 1, 55, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"PM1a_EVT_BLK", 4, 56, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"PM1b_EVT_BLK", 4, 60, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"PM1a_CNT_BLK", 4, 64, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"PM1b_CNT_BLK", 4, 68, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"PM2_CNT_BLK", 4, 72, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"PM_TMR_BLK", 4, 76, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"GPE0_BLK", 4, 80, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"GPE1_BLK", 4, 84, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"PM1_EVT_LEN", 1, 88, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"PM1_CNT_LEN", 1, 89, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"PM2_CNT_LEN", 1, 90, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"PM_TMR_LEN", 1, 91, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"GPE0_BLK_LEN", 1, 92, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"GPE1_BLK_LEN", 1, 93, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"GPE1_BASE", 1, 94, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"CST_CNT", 1, 95, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"P_LVL2_LAT", 2, 96, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"P_LVL3_LAT", 2, 98, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"FLUSH_SIZE", 2, 100, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"FLUSH_STRIDE", 2, 102, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"DUTY_OFFSET", 1, 104, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"DUTY_WIDTH", 1, 105, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"DAY_ALRM", 1, 106, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"MON_ALRM", 1, 107, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"CENTURY", 1, 108, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"IAPC_BOOT_ARCH", 2, 109, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Reserved", 1, 111, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Flags", 4, 112, L"0x%x", NULL, NULL, ValidateFlags, NULL},
+ {L"RESET_REG", 12, 116, NULL, DumpGas, NULL, NULL, NULL},
+ {L"RESET_VALUE", 1, 128, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"ARM_BOOT_ARCH", 2, 129, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"FADT Minor Version", 1, 131, L"0x%x", NULL, (VOID**)&FadtMinorRevision,
+ NULL, NULL},
+ {L"X_FIRMWARE_CTRL", 8, 132, L"0x%lx", NULL, NULL,
+ ValidateXFirmwareCtrl, NULL},
+ {L"X_DSDT", 8, 140, L"0x%lx", NULL, (VOID**)&X_DsdtAddress, NULL, NULL},
+ {L"X_PM1a_EVT_BLK", 12, 148, NULL, DumpGas, NULL, NULL, NULL},
+ {L"X_PM1b_EVT_BLK", 12, 160, NULL, DumpGas, NULL, NULL, NULL},
+ {L"X_PM1a_CNT_BLK", 12, 172, NULL, DumpGas, NULL, NULL, NULL},
+ {L"X_PM1b_CNT_BLK", 12, 184, NULL, DumpGas, NULL, NULL, NULL},
+ {L"X_PM2_CNT_BLK", 12, 196, NULL, DumpGas, NULL, NULL, NULL},
+ {L"X_PM_TMR_BLK", 12, 208, NULL, DumpGas, NULL, NULL, NULL},
+ {L"X_GPE0_BLK", 12, 220, NULL, DumpGas, NULL, NULL, NULL},
+ {L"X_GPE1_BLK", 12, 232, NULL, DumpGas, NULL, NULL, NULL},
+ {L"SLEEP_CONTROL_REG", 12, 244, NULL, DumpGas, NULL, NULL, NULL},
+ {L"SLEEP_STATUS_REG", 12, 256, NULL, DumpGas, NULL, NULL, NULL},
+ {L"Hypervisor VendorIdentity", 8, 268, L"%lx", NULL, NULL, NULL, NULL}
+};
+
+/** This function validates the Firmware Control Field.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+*/
+STATIC
+VOID
+EFIAPI
+ValidateFirmwareCtrl (
+ IN UINT8* Ptr,
+ IN VOID* Context
+)
+{
+#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
+ if (*(UINT32*)Ptr != 0) {
+ IncrementErrorCount ();
+ Print (
+ L"\nERROR: Firmware Control must be zero for ARM platforms."
+ );
+ }
+#endif
+}
+
+/** This function validates the X_Firmware Control Field.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+*/
+STATIC
+VOID
+EFIAPI
+ValidateXFirmwareCtrl (
+ IN UINT8* Ptr,
+ IN VOID* Context
+)
+{
+#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
+ if (*(UINT64*)Ptr != 0) {
+ IncrementErrorCount ();
+ Print (
+ L"\nERROR: X Firmware Control must be zero for ARM platforms."
+ );
+ }
+#endif
+}
+
+/** This function validates the flags.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+*/
+STATIC
+VOID
+EFIAPI
+ValidateFlags (
+ IN UINT8* Ptr,
+ IN VOID* Context
+)
+{
+#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
+ if (((*(UINT32*)Ptr) & HW_REDUCED_ACPI) == 0) {
+ IncrementErrorCount ();
+ Print (
+ L"\nERROR: HW_REDUCED_ACPI flag must be set for ARM platforms."
+ );
+ }
+#endif
+}
+
+/** This function parses the ACPI FADT table.
+ This function parses the FADT table and optionally traces the ACPI
+ table fields.
+
+ This function also performs validation of the ACPI table fields.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiFadt (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ )
+{
+ UINT8* DsdtPtr;
+
+ ParseAcpi (
+ Trace,
+ 0,
+ "FADT",
+ Ptr,
+ AcpiTableLength,
+ PARSER_PARAMS (FadtParser)
+ );
+
+ if (Trace) {
+ Print (L"\nSummary:\n");
+ PrintFieldName (2, L"FADT Version");
+ Print (L"%d.%d\n", *AcpiHdrInfo.Revision, *FadtMinorRevision);
+
+ if (*GetAcpiXsdtHeaderInfo ()->OemTableId != *AcpiHdrInfo.OemTableId) {
+ IncrementErrorCount ();
+ Print (L"ERROR: OEM Table Id does not match with RSDT/XSDT.\n");
+ }
+ }
+
+ // If X_DSDT is not zero then use X_DSDT and ignore DSDT,
+ // else use DSDT.
+ if (*X_DsdtAddress != 0) {
+ DsdtPtr = (UINT8*)(UINTN)(*X_DsdtAddress);
+ } else if (*DsdtAddress != 0) {
+ DsdtPtr = (UINT8*)(UINTN)(*DsdtAddress);
+ } else {
+ // Both DSDT and X_DSDT cannot be zero.
+#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
+ if (Trace) {
+ // The DSDT Table is mandatory for ARM systems
+ // as the CPU information MUST be presented in
+ // the DSDT.
+ IncrementErrorCount ();
+ Print (L"ERROR: Both X_DSDT and DSDT are NULL.\n");
+ }
+#endif
+ return;
+ }
+
+ ProcessAcpiTable (DsdtPtr);
+}
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Gtdt/GtdtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Gtdt/GtdtParser.c
new file mode 100644
index 0000000000..ce96604ee6
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Gtdt/GtdtParser.c
@@ -0,0 +1,293 @@
+/**
+ GTDT table parser
+
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Reference(s):
+ - ACPI 6.2 Specification - Errata A, September 2017
+ **/
+
+#include <IndustryStandard/Acpi.h>
+#include <Library/UefiLib.h>
+#include "AcpiParser.h"
+#include "AcpiTableParser.h"
+
+// Local variables
+STATIC CONST UINT32* GtdtPlatformTimerCount;
+STATIC CONST UINT32* GtdtPlatformTimerOffset;
+STATIC CONST UINT8* PlatformTimerType;
+STATIC CONST UINT16* PlatformTimerLength;
+STATIC CONST UINT32* GtBlockTimerCount;
+STATIC CONST UINT32* GtBlockTimerOffset;
+STATIC CONST UINT16* GtBlockLength;
+STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
+
+/** This function validates the GT Block timer count.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+*/
+STATIC
+VOID
+EFIAPI
+ValidateGtBlockTimerCount (
+ IN UINT8* Ptr,
+ IN VOID* Context
+ );
+
+/** An ACPI_PARSER array describing the ACPI GTDT Table.
+*/
+STATIC CONST ACPI_PARSER GtdtParser[] = {
+ PARSE_ACPI_HEADER (&AcpiHdrInfo),
+ {L"CntControlBase Physical Address", 8, 36, L"0x%lx", NULL, NULL,
+ NULL, NULL},
+ {L"Reserved", 4, 44, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Secure EL1 timer GSIV", 4, 48, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Secure EL1 timer FLAGS", 4, 52, L"0x%x", NULL, NULL, NULL, NULL},
+
+ {L"Non-Secure EL1 timer GSIV", 4, 56, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Non-Secure EL1 timer FLAGS", 4, 60, L"0x%x", NULL, NULL, NULL, NULL},
+
+ {L"Virtual timer GSIV", 4, 64, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Virtual timer FLAGS", 4, 68, L"0x%x", NULL, NULL, NULL, NULL},
+
+ {L"Non-Secure EL2 timer GSIV", 4, 72, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Non-Secure EL2 timer FLAGS", 4, 76, L"0x%x", NULL, NULL, NULL, NULL},
+
+ {L"CntReadBase Physical address", 8, 80, L"0x%lx", NULL, NULL, NULL, NULL},
+ {L"Platform Timer Count", 4, 88, L"%d", NULL,
+ (VOID**)&GtdtPlatformTimerCount, NULL, NULL},
+ {L"Platform Timer Offset", 4, 92, L"0x%x", NULL,
+ (VOID**)&GtdtPlatformTimerOffset, NULL, NULL}
+};
+
+/** An ACPI_PARSER array describing the Platform timer header.
+*/
+STATIC CONST ACPI_PARSER GtPlatformTimerHeaderParser[] = {
+ {L"Type", 1, 0, NULL, NULL, (VOID**)&PlatformTimerType, NULL, NULL},
+ {L"Length", 2, 1, NULL, NULL, (VOID**)&PlatformTimerLength, NULL, NULL},
+ {L"Reserved", 1, 3, NULL, NULL, NULL, NULL, NULL}
+};
+
+/** An ACPI_PARSER array describing the Platform GT Block.
+*/
+STATIC CONST ACPI_PARSER GtBlockParser[] = {
+ {L"Type", 1, 0, L"%d", NULL, NULL, NULL, NULL},
+ {L"Length", 2, 1, L"%d", NULL, (VOID**)&GtBlockLength, NULL, NULL},
+ {L"Reserved", 1, 3, L"%x", NULL, NULL, NULL, NULL},
+ {L"Physical address (CntCtlBase)", 8, 4, L"0x%lx", NULL, NULL, NULL, NULL},
+ {L"Timer Count", 4, 12, L"%d", NULL, (VOID**)&GtBlockTimerCount,
+ ValidateGtBlockTimerCount, NULL},
+ {L"Timer Offset", 4, 16, L"%d", NULL, (VOID**)&GtBlockTimerOffset, NULL,
+ NULL}
+};
+
+/** An ACPI_PARSER array describing the GT Block timer.
+*/
+STATIC CONST ACPI_PARSER GtBlockTimerParser[] = {
+ {L"Frame Number", 1, 0, L"%d", NULL, NULL, NULL, NULL},
+ {L"Reserved", 3, 1, L"%x %x %x", Dump3Chars, NULL, NULL, NULL},
+ {L"Physical address (CntBaseX)", 8, 4, L"0x%lx", NULL, NULL, NULL, NULL},
+ {L"Physical address (CntEL0BaseX)", 8, 12, L"0x%lx", NULL, NULL, NULL,
+ NULL},
+ {L"Physical Timer GSIV", 4, 20, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Physical Timer Flags", 4, 24, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Virtual Timer GSIV", 4, 28, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Virtual Timer Flags", 4, 32, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Common Flags", 4, 36, L"0x%x", NULL, NULL, NULL, NULL}
+};
+
+/** An ACPI_PARSER array describing the Platform Watchdog.
+*/
+STATIC CONST ACPI_PARSER SBSAGenericWatchdogParser[] = {
+ {L"Type", 1, 0, L"%d", NULL, NULL, NULL, NULL},
+ {L"Length", 2, 1, L"%d", NULL, NULL, NULL, NULL},
+ {L"Reserved", 1, 3, L"%x", NULL, NULL, NULL, NULL},
+ {L"RefreshFrame Physical address", 8, 4, L"0x%lx", NULL, NULL, NULL, NULL},
+ {L"ControlFrame Physical address", 8, 12, L"0x%lx", NULL, NULL, NULL, NULL},
+ {L"Watchdog Timer GSIV", 4, 20, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Watchdog Timer Flags", 4, 24, L"0x%x", NULL, NULL, NULL, NULL}
+};
+
+/** This function validates the GT Block timer count.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+*/
+STATIC
+VOID
+EFIAPI
+ValidateGtBlockTimerCount (
+ IN UINT8* Ptr,
+ IN VOID* Context
+ )
+{
+ UINT32 BlockTimerCount = *(UINT32*)Ptr;
+ if (BlockTimerCount > 8) {
+ IncrementErrorCount ();
+ Print (
+ L"\nERROR: Timer Count = %d. Max Timer Count is 8.",
+ BlockTimerCount
+ );
+ }
+}
+
+/** This function parses the Platform GT Block.
+
+ @param [in] Ptr Pointer to the start of the GT Block data.
+ @param [in] Length Length of the GT Block structure.
+*/
+STATIC
+VOID
+DumpGTBlock (
+ IN UINT8* Ptr,
+ IN UINT16 Length
+ )
+{
+ UINT32 Index;
+ UINT32 Offset;
+ UINT16 GTBlockTimerLength;
+
+ Offset = ParseAcpi (
+ TRUE,
+ 2,
+ "GT Block",
+ Ptr,
+ Length,
+ PARSER_PARAMS (GtBlockParser)
+ );
+ GTBlockTimerLength = (*GtBlockLength - Offset) / (*GtBlockTimerCount);
+ Length -= Offset;
+
+ if (*GtBlockTimerCount != 0) {
+ Ptr += (*GtBlockTimerOffset);
+ Index = 0;
+ while ((Index < (*GtBlockTimerCount)) && (Length >= GTBlockTimerLength)) {
+ Offset = ParseAcpi (
+ TRUE,
+ 2,
+ "GT Block Timer",
+ Ptr,
+ GTBlockTimerLength,
+ PARSER_PARAMS (GtBlockTimerParser)
+ );
+ // Increment by GT Block Timer structure size
+ Ptr += Offset;
+ Length -= Offset;
+ Index++;
+ }
+
+ if (Length != 0) {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR:GT Block Timer length mismatch. Unparsed %d bytes.\n",
+ Length
+ );
+ }
+ }
+}
+
+/** This function parses the Platform Watchdog timer.
+
+ @param [in] Ptr Pointer to the start of the watchdog timer data.
+ @param [in] Length Length of the watchdog timer structure.
+*/
+STATIC
+VOID
+DumpWatchdogTimer (
+ IN UINT8* Ptr,
+ IN UINT16 Length
+ )
+{
+ ParseAcpi (
+ TRUE,
+ 2,
+ "SBSA Generic Watchdog",
+ Ptr,
+ Length,
+ PARSER_PARAMS (SBSAGenericWatchdogParser)
+ );
+}
+
+/** This function parses the ACPI GTDT table.
+ When trace is enabled this function parses the GTDT table and
+ traces the ACPI table fields.
+
+ This function also parses the following platform timer structures:
+ - GT Block timer
+ - Watchdog timer
+
+ This function also performs validation of the ACPI table fields.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiGtdt (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ )
+{
+ UINT32 Index;
+ UINT8* TimerPtr;
+
+ if (!Trace) {
+ return;
+ }
+
+ ParseAcpi (
+ TRUE,
+ 0,
+ "GTDT",
+ Ptr,
+ AcpiTableLength,
+ PARSER_PARAMS (GtdtParser)
+ );
+
+ if (*GtdtPlatformTimerCount != 0) {
+ TimerPtr = Ptr + (*GtdtPlatformTimerOffset);
+ Index = 0;
+ do {
+ // Parse the Platform Timer Header
+ ParseAcpi (
+ FALSE,
+ 0,
+ NULL,
+ TimerPtr,
+ 4, // GT Platform Timer structure header length.
+ PARSER_PARAMS (GtPlatformTimerHeaderParser)
+ );
+ switch (*PlatformTimerType) {
+ case EFI_ACPI_6_2_GTDT_GT_BLOCK:
+ DumpGTBlock (TimerPtr, *PlatformTimerLength);
+ break;
+ case EFI_ACPI_6_2_GTDT_SBSA_GENERIC_WATCHDOG:
+ DumpWatchdogTimer (TimerPtr, *PlatformTimerLength);
+ break;
+ default:
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: INVALID Platform Timer Type = %d\n",
+ *PlatformTimerType
+ );
+ break;
+ } // switch
+ TimerPtr += (*PlatformTimerLength);
+ Index++;
+ } while (Index < *GtdtPlatformTimerCount);
+ }
+}
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c
new file mode 100644
index 0000000000..503a745718
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c
@@ -0,0 +1,700 @@
+/**
+ IORT table parser
+
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Reference(s):
+ - IO Remapping Table, Platform Design Document, Revision C, 15 May 2017
+**/
+
+#include <IndustryStandard/IoRemappingTable.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiLib.h>
+#include "AcpiParser.h"
+#include "AcpiTableParser.h"
+
+// Local variables
+STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
+
+/** The EIORT_NODE enum describes the IORT Node types.
+*/
+typedef enum IortNode {
+ EIORT_NODE_ITS_GROUP, ///< ITS Group node
+ EIORT_NODE_NAMED_COMPONENT, ///< Named Component node
+ EIORT_NODE_ROOT_COMPLEX, ///< Root Complex node
+ EIORT_NODE_SMMUV1_V2, ///< SMMU v1/v2 node
+ EIORT_NODE_SMMUV3, ///< SMMU v3 node
+ EIORT_NODE_PMCG, ///< PMC group node
+ EIORT_NODE_MAX
+} EIORT_NODE;
+
+// Local Variables
+STATIC CONST UINT32* IortNodeCount;
+STATIC CONST UINT32* IortNodeOffset;
+
+STATIC CONST UINT8* IortNodeType;
+STATIC CONST UINT16* IortNodeLength;
+STATIC CONST UINT32* IortIdMappingCount;
+STATIC CONST UINT32* IortIdMappingOffset;
+
+STATIC CONST UINT32* InterruptContextCount;
+STATIC CONST UINT32* InterruptContextOffset;
+STATIC CONST UINT32* PmuInterruptCount;
+STATIC CONST UINT32* PmuInterruptOffset;
+
+STATIC CONST UINT32* ItsCount;
+
+/** This function validates the ID Mapping array count for the ITS node.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+*/
+STATIC
+VOID
+EFIAPI
+ValidateItsIdMappingCount (
+ IN UINT8* Ptr,
+ IN VOID* Context
+ );
+
+/** This function validates the ID Mapping array offset for the ITS node.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+*/
+STATIC
+VOID
+EFIAPI
+ValidateItsIdArrayReference (
+ IN UINT8* Ptr,
+ IN VOID* Context
+ );
+
+/** Helper Macro for populating the IORT Node header in the ACPI_PARSER
+ array.
+
+ @param [out] ValidateIdMappingCount Optional pointer to a function for
+ validating the ID Mapping count.
+ @param [out] ValidateIdArrayReference Optional pointer to a function for
+ validating the ID Array reference.
+*/
+#define PARSE_IORT_NODE_HEADER(ValidateIdMappingCount, \
+ ValidateIdArrayReference) \
+ { L"Type", 1, 0, L"%d", NULL, (VOID**)&IortNodeType, NULL, NULL }, \
+ { L"Length", 2, 1, L"%d", NULL, (VOID**)&IortNodeLength, NULL, NULL }, \
+ { L"Revision", 1, 3, L"%d", NULL, NULL, NULL, NULL }, \
+ { L"Reserved", 4, 4, L"0x%x", NULL, NULL, NULL, NULL }, \
+ { L"Number of ID mappings", 4, 8, L"%d", NULL, \
+ (VOID**)&IortIdMappingCount, ValidateIdMappingCount, NULL }, \
+ { L"Reference to ID Array", 4, 12, L"0x%x", NULL, \
+ (VOID**)&IortIdMappingOffset, ValidateIdArrayReference, NULL }
+
+/** An ACPI_PARSER array describing the ACPI IORT Table
+*/
+STATIC CONST ACPI_PARSER IortParser[] = {
+ PARSE_ACPI_HEADER (&AcpiHdrInfo),
+ {L"Number of IORT Nodes", 4, 36, L"%d", NULL,
+ (VOID**)&IortNodeCount, NULL, NULL},
+ {L"Offset to Array of IORT Nodes", 4, 40, L"0x%x", NULL,
+ (VOID**)&IortNodeOffset, NULL, NULL},
+ {L"Reserved", 4, 44, L"0x%x", NULL, NULL, NULL, NULL}
+};
+
+/** An ACPI_PARSER array describing the IORT node header structure.
+*/
+STATIC CONST ACPI_PARSER IortNodeHeaderParser[] = {
+ PARSE_IORT_NODE_HEADER (NULL, NULL)
+};
+
+/** An ACPI_PARSER array describing the IORT SMMUv1/2 node.
+*/
+STATIC CONST ACPI_PARSER IortNodeSmmuV1V2Parser[] = {
+ PARSE_IORT_NODE_HEADER (NULL, NULL),
+ {L"Base Address", 8, 16, L"0x%lx", NULL, NULL, NULL, NULL},
+ {L"Span", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL},
+ {L"Model", 4, 32, L"%d", NULL, NULL, NULL, NULL},
+ {L"Flags", 4, 36, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Reference to Global Interrupt Array", 4, 40, L"0x%x", NULL, NULL, NULL,
+ NULL},
+ {L"Number of context interrupts", 4, 44, L"%d", NULL,
+ (VOID**)&InterruptContextCount, NULL, NULL},
+ {L"Reference to Context Interrupt Array", 4, 48, L"0x%x", NULL,
+ (VOID**)&InterruptContextOffset, NULL, NULL},
+ {L"Number of PMU Interrupts", 4, 52, L"%d", NULL,
+ (VOID**)&PmuInterruptCount, NULL, NULL},
+ {L"Reference to PMU Interrupt Array", 4, 56, L"0x%x", NULL,
+ (VOID**)&PmuInterruptOffset, NULL, NULL},
+
+ // Interrupt Array
+ {L"SMMU_NSgIrpt", 4, 60, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"SMMU_NSgIrpt interrupt flags", 4, 64, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"SMMU_NSgCfgIrpt", 4, 68, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"SMMU_NSgCfgIrpt interrupt flags", 4, 72, L"0x%x", NULL, NULL, NULL, NULL}
+};
+
+/** An ACPI_PARSER array describing the SMMUv1/2 Node Interrupt Array.
+*/
+STATIC CONST ACPI_PARSER InterruptArrayParser[] = {
+ {L" Interrupt GSIV", 4, 0, L"0x%x", NULL, NULL, NULL, NULL},
+ {L" Flags", 4, 4, L"0x%x", NULL, NULL, NULL, NULL}
+};
+
+/** An ACPI_PARSER array describing the IORT ID Mapping.
+*/
+STATIC CONST ACPI_PARSER IortNodeIdMappingParser[] = {
+ {L" Input base", 4, 0, L"0x%x", NULL, NULL, NULL, NULL},
+ {L" Number of IDs", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},
+ {L" Output base", 4, 8, L"0x%x", NULL, NULL, NULL, NULL},
+ {L" Output reference", 4, 12, L"0x%x", NULL, NULL, NULL, NULL},
+ {L" Flags", 4, 16, L"0x%x", NULL, NULL, NULL, NULL}
+};
+
+/** An ACPI_PARSER array describing the IORT SMMUv3 node.
+*/
+STATIC CONST ACPI_PARSER IortNodeSmmuV3Parser[] = {
+ PARSE_IORT_NODE_HEADER (NULL, NULL),
+ {L"Base Address", 8, 16, L"0x%lx", NULL, NULL, NULL, NULL},
+ {L"Flags", 4, 24, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Reserved", 4, 28, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"VATOS Address", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL},
+ {L"Model", 4, 40, L"%d", NULL, NULL, NULL, NULL},
+ {L"Event", 4, 44, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"PRI", 4, 48, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"GERR", 4, 52, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Sync", 4, 56, L"0x%x", NULL, NULL, NULL, NULL}
+};
+
+/** An ACPI_PARSER array describing the IORT ITS node.
+*/
+STATIC CONST ACPI_PARSER IortNodeItsParser[] = {
+ PARSE_IORT_NODE_HEADER (
+ ValidateItsIdMappingCount,
+ ValidateItsIdArrayReference
+ ),
+ {L" Number of ITSs", 4, 16, L"%d", NULL, (VOID**)&ItsCount, NULL}
+};
+
+/** An ACPI_PARSER array describing the ITS ID.
+*/
+STATIC CONST ACPI_PARSER ItsIdParser[] = {
+ { L" GIC ITS Identifier", 4, 0, L"%d", NULL, NULL, NULL }
+};
+
+/** An ACPI_PARSER array describing the IORT Names Component node.
+*/
+STATIC CONST ACPI_PARSER IortNodeNamedComponentParser[] = {
+ PARSE_IORT_NODE_HEADER (NULL, NULL),
+ {L"Node Flags", 4, 16, L"%d", NULL, NULL, NULL, NULL},
+ {L"Memory access properties", 8, 20, L"0x%lx", NULL, NULL, NULL, NULL},
+ {L"Device memory address size limit", 1, 28, L"%d", NULL, NULL, NULL, NULL}
+};
+
+/** An ACPI_PARSER array describing the IORT Root Complex node.
+*/
+STATIC CONST ACPI_PARSER IortNodeRootComplexParser[] = {
+ PARSE_IORT_NODE_HEADER (NULL, NULL),
+ {L"Memory access properties", 8, 16, L"0x%lx", NULL, NULL, NULL, NULL},
+ {L"ATS Attribute", 4, 24, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"PCI Segment number", 4, 28, L"0x%x", NULL, NULL, NULL, NULL}
+};
+
+/** An ACPI_PARSER array describing the IORT PMCG node.
+*/
+STATIC CONST ACPI_PARSER IortNodePmcgParser[] = {
+ PARSE_IORT_NODE_HEADER (NULL, NULL),
+ {L"Base Address", 8, 16, L"0x%lx", NULL, NULL, NULL, NULL},
+ {L"Overflow interrupt GSIV", 4, 24, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Node reference", 4, 28, L"0x%x", NULL, NULL, NULL, NULL},
+};
+
+/** This function validates the ID Mapping array count for the ITS node.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+*/
+STATIC
+VOID
+EFIAPI
+ValidateItsIdMappingCount (
+ IN UINT8* Ptr,
+ VOID* Context
+ )
+{
+ if (*(UINT32*)Ptr != 0) {
+ IncrementErrorCount ();
+ Print (L"\nERROR: IORT ID Mapping count must be zero.");
+ }
+}
+
+/** This function validates the ID Mapping array offset for the ITS node.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+*/
+STATIC
+VOID
+EFIAPI
+ValidateItsIdArrayReference (
+ IN UINT8* Ptr,
+ IN VOID* Context
+ )
+{
+ if (*(UINT32*)Ptr != 0) {
+ IncrementErrorCount ();
+ Print (L"\nERROR: IORT ID Mapping offset must be zero.");
+ }
+}
+
+/** This function parses the IORT Node Id Mapping array.
+
+ @param [in] Ptr Pointer to the start of the IORT Table.
+ @param [in] MappingCount The ID Mapping count.
+ @param [in] MappingOffset The offset of the ID Mapping array
+ from the start of the IORT table.
+*/
+STATIC
+VOID
+DumpIortNodeIdMappings (
+ IN UINT8* Ptr,
+ IN UINT32 MappingCount,
+ IN UINT32 MappingOffset
+ )
+{
+ UINT8* IdMappingPtr;
+ UINT32 Index;
+ UINT32 Offset;
+ CHAR8 Buffer[40]; // Used for AsciiName param of ParseAcpi
+
+ IdMappingPtr = Ptr + MappingOffset;
+ Index = 0;
+ while (Index < MappingCount) {
+ AsciiSPrint (
+ Buffer,
+ sizeof (Buffer),
+ "ID Mapping [%d]",
+ Index
+ );
+ Offset = ParseAcpi (
+ TRUE,
+ 4,
+ Buffer,
+ IdMappingPtr,
+ 20,
+ PARSER_PARAMS (IortNodeIdMappingParser)
+ );
+ IdMappingPtr += Offset;
+ Index++;
+ }
+}
+
+/** This function parses the IORT SMMUv1/2 node.
+
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the buffer.
+ @param [in] MappingCount The ID Mapping count.
+ @param [in] MappingOffset The offset of the ID Mapping array
+ from the start of the IORT table.
+*/
+STATIC
+VOID
+DumpIortNodeSmmuV1V2 (
+ IN UINT8* Ptr,
+ IN UINT16 Length,
+ IN UINT32 MappingCount,
+ IN UINT32 MappingOffset
+ )
+{
+ UINT32 Index;
+ UINT32 Offset;
+ CHAR8 Buffer[50]; // Used for AsciiName param of ParseAcpi
+
+ UINT8* ArrayPtr;
+
+ ParseAcpi (
+ TRUE,
+ 2,
+ "SMMUv1 or SMMUv2 Node",
+ Ptr,
+ Length,
+ PARSER_PARAMS (IortNodeSmmuV1V2Parser)
+ );
+
+ ArrayPtr = Ptr + *InterruptContextOffset;
+ Index = 0;
+ while (Index < *InterruptContextCount) {
+ AsciiSPrint (
+ Buffer,
+ sizeof (Buffer),
+ "Context Interrupts Array [%d]",
+ Index
+ );
+ Offset = ParseAcpi (
+ TRUE,
+ 4,
+ Buffer,
+ ArrayPtr,
+ 8,
+ PARSER_PARAMS (InterruptArrayParser)
+ );
+ ArrayPtr += Offset;
+ Index++;
+ }
+
+ ArrayPtr = Ptr + *PmuInterruptOffset;
+ Index = 0;
+ while (Index < *PmuInterruptCount) {
+ AsciiSPrint (
+ Buffer,
+ sizeof (Buffer),
+ "PMU Interrupts Array [%d]",
+ Index
+ );
+ Offset = ParseAcpi (
+ TRUE,
+ 4,
+ Buffer,
+ ArrayPtr,
+ 8,
+ PARSER_PARAMS (InterruptArrayParser)
+ );
+ ArrayPtr += Offset;
+ Index++;
+ }
+
+ if (*IortIdMappingCount != 0) {
+ DumpIortNodeIdMappings (Ptr, MappingCount, MappingOffset);
+ }
+}
+
+/** This function parses the IORT SMMUv3 node.
+
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the buffer.
+ @param [in] MappingCount The ID Mapping count.
+ @param [in] MappingOffset The offset of the ID Mapping array
+ from the start of the IORT table.
+*/
+STATIC
+VOID
+DumpIortNodeSmmuV3 (
+ IN UINT8* Ptr,
+ IN UINT16 Length,
+ IN UINT32 MappingCount,
+ IN UINT32 MappingOffset
+ )
+{
+ ParseAcpi (
+ TRUE,
+ 2,
+ "SMMUV3 Node",
+ Ptr,
+ Length,
+ PARSER_PARAMS (IortNodeSmmuV3Parser)
+ );
+
+ if (*IortIdMappingCount != 0) {
+ DumpIortNodeIdMappings (Ptr, MappingCount, MappingOffset);
+ }
+}
+
+/** This function parses the IORT ITS node.
+
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the buffer.
+*/
+STATIC
+VOID
+DumpIortNodeIts (
+ IN UINT8* Ptr,
+ IN UINT16 Length
+ )
+{
+ UINT32 Offset;
+ UINT32 Index;
+ UINT8* ItsIdPtr;
+ CHAR8 Buffer[80]; // Used for AsciiName param of ParseAcpi
+
+ Offset = ParseAcpi (
+ TRUE,
+ 2,
+ "ITS Node",
+ Ptr,
+ Length,
+ PARSER_PARAMS (IortNodeItsParser)
+ );
+
+ ItsIdPtr = Ptr + Offset;
+ Index = 0;
+ while (Index < *ItsCount) {
+ AsciiSPrint (
+ Buffer,
+ sizeof (Buffer),
+ "GIC ITS Identifier Array [%d]",
+ Index
+ );
+ Offset = ParseAcpi (
+ TRUE,
+ 4,
+ Buffer,
+ ItsIdPtr,
+ 4,
+ PARSER_PARAMS (ItsIdParser)
+ );
+ ItsIdPtr += Offset;
+ Index++;
+ }
+
+ // Note: ITS does not have the ID Mappings Array
+}
+
+/** This function parses the IORT Named Component node.
+
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the buffer.
+ @param [in] MappingCount The ID Mapping count.
+ @param [in] MappingOffset The offset of the ID Mapping array
+ from the start of the IORT table.
+*/
+STATIC
+VOID
+DumpIortNodeNamedComponent (
+ IN UINT8* Ptr,
+ IN UINT16 Length,
+ IN UINT32 MappingCount,
+ IN UINT32 MappingOffset
+ )
+{
+ UINT32 Offset;
+ UINT32 Index;
+ UINT8* DeviceNamePtr;
+ UINT32 DeviceNameLength;
+
+ Offset = ParseAcpi (
+ TRUE,
+ 2,
+ "Named Component Node",
+ Ptr,
+ Length,
+ PARSER_PARAMS (IortNodeNamedComponentParser)
+ );
+
+ DeviceNamePtr = Ptr + Offset;
+ // Estimate the Device Name length
+ DeviceNameLength = Length - Offset - (MappingCount * 20);
+ PrintFieldName (2, L"Device Object Name");
+ Index = 0;
+ while ((Index < DeviceNameLength) && (DeviceNamePtr[Index] != 0)) {
+ Print (L"%c", DeviceNamePtr[Index++]);
+ }
+ Print (L"\n");
+
+ if (*IortIdMappingCount != 0) {
+ DumpIortNodeIdMappings (Ptr, MappingCount, MappingOffset);
+ }
+}
+
+/** This function parses the IORT Root Complex node.
+
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the buffer.
+ @param [in] MappingCount The ID Mapping count.
+ @param [in] MappingOffset The offset of the ID Mapping array
+ from the start of the IORT table.
+*/
+STATIC
+VOID
+DumpIortNodeRootComplex (
+ IN UINT8* Ptr,
+ IN UINT16 Length,
+ IN UINT32 MappingCount,
+ IN UINT32 MappingOffset
+ )
+{
+ ParseAcpi (
+ TRUE,
+ 2,
+ "Root Complex Node",
+ Ptr,
+ Length,
+ PARSER_PARAMS (IortNodeRootComplexParser)
+ );
+
+ if (*IortIdMappingCount != 0) {
+ DumpIortNodeIdMappings (Ptr, MappingCount, MappingOffset);
+ }
+}
+
+/** This function parses the IORT PMCG node.
+
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] Length Length of the buffer.
+ @param [in] MappingCount The ID Mapping count.
+ @param [in] MappingOffset The offset of the ID Mapping array
+ from the start of the IORT table.
+*/
+STATIC
+VOID
+DumpIortNodePmcg (
+ IN UINT8* Ptr,
+ IN UINT16 Length,
+ IN UINT32 MappingCount,
+ IN UINT32 MappingOffset
+)
+{
+ ParseAcpi (
+ TRUE,
+ 2,
+ "PMCG Node",
+ Ptr,
+ Length,
+ PARSER_PARAMS (IortNodePmcgParser)
+ );
+
+ if (*IortIdMappingCount != 0) {
+ DumpIortNodeIdMappings (Ptr, MappingCount, MappingOffset);
+ }
+
+ if (*IortIdMappingCount > 1) {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: ID mapping must not be greater than 1. Id Mapping Count =%d\n",
+ *IortIdMappingCount
+ );
+ }
+}
+
+/** This function parses the ACPI IORT table.
+ When trace is enabled this function parses the IORT table and
+ traces the ACPI fields.
+
+ This function also parses the following nodes:
+ - ITS Group
+ - Named Component
+ - Root Complex
+ - SMMUv1/2
+ - SMMUv3
+ - PMCG
+
+ This function also performs validation of the ACPI table fields.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiIort (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ )
+{
+ UINT32 Offset;
+ UINT32 Index;
+ UINT8* NodePtr;
+
+ if (!Trace) {
+ return;
+ }
+
+ ParseAcpi (
+ TRUE,
+ 0,
+ "IORT",
+ Ptr,
+ AcpiTableLength,
+ PARSER_PARAMS (IortParser)
+ );
+ Offset = *IortNodeOffset;
+ NodePtr = Ptr + Offset;
+ Index = 0;
+
+ while ((Index < *IortNodeCount) && (Offset < AcpiTableLength)) {
+ // Parse the IORT Node Header
+ ParseAcpi (
+ FALSE,
+ 0,
+ "IORT Node Header",
+ NodePtr,
+ 16,
+ PARSER_PARAMS (IortNodeHeaderParser)
+ );
+ if (*IortNodeLength == 0) {
+ IncrementErrorCount ();
+ Print (L"ERROR: Parser error. Invalid table data.\n");
+ return;
+ }
+
+ PrintFieldName (2, L"* Node Offset *");
+ Print (L"0x%x\n", Offset);
+
+ switch (*IortNodeType) {
+ case EIORT_NODE_ITS_GROUP:
+ DumpIortNodeIts (
+ NodePtr,
+ *IortNodeLength
+ );
+ break;
+ case EIORT_NODE_NAMED_COMPONENT:
+ DumpIortNodeNamedComponent (
+ NodePtr,
+ *IortNodeLength,
+ *IortIdMappingCount,
+ *IortIdMappingOffset
+ );
+ break;
+ case EIORT_NODE_ROOT_COMPLEX:
+ DumpIortNodeRootComplex (
+ NodePtr,
+ *IortNodeLength,
+ *IortIdMappingCount,
+ *IortIdMappingOffset
+ );
+ break;
+ case EIORT_NODE_SMMUV1_V2:
+ DumpIortNodeSmmuV1V2 (
+ NodePtr,
+ *IortNodeLength,
+ *IortIdMappingCount,
+ *IortIdMappingOffset
+ );
+ break;
+ case EIORT_NODE_SMMUV3:
+ DumpIortNodeSmmuV3 (
+ NodePtr,
+ *IortNodeLength,
+ *IortIdMappingCount,
+ *IortIdMappingOffset
+ );
+ break;
+ case EIORT_NODE_PMCG:
+ DumpIortNodePmcg (
+ NodePtr,
+ *IortNodeLength,
+ *IortIdMappingCount,
+ *IortIdMappingOffset
+ );
+ break;
+
+ default:
+ IncrementErrorCount ();
+ Print (L"ERROR: Unsupported IORT Node type = %d\n", *IortNodeType);
+ } // switch
+
+ NodePtr += (*IortNodeLength);
+ Offset += (*IortNodeLength);
+ } // while
+}
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c
new file mode 100644
index 0000000000..2ccbb7b80e
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c
@@ -0,0 +1,313 @@
+/**
+ MADT table parser
+
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Reference(s):
+ - ACPI 6.2 Specification - Errata A, September 2017
+**/
+
+#include <IndustryStandard/Acpi.h>
+#include <Library/UefiLib.h>
+#include "AcpiParser.h"
+#include "AcpiTableParser.h"
+
+// Local Variables
+STATIC CONST UINT8* MadtInterruptControllerType;
+STATIC CONST UINT8* MadtInterruptControllerLength;
+STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
+
+// Forward declarations
+STATIC
+VOID
+EFIAPI
+ValidateGICDSystemVectorBase (
+ IN UINT8* Ptr,
+ IN VOID* Context
+);
+
+/** An ACPI_PARSER array describing the GICC Interrupt
+ Controller Structure.
+*/
+STATIC CONST ACPI_PARSER GicCParser[] = {
+ {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL},
+ {L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},
+
+ {L"CPU Interface Number", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"ACPI Processor UID", 4, 8, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Flags", 4, 12, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Parking Protocol Version", 4, 16, L"0x%x", NULL, NULL, NULL, NULL},
+
+ {L"Performance Interrupt GSIV", 4, 20, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Parked Address", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL},
+ {L"Physical Base Address", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL},
+ {L"GICV", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL},
+ {L"GICH", 8, 48, L"0x%lx", NULL, NULL, NULL, NULL},
+ {L"VGIC Maintenance interrupt", 4, 56, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"GICR Base Address", 8, 60, L"0x%lx", NULL, NULL, NULL, NULL},
+ {L"MPIDR", 8, 68, L"0x%lx", NULL, NULL, NULL, NULL},
+ {L"Processor Power Efficiency Class", 1, 76, L"0x%x", NULL, NULL, NULL,
+ NULL},
+ {L"Reserved", 3, 77, L"%x %x %x", Dump3Chars, NULL, NULL, NULL}
+};
+
+/** An ACPI_PARSER array describing the GICD Interrupt
+ Controller Structure.
+*/
+STATIC CONST ACPI_PARSER GicDParser[] = {
+ {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL},
+ {L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},
+
+ {L"GIC ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Physical Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},
+ {L"System Vector Base", 4, 16, L"0x%x", NULL, NULL,
+ ValidateGICDSystemVectorBase, NULL},
+ {L"GIC Version", 1, 20, L"%d", NULL, NULL, NULL, NULL},
+ {L"Reserved", 3, 21, L"%x %x %x", Dump3Chars, NULL, NULL, NULL}
+};
+
+/** An ACPI_PARSER array describing the MSI Frame Interrupt
+ Controller Structure.
+*/
+STATIC CONST ACPI_PARSER GicMSIFrameParser[] = {
+ {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL},
+ {L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},
+
+ {L"MSI Frame ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Physical Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},
+ {L"Flags", 4, 16, L"0x%x", NULL, NULL, NULL, NULL},
+
+ {L"SPI Count", 2, 20, L"%d", NULL, NULL, NULL, NULL},
+ {L"SPI Base", 2, 22, L"0x%x", NULL, NULL, NULL, NULL}
+};
+
+/** An ACPI_PARSER array describing the GICR Interrupt
+ Controller Structure.
+*/
+STATIC CONST ACPI_PARSER GicRParser[] = {
+ {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL},
+ {L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},
+
+ {L"Discovery Range Base Address", 8, 4, L"0x%lx", NULL, NULL, NULL,
+ NULL},
+ {L"Discovery Range Length", 4, 12, L"0x%x", NULL, NULL, NULL, NULL}
+};
+
+/** An ACPI_PARSER array describing the GIC ITS Interrupt
+ Controller Structure.
+*/
+STATIC CONST ACPI_PARSER GicITSParser[] = {
+ {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL},
+ {L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},
+
+ {L"GIC ITS ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Physical Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL},
+ {L"Reserved", 4, 16, L"0x%x", NULL, NULL, NULL, NULL}
+};
+
+/** An ACPI_PARSER array describing the ACPI MADT Table.
+*/
+STATIC CONST ACPI_PARSER MadtParser[] = {
+ PARSE_ACPI_HEADER (&AcpiHdrInfo),
+ {L"Local Interrupt Controller Address", 4, 36, L"0x%x", NULL, NULL, NULL,
+ NULL},
+ {L"Flags", 4, 40, L"0x%x", NULL, NULL, NULL, NULL}
+};
+
+/** An ACPI_PARSER array describing the MADT Interrupt
+ Controller Structure Header Structure.
+*/
+STATIC CONST ACPI_PARSER MadtInterruptControllerHeaderParser[] = {
+ {NULL, 1, 0, NULL, NULL, (VOID**)&MadtInterruptControllerType, NULL, NULL},
+ {L"Length", 1, 1, NULL, NULL, (VOID**)&MadtInterruptControllerLength, NULL,
+ NULL},
+ {L"Reserved", 2, 2, NULL, NULL, NULL, NULL, NULL}
+};
+
+/** This function validates the System Vector Base in the GICD.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+*/
+STATIC
+VOID
+EFIAPI
+ValidateGICDSystemVectorBase (
+ IN UINT8* Ptr,
+ IN VOID* Context
+)
+{
+ if (*(UINT32*)Ptr != 0) {
+ IncrementErrorCount ();
+ Print (
+ L"\nERROR: System Vector Base must be zero."
+ );
+ }
+}
+
+/** This function parses the ACPI MADT table.
+ When trace is enabled this function parses the MADT table and
+ traces the ACPI table fields.
+
+ This function currently parses the following Interrupt Controller
+ Structures:
+ - GICC
+ - GICD
+ - GIC MSI Frame
+ - GICR
+ - GIC ITS
+
+ This function also performs validation of the ACPI table fields.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiMadt (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ )
+{
+ UINT32 Offset;
+ UINT8* InterruptContollerPtr;
+ UINT32 GICDCount = 0;
+
+ if (!Trace) {
+ return;
+ }
+
+ Offset = ParseAcpi (
+ TRUE,
+ 0,
+ "MADT",
+ Ptr,
+ AcpiTableLength,
+ PARSER_PARAMS (MadtParser)
+ );
+ InterruptContollerPtr = Ptr + Offset;
+
+ while (Offset < AcpiTableLength) {
+ // Parse Interrupt Controller Structure to obtain Length.
+ ParseAcpi (
+ FALSE,
+ 0,
+ NULL,
+ InterruptContollerPtr,
+ 2, // Length is 1 byte at offset 1
+ PARSER_PARAMS (MadtInterruptControllerHeaderParser)
+ );
+
+ if (((Offset + (*MadtInterruptControllerLength)) > AcpiTableLength) ||
+ (*MadtInterruptControllerLength < 4)) {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Invalid Interrupt Controller Length,"
+ " Type = %d, Length = %d\n",
+ *MadtInterruptControllerType,
+ *MadtInterruptControllerLength
+ );
+ break;
+ }
+
+ switch (*MadtInterruptControllerType) {
+ case EFI_ACPI_6_2_GIC: {
+ ParseAcpi (
+ TRUE,
+ 2,
+ "GICC",
+ InterruptContollerPtr,
+ *MadtInterruptControllerLength,
+ PARSER_PARAMS (GicCParser)
+ );
+ break;
+ }
+
+ case EFI_ACPI_6_2_GICD: {
+ if (++GICDCount > 1) {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Only one GICD must be present,"
+ " GICDCount = %d\n",
+ GICDCount
+ );
+ }
+ ParseAcpi (
+ TRUE,
+ 2,
+ "GICD",
+ InterruptContollerPtr,
+ *MadtInterruptControllerLength,
+ PARSER_PARAMS (GicDParser)
+ );
+ break;
+ }
+
+ case EFI_ACPI_6_2_GIC_MSI_FRAME: {
+ ParseAcpi (
+ TRUE,
+ 2,
+ "GIC MSI Frame",
+ InterruptContollerPtr,
+ *MadtInterruptControllerLength,
+ PARSER_PARAMS (GicMSIFrameParser)
+ );
+ break;
+ }
+
+ case EFI_ACPI_6_2_GICR: {
+ ParseAcpi (
+ TRUE,
+ 2,
+ "GICR",
+ InterruptContollerPtr,
+ *MadtInterruptControllerLength,
+ PARSER_PARAMS (GicRParser)
+ );
+ break;
+ }
+
+ case EFI_ACPI_6_2_GIC_ITS: {
+ ParseAcpi (
+ TRUE,
+ 2,
+ "GIC ITS",
+ InterruptContollerPtr,
+ *MadtInterruptControllerLength,
+ PARSER_PARAMS (GicITSParser)
+ );
+ break;
+ }
+
+ default: {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Unknown Interrupt Controller Structure,"
+ " Type = %d, Length = %d\n",
+ *MadtInterruptControllerType,
+ *MadtInterruptControllerLength
+ );
+ }
+ } // switch
+
+ InterruptContollerPtr += *MadtInterruptControllerLength;
+ Offset += *MadtInterruptControllerLength;
+ } // while
+}
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Mcfg/McfgParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Mcfg/McfgParser.c
new file mode 100644
index 0000000000..a21b30dc0d
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Mcfg/McfgParser.c
@@ -0,0 +1,94 @@
+/**
+ MCFG table parser
+
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Reference(s):
+ - PCI Firmware Specification - Revision 3.2, January 26, 2015.
+**/
+
+#include <IndustryStandard/Acpi.h>
+#include <Library/UefiLib.h>
+#include "AcpiParser.h"
+#include "AcpiTableParser.h"
+
+// Local variables
+STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
+
+/** An ACPI_PARSER array describing the ACPI MCFG Table.
+*/
+STATIC CONST ACPI_PARSER McfgParser[] = {
+ PARSE_ACPI_HEADER (&AcpiHdrInfo),
+ {L"Reserved", 8, 36, L"0x%lx", NULL, NULL, NULL, NULL},
+};
+
+/** An ACPI_PARSER array describing the PCI configuration Space
+ Base Address structure.
+*/
+STATIC CONST ACPI_PARSER PciCfgSpaceBaseAddrParser[] = {
+ {L"Base Address", 8, 0, L"0x%lx", NULL, NULL, NULL, NULL},
+ {L"PCI Segment Group No.", 2, 8, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Start Bus No.", 1, 10, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"End Bus No.", 1, 11, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Reserved", 4, 12, L"0x%x", NULL, NULL, NULL, NULL}
+};
+
+/** This function parses the ACPI MCFG table.
+ When trace is enabled this function parses the MCFG table and
+ traces the ACPI table fields.
+
+ This function also performs validation of the ACPI table fields.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiMcfg (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ )
+{
+ UINT32 Offset;
+ UINT32 PciCfgOffset;
+ UINT8* PciCfgSpacePtr;
+
+ if (!Trace) {
+ return;
+ }
+
+ Offset = ParseAcpi (
+ TRUE,
+ 0,
+ "MCFG",
+ Ptr,
+ AcpiTableLength,
+ PARSER_PARAMS (McfgParser)
+ );
+
+ PciCfgSpacePtr = Ptr + Offset;
+
+ while (Offset < AcpiTableLength) {
+ PciCfgOffset = ParseAcpi (
+ TRUE,
+ 2,
+ "PCI Configuration Space",
+ PciCfgSpacePtr,
+ (AcpiTableLength - Offset),
+ PARSER_PARAMS (PciCfgSpaceBaseAddrParser)
+ );
+ PciCfgSpacePtr += PciCfgOffset;
+ Offset += PciCfgOffset;
+ }
+}
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rsdp/RsdpParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rsdp/RsdpParser.c
new file mode 100644
index 0000000000..c7acdceb94
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rsdp/RsdpParser.c
@@ -0,0 +1,169 @@
+/**
+ RSDP table parser
+
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Reference(s):
+ - ACPI 6.2 Specification - Errata A, September 2017
+**/
+
+#include <Library/UefiLib.h>
+#include "AcpiParser.h"
+#include "AcpiTableParser.h"
+
+// Local Variables
+STATIC CONST UINT64* XsdtAddress;
+
+/** This function validates the RSDT Address.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+*/
+STATIC
+VOID
+EFIAPI
+ValidateRsdtAddress (
+ IN UINT8* Ptr,
+ IN VOID* Context
+ );
+
+/** This function validates the XSDT Address.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+*/
+STATIC
+VOID
+EFIAPI
+ValidateXsdtAddress (
+ IN UINT8* Ptr,
+ IN VOID* Context
+ );
+
+/** An array describing the ACPI RSDP Table.
+*/
+STATIC CONST ACPI_PARSER RsdpParser[] = {
+ {L"Signature", 8, 0, NULL, Dump8Chars, NULL, NULL, NULL},
+ {L"Checksum", 1, 8, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Oem ID", 6, 9, NULL, Dump6Chars, NULL, NULL, NULL},
+ {L"Revision", 1, 15, L"%d", NULL, NULL, NULL, NULL},
+ {L"RSDT Address", 4, 16, L"0x%x", NULL, NULL, ValidateRsdtAddress, NULL},
+ {L"Length", 4, 20, L"%d", NULL, NULL, NULL, NULL},
+ {L"XSDT Address", 8, 24, L"0x%lx", NULL, (VOID**)&XsdtAddress,
+ ValidateXsdtAddress, NULL},
+ {L"Extended Checksum", 1, 32, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Reserved", 3, 33, L"%x %x %x", Dump3Chars, NULL, NULL, NULL}
+};
+
+/** This function validates the RSDT Address.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+*/
+STATIC
+VOID
+EFIAPI
+ValidateRsdtAddress (
+ IN UINT8* Ptr,
+ IN VOID* Context
+ )
+{
+#if defined(MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
+ // Reference: Server Base Boot Requirements System Software on ARM Platforms
+ // Section: 4.2.1.1 RSDP
+ // Root System Description Pointer (RSDP), ACPI ? 5.2.5.
+ // - Within the RSDP, the RsdtAddress field must be null (zero) and the
+ // XsdtAddresss MUST be a valid, non-null, 64-bit value.
+ UINT32 RsdtAddr = *(UINT32*)Ptr;
+ if (RsdtAddr != 0) {
+ IncrementErrorCount ();
+ Print (
+ L"\nERROR: Rsdt Address = 0x%p. This must be NULL on ARM Platforms.",
+ RsdtAddr
+ );
+ }
+#endif
+}
+
+/** This function validates the XSDT Address.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+*/
+STATIC
+VOID
+EFIAPI
+ValidateXsdtAddress (
+ IN UINT8* Ptr,
+ IN VOID* Context
+ )
+{
+#if defined(MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
+ // Reference: Server Base Boot Requirements System Software on ARM Platforms
+ // Section: 4.2.1.1 RSDP
+ // Root System Description Pointer (RSDP), ACPI ? 5.2.5.
+ // - Within the RSDP, the RsdtAddress field must be null (zero) and the
+ // XsdtAddresss MUST be a valid, non-null, 64-bit value.
+ UINT64 XsdtAddr = *(UINT64*)Ptr;
+ if (XsdtAddr == 0) {
+ IncrementErrorCount ();
+ Print (
+ L"\nERROR: Xsdt Address = 0x%p. This must not be NULL on ARM Platforms.",
+ XsdtAddr
+ );
+ }
+#endif
+}
+
+/** This function parses the ACPI RSDP table.
+
+ This function invokes the parser for the XSDT table.
+ * Note - This function does not support parsing of RSDT table.
+
+ This function also performs a RAW dump of the ACPI table and
+ validates the checksum.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiRsdp (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ )
+{
+ if (Trace) {
+ DumpRaw (Ptr, AcpiTableLength);
+ VerifyChecksum (TRUE, Ptr, AcpiTableLength);
+ }
+
+ ParseAcpi (Trace, 0, "RSDP", Ptr, AcpiTableLength, PARSER_PARAMS (RsdpParser));
+
+ // This code currently supports parsing of XSDT table only
+ // and does not parse the RSDT table. Platforms provide the
+ // RSDT to enable compatibility with ACPI 1.0 operating systems.
+ // Therefore the RSDT should not be used on ARM platforms.
+ if ((*XsdtAddress) == 0) {
+ IncrementErrorCount ();
+ Print (L"ERROR: XSDT Pointer is not set.\n");
+ return;
+ }
+
+ ProcessAcpiTable ((UINT8*)(UINTN)(*XsdtAddress));
+}
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Slit/SlitParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Slit/SlitParser.c
new file mode 100644
index 0000000000..5f99fd46a0
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Slit/SlitParser.c
@@ -0,0 +1,142 @@
+/**
+ SLIT table parser
+
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Reference(s):
+ - ACPI 6.2 Specification - Errata A, September 2017
+**/
+
+#include <IndustryStandard/Acpi.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiLib.h>
+#include "AcpiParser.h"
+#include "AcpiTableParser.h"
+
+// Local Variables
+STATIC CONST UINT64* SlitSystemLocalityCount;
+STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
+
+/** An ACPI_PARSER array describing the ACPI SLIT table.
+*/
+STATIC CONST ACPI_PARSER SlitParser[] = {
+ PARSE_ACPI_HEADER (&AcpiHdrInfo),
+ {L"Number of System Localities", 8, 36, L"0x%lx", NULL,
+ (VOID**)&SlitSystemLocalityCount, NULL, NULL}
+};
+
+/** Macro to get the value of a System Locality
+*/
+#define SLIT_ELEMENT(Ptr, i, j) *(Ptr + (i * LocalityCount) + j)
+
+/** This function parses the ACPI SLIT table.
+ When trace is enabled this function parses the SLIT table and
+ traces the ACPI table fields.
+
+ This function also validates System Localities for the following:
+ - Diagonal elements have a normalized value of 10
+ - Relative distance from System Locality at i*N+j is same as
+ j*N+i
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiSlit (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ )
+{
+ UINT32 Offset;
+ UINT64 i;
+ UINT64 j;
+ UINT64 LocalityCount;
+ UINT8* LocalityPtr;
+ CHAR16 Buffer[80]; // Used for AsciiName param of ParseAcpi
+
+ if (!Trace) {
+ return;
+ }
+
+ Offset = ParseAcpi (
+ TRUE,
+ 0,
+ "SLIT",
+ Ptr,
+ AcpiTableLength,
+ PARSER_PARAMS (SlitParser)
+ );
+ LocalityPtr = Ptr + Offset;
+
+ LocalityCount = *SlitSystemLocalityCount;
+ // We only print the Localities if the count is less than 16
+ // If the locality count is more than 16 then refer to the
+ // raw data dump.
+ if (LocalityCount < 16) {
+ UnicodeSPrint (
+ Buffer,
+ sizeof (Buffer),
+ L"Entry[0x%lx][0x%lx]",
+ LocalityCount,
+ LocalityCount
+ );
+ PrintFieldName (0, Buffer);
+ Print (L"\n");
+ Print (L" ");
+ for (j = 0; j < LocalityCount; j++) {
+ Print (L" (%3d) ", j);
+ }
+ Print (L"\n");
+ for (i = 0; i < LocalityCount; i++) {
+ Print (L" (%3d) ", i);
+ for (j = 0; j < LocalityCount; j++) {
+ Print (L" %3d ", SLIT_ELEMENT (LocalityPtr, i, j));
+ }
+ Print (L"\n");
+ }
+ }
+
+ // Validate
+ for (i = 0; i < LocalityCount; i++) {
+ for (j = 0; j < LocalityCount; j++) {
+ // Element[x][x] must be equal to 10
+ if ((i == j) && (SLIT_ELEMENT (LocalityPtr, i, j) != 10)) {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Diagonal Element[0x%lx][0x%lx] (%3d)."
+ " Normalized Value is not 10\n",
+ i,
+ j,
+ SLIT_ELEMENT (LocalityPtr, i, j)
+ );
+ }
+ // Element[i][j] must be equal to Element[j][i]
+ if (SLIT_ELEMENT (LocalityPtr, i, j) !=
+ SLIT_ELEMENT (LocalityPtr, j, i)) {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Relative distances for Element[0x%lx][0x%lx] (%3d) and \n"
+ "Element[0x%lx][0x%lx] (%3d) do not match.\n",
+ i,
+ j,
+ SLIT_ELEMENT (LocalityPtr, i, j),
+ j,
+ i,
+ SLIT_ELEMENT (LocalityPtr, j, i)
+ );
+ }
+ }
+ }
+}
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Spcr/SpcrParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Spcr/SpcrParser.c
new file mode 100644
index 0000000000..841a27ffdf
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Spcr/SpcrParser.c
@@ -0,0 +1,168 @@
+/**
+ SPCR table parser
+
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Reference(s):
+ - Microsoft Serial Port Console Redirection Table
+ Specification - Version 1.03 - August 10, 2015.
+**/
+
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/SerialPortConsoleRedirectionTable.h>
+#include <Library/UefiLib.h>
+#include "AcpiParser.h"
+#include "AcpiTableParser.h"
+
+// Local variables
+STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
+
+/** This function validates the Interrupt Type.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+*/
+STATIC
+VOID
+EFIAPI
+ValidateInterruptType (
+ IN UINT8* Ptr,
+ IN VOID* Context
+ );
+
+/** This function validates the Irq.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+*/
+STATIC
+VOID
+EFIAPI
+ValidateIrq (
+ IN UINT8* Ptr,
+ IN VOID* Context
+ );
+
+/** An ACPI_PARSER array describing the ACPI SPCR Table.
+*/
+STATIC CONST ACPI_PARSER SpcrParser[] = {
+ PARSE_ACPI_HEADER (&AcpiHdrInfo),
+ {L"Interface Type", 1, 36, L"%d", NULL, NULL, NULL, NULL},
+ {L"Reserved", 3, 37, L"%x %x %x", Dump3Chars, NULL, NULL, NULL},
+ {L"Base Address", 12, 40, NULL, DumpGas, NULL, NULL, NULL},
+ {L"Interrupt Type", 1, 52, L"%d", NULL, NULL, ValidateInterruptType, NULL},
+ {L"IRQ", 1, 53, L"%d", NULL, NULL, ValidateIrq, NULL},
+ {L"Global System Interrupt", 4, 54, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Baud Rate", 1, 58, L"%d", NULL, NULL, NULL, NULL},
+ {L"Parity", 1, 59, L"%d", NULL, NULL, NULL, NULL},
+ {L"Stop Bits", 1, 60, L"%d", NULL, NULL, NULL, NULL},
+ {L"Flow Control", 1, 61, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Terminal Type", 1, 62, L"%d", NULL, NULL, NULL, NULL},
+ {L"Reserved", 1, 63, L"%x", NULL, NULL, NULL, NULL},
+
+ {L"PCI Device ID", 2, 64, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"PCI Vendor ID", 2, 66, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"PCI Bus Number", 1, 68, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"PCI Device Number", 1, 69, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"PCI Function Number", 1, 70, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"PCI Flags", 4, 71, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"PCI Segment", 1, 75, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Reserved", 4, 76, L"%x", NULL, NULL, NULL, NULL}
+};
+
+/** This function validates the Interrupt Type.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+*/
+STATIC
+VOID
+EFIAPI
+ValidateInterruptType (
+ IN UINT8* Ptr,
+ IN VOID* Context
+ )
+{
+#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
+ UINT8 InterruptType = *Ptr;
+ if (InterruptType !=
+ EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERRUPT_TYPE_GIC) {
+ IncrementErrorCount ();
+ Print (
+ L"\nERROR: InterruptType = %d. This must be 8 on ARM Platforms",
+ InterruptType
+ );
+ }
+#endif
+}
+
+/** This function validates the Irq.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+*/
+STATIC
+VOID
+EFIAPI
+ValidateIrq (
+ IN UINT8* Ptr,
+ IN VOID* Context
+ )
+{
+#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
+ UINT8 Irq = *Ptr;
+ if (Irq != 0) {
+ IncrementErrorCount ();
+ Print (
+ L"\nERROR: Irq = %d. This must be zero on ARM Platforms\n",
+ Irq
+ );
+ }
+#endif
+}
+
+/** This function parses the ACPI SPCR table.
+ When trace is enabled this function parses the SPCR table and
+ traces the ACPI table fields.
+
+ This function also performs validations of the ACPI table fields.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiSpcr (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ )
+{
+ if (!Trace) {
+ return;
+ }
+
+ // Dump the SPCR
+ ParseAcpi (
+ TRUE,
+ 0,
+ "SPCR",
+ Ptr,
+ AcpiTableLength,
+ PARSER_PARAMS (SpcrParser)
+ );
+}
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Srat/SratParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Srat/SratParser.c
new file mode 100644
index 0000000000..86da55935c
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Srat/SratParser.c
@@ -0,0 +1,330 @@
+/**
+ SRAT table parser
+
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Reference(s):
+ - ACPI 6.2 Specification - Errata A, September 2017
+**/
+
+#include <IndustryStandard/Acpi.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiLib.h>
+#include "AcpiParser.h"
+#include "AcpiTableParser.h"
+
+// Local Variables
+STATIC CONST UINT8* SratRAType;
+STATIC CONST UINT8* SratRALength;
+STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
+
+/** This function validates the Reserved field in the SRAT table header.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+*/
+STATIC
+VOID
+EFIAPI
+ValidateSratReserved (
+ IN UINT8* Ptr,
+ IN VOID* Context
+ );
+
+/** This function traces the APIC Proximity Domain field.
+
+ @param [in] Format Format string for tracing the data.
+ @param [in] Ptr Pointer to the start of the buffer.
+*/
+STATIC
+VOID
+DumpSratApicProximity (
+ IN CONST CHAR16* Format,
+ IN UINT8* Ptr
+ );
+
+/** An ACPI_PARSER array describing the SRAT Table.
+*/
+STATIC CONST ACPI_PARSER SratParser[] = {
+ PARSE_ACPI_HEADER (&AcpiHdrInfo),
+ {L"Reserved", 4, 36, L"0x%x", NULL, NULL, ValidateSratReserved, NULL},
+ {L"Reserved", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL}
+};
+
+/** An ACPI_PARSER array describing the Resource Allocation
+ structure header.
+*/
+STATIC CONST ACPI_PARSER SratResourceAllocationParser[] = {
+ {L"Type", 1, 0, NULL, NULL, (VOID**)&SratRAType, NULL, NULL},
+ {L"Length", 1, 1, NULL, NULL, (VOID**)&SratRALength, NULL, NULL}
+};
+
+/** An ACPI_PARSER array describing the GICC Affinity structure.
+*/
+STATIC CONST ACPI_PARSER SratGicCAffinityParser[] = {
+ {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Length", 1, 1, L"0x%x", NULL, NULL, NULL, NULL},
+
+ {L"Proximity Domain", 4, 2, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"ACPI Processor UID", 4, 6, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Flags", 4, 10, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Clock Domain", 4, 14, L"0x%x", NULL, NULL, NULL, NULL}
+};
+
+/** An ACPI_PARSER array describing the GIC ITS Affinity structure.
+*/
+STATIC CONST ACPI_PARSER SratGicITSAffinityParser[] = {
+ {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Length", 1, 1, L"0x%x", NULL, NULL, NULL, NULL},
+
+ {L"Proximity Domain", 4, 2, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Reserved", 2, 6, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"ITS Id", 4, 8, L"0x%x", NULL, NULL, NULL, NULL},
+};
+
+/** An ACPI_PARSER array describing the Memory Affinity structure.
+*/
+STATIC CONST ACPI_PARSER SratMemAffinityParser[] = {
+ {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Length", 1, 1, L"0x%x", NULL, NULL, NULL, NULL},
+
+ {L"Proximity Domain", 4, 2, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Reserved", 2, 6, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Base Address Low", 4, 8, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Base Address High", 4, 12, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Length Low", 4, 16, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Length High", 4, 20, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Reserved", 4, 24, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Flags", 4, 28, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Reserved", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL}
+};
+
+/** An ACPI_PARSER array describing the APIC/SAPIC Affinity structure.
+*/
+STATIC CONST ACPI_PARSER SratApciSapicAffinityParser[] = {
+ {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Length", 1, 1, L"0x%x", NULL, NULL, NULL, NULL},
+
+ {L"Proximity Domain [7:0]", 1, 2, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"APIC ID", 1, 3, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Flags", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Local SAPIC EID", 1, 8, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Proximity Domain [31:8]", 3, 9, L"0x%x", DumpSratApicProximity,
+ NULL, NULL, NULL},
+ {L"Clock Domain", 4, 12, L"0x%x", NULL, NULL, NULL, NULL}
+};
+
+/** An ACPI_PARSER array describing the Processor Local x2APIC
+ Affinity structure.
+*/
+STATIC CONST ACPI_PARSER SratX2ApciAffinityParser[] = {
+ {L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Length", 1, 1, L"0x%x", NULL, NULL, NULL, NULL},
+
+ {L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Proximity Domain", 4, 4, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"X2APIC ID", 4, 8, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Flags", 4, 12, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Clock Domain", 4, 16, L"0x%x", NULL, NULL, NULL, NULL},
+ {L"Reserved", 4, 20, L"0x%x", NULL, NULL, NULL, NULL}
+};
+
+/** This function validates the Reserved field in the SRAT table header.
+
+ @param [in] Ptr Pointer to the start of the field data.
+ @param [in] Context Pointer to context specific information e.g. this
+ could be a pointer to the ACPI table header.
+*/
+STATIC
+VOID
+EFIAPI
+ValidateSratReserved (
+ IN UINT8* Ptr,
+ IN VOID* Context
+ )
+{
+ if (*(UINT32*)Ptr != 1) {
+ IncrementErrorCount ();
+ Print (L"\nERROR: Reserved should be 1 for backward compatibility.\n");
+ }
+}
+
+/** This function traces the APIC Proximity Domain field.
+
+ @param [in] Format Format string for tracing the data.
+ @param [in] Ptr Pointer to the start of the buffer.
+*/
+STATIC
+VOID
+DumpSratApicProximity (
+ IN CONST CHAR16* Format,
+ IN UINT8* Ptr
+ )
+{
+ UINT32 ProximityDomain = Ptr[0] | (Ptr[1] << 8) | (Ptr[2] << 16);
+ Print (Format, ProximityDomain);
+}
+
+/** This function parses the ACPI SRAT table.
+ When trace is enabled this function parses the SRAT table and
+ traces the ACPI table fields.
+
+ This function parses the following Resource Allocation Structures:
+ - Processor Local APIC/SAPIC Affinity Structure
+ - Memory Affinity Structure
+ - Processor Local x2APIC Affinity Structure
+ - GICC Affinity Structure
+
+ This function also performs validation of the ACPI table fields.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiSrat (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ )
+{
+ UINT32 Offset;
+ UINT8* ResourcePtr;
+ UINT32 GicCAffinityIndex = 0;
+ UINT32 GicITSAffinityIndex = 0;
+ UINT32 MemoryAffinityIndex = 0;
+ UINT32 ApicSapicAffinityIndex = 0;
+ UINT32 X2ApicAffinityIndex = 0;
+ CHAR8 Buffer[80]; // Used for AsciiName param of ParseAcpi
+
+ if (!Trace) {
+ return;
+ }
+
+ Offset = ParseAcpi (
+ TRUE,
+ 0,
+ "SRAT",
+ Ptr,
+ AcpiTableLength,
+ PARSER_PARAMS (SratParser)
+ );
+ ResourcePtr = Ptr + Offset;
+
+ while (Offset < AcpiTableLength) {
+ ParseAcpi (
+ FALSE,
+ 0,
+ NULL,
+ ResourcePtr,
+ 2, // The length is 1 byte at offset 1
+ PARSER_PARAMS (SratResourceAllocationParser)
+ );
+
+ switch (*SratRAType) {
+ case EFI_ACPI_6_2_GICC_AFFINITY:
+ AsciiSPrint (
+ Buffer,
+ sizeof (Buffer),
+ "GICC Affinity Structure [%d]",
+ GicCAffinityIndex++
+ );
+ ParseAcpi (
+ TRUE,
+ 2,
+ Buffer,
+ ResourcePtr,
+ *SratRALength,
+ PARSER_PARAMS (SratGicCAffinityParser)
+ );
+ break;
+
+ case EFI_ACPI_6_2_GIC_ITS_AFFINITY:
+ AsciiSPrint (
+ Buffer,
+ sizeof (Buffer),
+ "GIC ITS Affinity Structure [%d]",
+ GicITSAffinityIndex++
+ );
+ ParseAcpi (
+ TRUE,
+ 2,
+ Buffer,
+ ResourcePtr,
+ *SratRALength,
+ PARSER_PARAMS (SratGicITSAffinityParser)
+ );
+ break;
+
+ case EFI_ACPI_6_2_MEMORY_AFFINITY:
+ AsciiSPrint (
+ Buffer,
+ sizeof (Buffer),
+ "Memory Affinity Structure [%d]",
+ MemoryAffinityIndex++
+ );
+ ParseAcpi (
+ TRUE,
+ 2,
+ Buffer,
+ ResourcePtr,
+ *SratRALength,
+ PARSER_PARAMS (SratMemAffinityParser)
+ );
+ break;
+
+ case EFI_ACPI_6_2_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY:
+ AsciiSPrint (
+ Buffer,
+ sizeof (Buffer),
+ "APIC/SAPIC Affinity Structure [%d]",
+ ApicSapicAffinityIndex++
+ );
+ ParseAcpi (
+ TRUE,
+ 2,
+ Buffer,
+ ResourcePtr,
+ *SratRALength,
+ PARSER_PARAMS (SratApciSapicAffinityParser)
+ );
+ break;
+
+ case EFI_ACPI_6_2_PROCESSOR_LOCAL_X2APIC_AFFINITY:
+ AsciiSPrint (
+ Buffer,
+ sizeof (Buffer),
+ "X2APIC Affinity Structure [%d]",
+ X2ApicAffinityIndex++
+ );
+ ParseAcpi (
+ TRUE,
+ 2,
+ Buffer,
+ ResourcePtr,
+ *SratRALength,
+ PARSER_PARAMS (SratX2ApciAffinityParser)
+ );
+ break;
+
+ default:
+ IncrementErrorCount ();
+ Print (L"ERROR: Unknown SRAT Affinity type = 0x%x\n", *SratRAType);
+ break;
+ }
+
+ ResourcePtr += (*SratRALength);
+ Offset += (*SratRALength);
+ }
+}
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Ssdt/SsdtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Ssdt/SsdtParser.c
new file mode 100644
index 0000000000..a77ccbe060
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Ssdt/SsdtParser.c
@@ -0,0 +1,47 @@
+/**
+ SSDT table parser
+
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Reference(s):
+ - ACPI 6.2 Specification - Errata A, September 2017
+**/
+
+#include <IndustryStandard/Acpi.h>
+#include <Library/UefiLib.h>
+#include "AcpiParser.h"
+#include "AcpiTableParser.h"
+
+/** This function parses the ACPI SSDT table.
+ When trace is enabled this function parses the SSDT table and
+ traces the ACPI table fields.
+ For the SSDT table only the ACPI header fields are
+ parsed and traced.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiSsdt (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ )
+{
+ if (!Trace) {
+ return;
+ }
+
+ DumpAcpiHeader (Ptr);
+}
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Xsdt/XsdtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Xsdt/XsdtParser.c
new file mode 100644
index 0000000000..0ed65d2e72
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Xsdt/XsdtParser.c
@@ -0,0 +1,153 @@
+/**
+ XSDT table parser
+
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Reference(s):
+ - ACPI 6.2 Specification - Errata A, September 2017
+**/
+
+#include <IndustryStandard/Acpi.h>
+#include <Library/UefiLib.h>
+#include <Library/PrintLib.h>
+#include "AcpiParser.h"
+#include "AcpiTableParser.h"
+
+// Local variables
+STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
+
+/** An ACPI_PARSER array describing the ACPI XSDT table.
+*/
+STATIC CONST ACPI_PARSER XsdtParser[] = {
+ PARSE_ACPI_HEADER (&AcpiHdrInfo)
+};
+
+CONST ACPI_DESCRIPTION_HEADER_INFO* CONST
+EFIAPI
+GetAcpiXsdtHeaderInfo (
+ VOID
+)
+{
+ return &AcpiHdrInfo;
+}
+
+/** This function parses the ACPI XSDT table
+ and optionally traces the ACPI table fields.
+
+ This function also performs validation of the XSDT table.
+
+ @param [in] Trace If TRUE, trace the ACPI fields.
+ @param [in] Ptr Pointer to the start of the buffer.
+ @param [in] AcpiTableLength Length of the ACPI table.
+ @param [in] AcpiTableRevision Revision of the ACPI table.
+*/
+VOID
+EFIAPI
+ParseAcpiXsdt (
+ IN BOOLEAN Trace,
+ IN UINT8* Ptr,
+ IN UINT32 AcpiTableLength,
+ IN UINT8 AcpiTableRevision
+ )
+{
+ UINT32 Offset;
+ UINT32 TableOffset;
+ UINT64* TablePointer;
+ UINTN EntryIndex;
+ CHAR16 Buffer[32];
+
+ // Parse the ACPI header to get the length
+ ParseAcpi (
+ FALSE,
+ 0,
+ "XSDT",
+ Ptr,
+ ACPI_DESCRIPTION_HEADER_LENGTH,
+ PARSER_PARAMS (XsdtParser)
+ );
+
+ Offset = ParseAcpi (
+ Trace,
+ 0,
+ "XSDT",
+ Ptr,
+ *AcpiHdrInfo.Length,
+ PARSER_PARAMS (XsdtParser)
+ );
+
+ TableOffset = Offset;
+
+ if (Trace) {
+ EntryIndex = 0;
+ TablePointer = (UINT64*)(Ptr + TableOffset);
+ while (Offset < (*AcpiHdrInfo.Length)) {
+ CONST UINT32* Signature;
+ CONST UINT32* Length;
+ CONST UINT8* Revision;
+
+ if ((UINT64*)(UINTN)(*TablePointer) != NULL) {
+ UINT8* Ptr;
+
+ ParseAcpiHeader (
+ (UINT8*)(UINTN)(*TablePointer),
+ &Signature,
+ &Length,
+ &Revision
+ );
+
+ Ptr = (UINT8*)Signature;
+
+ UnicodeSPrint (
+ Buffer,
+ sizeof (Buffer),
+ L"Entry[%d] - %c%c%c%c",
+ EntryIndex++,
+ Ptr[0],
+ Ptr[1],
+ Ptr[2],
+ Ptr[3]
+ );
+ } else {
+ UnicodeSPrint (
+ Buffer,
+ sizeof (Buffer),
+ L"Entry[%d]",
+ EntryIndex++
+ );
+ }
+
+ PrintFieldName (2, Buffer);
+ Print (L"0x%lx\n", *TablePointer);
+
+ // Validate the table pointers are not NULL
+ if ((UINT64*)(UINTN)(*TablePointer) == NULL) {
+ IncrementErrorCount ();
+ Print (
+ L"ERROR: Invalid table entry at 0x%lx, table address is 0x%lx\n",
+ TablePointer,
+ *TablePointer
+ );
+ }
+ Offset += sizeof (UINT64);
+ TablePointer++;
+ } // while
+ }
+
+ // Process the tables
+ Offset = TableOffset;
+ TablePointer = (UINT64*)(Ptr + TableOffset);
+ while (Offset < (*AcpiHdrInfo.Length)) {
+ if ((UINT64*)(UINTN)(*TablePointer) != NULL) {
+ ProcessAcpiTable ((UINT8*)(UINTN)(*TablePointer));
+ }
+ Offset += sizeof (UINT64);
+ TablePointer++;
+ } // while
+}
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
new file mode 100644
index 0000000000..7de28691be
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c
@@ -0,0 +1,167 @@
+/**
+ Main file for 'acpiview' Shell command function.
+
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#include <Guid/ShellLibHiiGuid.h>
+#include <IndustryStandard/Acpi.h>
+#include <Library/HiiLib.h>
+#include <Library/ShellCommandLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Uefi.h>
+#include "AcpiParser.h"
+#include "AcpiTableParser.h"
+#include "AcpiView.h"
+#include "UefiShellAcpiViewCommandLib.h"
+
+CONST CHAR16 gShellAcpiViewFileName[] = L"ShellCommand";
+
+/**
+ A list of available table parsers.
+*/
+STATIC
+CONST
+ACPI_TABLE_PARSER ParserList[] = {
+ {EFI_ACPI_6_2_BOOT_GRAPHICS_RESOURCE_TABLE_SIGNATURE, ParseAcpiBgrt},
+ {EFI_ACPI_6_2_DEBUG_PORT_2_TABLE_SIGNATURE, ParseAcpiDbg2},
+ {EFI_ACPI_6_2_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
+ ParseAcpiDsdt},
+ {EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiFadt},
+ {EFI_ACPI_6_2_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiGtdt},
+ {EFI_ACPI_6_2_IO_REMAPPING_TABLE_SIGNATURE, ParseAcpiIort},
+ {EFI_ACPI_6_2_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiMadt},
+ {EFI_ACPI_6_2_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
+ ParseAcpiMcfg},
+ {RSDP_TABLE_INFO, ParseAcpiRsdp},
+ {EFI_ACPI_6_2_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE, ParseAcpiSlit},
+ {EFI_ACPI_6_2_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, ParseAcpiSpcr},
+ {EFI_ACPI_6_2_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE, ParseAcpiSrat},
+ {EFI_ACPI_6_2_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiSsdt},
+ {EFI_ACPI_6_2_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiXsdt}
+};
+
+/** This function registers all the available table parsers.
+
+ @retval EFI_SUCCESS The parser is registered.
+ @retval EFI_ALREADY_STARTED The parser for the ACPI Table
+ was already registered.
+ @retval EFI_INVALID_PARAMETER A parameter is invalid.
+ @retval EFI_OUT_OF_RESOURCES No space to register the
+ parser.
+*/
+EFI_STATUS
+RegisterAllParsers (
+ )
+{
+ EFI_STATUS Status;
+ UINTN Count = sizeof (ParserList) / sizeof (ParserList[0]);
+ while (Count-- != 0) {
+ Status = RegisterParser (
+ ParserList[Count].Signature,
+ ParserList[Count].Parser
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+ return Status;
+}
+
+/**
+ Return the file name of the help text file if not using HII.
+
+ @return The string pointer to the file name.
+*/
+CONST CHAR16*
+EFIAPI
+ShellCommandGetManFileNameAcpiView (
+ VOID
+ )
+{
+ return gShellAcpiViewFileName;
+}
+
+/**
+ Constructor for the Shell AcpiView Command library.
+
+ Install the handlers for acpiview UEFI Shell command.
+
+ @param ImageHandle The image handle of the process.
+ @param SystemTable The EFI System Table pointer.
+
+ @retval EFI_SUCCESS The Shell command handlers were installed
+ successfully.
+ @retval EFI_DEVICE_ERROR Hii package failed to install.
+*/
+EFI_STATUS
+EFIAPI
+UefiShellAcpiViewCommandLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ gShellAcpiViewHiiHandle = NULL;
+
+ // Check Shell Profile Debug1 bit of the profiles mask
+ if ((FixedPcdGet8 (PcdShellProfileMask) & BIT1) == 0) {
+ return EFI_SUCCESS;
+ }
+
+ Status = RegisterAllParsers ();
+ if (EFI_ERROR (Status)) {
+ Print (L"acpiview: Error failed to register parser.\n");
+ return Status;
+ }
+
+ gShellAcpiViewHiiHandle = HiiAddPackages (
+ &gShellAcpiViewHiiGuid,
+ gImageHandle,
+ UefiShellAcpiViewCommandLibStrings,
+ NULL
+ );
+ if (gShellAcpiViewHiiHandle == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+ // Install our Shell command handler
+ ShellCommandRegisterCommandName (
+ L"acpiview",
+ ShellCommandRunAcpiView,
+ ShellCommandGetManFileNameAcpiView,
+ 0,
+ L"acpiview",
+ TRUE,
+ gShellAcpiViewHiiHandle,
+ STRING_TOKEN (STR_GET_HELP_ACPIVIEW)
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Destructor for the library. free any resources.
+
+ @param ImageHandle The image handle of the process.
+ @param SystemTable The EFI System Table pointer.
+*/
+EFI_STATUS
+EFIAPI
+UefiShellAcpiViewCommandLibDestructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ if (gShellAcpiViewHiiHandle != NULL) {
+ HiiRemovePackages (gShellAcpiViewHiiHandle);
+ }
+ return EFI_SUCCESS;
+}
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.h
new file mode 100644
index 0000000000..59c8e21544
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.h
@@ -0,0 +1,32 @@
+/**
+ Header file for 'acpiview' Shell command functions.
+
+ Copyright (c) 2016 - 2017, ARM Limited. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#ifndef UEFI_SHELL_ACPIVIEW_COMMAND_LIB_H_
+#define UEFI_SHELL_ACPIVIEW_COMMAND_LIB_H_
+
+extern EFI_HII_HANDLE gShellAcpiViewHiiHandle;
+
+/**
+ Function for 'acpiview' command.
+
+ @param[in] ImageHandle Handle to the Image (NULL if Internal).
+ @param[in] SystemTable Pointer to the System Table (NULL if Internal).
+*/
+SHELL_STATUS
+EFIAPI
+ShellCommandRunAcpiView (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+#endif // UEFI_SHELL_ACPIVIEW_COMMAND_LIB_H_
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
new file mode 100644
index 0000000000..dbdb7e301b
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
@@ -0,0 +1,74 @@
+## @file
+# Provides Shell 'acpiview' command functions
+#
+# Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010019
+ BASE_NAME = UefiShellAcpiViewCommandLib
+ FILE_GUID = FB5B305E-84F5-461F-940D-82D345757AFA
+ MODULE_TYPE = UEFI_APPLICATION
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = NULL|UEFI_APPLICATION UEFI_DRIVER
+ CONSTRUCTOR = UefiShellAcpiViewCommandLibConstructor
+ DESTRUCTOR = UefiShellAcpiViewCommandLibDestructor
+
+[Sources.common]
+ UefiShellAcpiViewCommandLib.uni
+ UefiShellAcpiViewCommandLib.c
+ UefiShellAcpiViewCommandLib.h
+ AcpiParser.c
+ AcpiTableParser.c
+ AcpiView.c
+ Parsers/Bgrt/BgrtParser.c
+ Parsers/Dbg2/Dbg2Parser.c
+ Parsers/Dsdt/DsdtParser.c
+ Parsers/Fadt/FadtParser.c
+ Parsers/Gtdt/GtdtParser.c
+ Parsers/Iort/IortParser.c
+ Parsers/Madt/MadtParser.c
+ Parsers/Mcfg/McfgParser.c
+ Parsers/Rsdp/RsdpParser.c
+ Parsers/Slit/SlitParser.c
+ Parsers/Spcr/SpcrParser.c
+ Parsers/Srat/SratParser.c
+ Parsers/Ssdt/SsdtParser.c
+ Parsers/Xsdt/XsdtParser.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ShellPkg/ShellPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+
+[LibraryClasses]
+ MemoryAllocationLib
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ ShellCommandLib
+ ShellLib
+ UefiLib
+ UefiRuntimeServicesTableLib
+ UefiBootServicesTableLib
+ PcdLib
+ HiiLib
+ PrintLib
+ FileHandleLib
+
+
+[FixedPcd]
+ gEfiShellPkgTokenSpaceGuid.PcdShellProfileMask ## CONSUMES
+
+[Guids]
+ gShellAcpiViewHiiGuid ## CONSUMES ## HII
+ gEfiAcpiTableGuid ## SOMETIMES_CONSUMES ## SystemTable
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni
new file mode 100644
index 0000000000..1c4d66e1ff
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni
@@ -0,0 +1,127 @@
+// /**
+//
+// Copyright (c) 2016 - 2017, ARM Limited. All rights reserved.<BR>
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// Module Name:
+//
+// UefiShellAcpiViewCommandLib.uni
+//
+// Abstract:
+//
+// String definitions for UEFI Shell acpiview command
+//
+//
+// */
+
+/=#
+
+#langdef en-US "english"
+
+#string STR_GEN_PROBLEM #language en-US "%H%s%N: Unknown flag - '%H%s%N'\r\n"
+#string STR_GEN_NO_VALUE #language en-US "%H%s%N: Missing argument for flag - '%H%s%N'\r\n"
+#string STR_GEN_TOO_MANY #language en-US "%H%s%N: Too many arguments.\r\n"
+#string STR_GEN_MISSING_OPTION #language en-US "%H%s%N: Missing option '%H%s%N' required by flag - '%H%s%N'\r\n"
+#string STR_GEN_READONLY_MEDIA #language en-US "%H%s%N: Unable to write to the current directory, check if media is writable.\r\n"
+
+#string STR_GET_HELP_ACPIVIEW #language en-US ""
+".TH acpiview 0 "Display ACPI information."\r\n"
+".SH NAME\r\n"
+"Display ACPI Table information.\r\n"
+".SH SYNOPSIS\r\n"
+" \r\n"
+"ACPIVIEW [[-?] | [[-l] | [-s AcpiTable [-d]]] [-c] [-v] [-h Highlight]]\r\n"
+" \r\n"
+".SH OPTIONS\r\n"
+" \r\n"
+" -l - Display list of installed ACPI Tables.\r\n"
+" -s - Display only the specified AcpiTable type.\r\n"
+" AcpiTable : The required ACPI Table type.\r\n"
+" -d - Generate a binary file dump of the specified AcpiTable.\r\n"
+" -c - Consistency checking (enabled by default).\r\n"
+" -v - Display verbose data (enabled by default).\r\n"
+" -h - Enable/Disable Colour Highlighting.\r\n"
+" Highlight : TRUE/ON enables highlighting;\r\n"
+" FALSE/OFF (default) disables highlighting.\r\n"
+" -? - Show help.\r\n"
+" \r\n"
+".SH DESCRIPTION\r\n"
+" \r\n"
+" This program is provided to allow examination of ACPI table values from the\r\n"
+" UEFI Shell. This can help with investigations, especially at that stage where\r\n"
+" the tables are not enabling an OS to boot.\r\n"
+" The program is not exhaustive, and only encapsulates detailed knowledge of a\r\n"
+" limited number of table types.\r\n"
+" \r\n"
+" Default behaviour is to display the content of all tables installed.\r\n"
+" 'Known' table types (listed in NOTES below) will be parsed and displayed\r\n"
+" with descriptions and field values. Where appropriate a degree of consistency\r\n"
+" checking is done and errors may be reported in the output.\r\n"
+" Other table types will be displayed as an array of Hexadecimal bytes.\r\n"
+" \r\n"
+" To facilitate debugging, the -s and -d options can be used to generate a\r\n"
+" binary file image of a table that can be copied elsewhere for investigation\r\n"
+" using tools such as those provided by acpica.org. This is especially relevant\r\n"
+" for AML type tables like DSDT and SSDT.\r\n"
+" \r\n"
+"NOTES:\r\n"
+" 1. The AcpiTable parameter can match any installed table type.\r\n"
+" Tables without specific handling will be displayed as a raw hex dump (or\r\n"
+" dumped to a file if -d is used).\r\n"
+" 2. Formatted display and checking is provided for these signature types:\r\n"
+" APIC - Multiple APIC Description Table (MADT)\r\n"
+" BGRT - Boot Graphics Resource Table\r\n"
+" DBG2 - Debug Port Table 2\r\n"
+" FACP - Fixed ACPI Description Table (FADT)\r\n"
+" GTDT - Generic Timer Description Table\r\n"
+" IORT - IO Remapping Table\r\n"
+" MCFG - Memory Mapped Config Space Base Address Description Table\r\n"
+" RSDP - Root System Description Pointer\r\n"
+" SLIT - System Locality Information Table\r\n"
+" SPCR - Serial Port Console Redirection Table\r\n"
+" SRAT - System Resource Affinity Table\r\n"
+" XSDT - Extended System Description Table\r\n"
+" \r\n"
+".SH STANDARDS\r\n"
+" \r\n"
+" Table details correspond to those in 'Advanced Configuration and Power\r\n"
+" Interface Specification' Version 6.2 Errata A, [September 2017]\r\n"
+" (http://www.uefi.org/sites/default/files/resources/ACPI%206_2_A_Sept29.pdf)\r\n"
+" \r\n"
+" NOTE: The nature of the ACPI standard means that almost all tables in 6.1 will\r\n"
+" be 'backwards compatible' with prior version of the specification in\r\n"
+" terms of structure, so formatted output should be correct. The main\r\n"
+" exception will be that previously 'reserved' fields will be reported\r\n"
+" with new names, where they have been added in later versions of the\r\n"
+" specification.\r\n"
+" \r\n"
+".SH EXAMPLES\r\n"
+" \r\n"
+" \r\n"
+"EXAMPLES:\r\n"
+" * To display a list of the installed table types:\r\n"
+" fs0:\> acpiview -l\r\n"
+" \r\n"
+" * To parse and display a specific table type:\r\n"
+" fs0:\> acpiview -s GTDT\r\n"
+" \r\n"
+" * To save a binary dump of the contents of a table to a file\r\n"
+" in the current working directory:\r\n"
+" fs0:\> acpiview -s DSDT -d\r\n"
+" \r\n"
+" * To display contents of all ACPI tables:\r\n"
+" fs0:\> acpiview\r\n"
+" \r\n"
+".SH RETURNVALUES\r\n"
+" \r\n"
+"RETURN VALUES:\r\n"
+" SHELL_SUCCESS Data was displayed as requested.\r\n"
+" SHELL_INVALID_PARAMETER ACPI Table parsing failed.\r\n"
+" \r\n"
+