From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=134.134.136.65; helo=mga03.intel.com; envelope-from=ruiyu.ni@intel.com; receiver=edk2-devel@lists.01.org Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 5D98422489C85 for ; Fri, 16 Mar 2018 00:05:35 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 16 Mar 2018 00:11:59 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.48,313,1517904000"; d="scan'208";a="24997571" Received: from ray-dev.ccr.corp.intel.com (HELO [10.239.9.4]) ([10.239.9.4]) by fmsmga008.fm.intel.com with ESMTP; 16 Mar 2018 00:11:56 -0700 To: Sami Mujawar , "jaben.carsey@intel.com" Cc: "leif.lindholm@linaro.org" , Stephanie Hughes-Fitt , "jiewen.yao@intel.com" , "edk2-devel@lists.01.org" , nd References: <20180308162602.28152-1-sami.mujawar@arm.com> From: "Ni, Ruiyu" Message-ID: Date: Fri, 16 Mar 2018 15:11:55 +0800 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Thunderbird/52.6.0 MIME-Version: 1.0 In-Reply-To: Subject: Re: [PATCH v5] ShellPkg: Add acpiview tool to dump ACPI tables X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 16 Mar 2018 07:05:35 -0000 Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 8bit On 3/16/2018 2:48 AM, Sami Mujawar wrote: > Hi, > > Please let me know if there is anything more you need from me before you can accept this patch. > > Regards, > > Sami Mujawar > > -----Original Message----- > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Sami Mujawar > Sent: 08 March 2018 04:26 PM > To: edk2-devel@lists.01.org > Cc: ruiyu.ni@intel.com; leif.lindholm@linaro.org; Stephanie Hughes-Fitt ; jiewen.yao@intel.com; jaben.carsey@intel.com; nd > Subject: [edk2] [PATCH v5] ShellPkg: Add acpiview tool to dump ACPI tables > > [This sender failed our fraud detection checks and may not be who they appear to be. Learn about spoofing at http://aka.ms/LearnAboutSpoofing] > > This program is provided to allow examination of ACPI table contents > from the UEFI Shell. This can help with investigations, especially at > that stage where the tables are not enabling an OS to boot. > The program is not exhaustive, and only encapsulates detailed knowledge > of a limited number of table types. > > Default behaviour is to display the content of all tables installed. > 'Known' table types will be parsed and displayed with descriptions and > field values. Where appropriate a degree of consistency checking is > done and errors may be reported in the output. > Other table types will be displayed as an array of Hexadecimal bytes. > > To facilitate debugging, the -s and -d options can be used to generate a > binary file image of a table that can be copied elsewhere for > investigation using tools such as those provided by acpica.org. This is > especially relevant for AML type tables like DSDT and SSDT. > > The inspiration for this is the existing smbiosview Debug1 Shell > command. > > Many tables are not explicitly handled, in part because no examples are > available for our testing. > > The program is designed to be extended to new tables with minimal > effort, and contributions are invited. > > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Sami Mujawar > Signed-off-by: Evan Lloyd > Reviewed-by: Jaben Carsey > --- > > The updated changes can be viewed at: > https://github.com/samimujawar/edk2/tree/188_acpiview_v5 > > Notes: > v5: > - But for now, let's remove any public library APIs. > Adding public APIs is very easy. But removing them is > almost impossible. > If we think it's valuable to add them, we can add them > in future. [RAY] > - Removed public library API's. [SAMI] > > v4: > - Firstly, public library APIs should have "EFIAPI" decorator. [RAY] > - Resubmitting updated patch with "EFIAPI" decorator. [SAMI] > > - Secondly, I am wondering if it's possible to not expose any > library classes for handling of more ACPI tables. > I agree to implement UefiShellAcpiViewCommandLib in a way for easy > extension for handling of more ACPI tables, but I prefer to keep the > interfaces internally inside the UefiShellAcpiViewCommandLib. [RAY] > - Updated as suggested. [SAMI] > > v3: > - Can the individual "child" libraries be placed into > subdirectories under UefiShellAcpiViewCommandLib directory > for clear separation? [JABEN] > - Patch updated to move individual "child" libraries into > subdirectories. [SAMI] > > - In UefiShellAcpiViewCommandLib,c what's the motivation for all > the wrappers around print? I see that some are for memory access > restrictions, but the rest? PrintGuid, looks the same as using > %g with Print()... [JABEN] > - The print wrappers enable a common styled formatted printing for > the ACPI fields. The ACPIview table parsing framework utilizes a > table-driven approach for parsing the tables and these functions > are invoked by the framework based on the field size and type. > However you are right, it is superfluous in the case of PrintGuid > (Which has now been removed in the updated patch). [SAMI] > > - Do we want to change the main entrypoint to a DynamicCommand > since this command is not in the shell spec? If yes, do we want > to do that first or after? [JABEN] > - The ECR 1784 for ACPIview appears to be 'Approved as new content > for the Shell Spec.' in Mantis, > see https://mantis.uefi.org/mantis/view.php?id=1784. > As I understand it, the ECR change needs to be propagated to the > Shell specification and is pending. In light of the above, I think > that adding DynamicCommand support is not necessary. Please let me > know if you feel otherwise. [SAMI] > > ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c | 662 +++++++++++++++++ > ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h | 759 ++++++++++++++++++++ > ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.c | 215 ++++++ > ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h | 126 ++++ > ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c | 601 ++++++++++++++++ > ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.h | 103 +++ > ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Bgrt/BgrtParser.c | 69 ++ > ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c | 242 +++++++ > ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dsdt/DsdtParser.c | 47 ++ > ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c | 261 +++++++ > ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Gtdt/GtdtParser.c | 293 ++++++++ > ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c | 700 ++++++++++++++++++ > ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c | 313 ++++++++ > ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Mcfg/McfgParser.c | 94 +++ > ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rsdp/RsdpParser.c | 169 +++++ > ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Slit/SlitParser.c | 142 ++++ > ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Spcr/SpcrParser.c | 168 +++++ > ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Srat/SratParser.c | 330 +++++++++ > ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Ssdt/SsdtParser.c | 47 ++ > ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Xsdt/XsdtParser.c | 153 ++++ > ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c | 167 +++++ > ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.h | 32 + > ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf | 74 ++ > ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni | 127 ++++ > ShellPkg/ShellPkg.dec | 3 +- > 25 files changed, 5896 insertions(+), 1 deletion(-) > > diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c > new file mode 100644 > index 0000000000000000000000000000000000000000..318f386fda165146bad49f9edbc111d4e218db98 > --- /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 > +#include > +#include > +#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 0000000000000000000000000000000000000000..4dadd4d10423cb60ca17c1b1d285c55e2e58a0e0 > --- /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 0000000000000000000000000000000000000000..14a8b1441143d1e35fb594f5f1a20481cba1ef20 > --- /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 > +#include > +#include > +#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 0000000000000000000000000000000000000000..a69d56da6cf728bb98df265de3ae030d85120494 > --- /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 0000000000000000000000000000000000000000..3bb142538c0099dcdd2dfa3d208d3350c425accb > --- /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 > +#include > +#include > +#include > +#include > +#include > +#include > +#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 0000000000000000000000000000000000000000..03561ea81686821e37c05d90f053731fde63fbb5 > --- /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 0000000000000000000000000000000000000000..0b3f9a79012a97d03d88eb3e160b77d869fce394 > --- /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 > +#include > +#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 0000000000000000000000000000000000000000..f70a1328cc97656f5d651eb01e80df3236291a4a > --- /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 > +#include > +#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 0000000000000000000000000000000000000000..ef459a12099cae888676123e8d569460fd684db2 > --- /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 > +#include > +#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 0000000000000000000000000000000000000000..fdccb2ac3bd7698bbe1ce067964be53519813db1 > --- /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 > +#include > +#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 0000000000000000000000000000000000000000..ce96604ee6f800adfbd861691ffa7093b9bd8239 > --- /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 > +#include > +#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 0000000000000000000000000000000000000000..503a745718d23082c7bc4b0bc920355a839fc895 > --- /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 > +#include > +#include > +#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 0000000000000000000000000000000000000000..2ccbb7b80edc3b4c1e51a55b416bde11a145f25d > --- /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 > +#include > +#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 0000000000000000000000000000000000000000..a21b30dc0d5b601084e4ffcd07e73b66d118b326 > --- /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 > +#include > +#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 0000000000000000000000000000000000000000..9d3fe7a259142264ad575ab39e212a2d9e8da633 > --- /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 > +#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 0000000000000000000000000000000000000000..5f99fd46a03acc414b72212ca9f556e8aa232985 > --- /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 > +#include > +#include > +#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 0000000000000000000000000000000000000000..841a27ffdfab78210545d0be95e101f68becfefc > --- /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 > +#include > +#include > +#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 0000000000000000000000000000000000000000..86da55935c83539691f53e0b4c57a6356210bbdc > --- /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 > +#include > +#include > +#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 0000000000000000000000000000000000000000..a77ccbe06068e5da47ff5488cf9abc94c5583c9c > --- /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 > +#include > +#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 0000000000000000000000000000000000000000..0ed65d2e72cd213ad7695fefd4a5a0c06f96ff2c > --- /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 > +#include > +#include > +#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 0000000000000000000000000000000000000000..7de28691be26bc14e26c4c284e406700669c77cf > --- /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.
> + 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 > +#include > +#include > +#include > +#include > +#include > +#include > +#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 0000000000000000000000000000000000000000..59c8e21544d6829ac872958f6b84358e1f91b02f > --- /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.
> + 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 0000000000000000000000000000000000000000..dbdb7e301b4a53e53886e9a1f05b3fb2921a90d9 > --- /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.
> +# > +# 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 0000000000000000000000000000000000000000..1c4d66e1ff507054d4aa42bd47bfae8824c218e6 > --- /dev/null > +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni > @@ -0,0 +1,127 @@ > +// /** > +// > +// Copyright (c) 2016 - 2017, 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. > +// > +// 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" > + > diff --git a/ShellPkg/ShellPkg.dec b/ShellPkg/ShellPkg.dec > index 0c4f74ff41726c4a28ed082849c1b864b1c48752..c090aa4d08be3aad4d9aedb542c01056bce46969 100644 > --- a/ShellPkg/ShellPkg.dec > +++ b/ShellPkg/ShellPkg.dec > @@ -3,6 +3,7 @@ > # > # (C) Copyright 2013-2014 Hewlett-Packard Development Company, L.P.
> # Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.
> +# 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. > @@ -56,7 +57,7 @@ [Guids] > gShellNetwork2HiiGuid = {0x174b2b5, 0xf505, 0x4b12, {0xaa, 0x60, 0x59, 0xdf, 0xf8, 0xd6, 0xea, 0x37}} > gShellTftpHiiGuid = {0x738a9314, 0x82c1, 0x4592, {0x8f, 0xf7, 0xc1, 0xbd, 0xf1, 0xb2, 0x0e, 0xd4}} > gShellBcfgHiiGuid = {0x5f5f605d, 0x1583, 0x4a2d, {0xa6, 0xb2, 0xeb, 0x12, 0xda, 0xb4, 0xa2, 0xb6}} > - > + gShellAcpiViewHiiGuid = {0xda8ccdf4, 0xed8f, 0x4ffc, {0xb5, 0xef, 0x2e, 0xf5, 0x5e, 0x24, 0x93, 0x2a}} > # FILE_GUID as defined in ShellPkg/Application/Shell/Shell.inf > gUefiShellFileGuid = {0x7c04a583, 0x9e3e, 0x4f1c, {0xad, 0x65, 0xe0, 0x52, 0x68, 0xd0, 0xb4, 0xd1}} > > -- > 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)' > > Sami, Thank you very much for the big feature enabling. Reviewed-by: Ruiyu Ni Maybe minor bugs exist. Let's fix them after checking the big patch in. -- Thanks, Ray