diff options
Diffstat (limited to 'ShellPkg/Library/UefiShellAcpiViewCommandLib')
39 files changed, 11894 insertions, 11894 deletions
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c index eac9286176..63269b270d 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.c @@ -1,942 +1,942 @@ -/** @file
- ACPI parser
-
- Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.
- Copyright (c) 2022, AMD Incorporated. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#include <Uefi.h>
-#include <Library/UefiLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/BaseMemoryLib.h>
-#include "AcpiParser.h"
-#include "AcpiView.h"
-#include "AcpiViewConfig.h"
-
-STATIC UINT32 gIndent;
-STATIC UINT32 mTableErrorCount;
-STATIC UINT32 mTableWarningCount;
-
-STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
-
-/**
- An ACPI_PARSER array describing the ACPI header.
-**/
-STATIC CONST ACPI_PARSER AcpiHeaderParser[] = {
- PARSE_ACPI_HEADER (&AcpiHdrInfo)
-};
-
-/**
- This function resets the ACPI table error counter to Zero.
-**/
-VOID
-ResetErrorCount (
- VOID
- )
-{
- mTableErrorCount = 0;
-}
-
-/**
- This function returns the ACPI table error count.
-
- @retval Returns the count of errors detected in the ACPI tables.
-**/
-UINT32
-GetErrorCount (
- VOID
- )
-{
- return mTableErrorCount;
-}
-
-/**
- This function resets the ACPI table warning counter to Zero.
-**/
-VOID
-ResetWarningCount (
- VOID
- )
-{
- mTableWarningCount = 0;
-}
-
-/**
- This function returns the ACPI table warning count.
-
- @retval Returns the count of warning detected in the ACPI tables.
-**/
-UINT32
-GetWarningCount (
- VOID
- )
-{
- return mTableWarningCount;
-}
-
-/**
- This function increments the ACPI table error counter.
-**/
-VOID
-EFIAPI
-IncrementErrorCount (
- VOID
- )
-{
- mTableErrorCount++;
-}
-
-/**
- This function increments the ACPI table warning counter.
-**/
-VOID
-EFIAPI
-IncrementWarningCount (
- VOID
- )
-{
- mTableWarningCount++;
-}
-
-/**
- This function verifies the ACPI table checksum.
-
- This function verifies the checksum for the ACPI table and optionally
- prints the status.
-
- @param [in] Log If TRUE log the status of the checksum.
- @param [in] Ptr Pointer to the start of the table buffer.
- @param [in] Length The length of the buffer.
-
- @retval TRUE The checksum is OK.
- @retval FALSE The checksum failed.
-**/
-BOOLEAN
-EFIAPI
-VerifyChecksum (
- IN BOOLEAN Log,
- IN UINT8 *Ptr,
- IN UINT32 Length
- )
-{
- UINTN ByteCount;
- UINT8 Checksum;
- UINTN OriginalAttribute;
-
- //
- // set local variables to suppress incorrect compiler/analyzer warnings
- //
- OriginalAttribute = 0;
- ByteCount = 0;
- Checksum = 0;
-
- while (ByteCount < Length) {
- Checksum += *(Ptr++);
- ByteCount++;
- }
-
- if (Log) {
- OriginalAttribute = gST->ConOut->Mode->Attribute;
- if (Checksum == 0) {
- if (GetColourHighlighting ()) {
- gST->ConOut->SetAttribute (
- gST->ConOut,
- EFI_TEXT_ATTR (
- EFI_GREEN,
- ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)
- )
- );
- }
-
- Print (L"Table Checksum : OK\n\n");
- } else {
- IncrementErrorCount ();
- if (GetColourHighlighting ()) {
- gST->ConOut->SetAttribute (
- gST->ConOut,
- EFI_TEXT_ATTR (
- EFI_RED,
- ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)
- )
- );
- }
-
- Print (L"Table Checksum : FAILED (0x%X)\n\n", Checksum);
- }
-
- if (GetColourHighlighting ()) {
- gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);
- }
- }
-
- return (Checksum == 0);
-}
-
-/**
- This function performs a raw data dump of the ACPI table.
-
- @param [in] Ptr Pointer to the start of the table buffer.
- @param [in] Length The length of the buffer.
-**/
-VOID
-EFIAPI
-DumpRaw (
- IN UINT8 *Ptr,
- IN UINT32 Length
- )
-{
- UINTN ByteCount;
- UINTN PartLineChars;
- UINTN AsciiBufferIndex;
- CHAR8 AsciiBuffer[17];
-
- ByteCount = 0;
- AsciiBufferIndex = 0;
-
- Print (L"Address : 0x%p\n", Ptr);
- Print (L"Length : %d\n", Length);
-
- while (ByteCount < Length) {
- if ((ByteCount & 0x0F) == 0) {
- AsciiBuffer[AsciiBufferIndex] = '\0';
- Print (L" %a\n%08X : ", AsciiBuffer, ByteCount);
- AsciiBufferIndex = 0;
- } else if ((ByteCount & 0x07) == 0) {
- Print (L"- ");
- }
-
- if ((*Ptr >= ' ') && (*Ptr < 0x7F)) {
- AsciiBuffer[AsciiBufferIndex++] = *Ptr;
- } else {
- AsciiBuffer[AsciiBufferIndex++] = '.';
- }
-
- Print (L"%02X ", *Ptr++);
-
- ByteCount++;
- }
-
- // Justify the final line using spaces before printing
- // the ASCII data.
- PartLineChars = (Length & 0x0F);
- if (PartLineChars != 0) {
- PartLineChars = 48 - (PartLineChars * 3);
- if ((Length & 0x0F) <= 8) {
- PartLineChars += 2;
- }
-
- while (PartLineChars > 0) {
- Print (L" ");
- PartLineChars--;
- }
- }
-
- // Print ASCII data for the final line.
- AsciiBuffer[AsciiBufferIndex] = '\0';
- Print (L" %a\n\n", AsciiBuffer);
-}
-
-/**
- This function traces 1 byte of data as specified in the format string.
-
- @param [in] Format The format string for tracing the data.
- @param [in] Ptr Pointer to the start of the buffer.
-**/
-VOID
-EFIAPI
-DumpUint8 (
- IN CONST CHAR16 *Format,
- IN UINT8 *Ptr
- )
-{
- Print (Format, *Ptr);
-}
-
-/**
- This function traces 2 bytes of data as specified in the format string.
-
- @param [in] Format The format string for tracing the data.
- @param [in] Ptr Pointer to the start of the buffer.
-**/
-VOID
-EFIAPI
-DumpUint16 (
- IN CONST CHAR16 *Format,
- IN UINT8 *Ptr
- )
-{
- Print (Format, *(UINT16 *)Ptr);
-}
-
-/**
- This function traces 4 bytes of data as specified in the format string.
-
- @param [in] Format The format string for tracing the data.
- @param [in] Ptr Pointer to the start of the buffer.
-**/
-VOID
-EFIAPI
-DumpUint32 (
- IN CONST CHAR16 *Format,
- IN UINT8 *Ptr
- )
-{
- Print (Format, *(UINT32 *)Ptr);
-}
-
-/**
- This function traces 8 bytes of data as specified by the format string.
-
- @param [in] Format The format string for tracing the data.
- @param [in] Ptr Pointer to the start of the buffer.
-**/
-VOID
-EFIAPI
-DumpUint64 (
- IN CONST CHAR16 *Format,
- IN UINT8 *Ptr
- )
-{
- // Some fields are not aligned and this causes alignment faults
- // on ARM platforms if the compiler generates LDRD instructions.
- // Perform word access so that LDRD instructions are not generated.
- UINT64 Val;
-
- Val = *(UINT32 *)(Ptr + sizeof (UINT32));
-
- Val = LShiftU64 (Val, 32);
- Val |= (UINT64)*(UINT32 *)Ptr;
-
- Print (Format, Val);
-}
-
-/**
- This function traces 3 characters which can be optionally
- formated using the format string if specified.
-
- If no format string is specified the Format must be NULL.
-
- @param [in] Format Optional format string for tracing the data.
- @param [in] Ptr Pointer to the start of the buffer.
-**/
-VOID
-EFIAPI
-Dump3Chars (
- IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
- )
-{
- Print (
- (Format != NULL) ? Format : L"%c%c%c",
- Ptr[0],
- Ptr[1],
- Ptr[2]
- );
-}
-
-/**
- This function traces 4 characters which can be optionally
- formated using the format string if specified.
-
- If no format string is specified the Format must be NULL.
-
- @param [in] Format Optional format string for tracing the data.
- @param [in] Ptr Pointer to the start of the buffer.
-**/
-VOID
-EFIAPI
-Dump4Chars (
- IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
- )
-{
- Print (
- (Format != NULL) ? Format : L"%c%c%c%c",
- Ptr[0],
- Ptr[1],
- Ptr[2],
- Ptr[3]
- );
-}
-
-/**
- This function traces 6 characters which can be optionally
- formated using the format string if specified.
-
- If no format string is specified the Format must be NULL.
-
- @param [in] Format Optional format string for tracing the data.
- @param [in] Ptr Pointer to the start of the buffer.
-**/
-VOID
-EFIAPI
-Dump6Chars (
- IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
- )
-{
- Print (
- (Format != NULL) ? Format : L"%c%c%c%c%c%c",
- Ptr[0],
- Ptr[1],
- Ptr[2],
- Ptr[3],
- Ptr[4],
- Ptr[5]
- );
-}
-
-/**
- This function traces 8 characters which can be optionally
- formated using the format string if specified.
-
- If no format string is specified the Format must be NULL.
-
- @param [in] Format Optional format string for tracing the data.
- @param [in] Ptr Pointer to the start of the buffer.
-**/
-VOID
-EFIAPI
-Dump8Chars (
- IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
- )
-{
- Print (
- (Format != NULL) ? Format : L"%c%c%c%c%c%c%c%c",
- Ptr[0],
- Ptr[1],
- Ptr[2],
- Ptr[3],
- Ptr[4],
- Ptr[5],
- Ptr[6],
- Ptr[7]
- );
-}
-
-/**
- This function traces 12 characters which can be optionally
- formated using the format string if specified.
-
- If no format string is specified the Format must be NULL.
-
- @param [in] Format Optional format string for tracing the data.
- @param [in] Ptr Pointer to the start of the buffer.
-**/
-VOID
-EFIAPI
-Dump12Chars (
- IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
- )
-{
- Print (
- (Format != NULL) ? Format : L"%c%c%c%c%c%c%c%c%c%c%c%c",
- Ptr[0],
- Ptr[1],
- Ptr[2],
- Ptr[3],
- Ptr[4],
- Ptr[5],
- Ptr[6],
- Ptr[7],
- Ptr[8],
- Ptr[9],
- Ptr[10],
- Ptr[11]
- );
-}
-
-/**
- This function indents and prints the ACPI table Field Name.
-
- @param [in] Indent Number of spaces to add to the global table indent.
- The global table indent is 0 by default; however
- this value is updated on entry to the ParseAcpi()
- by adding the indent value provided to ParseAcpi()
- and restored back on exit.
- Therefore the total indent in the output is
- dependent on from where this function is called.
- @param [in] FieldName Pointer to the Field Name.
-**/
-VOID
-EFIAPI
-PrintFieldName (
- IN UINT32 Indent,
- IN CONST CHAR16 *FieldName
- )
-{
- Print (
- L"%*a%-*s : ",
- gIndent + Indent,
- "",
- (OUTPUT_FIELD_COLUMN_WIDTH - gIndent - Indent),
- FieldName
- );
-}
-
-/**
- This function is used to parse an ACPI table buffer.
-
- The ACPI table buffer is parsed using the ACPI table parser information
- specified by a pointer to an array of ACPI_PARSER elements. This parser
- function iterates through each item on the ACPI_PARSER array and logs the
- ACPI table fields.
-
- This function can optionally be used to parse ACPI tables and fetch specific
- field values. The ItemPtr member of the ACPI_PARSER structure (where used)
- is updated by this parser function to point to the selected field data
- (e.g. useful for variable length nested fields).
-
- @param [in] Trace Trace the ACPI fields TRUE else only parse the
- table.
- @param [in] Indent Number of spaces to indent the output.
- @param [in] AsciiName Optional pointer to an ASCII string that describes
- the table being parsed.
- @param [in] Ptr Pointer to the start of the buffer.
- @param [in] Length Length of the buffer pointed by Ptr.
- @param [in] Parser Pointer to an array of ACPI_PARSER structure that
- describes the table being parsed.
- @param [in] ParserItems Number of items in the ACPI_PARSER array.
-
- @retval Number of bytes parsed.
-**/
-UINT32
-EFIAPI
-ParseAcpi (
- IN BOOLEAN Trace,
- IN UINT32 Indent,
- IN CONST CHAR8 *AsciiName OPTIONAL,
- IN UINT8 *Ptr,
- IN UINT32 Length,
- IN CONST ACPI_PARSER *Parser,
- IN UINT32 ParserItems
- )
-{
- UINT32 Index;
- UINT32 Offset;
- BOOLEAN HighLight;
- UINTN OriginalAttribute;
-
- //
- // set local variables to suppress incorrect compiler/analyzer warnings
- //
- OriginalAttribute = 0;
- Offset = 0;
-
- // Increment the Indent
- gIndent += Indent;
-
- if (Trace && (AsciiName != NULL)) {
- HighLight = GetColourHighlighting ();
-
- if (HighLight) {
- OriginalAttribute = gST->ConOut->Mode->Attribute;
- gST->ConOut->SetAttribute (
- gST->ConOut,
- EFI_TEXT_ATTR (
- EFI_YELLOW,
- ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)
- )
- );
- }
-
- Print (
- L"%*a%-*a :\n",
- gIndent,
- "",
- (OUTPUT_FIELD_COLUMN_WIDTH - gIndent),
- AsciiName
- );
- if (HighLight) {
- gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);
- }
- }
-
- for (Index = 0; Index < ParserItems; Index++) {
- if ((Offset + Parser[Index].Length) > Length) {
- // For fields outside the buffer length provided, reset any pointers
- // which were supposed to be updated by this function call
- if (Parser[Index].ItemPtr != NULL) {
- *Parser[Index].ItemPtr = NULL;
- }
-
- // We don't parse past the end of the max length specified
- continue;
- }
-
- if (GetConsistencyChecking () &&
- (Offset != Parser[Index].Offset))
- {
- IncrementErrorCount ();
- Print (
- L"\nERROR: %a: Offset Mismatch for %s\n"
- L"CurrentOffset = %d FieldOffset = %d\n",
- AsciiName,
- Parser[Index].NameStr,
- Offset,
- Parser[Index].Offset
- );
- }
-
- if (Trace) {
- // if there is a Formatter function let the function handle
- // the printing else if a Format is specified in the table use
- // the Format for printing
- PrintFieldName (2, Parser[Index].NameStr);
- if (Parser[Index].PrintFormatter != NULL) {
- Parser[Index].PrintFormatter (Parser[Index].Format, Ptr);
- } else if (Parser[Index].Format != NULL) {
- switch (Parser[Index].Length) {
- case 1:
- DumpUint8 (Parser[Index].Format, Ptr);
- break;
- case 2:
- DumpUint16 (Parser[Index].Format, Ptr);
- break;
- case 4:
- DumpUint32 (Parser[Index].Format, Ptr);
- break;
- case 8:
- DumpUint64 (Parser[Index].Format, Ptr);
- break;
- default:
- Print (
- L"\nERROR: %a: CANNOT PARSE THIS FIELD, Field Length = %d\n",
- AsciiName,
- Parser[Index].Length
- );
- } // switch
- }
-
- // Validating only makes sense if we are tracing
- // the parsed table entries, to report by table name.
- if (GetConsistencyChecking () &&
- (Parser[Index].FieldValidator != NULL))
- {
- Parser[Index].FieldValidator (Ptr, Parser[Index].Context);
- }
-
- Print (L"\n");
- } // if (Trace)
-
- if (Parser[Index].ItemPtr != NULL) {
- *Parser[Index].ItemPtr = (VOID *)Ptr;
- }
-
- Ptr += Parser[Index].Length;
- Offset += Parser[Index].Length;
- } // for
-
- // Decrement the Indent
- gIndent -= Indent;
- return Offset;
-}
-
-/**
- An array describing the ACPI Generic Address Structure.
- The GasParser array is used by the ParseAcpi function to parse and/or trace
- the GAS structure.
-**/
-STATIC CONST ACPI_PARSER GasParser[] = {
- { L"Address Space ID", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Register Bit Width", 1, 1, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Register Bit Offset", 1, 2, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Access Size", 1, 3, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Address", 8, 4, L"0x%lx", NULL, NULL, NULL, NULL }
-};
-
-/**
- This function indents and traces the GAS structure as described by the GasParser.
-
- @param [in] Ptr Pointer to the start of the buffer.
- @param [in] Indent Number of spaces to indent the output.
- @param [in] Length Length of the GAS structure buffer.
-
- @retval Number of bytes parsed.
-**/
-UINT32
-EFIAPI
-DumpGasStruct (
- IN UINT8 *Ptr,
- IN UINT32 Indent,
- IN UINT32 Length
- )
-{
- Print (L"\n");
- return ParseAcpi (
- TRUE,
- Indent,
- NULL,
- Ptr,
- Length,
- PARSER_PARAMS (GasParser)
- );
-}
-
-/**
- This function traces the GAS structure as described by the GasParser.
-
- @param [in] Format Optional format string for tracing the data.
- @param [in] Ptr Pointer to the start of the buffer.
-**/
-VOID
-EFIAPI
-DumpGas (
- IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
- )
-{
- DumpGasStruct (Ptr, 2, sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE));
-}
-
-/**
- This function traces the ACPI header as described by the AcpiHeaderParser.
-
- @param [in] Ptr Pointer to the start of the buffer.
-
- @retval Number of bytes parsed.
-**/
-UINT32
-EFIAPI
-DumpAcpiHeader (
- IN UINT8 *Ptr
- )
-{
- return ParseAcpi (
- TRUE,
- 0,
- "ACPI Table Header",
- Ptr,
- sizeof (EFI_ACPI_DESCRIPTION_HEADER),
- PARSER_PARAMS (AcpiHeaderParser)
- );
-}
-
-/**
- This function parses the ACPI header as described by the AcpiHeaderParser.
-
- This function optionally returns the signature, length and revision of the
- ACPI table.
-
- @param [in] Ptr Pointer to the start of the buffer.
- @param [out] Signature Gets location of the ACPI table signature.
- @param [out] Length Gets location of the length of the ACPI table.
- @param [out] Revision Gets location of the revision of the ACPI table.
-
- @retval Number of bytes parsed.
-**/
-UINT32
-EFIAPI
-ParseAcpiHeader (
- IN UINT8 *Ptr,
- OUT CONST UINT32 **Signature,
- OUT CONST UINT32 **Length,
- OUT CONST UINT8 **Revision
- )
-{
- UINT32 BytesParsed;
-
- BytesParsed = ParseAcpi (
- FALSE,
- 0,
- NULL,
- Ptr,
- sizeof (EFI_ACPI_DESCRIPTION_HEADER),
- PARSER_PARAMS (AcpiHeaderParser)
- );
-
- *Signature = AcpiHdrInfo.Signature;
- *Length = AcpiHdrInfo.Length;
- *Revision = AcpiHdrInfo.Revision;
-
- return BytesParsed;
-}
-
-/**
- This function is used to parse an ACPI table bitfield buffer.
-
- The ACPI table buffer is parsed using the ACPI table parser information
- specified by a pointer to an array of ACPI_PARSER elements. This parser
- function iterates through each item on the ACPI_PARSER array and logs the ACPI table bitfields.
-
- This function can optionally be used to parse ACPI tables and fetch specific
- field values. The ItemPtr member of the ACPI_PARSER structure (where used)
- is updated by this parser function to point to the selected field data
- (e.g. useful for variable length nested fields).
-
- ItemPtr member of ACPI_PARSER is not supported with this function.
-
- @param [in] Trace Trace the ACPI fields TRUE else only parse the
- table.
- @param [in] Indent Number of spaces to indent the output.
- @param [in] AsciiName Optional pointer to an ASCII string that describes
- the table being parsed.
- @param [in] Ptr Pointer to the start of the buffer.
- @param [in] Length Length in bytes of the buffer pointed by Ptr.
- @param [in] Parser Pointer to an array of ACPI_PARSER structure that
- describes the table being parsed.
- @param [in] ParserItems Number of items in the ACPI_PARSER array.
-
- @retval Number of bits parsed.
-**/
-UINT32
-EFIAPI
-ParseAcpiBitFields (
- IN BOOLEAN Trace,
- IN UINT32 Indent,
- IN CONST CHAR8 *AsciiName OPTIONAL,
- IN UINT8 *Ptr,
- IN UINT32 Length,
- IN CONST ACPI_PARSER *Parser,
- IN UINT32 ParserItems
- )
-{
- UINT32 Index;
- UINT32 Offset;
- BOOLEAN HighLight;
- UINTN OriginalAttribute;
-
- UINT64 Data;
- UINT64 BitsData;
-
- if ((Length == 0) || (Length > 8)) {
- IncrementErrorCount ();
- Print (
- L"\nERROR: Bitfield Length(%d) is zero or exceeding the 64 bit limit.\n",
- Length
- );
- return 0;
- }
-
- //
- // set local variables to suppress incorrect compiler/analyzer warnings
- //
- OriginalAttribute = 0;
- Offset = 0;
-
- // Increment the Indent
- gIndent += Indent;
-
- CopyMem ((VOID *)&BitsData, (VOID *)Ptr, Length);
- if (Trace && (AsciiName != NULL)) {
- HighLight = GetColourHighlighting ();
-
- if (HighLight) {
- OriginalAttribute = gST->ConOut->Mode->Attribute;
- gST->ConOut->SetAttribute (
- gST->ConOut,
- EFI_TEXT_ATTR (
- EFI_YELLOW,
- ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4)
- )
- );
- }
-
- Print (
- L"%*a%-*a :\n",
- gIndent,
- "",
- (OUTPUT_FIELD_COLUMN_WIDTH - gIndent),
- AsciiName
- );
- if (HighLight) {
- gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute);
- }
- }
-
- for (Index = 0; Index < ParserItems; Index++) {
- if ((Offset + Parser[Index].Length) > (Length * 8)) {
- // For fields outside the buffer length provided, reset any pointers
- // which were supposed to be updated by this function call
- if (Parser[Index].ItemPtr != NULL) {
- *Parser[Index].ItemPtr = NULL;
- }
-
- // We don't parse past the end of the max length specified
- continue;
- }
-
- if (Parser[Index].Length == 0) {
- IncrementErrorCount ();
- // don't parse the bitfield whose length is zero
- Print (
- L"\nERROR: %a: Cannot parse this field, Field Length = %d\n",
- Parser[Index].Length
- );
- continue;
- }
-
- if (GetConsistencyChecking () &&
- (Offset != Parser[Index].Offset))
- {
- IncrementErrorCount ();
- Print (
- L"\nERROR: %a: Offset Mismatch for %s\n"
- L"CurrentOffset = %d FieldOffset = %d\n",
- AsciiName,
- Parser[Index].NameStr,
- Offset,
- Parser[Index].Offset
- );
- }
-
- // extract Bitfield data for the current item
- Data = RShiftU64 (BitsData, Parser[Index].Offset) & ~(LShiftU64 (~0ULL, Parser[Index].Length));
-
- if (Trace) {
- // if there is a Formatter function let the function handle
- // the printing else if a Format is specified in the table use
- // the Format for printing
- PrintFieldName (2, Parser[Index].NameStr);
- if (Parser[Index].PrintFormatter != NULL) {
- Parser[Index].PrintFormatter (Parser[Index].Format, (UINT8 *)&Data);
- } else if (Parser[Index].Format != NULL) {
- // convert bit length to byte length
- switch ((Parser[Index].Length + 7) >> 3) {
- // print the data depends on byte size
- case 1:
- DumpUint8 (Parser[Index].Format, (UINT8 *)&Data);
- break;
- case 2:
- DumpUint16 (Parser[Index].Format, (UINT8 *)&Data);
- break;
- case 3:
- case 4:
- DumpUint32 (Parser[Index].Format, (UINT8 *)&Data);
- break;
- case 5:
- case 6:
- case 7:
- case 8:
- DumpUint64 (Parser[Index].Format, (UINT8 *)&Data);
- break;
- default:
- Print (
- L"\nERROR: %a: CANNOT PARSE THIS FIELD, Field Length = %d\n",
- AsciiName,
- Parser[Index].Length
- );
- } // switch
- }
-
- // Validating only makes sense if we are tracing
- // the parsed table entries, to report by table name.
- if (GetConsistencyChecking () &&
- (Parser[Index].FieldValidator != NULL))
- {
- Parser[Index].FieldValidator ((UINT8 *)&Data, Parser[Index].Context);
- }
-
- Print (L"\n");
- } // if (Trace)
-
- Offset += Parser[Index].Length;
- } // for
-
- // Decrement the Indent
- gIndent -= Indent;
- return Offset;
-}
+/** @file + ACPI parser + + Copyright (c) 2016 - 2021, Arm Limited. All rights reserved. + Copyright (c) 2022, AMD Incorporated. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <Uefi.h> +#include <Library/UefiLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/BaseMemoryLib.h> +#include "AcpiParser.h" +#include "AcpiView.h" +#include "AcpiViewConfig.h" + +STATIC UINT32 gIndent; +STATIC UINT32 mTableErrorCount; +STATIC UINT32 mTableWarningCount; + +STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; + +/** + An ACPI_PARSER array describing the ACPI header. +**/ +STATIC CONST ACPI_PARSER AcpiHeaderParser[] = { + PARSE_ACPI_HEADER (&AcpiHdrInfo) +}; + +/** + This function resets the ACPI table error counter to Zero. +**/ +VOID +ResetErrorCount ( + VOID + ) +{ + mTableErrorCount = 0; +} + +/** + This function returns the ACPI table error count. + + @retval Returns the count of errors detected in the ACPI tables. +**/ +UINT32 +GetErrorCount ( + VOID + ) +{ + return mTableErrorCount; +} + +/** + This function resets the ACPI table warning counter to Zero. +**/ +VOID +ResetWarningCount ( + VOID + ) +{ + mTableWarningCount = 0; +} + +/** + This function returns the ACPI table warning count. + + @retval Returns the count of warning detected in the ACPI tables. +**/ +UINT32 +GetWarningCount ( + VOID + ) +{ + return mTableWarningCount; +} + +/** + This function increments the ACPI table error counter. +**/ +VOID +EFIAPI +IncrementErrorCount ( + VOID + ) +{ + mTableErrorCount++; +} + +/** + This function increments the ACPI table warning counter. +**/ +VOID +EFIAPI +IncrementWarningCount ( + VOID + ) +{ + mTableWarningCount++; +} + +/** + This function verifies the ACPI table checksum. + + This function verifies the checksum for the ACPI table and optionally + prints the status. + + @param [in] Log If TRUE log the status of the checksum. + @param [in] Ptr Pointer to the start of the table buffer. + @param [in] Length The length of the buffer. + + @retval TRUE The checksum is OK. + @retval FALSE The checksum failed. +**/ +BOOLEAN +EFIAPI +VerifyChecksum ( + IN BOOLEAN Log, + IN UINT8 *Ptr, + IN UINT32 Length + ) +{ + UINTN ByteCount; + UINT8 Checksum; + UINTN OriginalAttribute; + + // + // set local variables to suppress incorrect compiler/analyzer warnings + // + OriginalAttribute = 0; + ByteCount = 0; + Checksum = 0; + + while (ByteCount < Length) { + Checksum += *(Ptr++); + ByteCount++; + } + + if (Log) { + OriginalAttribute = gST->ConOut->Mode->Attribute; + if (Checksum == 0) { + if (GetColourHighlighting ()) { + gST->ConOut->SetAttribute ( + gST->ConOut, + EFI_TEXT_ATTR ( + EFI_GREEN, + ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4) + ) + ); + } + + Print (L"Table Checksum : OK\n\n"); + } else { + IncrementErrorCount (); + if (GetColourHighlighting ()) { + gST->ConOut->SetAttribute ( + gST->ConOut, + EFI_TEXT_ATTR ( + EFI_RED, + ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4) + ) + ); + } + + Print (L"Table Checksum : FAILED (0x%X)\n\n", Checksum); + } + + if (GetColourHighlighting ()) { + gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute); + } + } + + return (Checksum == 0); +} + +/** + This function performs a raw data dump of the ACPI table. + + @param [in] Ptr Pointer to the start of the table buffer. + @param [in] Length The length of the buffer. +**/ +VOID +EFIAPI +DumpRaw ( + IN UINT8 *Ptr, + IN UINT32 Length + ) +{ + UINTN ByteCount; + UINTN PartLineChars; + UINTN AsciiBufferIndex; + CHAR8 AsciiBuffer[17]; + + ByteCount = 0; + AsciiBufferIndex = 0; + + Print (L"Address : 0x%p\n", Ptr); + Print (L"Length : %d\n", Length); + + while (ByteCount < Length) { + if ((ByteCount & 0x0F) == 0) { + AsciiBuffer[AsciiBufferIndex] = '\0'; + Print (L" %a\n%08X : ", AsciiBuffer, ByteCount); + AsciiBufferIndex = 0; + } else if ((ByteCount & 0x07) == 0) { + Print (L"- "); + } + + if ((*Ptr >= ' ') && (*Ptr < 0x7F)) { + AsciiBuffer[AsciiBufferIndex++] = *Ptr; + } else { + AsciiBuffer[AsciiBufferIndex++] = '.'; + } + + Print (L"%02X ", *Ptr++); + + ByteCount++; + } + + // Justify the final line using spaces before printing + // the ASCII data. + PartLineChars = (Length & 0x0F); + if (PartLineChars != 0) { + PartLineChars = 48 - (PartLineChars * 3); + if ((Length & 0x0F) <= 8) { + PartLineChars += 2; + } + + while (PartLineChars > 0) { + Print (L" "); + PartLineChars--; + } + } + + // Print ASCII data for the final line. + AsciiBuffer[AsciiBufferIndex] = '\0'; + Print (L" %a\n\n", AsciiBuffer); +} + +/** + This function traces 1 byte of data as specified in the format string. + + @param [in] Format The format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. +**/ +VOID +EFIAPI +DumpUint8 ( + IN CONST CHAR16 *Format, + IN UINT8 *Ptr + ) +{ + Print (Format, *Ptr); +} + +/** + This function traces 2 bytes of data as specified in the format string. + + @param [in] Format The format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. +**/ +VOID +EFIAPI +DumpUint16 ( + IN CONST CHAR16 *Format, + IN UINT8 *Ptr + ) +{ + Print (Format, *(UINT16 *)Ptr); +} + +/** + This function traces 4 bytes of data as specified in the format string. + + @param [in] Format The format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. +**/ +VOID +EFIAPI +DumpUint32 ( + IN CONST CHAR16 *Format, + IN UINT8 *Ptr + ) +{ + Print (Format, *(UINT32 *)Ptr); +} + +/** + This function traces 8 bytes of data as specified by the format string. + + @param [in] Format The format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. +**/ +VOID +EFIAPI +DumpUint64 ( + IN CONST CHAR16 *Format, + IN UINT8 *Ptr + ) +{ + // Some fields are not aligned and this causes alignment faults + // on ARM platforms if the compiler generates LDRD instructions. + // Perform word access so that LDRD instructions are not generated. + UINT64 Val; + + Val = *(UINT32 *)(Ptr + sizeof (UINT32)); + + Val = LShiftU64 (Val, 32); + Val |= (UINT64)*(UINT32 *)Ptr; + + Print (Format, Val); +} + +/** + This function traces 3 characters which can be optionally + formated using the format string if specified. + + If no format string is specified the Format must be NULL. + + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. +**/ +VOID +EFIAPI +Dump3Chars ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + Print ( + (Format != NULL) ? Format : L"%c%c%c", + Ptr[0], + Ptr[1], + Ptr[2] + ); +} + +/** + This function traces 4 characters which can be optionally + formated using the format string if specified. + + If no format string is specified the Format must be NULL. + + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. +**/ +VOID +EFIAPI +Dump4Chars ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + Print ( + (Format != NULL) ? Format : L"%c%c%c%c", + Ptr[0], + Ptr[1], + Ptr[2], + Ptr[3] + ); +} + +/** + This function traces 6 characters which can be optionally + formated using the format string if specified. + + If no format string is specified the Format must be NULL. + + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. +**/ +VOID +EFIAPI +Dump6Chars ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + Print ( + (Format != NULL) ? Format : L"%c%c%c%c%c%c", + Ptr[0], + Ptr[1], + Ptr[2], + Ptr[3], + Ptr[4], + Ptr[5] + ); +} + +/** + This function traces 8 characters which can be optionally + formated using the format string if specified. + + If no format string is specified the Format must be NULL. + + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. +**/ +VOID +EFIAPI +Dump8Chars ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + Print ( + (Format != NULL) ? Format : L"%c%c%c%c%c%c%c%c", + Ptr[0], + Ptr[1], + Ptr[2], + Ptr[3], + Ptr[4], + Ptr[5], + Ptr[6], + Ptr[7] + ); +} + +/** + This function traces 12 characters which can be optionally + formated using the format string if specified. + + If no format string is specified the Format must be NULL. + + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. +**/ +VOID +EFIAPI +Dump12Chars ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + Print ( + (Format != NULL) ? Format : L"%c%c%c%c%c%c%c%c%c%c%c%c", + Ptr[0], + Ptr[1], + Ptr[2], + Ptr[3], + Ptr[4], + Ptr[5], + Ptr[6], + Ptr[7], + Ptr[8], + Ptr[9], + Ptr[10], + Ptr[11] + ); +} + +/** + This function indents and prints the ACPI table Field Name. + + @param [in] Indent Number of spaces to add to the global table indent. + The global table indent is 0 by default; however + this value is updated on entry to the ParseAcpi() + by adding the indent value provided to ParseAcpi() + and restored back on exit. + Therefore the total indent in the output is + dependent on from where this function is called. + @param [in] FieldName Pointer to the Field Name. +**/ +VOID +EFIAPI +PrintFieldName ( + IN UINT32 Indent, + IN CONST CHAR16 *FieldName + ) +{ + Print ( + L"%*a%-*s : ", + gIndent + Indent, + "", + (OUTPUT_FIELD_COLUMN_WIDTH - gIndent - Indent), + FieldName + ); +} + +/** + This function is used to parse an ACPI table buffer. + + The ACPI table buffer is parsed using the ACPI table parser information + specified by a pointer to an array of ACPI_PARSER elements. This parser + function iterates through each item on the ACPI_PARSER array and logs the + ACPI table fields. + + This function can optionally be used to parse ACPI tables and fetch specific + field values. The ItemPtr member of the ACPI_PARSER structure (where used) + is updated by this parser function to point to the selected field data + (e.g. useful for variable length nested fields). + + @param [in] Trace Trace the ACPI fields TRUE else only parse the + table. + @param [in] Indent Number of spaces to indent the output. + @param [in] AsciiName Optional pointer to an ASCII string that describes + the table being parsed. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the buffer pointed by Ptr. + @param [in] Parser Pointer to an array of ACPI_PARSER structure that + describes the table being parsed. + @param [in] ParserItems Number of items in the ACPI_PARSER array. + + @retval Number of bytes parsed. +**/ +UINT32 +EFIAPI +ParseAcpi ( + IN BOOLEAN Trace, + IN UINT32 Indent, + IN CONST CHAR8 *AsciiName OPTIONAL, + IN UINT8 *Ptr, + IN UINT32 Length, + IN CONST ACPI_PARSER *Parser, + IN UINT32 ParserItems + ) +{ + UINT32 Index; + UINT32 Offset; + BOOLEAN HighLight; + UINTN OriginalAttribute; + + // + // set local variables to suppress incorrect compiler/analyzer warnings + // + OriginalAttribute = 0; + Offset = 0; + + // Increment the Indent + gIndent += Indent; + + if (Trace && (AsciiName != NULL)) { + HighLight = GetColourHighlighting (); + + if (HighLight) { + OriginalAttribute = gST->ConOut->Mode->Attribute; + gST->ConOut->SetAttribute ( + gST->ConOut, + EFI_TEXT_ATTR ( + EFI_YELLOW, + ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4) + ) + ); + } + + Print ( + L"%*a%-*a :\n", + gIndent, + "", + (OUTPUT_FIELD_COLUMN_WIDTH - gIndent), + AsciiName + ); + if (HighLight) { + gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute); + } + } + + for (Index = 0; Index < ParserItems; Index++) { + if ((Offset + Parser[Index].Length) > Length) { + // For fields outside the buffer length provided, reset any pointers + // which were supposed to be updated by this function call + if (Parser[Index].ItemPtr != NULL) { + *Parser[Index].ItemPtr = NULL; + } + + // We don't parse past the end of the max length specified + continue; + } + + if (GetConsistencyChecking () && + (Offset != Parser[Index].Offset)) + { + IncrementErrorCount (); + Print ( + L"\nERROR: %a: Offset Mismatch for %s\n" + L"CurrentOffset = %d FieldOffset = %d\n", + AsciiName, + Parser[Index].NameStr, + Offset, + Parser[Index].Offset + ); + } + + if (Trace) { + // if there is a Formatter function let the function handle + // the printing else if a Format is specified in the table use + // the Format for printing + PrintFieldName (2, Parser[Index].NameStr); + if (Parser[Index].PrintFormatter != NULL) { + Parser[Index].PrintFormatter (Parser[Index].Format, Ptr); + } else if (Parser[Index].Format != NULL) { + switch (Parser[Index].Length) { + case 1: + DumpUint8 (Parser[Index].Format, Ptr); + break; + case 2: + DumpUint16 (Parser[Index].Format, Ptr); + break; + case 4: + DumpUint32 (Parser[Index].Format, Ptr); + break; + case 8: + DumpUint64 (Parser[Index].Format, Ptr); + break; + default: + Print ( + L"\nERROR: %a: CANNOT PARSE THIS FIELD, Field Length = %d\n", + AsciiName, + Parser[Index].Length + ); + } // switch + } + + // Validating only makes sense if we are tracing + // the parsed table entries, to report by table name. + if (GetConsistencyChecking () && + (Parser[Index].FieldValidator != NULL)) + { + Parser[Index].FieldValidator (Ptr, Parser[Index].Context); + } + + Print (L"\n"); + } // if (Trace) + + if (Parser[Index].ItemPtr != NULL) { + *Parser[Index].ItemPtr = (VOID *)Ptr; + } + + Ptr += Parser[Index].Length; + Offset += Parser[Index].Length; + } // for + + // Decrement the Indent + gIndent -= Indent; + return Offset; +} + +/** + An array describing the ACPI Generic Address Structure. + The GasParser array is used by the ParseAcpi function to parse and/or trace + the GAS structure. +**/ +STATIC CONST ACPI_PARSER GasParser[] = { + { L"Address Space ID", 1, 0, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Register Bit Width", 1, 1, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Register Bit Offset", 1, 2, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Access Size", 1, 3, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Address", 8, 4, L"0x%lx", NULL, NULL, NULL, NULL } +}; + +/** + This function indents and traces the GAS structure as described by the GasParser. + + @param [in] Ptr Pointer to the start of the buffer. + @param [in] Indent Number of spaces to indent the output. + @param [in] Length Length of the GAS structure buffer. + + @retval Number of bytes parsed. +**/ +UINT32 +EFIAPI +DumpGasStruct ( + IN UINT8 *Ptr, + IN UINT32 Indent, + IN UINT32 Length + ) +{ + Print (L"\n"); + return ParseAcpi ( + TRUE, + Indent, + NULL, + Ptr, + Length, + PARSER_PARAMS (GasParser) + ); +} + +/** + This function traces the GAS structure as described by the GasParser. + + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. +**/ +VOID +EFIAPI +DumpGas ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + DumpGasStruct (Ptr, 2, sizeof (EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE)); +} + +/** + This function traces the ACPI header as described by the AcpiHeaderParser. + + @param [in] Ptr Pointer to the start of the buffer. + + @retval Number of bytes parsed. +**/ +UINT32 +EFIAPI +DumpAcpiHeader ( + IN UINT8 *Ptr + ) +{ + return ParseAcpi ( + TRUE, + 0, + "ACPI Table Header", + Ptr, + sizeof (EFI_ACPI_DESCRIPTION_HEADER), + PARSER_PARAMS (AcpiHeaderParser) + ); +} + +/** + This function parses the ACPI header as described by the AcpiHeaderParser. + + This function optionally returns the signature, length and revision of the + ACPI table. + + @param [in] Ptr Pointer to the start of the buffer. + @param [out] Signature Gets location of the ACPI table signature. + @param [out] Length Gets location of the length of the ACPI table. + @param [out] Revision Gets location of the revision of the ACPI table. + + @retval Number of bytes parsed. +**/ +UINT32 +EFIAPI +ParseAcpiHeader ( + IN UINT8 *Ptr, + OUT CONST UINT32 **Signature, + OUT CONST UINT32 **Length, + OUT CONST UINT8 **Revision + ) +{ + UINT32 BytesParsed; + + BytesParsed = ParseAcpi ( + FALSE, + 0, + NULL, + Ptr, + sizeof (EFI_ACPI_DESCRIPTION_HEADER), + PARSER_PARAMS (AcpiHeaderParser) + ); + + *Signature = AcpiHdrInfo.Signature; + *Length = AcpiHdrInfo.Length; + *Revision = AcpiHdrInfo.Revision; + + return BytesParsed; +} + +/** + This function is used to parse an ACPI table bitfield buffer. + + The ACPI table buffer is parsed using the ACPI table parser information + specified by a pointer to an array of ACPI_PARSER elements. This parser + function iterates through each item on the ACPI_PARSER array and logs the ACPI table bitfields. + + This function can optionally be used to parse ACPI tables and fetch specific + field values. The ItemPtr member of the ACPI_PARSER structure (where used) + is updated by this parser function to point to the selected field data + (e.g. useful for variable length nested fields). + + ItemPtr member of ACPI_PARSER is not supported with this function. + + @param [in] Trace Trace the ACPI fields TRUE else only parse the + table. + @param [in] Indent Number of spaces to indent the output. + @param [in] AsciiName Optional pointer to an ASCII string that describes + the table being parsed. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length in bytes of the buffer pointed by Ptr. + @param [in] Parser Pointer to an array of ACPI_PARSER structure that + describes the table being parsed. + @param [in] ParserItems Number of items in the ACPI_PARSER array. + + @retval Number of bits parsed. +**/ +UINT32 +EFIAPI +ParseAcpiBitFields ( + IN BOOLEAN Trace, + IN UINT32 Indent, + IN CONST CHAR8 *AsciiName OPTIONAL, + IN UINT8 *Ptr, + IN UINT32 Length, + IN CONST ACPI_PARSER *Parser, + IN UINT32 ParserItems + ) +{ + UINT32 Index; + UINT32 Offset; + BOOLEAN HighLight; + UINTN OriginalAttribute; + + UINT64 Data; + UINT64 BitsData; + + if ((Length == 0) || (Length > 8)) { + IncrementErrorCount (); + Print ( + L"\nERROR: Bitfield Length(%d) is zero or exceeding the 64 bit limit.\n", + Length + ); + return 0; + } + + // + // set local variables to suppress incorrect compiler/analyzer warnings + // + OriginalAttribute = 0; + Offset = 0; + + // Increment the Indent + gIndent += Indent; + + CopyMem ((VOID *)&BitsData, (VOID *)Ptr, Length); + if (Trace && (AsciiName != NULL)) { + HighLight = GetColourHighlighting (); + + if (HighLight) { + OriginalAttribute = gST->ConOut->Mode->Attribute; + gST->ConOut->SetAttribute ( + gST->ConOut, + EFI_TEXT_ATTR ( + EFI_YELLOW, + ((OriginalAttribute&(BIT4|BIT5|BIT6))>>4) + ) + ); + } + + Print ( + L"%*a%-*a :\n", + gIndent, + "", + (OUTPUT_FIELD_COLUMN_WIDTH - gIndent), + AsciiName + ); + if (HighLight) { + gST->ConOut->SetAttribute (gST->ConOut, OriginalAttribute); + } + } + + for (Index = 0; Index < ParserItems; Index++) { + if ((Offset + Parser[Index].Length) > (Length * 8)) { + // For fields outside the buffer length provided, reset any pointers + // which were supposed to be updated by this function call + if (Parser[Index].ItemPtr != NULL) { + *Parser[Index].ItemPtr = NULL; + } + + // We don't parse past the end of the max length specified + continue; + } + + if (Parser[Index].Length == 0) { + IncrementErrorCount (); + // don't parse the bitfield whose length is zero + Print ( + L"\nERROR: %a: Cannot parse this field, Field Length = %d\n", + Parser[Index].Length + ); + continue; + } + + if (GetConsistencyChecking () && + (Offset != Parser[Index].Offset)) + { + IncrementErrorCount (); + Print ( + L"\nERROR: %a: Offset Mismatch for %s\n" + L"CurrentOffset = %d FieldOffset = %d\n", + AsciiName, + Parser[Index].NameStr, + Offset, + Parser[Index].Offset + ); + } + + // extract Bitfield data for the current item + Data = RShiftU64 (BitsData, Parser[Index].Offset) & ~(LShiftU64 (~0ULL, Parser[Index].Length)); + + if (Trace) { + // if there is a Formatter function let the function handle + // the printing else if a Format is specified in the table use + // the Format for printing + PrintFieldName (2, Parser[Index].NameStr); + if (Parser[Index].PrintFormatter != NULL) { + Parser[Index].PrintFormatter (Parser[Index].Format, (UINT8 *)&Data); + } else if (Parser[Index].Format != NULL) { + // convert bit length to byte length + switch ((Parser[Index].Length + 7) >> 3) { + // print the data depends on byte size + case 1: + DumpUint8 (Parser[Index].Format, (UINT8 *)&Data); + break; + case 2: + DumpUint16 (Parser[Index].Format, (UINT8 *)&Data); + break; + case 3: + case 4: + DumpUint32 (Parser[Index].Format, (UINT8 *)&Data); + break; + case 5: + case 6: + case 7: + case 8: + DumpUint64 (Parser[Index].Format, (UINT8 *)&Data); + break; + default: + Print ( + L"\nERROR: %a: CANNOT PARSE THIS FIELD, Field Length = %d\n", + AsciiName, + Parser[Index].Length + ); + } // switch + } + + // Validating only makes sense if we are tracing + // the parsed table entries, to report by table name. + if (GetConsistencyChecking () && + (Parser[Index].FieldValidator != NULL)) + { + Parser[Index].FieldValidator ((UINT8 *)&Data, Parser[Index].Context); + } + + Print (L"\n"); + } // if (Trace) + + Offset += Parser[Index].Length; + } // for + + // Decrement the Indent + gIndent -= Indent; + return Offset; +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h index 6468fe5d8c..9464c4b0c6 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiParser.h @@ -1,1025 +1,1025 @@ -/** @file
- Header file for ACPI parser
-
- Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
- Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.
- Copyright (c) 2022, AMD Incorporated. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#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 traces 12 characters which can be optionally
- formated using the format string if specified.
-
- If no format string is specified the Format must be NULL.
-
- @param [in] Format Optional format string for tracing the data.
- @param [in] Ptr Pointer to the start of the buffer.
-**/
-VOID
-EFIAPI
-Dump12Chars (
- IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
- );
-
-/**
- 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'.
-
- ParseAcpiBitFields() uses AcpiParser structure to parse the bit fields.
- It considers Length as a number of bits that need to be parsed.
- Also, the Offset field will be considered as starting offset of the bitfield.
-
- 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)
- /// Length(in bits) of the bitfield if used with ParseAcpiBitFields().
- UINT32 Length;
-
- /// The offset of the field from the start of the table.
- /// (Byte Offset column from ACPI table spec)
- /// The Bit offset of the field if used with ParseAcpiBitFields().
- 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. This value is set after the FieldValidator
- /// has been called and therefore should not be used by the FieldValidator.
- /// If unused this must be set to NULL.
- /// ItemPtr is not supported with ParseAcpiBitFields().
- 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 function is used to parse an ACPI table bitfield buffer.
-
- The ACPI table buffer is parsed using the ACPI table parser information
- specified by a pointer to an array of ACPI_PARSER elements. This parser
- function iterates through each item on the ACPI_PARSER array and logs the ACPI table bitfields.
-
- This function can optionally be used to parse ACPI tables and fetch specific
- field values. The ItemPtr member of the ACPI_PARSER structure (where used)
- is updated by this parser function to point to the selected field data
- (e.g. useful for variable length nested fields).
-
- ItemPtr member of ACPI_PARSER is not supported with this function.
-
- @param [in] Trace Trace the ACPI fields TRUE else only parse the
- table.
- @param [in] Indent Number of spaces to indent the output.
- @param [in] AsciiName Optional pointer to an ASCII string that describes
- the table being parsed.
- @param [in] Ptr Pointer to the start of the buffer.
- @param [in] Length Length of the buffer pointed by Ptr.
- @param [in] Parser Pointer to an array of ACPI_PARSER structure that
- describes the table being parsed.
- @param [in] ParserItems Number of items in the ACPI_PARSER array.
-
- @retval Number of bits parsed.
-**/
-UINT32
-EFIAPI
-ParseAcpiBitFields (
- IN BOOLEAN Trace,
- IN UINT32 Indent,
- IN CONST CHAR8 *AsciiName OPTIONAL,
- IN UINT8 *Ptr,
- IN UINT32 Length,
- IN CONST ACPI_PARSER *Parser,
- IN UINT32 ParserItems
- );
-
-/**
- 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 }
-
-/**
- This function indents and traces the GAS structure as described by the GasParser.
-
- @param [in] Ptr Pointer to the start of the buffer.
- @param [in] Indent Number of spaces to indent the output.
- @param [in] Length Length of the GAS structure buffer.
-
- @retval Number of bytes parsed.
-**/
-UINT32
-EFIAPI
-DumpGasStruct (
- IN UINT8 *Ptr,
- IN UINT32 Indent,
- IN UINT32 Length
- );
-
-/**
- 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 AEST table.
- When trace is enabled this function parses the AEST 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
-ParseAcpiAest (
- IN BOOLEAN Trace,
- IN UINT8 *Ptr,
- IN UINT32 AcpiTableLength,
- IN UINT8 AcpiTableRevision
- );
-
-/**
- This function parses the ACPI APMT table.
- When trace is enabled this function parses the APMT 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
-ParseAcpiApmt (
- IN BOOLEAN Trace,
- IN UINT8 *Ptr,
- IN UINT32 AcpiTableLength,
- IN UINT8 AcpiTableRevision
- );
-
-/**
- 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 ERST table.
- When trace is enabled this function parses the ERST 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
-ParseAcpiErst (
- IN BOOLEAN Trace,
- IN UINT8 *Ptr,
- IN UINT32 AcpiTableLength,
- IN UINT8 AcpiTableRevision
- );
-
-/**
- This function parses the ACPI FACS table.
- When trace is enabled this function parses the FACS 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
-ParseAcpiFacs (
- 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 HMAT table.
- When trace is enabled this function parses the HMAT table and
- traces the ACPI table fields.
-
- This function parses the following HMAT structures:
- - Memory Proximity Domain Attributes Structure (Type 0)
- - System Locality Latency and Bandwidth Info Structure (Type 1)
- - Memory Side Cache Info structure (Type 2)
-
- 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
-ParseAcpiHmat (
- IN BOOLEAN Trace,
- IN UINT8 *Ptr,
- IN UINT32 AcpiTableLength,
- IN UINT8 AcpiTableRevision
- );
-
-/**
- This function parses the ACPI HPET 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
-ParseAcpiHpet (
- 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 PCCT table including its sub-structures
- of type 0 through 4.
- When trace is enabled this function parses the PCCT 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
-ParseAcpiPcct (
- IN BOOLEAN Trace,
- IN UINT8 *Ptr,
- IN UINT32 AcpiTableLength,
- IN UINT8 AcpiTableRevision
- );
-
-/**
- This function parses the ACPI PPTT table.
- When trace is enabled this function parses the PPTT 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
-ParseAcpiPptt (
- 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 WSMT 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
-ParseAcpiWsmt (
- 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_
+/** @file + Header file for ACPI parser + + Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + Copyright (c) 2016 - 2020, Arm Limited. All rights reserved. + Copyright (c) 2022, AMD Incorporated. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#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 traces 12 characters which can be optionally + formated using the format string if specified. + + If no format string is specified the Format must be NULL. + + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. +**/ +VOID +EFIAPI +Dump12Chars ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ); + +/** + 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'. + + ParseAcpiBitFields() uses AcpiParser structure to parse the bit fields. + It considers Length as a number of bits that need to be parsed. + Also, the Offset field will be considered as starting offset of the bitfield. + + 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) + /// Length(in bits) of the bitfield if used with ParseAcpiBitFields(). + UINT32 Length; + + /// The offset of the field from the start of the table. + /// (Byte Offset column from ACPI table spec) + /// The Bit offset of the field if used with ParseAcpiBitFields(). + 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. This value is set after the FieldValidator + /// has been called and therefore should not be used by the FieldValidator. + /// If unused this must be set to NULL. + /// ItemPtr is not supported with ParseAcpiBitFields(). + 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 function is used to parse an ACPI table bitfield buffer. + + The ACPI table buffer is parsed using the ACPI table parser information + specified by a pointer to an array of ACPI_PARSER elements. This parser + function iterates through each item on the ACPI_PARSER array and logs the ACPI table bitfields. + + This function can optionally be used to parse ACPI tables and fetch specific + field values. The ItemPtr member of the ACPI_PARSER structure (where used) + is updated by this parser function to point to the selected field data + (e.g. useful for variable length nested fields). + + ItemPtr member of ACPI_PARSER is not supported with this function. + + @param [in] Trace Trace the ACPI fields TRUE else only parse the + table. + @param [in] Indent Number of spaces to indent the output. + @param [in] AsciiName Optional pointer to an ASCII string that describes + the table being parsed. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the buffer pointed by Ptr. + @param [in] Parser Pointer to an array of ACPI_PARSER structure that + describes the table being parsed. + @param [in] ParserItems Number of items in the ACPI_PARSER array. + + @retval Number of bits parsed. +**/ +UINT32 +EFIAPI +ParseAcpiBitFields ( + IN BOOLEAN Trace, + IN UINT32 Indent, + IN CONST CHAR8 *AsciiName OPTIONAL, + IN UINT8 *Ptr, + IN UINT32 Length, + IN CONST ACPI_PARSER *Parser, + IN UINT32 ParserItems + ); + +/** + 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 } + +/** + This function indents and traces the GAS structure as described by the GasParser. + + @param [in] Ptr Pointer to the start of the buffer. + @param [in] Indent Number of spaces to indent the output. + @param [in] Length Length of the GAS structure buffer. + + @retval Number of bytes parsed. +**/ +UINT32 +EFIAPI +DumpGasStruct ( + IN UINT8 *Ptr, + IN UINT32 Indent, + IN UINT32 Length + ); + +/** + 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 AEST table. + When trace is enabled this function parses the AEST 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 +ParseAcpiAest ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ); + +/** + This function parses the ACPI APMT table. + When trace is enabled this function parses the APMT 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 +ParseAcpiApmt ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ); + +/** + 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 ERST table. + When trace is enabled this function parses the ERST 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 +ParseAcpiErst ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ); + +/** + This function parses the ACPI FACS table. + When trace is enabled this function parses the FACS 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 +ParseAcpiFacs ( + 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 HMAT table. + When trace is enabled this function parses the HMAT table and + traces the ACPI table fields. + + This function parses the following HMAT structures: + - Memory Proximity Domain Attributes Structure (Type 0) + - System Locality Latency and Bandwidth Info Structure (Type 1) + - Memory Side Cache Info structure (Type 2) + + 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 +ParseAcpiHmat ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ); + +/** + This function parses the ACPI HPET 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 +ParseAcpiHpet ( + 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 PCCT table including its sub-structures + of type 0 through 4. + When trace is enabled this function parses the PCCT 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 +ParseAcpiPcct ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ); + +/** + This function parses the ACPI PPTT table. + When trace is enabled this function parses the PPTT 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 +ParseAcpiPptt ( + 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 WSMT 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 +ParseAcpiWsmt ( + 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 index 75b949429e..7d674bfbe7 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.c @@ -1,253 +1,253 @@ -/** @file
- ACPI table parser
-
- Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Glossary:
- - Sbbr or SBBR - Server Base Boot Requirements
-
- @par Reference(s):
- - Arm Server Base Boot Requirements 1.2, September 2019
-**/
-
-#include <Uefi.h>
-#include <IndustryStandard/Acpi.h>
-#include <Library/UefiLib.h>
-#include "AcpiParser.h"
-#include "AcpiTableParser.h"
-#include "AcpiView.h"
-#include "AcpiViewConfig.h"
-
-#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
- #include "Arm/SbbrValidator.h"
-#endif
-
-/**
- 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;
- CONST UINT8 *SignaturePtr;
- PARSE_ACPI_TABLE_PROC ParserProc;
-
- ParseAcpiHeader (
- Ptr,
- &AcpiTableSignature,
- &AcpiTableLength,
- &AcpiTableRevision
- );
-
- Trace = ProcessTableReportOptions (
- *AcpiTableSignature,
- Ptr,
- *AcpiTableLength
- );
-
- if (Trace) {
- DumpRaw (Ptr, *AcpiTableLength);
-
- // Do not process the ACPI table any further if the table length read
- // is invalid. The ACPI table should at least contain the table header.
- if (*AcpiTableLength < sizeof (EFI_ACPI_DESCRIPTION_HEADER)) {
- SignaturePtr = (CONST UINT8 *)AcpiTableSignature;
- IncrementErrorCount ();
- Print (
- L"ERROR: Invalid %c%c%c%c table length. Length = %d\n",
- SignaturePtr[0],
- SignaturePtr[1],
- SignaturePtr[2],
- SignaturePtr[3],
- *AcpiTableLength
- );
- return;
- }
-
- if (GetConsistencyChecking ()) {
- VerifyChecksum (TRUE, Ptr, *AcpiTableLength);
- }
- }
-
- #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
- if (GetMandatoryTableValidate ()) {
- ArmSbbrIncrementTableCount (*AcpiTableSignature);
- }
-
- #endif
-
- 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
- );
-}
+/** @file + ACPI table parser + + Copyright (c) 2016 - 2020, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - Sbbr or SBBR - Server Base Boot Requirements + + @par Reference(s): + - Arm Server Base Boot Requirements 1.2, September 2019 +**/ + +#include <Uefi.h> +#include <IndustryStandard/Acpi.h> +#include <Library/UefiLib.h> +#include "AcpiParser.h" +#include "AcpiTableParser.h" +#include "AcpiView.h" +#include "AcpiViewConfig.h" + +#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64) + #include "Arm/SbbrValidator.h" +#endif + +/** + 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; + CONST UINT8 *SignaturePtr; + PARSE_ACPI_TABLE_PROC ParserProc; + + ParseAcpiHeader ( + Ptr, + &AcpiTableSignature, + &AcpiTableLength, + &AcpiTableRevision + ); + + Trace = ProcessTableReportOptions ( + *AcpiTableSignature, + Ptr, + *AcpiTableLength + ); + + if (Trace) { + DumpRaw (Ptr, *AcpiTableLength); + + // Do not process the ACPI table any further if the table length read + // is invalid. The ACPI table should at least contain the table header. + if (*AcpiTableLength < sizeof (EFI_ACPI_DESCRIPTION_HEADER)) { + SignaturePtr = (CONST UINT8 *)AcpiTableSignature; + IncrementErrorCount (); + Print ( + L"ERROR: Invalid %c%c%c%c table length. Length = %d\n", + SignaturePtr[0], + SignaturePtr[1], + SignaturePtr[2], + SignaturePtr[3], + *AcpiTableLength + ); + return; + } + + if (GetConsistencyChecking ()) { + VerifyChecksum (TRUE, Ptr, *AcpiTableLength); + } + } + + #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64) + if (GetMandatoryTableValidate ()) { + ArmSbbrIncrementTableCount (*AcpiTableSignature); + } + + #endif + + 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 index cd8aa27d9e..bcb67ac2c7 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiTableParser.h @@ -1,127 +1,127 @@ -/** @file
- Header file for ACPI table parser
-
- Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#ifndef ACPITABLEPARSER_H_
-#define ACPITABLEPARSER_H_
-
-/**
- The maximum number of ACPI table parsers.
-*/
-#define MAX_ACPI_TABLE_PARSERS 32
-
-/** 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_
+/** @file + Header file for ACPI table parser + + Copyright (c) 2016 - 2020, Arm Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef ACPITABLEPARSER_H_ +#define ACPITABLEPARSER_H_ + +/** + The maximum number of ACPI table parsers. +*/ +#define MAX_ACPI_TABLE_PARSERS 32 + +/** 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 index 9cdfcb3fae..5a64a69d6a 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.c @@ -1,340 +1,340 @@ -/** @file
-
- Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Glossary:
- - Sbbr or SBBR - Server Base Boot Requirements
-
- @par Reference(s):
- - Arm Server Base Boot Requirements 1.2, September 2019
-**/
-
-#include <Library/PrintLib.h>
-#include <Library/UefiLib.h>
-#include <Library/ShellLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/AcpiViewCommandLib.h>
-#include "AcpiParser.h"
-#include "AcpiTableParser.h"
-#include "AcpiView.h"
-#include "AcpiViewConfig.h"
-
-#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
- #include "Arm/SbbrValidator.h"
-#endif
-
-STATIC UINT32 mTableCount;
-STATIC UINT32 mBinTableCount;
-
-/**
- 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
- )
-{
- CHAR16 FileNameBuffer[MAX_FILE_NAME_LEN];
- UINTN TransferBytes;
- SELECTED_ACPI_TABLE *SelectedTable;
-
- GetSelectedAcpiTable (&SelectedTable);
-
- UnicodeSPrint (
- FileNameBuffer,
- sizeof (FileNameBuffer),
- L".\\%s%04d.bin",
- SelectedTable->Name,
- mBinTableCount++
- );
-
- Print (L"Dumping ACPI table to : %s ... ", FileNameBuffer);
-
- TransferBytes = ShellDumpBufferToFile (FileNameBuffer, Ptr, Length);
- 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;
- BOOLEAN Log;
- BOOLEAN HighLight;
- SELECTED_ACPI_TABLE *SelectedTable;
-
- //
- // set local variables to suppress incorrect compiler/analyzer warnings
- //
- OriginalAttribute = 0;
- SignaturePtr = (UINT8 *)(UINTN)&Signature;
- Log = FALSE;
- HighLight = GetColourHighlighting ();
- GetSelectedAcpiTable (&SelectedTable);
-
- switch (GetReportOption ()) {
- case ReportAll:
- Log = TRUE;
- break;
- case ReportSelected:
- if (Signature == SelectedTable->Type) {
- Log = TRUE;
- SelectedTable->Found = TRUE;
- }
-
- break;
- case ReportTableList:
- 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 ReportDumpBinFile:
- if (Signature == SelectedTable->Type) {
- SelectedTable->Found = TRUE;
- DumpAcpiTableToFile (TablePtr, Length);
- }
-
- break;
- case ReportMax:
- // 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 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.
-**/
-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;
- SELECTED_ACPI_TABLE *SelectedTable;
-
- //
- // set local variables to suppress incorrect compiler/analyzer warnings
- //
- EfiConfigurationTable = NULL;
- OriginalAttribute = 0;
-
- // Reset Table counts
- mTableCount = 0;
- mBinTableCount = 0;
-
- // Reset The error/warning counters
- ResetErrorCount ();
- ResetWarningCount ();
-
- // Retrieve the user selection of ACPI table to process
- GetSelectedAcpiTable (&SelectedTable);
-
- // 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;
- }
-
- #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
- if (GetMandatoryTableValidate ()) {
- ArmSbbrResetTableCounts ();
- }
-
- #endif
-
- // 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;
- }
-
- #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
- if (GetMandatoryTableValidate ()) {
- ArmSbbrReqsValidate ((ARM_SBBR_VERSION)GetMandatoryTableSpec ());
- }
-
- #endif
-
- ReportOption = GetReportOption ();
- if (ReportTableList != ReportOption) {
- if (((ReportSelected == ReportOption) ||
- (ReportDumpBinFile == ReportOption)) &&
- (!SelectedTable->Found))
- {
- Print (L"\nRequested ACPI Table not found.\n");
- } else if (GetConsistencyChecking () &&
- (ReportDumpBinFile != 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;
-}
+/** @file + + Copyright (c) 2016 - 2020, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - Sbbr or SBBR - Server Base Boot Requirements + + @par Reference(s): + - Arm Server Base Boot Requirements 1.2, September 2019 +**/ + +#include <Library/PrintLib.h> +#include <Library/UefiLib.h> +#include <Library/ShellLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/AcpiViewCommandLib.h> +#include "AcpiParser.h" +#include "AcpiTableParser.h" +#include "AcpiView.h" +#include "AcpiViewConfig.h" + +#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64) + #include "Arm/SbbrValidator.h" +#endif + +STATIC UINT32 mTableCount; +STATIC UINT32 mBinTableCount; + +/** + 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 + ) +{ + CHAR16 FileNameBuffer[MAX_FILE_NAME_LEN]; + UINTN TransferBytes; + SELECTED_ACPI_TABLE *SelectedTable; + + GetSelectedAcpiTable (&SelectedTable); + + UnicodeSPrint ( + FileNameBuffer, + sizeof (FileNameBuffer), + L".\\%s%04d.bin", + SelectedTable->Name, + mBinTableCount++ + ); + + Print (L"Dumping ACPI table to : %s ... ", FileNameBuffer); + + TransferBytes = ShellDumpBufferToFile (FileNameBuffer, Ptr, Length); + 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; + BOOLEAN Log; + BOOLEAN HighLight; + SELECTED_ACPI_TABLE *SelectedTable; + + // + // set local variables to suppress incorrect compiler/analyzer warnings + // + OriginalAttribute = 0; + SignaturePtr = (UINT8 *)(UINTN)&Signature; + Log = FALSE; + HighLight = GetColourHighlighting (); + GetSelectedAcpiTable (&SelectedTable); + + switch (GetReportOption ()) { + case ReportAll: + Log = TRUE; + break; + case ReportSelected: + if (Signature == SelectedTable->Type) { + Log = TRUE; + SelectedTable->Found = TRUE; + } + + break; + case ReportTableList: + 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 ReportDumpBinFile: + if (Signature == SelectedTable->Type) { + SelectedTable->Found = TRUE; + DumpAcpiTableToFile (TablePtr, Length); + } + + break; + case ReportMax: + // 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 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. +**/ +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; + SELECTED_ACPI_TABLE *SelectedTable; + + // + // set local variables to suppress incorrect compiler/analyzer warnings + // + EfiConfigurationTable = NULL; + OriginalAttribute = 0; + + // Reset Table counts + mTableCount = 0; + mBinTableCount = 0; + + // Reset The error/warning counters + ResetErrorCount (); + ResetWarningCount (); + + // Retrieve the user selection of ACPI table to process + GetSelectedAcpiTable (&SelectedTable); + + // 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; + } + + #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64) + if (GetMandatoryTableValidate ()) { + ArmSbbrResetTableCounts (); + } + + #endif + + // 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; + } + + #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64) + if (GetMandatoryTableValidate ()) { + ArmSbbrReqsValidate ((ARM_SBBR_VERSION)GetMandatoryTableSpec ()); + } + + #endif + + ReportOption = GetReportOption (); + if (ReportTableList != ReportOption) { + if (((ReportSelected == ReportOption) || + (ReportDumpBinFile == ReportOption)) && + (!SelectedTable->Found)) + { + Print (L"\nRequested ACPI Table not found.\n"); + } else if (GetConsistencyChecking () && + (ReportDumpBinFile != 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; +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.h index 5f1bc0ebb0..787bf5e141 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.h +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiView.h @@ -1,94 +1,94 @@ -/** @file
- Header file for AcpiView
-
- Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#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
-
-/**
- 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 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 of 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
- );
-
-/**
- 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 EFI_NOT_FOUND The RSDP pointer was not found.
- @retval EFI_UNSUPPORTED The RSDP version was less than 2.
- @retval EFI_SUCCESS The command was successful.
-**/
-EFI_STATUS
-EFIAPI
-AcpiView (
- IN EFI_SYSTEM_TABLE *SystemTable
- );
-
-#endif // ACPIVIEW_H_
+/** @file + Header file for AcpiView + + Copyright (c) 2016 - 2020, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#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 + +/** + 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 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 of 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 + ); + +/** + 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 EFI_NOT_FOUND The RSDP pointer was not found. + @retval EFI_UNSUPPORTED The RSDP version was less than 2. + @retval EFI_SUCCESS The command was successful. +**/ +EFI_STATUS +EFIAPI +AcpiView ( + IN EFI_SYSTEM_TABLE *SystemTable + ); + +#endif // ACPIVIEW_H_ diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiViewConfig.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiViewConfig.c index 8f6823f64b..dbedea3483 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiViewConfig.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiViewConfig.c @@ -1,248 +1,248 @@ -/** @file
- State and accessors for 'acpiview' configuration.
-
- Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-
-#include "AcpiViewConfig.h"
-
-// Report variables
-STATIC BOOLEAN mConsistencyCheck;
-STATIC BOOLEAN mColourHighlighting;
-STATIC EREPORT_OPTION mReportType;
-STATIC BOOLEAN mMandatoryTableValidate;
-STATIC UINTN mMandatoryTableSpec;
-
-// User selection of which ACPI table should be checked
-SELECTED_ACPI_TABLE mSelectedAcpiTable;
-
-/**
- Reset the AcpiView user configuration to defaults
-**/
-VOID
-EFIAPI
-AcpiConfigSetDefaults (
- VOID
- )
-{
- mReportType = ReportAll;
- mSelectedAcpiTable.Type = 0;
- mSelectedAcpiTable.Name = NULL;
- mSelectedAcpiTable.Found = FALSE;
- mConsistencyCheck = TRUE;
- mMandatoryTableValidate = FALSE;
- mMandatoryTableSpec = 0;
-}
-
-/**
- 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;
- CHAR8 Ptr[4];
-
- ZeroMem (Ptr, sizeof (Ptr));
- Index = 0;
-
- // 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 selects an ACPI table in current context.
- The string name of the table is converted into UINT32
- table signature.
-
- @param [in] TableName The name of the ACPI table to select.
-**/
-VOID
-EFIAPI
-SelectAcpiTable (
- IN CONST CHAR16 *TableName
- )
-{
- ASSERT (TableName != NULL);
-
- mSelectedAcpiTable.Name = TableName;
- mSelectedAcpiTable.Type = ConvertStrToAcpiSignature (mSelectedAcpiTable.Name);
-}
-
-/**
- This function returns the selected ACPI table.
-
- @param [out] SelectedAcpiTable Pointer that will contain the returned struct.
-**/
-VOID
-EFIAPI
-GetSelectedAcpiTable (
- OUT SELECTED_ACPI_TABLE **SelectedAcpiTable
- )
-{
- *SelectedAcpiTable = &mSelectedAcpiTable;
-}
-
-/**
- This function returns the colour highlighting status.
-
- @retval TRUE Colour highlighting is enabled.
-**/
-BOOLEAN
-EFIAPI
-GetColourHighlighting (
- VOID
- )
-{
- return mColourHighlighting;
-}
-
-/**
- This function sets the colour highlighting status.
-
- @param [in] Highlight The highlight status.
-**/
-VOID
-EFIAPI
-SetColourHighlighting (
- BOOLEAN Highlight
- )
-{
- mColourHighlighting = Highlight;
-}
-
-/**
- This function returns the consistency checking status.
-
- @retval TRUE Consistency checking is enabled.
-**/
-BOOLEAN
-EFIAPI
-GetConsistencyChecking (
- VOID
- )
-{
- return mConsistencyCheck;
-}
-
-/**
- This function sets the consistency checking status.
-
- @param [in] ConsistencyChecking The consistency checking status.
-**/
-VOID
-EFIAPI
-SetConsistencyChecking (
- BOOLEAN ConsistencyChecking
- )
-{
- mConsistencyCheck = ConsistencyChecking;
-}
-
-/**
- This function returns the report options.
-
- @return The current report option.
-**/
-EREPORT_OPTION
-EFIAPI
-GetReportOption (
- VOID
- )
-{
- return mReportType;
-}
-
-/**
- This function sets the report options.
-
- @param [in] ReportType The report option to set.
-**/
-VOID
-EFIAPI
-SetReportOption (
- EREPORT_OPTION ReportType
- )
-{
- mReportType = ReportType;
-}
-
-/**
- This function returns the ACPI table requirements validation flag.
-
- @retval TRUE Check for mandatory table presence should be performed.
-**/
-BOOLEAN
-EFIAPI
-GetMandatoryTableValidate (
- VOID
- )
-{
- return mMandatoryTableValidate;
-}
-
-/**
- This function sets the ACPI table requirements validation flag.
-
- @param [in] Validate Enable/Disable ACPI table requirements validation.
-**/
-VOID
-EFIAPI
-SetMandatoryTableValidate (
- BOOLEAN Validate
- )
-{
- mMandatoryTableValidate = Validate;
-}
-
-/**
- This function returns the identifier of specification to validate ACPI table
- requirements against.
-
- @return ID of specification listing mandatory tables.
-**/
-UINTN
-EFIAPI
-GetMandatoryTableSpec (
- VOID
- )
-{
- return mMandatoryTableSpec;
-}
-
-/**
- This function sets the identifier of specification to validate ACPI table
- requirements against.
-
- @param [in] Spec ID of specification listing mandatory tables.
-**/
-VOID
-EFIAPI
-SetMandatoryTableSpec (
- UINTN Spec
- )
-{
- mMandatoryTableSpec = Spec;
-}
+/** @file + State and accessors for 'acpiview' configuration. + + Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> + +#include "AcpiViewConfig.h" + +// Report variables +STATIC BOOLEAN mConsistencyCheck; +STATIC BOOLEAN mColourHighlighting; +STATIC EREPORT_OPTION mReportType; +STATIC BOOLEAN mMandatoryTableValidate; +STATIC UINTN mMandatoryTableSpec; + +// User selection of which ACPI table should be checked +SELECTED_ACPI_TABLE mSelectedAcpiTable; + +/** + Reset the AcpiView user configuration to defaults +**/ +VOID +EFIAPI +AcpiConfigSetDefaults ( + VOID + ) +{ + mReportType = ReportAll; + mSelectedAcpiTable.Type = 0; + mSelectedAcpiTable.Name = NULL; + mSelectedAcpiTable.Found = FALSE; + mConsistencyCheck = TRUE; + mMandatoryTableValidate = FALSE; + mMandatoryTableSpec = 0; +} + +/** + 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; + CHAR8 Ptr[4]; + + ZeroMem (Ptr, sizeof (Ptr)); + Index = 0; + + // 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 selects an ACPI table in current context. + The string name of the table is converted into UINT32 + table signature. + + @param [in] TableName The name of the ACPI table to select. +**/ +VOID +EFIAPI +SelectAcpiTable ( + IN CONST CHAR16 *TableName + ) +{ + ASSERT (TableName != NULL); + + mSelectedAcpiTable.Name = TableName; + mSelectedAcpiTable.Type = ConvertStrToAcpiSignature (mSelectedAcpiTable.Name); +} + +/** + This function returns the selected ACPI table. + + @param [out] SelectedAcpiTable Pointer that will contain the returned struct. +**/ +VOID +EFIAPI +GetSelectedAcpiTable ( + OUT SELECTED_ACPI_TABLE **SelectedAcpiTable + ) +{ + *SelectedAcpiTable = &mSelectedAcpiTable; +} + +/** + This function returns the colour highlighting status. + + @retval TRUE Colour highlighting is enabled. +**/ +BOOLEAN +EFIAPI +GetColourHighlighting ( + VOID + ) +{ + return mColourHighlighting; +} + +/** + This function sets the colour highlighting status. + + @param [in] Highlight The highlight status. +**/ +VOID +EFIAPI +SetColourHighlighting ( + BOOLEAN Highlight + ) +{ + mColourHighlighting = Highlight; +} + +/** + This function returns the consistency checking status. + + @retval TRUE Consistency checking is enabled. +**/ +BOOLEAN +EFIAPI +GetConsistencyChecking ( + VOID + ) +{ + return mConsistencyCheck; +} + +/** + This function sets the consistency checking status. + + @param [in] ConsistencyChecking The consistency checking status. +**/ +VOID +EFIAPI +SetConsistencyChecking ( + BOOLEAN ConsistencyChecking + ) +{ + mConsistencyCheck = ConsistencyChecking; +} + +/** + This function returns the report options. + + @return The current report option. +**/ +EREPORT_OPTION +EFIAPI +GetReportOption ( + VOID + ) +{ + return mReportType; +} + +/** + This function sets the report options. + + @param [in] ReportType The report option to set. +**/ +VOID +EFIAPI +SetReportOption ( + EREPORT_OPTION ReportType + ) +{ + mReportType = ReportType; +} + +/** + This function returns the ACPI table requirements validation flag. + + @retval TRUE Check for mandatory table presence should be performed. +**/ +BOOLEAN +EFIAPI +GetMandatoryTableValidate ( + VOID + ) +{ + return mMandatoryTableValidate; +} + +/** + This function sets the ACPI table requirements validation flag. + + @param [in] Validate Enable/Disable ACPI table requirements validation. +**/ +VOID +EFIAPI +SetMandatoryTableValidate ( + BOOLEAN Validate + ) +{ + mMandatoryTableValidate = Validate; +} + +/** + This function returns the identifier of specification to validate ACPI table + requirements against. + + @return ID of specification listing mandatory tables. +**/ +UINTN +EFIAPI +GetMandatoryTableSpec ( + VOID + ) +{ + return mMandatoryTableSpec; +} + +/** + This function sets the identifier of specification to validate ACPI table + requirements against. + + @param [in] Spec ID of specification listing mandatory tables. +**/ +VOID +EFIAPI +SetMandatoryTableSpec ( + UINTN Spec + ) +{ + mMandatoryTableSpec = Spec; +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiViewConfig.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiViewConfig.h index c58755bf1d..6df4665bc0 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiViewConfig.h +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/AcpiViewConfig.h @@ -1,177 +1,177 @@ -/** @file
- Header file for 'acpiview' configuration.
-
- Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#ifndef ACPI_VIEW_CONFIG_H_
-#define ACPI_VIEW_CONFIG_H_
-
-/**
- This function returns the colour highlighting status.
-
- @retval TRUE Colour highlighting is enabled.
-**/
-BOOLEAN
-EFIAPI
-GetColourHighlighting (
- VOID
- );
-
-/**
- This function sets the colour highlighting status.
-
- @param [in] Highlight The highlight status.
-**/
-VOID
-EFIAPI
-SetColourHighlighting (
- BOOLEAN Highlight
- );
-
-/**
- This function returns the consistency checking status.
-
- @retval TRUE Consistency checking is enabled.
-**/
-BOOLEAN
-EFIAPI
-GetConsistencyChecking (
- VOID
- );
-
-/**
- This function sets the consistency checking status.
-
- @param [in] ConsistencyChecking The consistency checking status.
-**/
-VOID
-EFIAPI
-SetConsistencyChecking (
- BOOLEAN ConsistencyChecking
- );
-
-/**
- This function returns the ACPI table requirements validation flag.
-
- @retval TRUE Check for mandatory table presence should be performed.
-**/
-BOOLEAN
-EFIAPI
-GetMandatoryTableValidate (
- VOID
- );
-
-/**
- This function sets the ACPI table requirements validation flag.
-
- @param [in] Validate Enable/Disable ACPI table requirements validation.
-**/
-VOID
-EFIAPI
-SetMandatoryTableValidate (
- BOOLEAN Validate
- );
-
-/**
- This function returns the identifier of specification to validate ACPI table
- requirements against.
-
- @return ID of specification listing mandatory tables.
-**/
-UINTN
-EFIAPI
-GetMandatoryTableSpec (
- VOID
- );
-
-/**
- This function sets the identifier of specification to validate ACPI table
- requirements against.
-
- @param [in] Spec ID of specification listing mandatory tables.
-**/
-VOID
-EFIAPI
-SetMandatoryTableSpec (
- UINTN Spec
- );
-
-/**
- The EREPORT_OPTION enum describes ACPI table Reporting options.
-**/
-typedef enum {
- ReportAll, ///< Report All tables.
- ReportSelected, ///< Report Selected table.
- ReportTableList, ///< Report List of tables.
- ReportDumpBinFile, ///< Dump selected table to a file.
- ReportMax,
-} EREPORT_OPTION;
-
-/**
- This function returns the report options.
-
- @return The current report option.
-**/
-EREPORT_OPTION
-EFIAPI
-GetReportOption (
- VOID
- );
-
-/**
- This function sets the report options.
-
- @param [in] ReportType The report option to set.
-**/
-VOID
-EFIAPI
-SetReportOption (
- EREPORT_OPTION ReportType
- );
-
-/**
- A structure holding the user selection detailing which
- ACPI table is to be examined by the AcpiView code.
-**/
-typedef struct {
- UINT32 Type; ///< 32bit signature of the selected ACPI table.
- CONST CHAR16 *Name; ///< User friendly name of the selected ACPI table.
- BOOLEAN Found; ///< The selected table has been found in the system.
-} SELECTED_ACPI_TABLE;
-
-/**
- This function returns the selected ACPI table.
-
- @param [out] SelectedAcpiTable Pointer that will contain the returned struct.
-**/
-VOID
-EFIAPI
-GetSelectedAcpiTable (
- OUT SELECTED_ACPI_TABLE **SelectedAcpiTable
- );
-
-/**
- This function selects an ACPI table in current context.
- The string name of the table is converted into UINT32
- table signature.
-
- @param [in] TableName The name of the ACPI table to select.
-**/
-VOID
-EFIAPI
-SelectAcpiTable (
- CONST CHAR16 *TableName
- );
-
-/**
- Reset the AcpiView user configuration to defaults.
-**/
-VOID
-EFIAPI
-AcpiConfigSetDefaults (
- VOID
- );
-
-#endif // ACPI_VIEW_CONFIG_H_
+/** @file + Header file for 'acpiview' configuration. + + Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef ACPI_VIEW_CONFIG_H_ +#define ACPI_VIEW_CONFIG_H_ + +/** + This function returns the colour highlighting status. + + @retval TRUE Colour highlighting is enabled. +**/ +BOOLEAN +EFIAPI +GetColourHighlighting ( + VOID + ); + +/** + This function sets the colour highlighting status. + + @param [in] Highlight The highlight status. +**/ +VOID +EFIAPI +SetColourHighlighting ( + BOOLEAN Highlight + ); + +/** + This function returns the consistency checking status. + + @retval TRUE Consistency checking is enabled. +**/ +BOOLEAN +EFIAPI +GetConsistencyChecking ( + VOID + ); + +/** + This function sets the consistency checking status. + + @param [in] ConsistencyChecking The consistency checking status. +**/ +VOID +EFIAPI +SetConsistencyChecking ( + BOOLEAN ConsistencyChecking + ); + +/** + This function returns the ACPI table requirements validation flag. + + @retval TRUE Check for mandatory table presence should be performed. +**/ +BOOLEAN +EFIAPI +GetMandatoryTableValidate ( + VOID + ); + +/** + This function sets the ACPI table requirements validation flag. + + @param [in] Validate Enable/Disable ACPI table requirements validation. +**/ +VOID +EFIAPI +SetMandatoryTableValidate ( + BOOLEAN Validate + ); + +/** + This function returns the identifier of specification to validate ACPI table + requirements against. + + @return ID of specification listing mandatory tables. +**/ +UINTN +EFIAPI +GetMandatoryTableSpec ( + VOID + ); + +/** + This function sets the identifier of specification to validate ACPI table + requirements against. + + @param [in] Spec ID of specification listing mandatory tables. +**/ +VOID +EFIAPI +SetMandatoryTableSpec ( + UINTN Spec + ); + +/** + The EREPORT_OPTION enum describes ACPI table Reporting options. +**/ +typedef enum { + ReportAll, ///< Report All tables. + ReportSelected, ///< Report Selected table. + ReportTableList, ///< Report List of tables. + ReportDumpBinFile, ///< Dump selected table to a file. + ReportMax, +} EREPORT_OPTION; + +/** + This function returns the report options. + + @return The current report option. +**/ +EREPORT_OPTION +EFIAPI +GetReportOption ( + VOID + ); + +/** + This function sets the report options. + + @param [in] ReportType The report option to set. +**/ +VOID +EFIAPI +SetReportOption ( + EREPORT_OPTION ReportType + ); + +/** + A structure holding the user selection detailing which + ACPI table is to be examined by the AcpiView code. +**/ +typedef struct { + UINT32 Type; ///< 32bit signature of the selected ACPI table. + CONST CHAR16 *Name; ///< User friendly name of the selected ACPI table. + BOOLEAN Found; ///< The selected table has been found in the system. +} SELECTED_ACPI_TABLE; + +/** + This function returns the selected ACPI table. + + @param [out] SelectedAcpiTable Pointer that will contain the returned struct. +**/ +VOID +EFIAPI +GetSelectedAcpiTable ( + OUT SELECTED_ACPI_TABLE **SelectedAcpiTable + ); + +/** + This function selects an ACPI table in current context. + The string name of the table is converted into UINT32 + table signature. + + @param [in] TableName The name of the ACPI table to select. +**/ +VOID +EFIAPI +SelectAcpiTable ( + CONST CHAR16 *TableName + ); + +/** + Reset the AcpiView user configuration to defaults. +**/ +VOID +EFIAPI +AcpiConfigSetDefaults ( + VOID + ); + +#endif // ACPI_VIEW_CONFIG_H_ diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Arm/SbbrValidator.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Arm/SbbrValidator.c index 5b0e578af9..ea7bac35af 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Arm/SbbrValidator.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Arm/SbbrValidator.c @@ -1,223 +1,223 @@ -/** @file
- Arm Server Base Boot Requirements ACPI table requirement validator.
-
- Copyright (c) 2020, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Glossary:
- - Sbbr or SBBR - Server Base Boot Requirements
- - Sbsa or SBSA - Server Base System Architecture
-
- @par Reference(s):
- - Arm Server Base Boot Requirements 1.2, September 2019
- - Arm Server Base Boot Requirements 1.1, May 2018
- - Arm Server Base Boot Requirements 1.0, March 2016
- - Arm Server Base System Architecture 6.0
-**/
-
-#include <Library/DebugLib.h>
-#include <Library/UefiLib.h>
-#include "AcpiParser.h"
-#include "Arm/SbbrValidator.h"
-
-/**
- SBBR specification version strings
-**/
-STATIC CONST CHAR8 *ArmSbbrVersions[ArmSbbrVersionMax] = {
- "1.0", // ArmSbbrVersion_1_0
- "1.1", // ArmSbbrVersion_1_1
- "1.2" // ArmSbbrVersion_1_2
-};
-
-/**
- SBBR 1.0 mandatory ACPI tables
-**/
-STATIC CONST UINT32 ArmSbbr10Mandatory[] = {
- EFI_ACPI_6_3_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
- EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
- EFI_ACPI_6_3_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
- EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
- EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE,
- EFI_ACPI_6_3_DEBUG_PORT_2_TABLE_SIGNATURE,
- EFI_ACPI_6_3_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE
-};
-
-/**
- SBBR 1.1 mandatory ACPI tables
-**/
-STATIC CONST UINT32 ArmSbbr11Mandatory[] = {
- EFI_ACPI_6_3_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
- EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
- EFI_ACPI_6_3_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
- EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
- EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE,
- EFI_ACPI_6_3_DEBUG_PORT_2_TABLE_SIGNATURE,
- EFI_ACPI_6_3_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE,
- EFI_ACPI_6_3_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE
-};
-
-/**
- SBBR 1.2 mandatory ACPI tables
-**/
-STATIC CONST UINT32 ArmSbbr12Mandatory[] = {
- EFI_ACPI_6_3_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
- EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
- EFI_ACPI_6_3_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
- EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
- EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE,
- EFI_ACPI_6_3_DEBUG_PORT_2_TABLE_SIGNATURE,
- EFI_ACPI_6_3_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE,
- EFI_ACPI_6_3_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
- EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE
-};
-
-/**
- Mandatory ACPI tables for every SBBR specification version.
-**/
-STATIC CONST ACPI_SBBR_REQ ArmSbbrReqs[ArmSbbrVersionMax] = {
- { ArmSbbr10Mandatory, ARRAY_SIZE (ArmSbbr10Mandatory) }, // SBBR v1.0
- { ArmSbbr11Mandatory, ARRAY_SIZE (ArmSbbr11Mandatory) }, // SBBR v1.1
- { ArmSbbr12Mandatory, ARRAY_SIZE (ArmSbbr12Mandatory) } // SBBR v1.2
-};
-
-/**
- Data structure to track instance counts for all ACPI tables which are
- defined as 'mandatory' in any SBBR version.
-**/
-STATIC ACPI_TABLE_COUNTER ArmSbbrTableCounts[] = {
- { EFI_ACPI_6_3_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, 0 },
- { EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, 0 },
- { EFI_ACPI_6_3_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, 0 },
- { EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, 0 },
- { EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE, 0 },
- { EFI_ACPI_6_3_DEBUG_PORT_2_TABLE_SIGNATURE, 0 },
- { EFI_ACPI_6_3_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, 0 },
- { EFI_ACPI_6_3_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE, 0 },
- { EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE, 0 }
-};
-
-/**
- Reset the platform ACPI table instance count for all SBBR-mandatory tables.
-**/
-VOID
-EFIAPI
-ArmSbbrResetTableCounts (
- VOID
- )
-{
- UINT32 Table;
-
- for (Table = 0; Table < ARRAY_SIZE (ArmSbbrTableCounts); Table++) {
- ArmSbbrTableCounts[Table].Count = 0;
- }
-}
-
-/**
- Increment instance count for SBBR-mandatory ACPI table with the given
- signature.
-
- @param [in] Signature ACPI table signature.
-
- @retval TRUE Count incremented successfully.
- @retval FALSE Table with the input signature not found.
-**/
-BOOLEAN
-EFIAPI
-ArmSbbrIncrementTableCount (
- UINT32 Signature
- )
-{
- UINT32 Table;
-
- for (Table = 0; Table < ARRAY_SIZE (ArmSbbrTableCounts); Table++) {
- if (Signature == ArmSbbrTableCounts[Table].Signature) {
- ArmSbbrTableCounts[Table].Count++;
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-/**
- Validate that all ACPI tables required by the given SBBR specification
- version are installed on the platform.
-
- @param [in] Version SBBR spec version to validate against.
-
- @retval EFI_SUCCESS All required tables are present.
- @retval EFI_INVALID_PARAMETER Invalid SBBR version.
- @retval EFI_NOT_FOUND One or more mandatory tables are missing.
- @retval EFI_UNSUPPORTED Mandatory ACPI table does not have its
- instance count tracked.
-**/
-EFI_STATUS
-EFIAPI
-ArmSbbrReqsValidate (
- ARM_SBBR_VERSION Version
- )
-{
- UINT32 Table;
- UINT32 Index;
- UINT32 MandatoryTable;
- CONST UINT8 *SignaturePtr;
- BOOLEAN IsArmSbbrViolated;
-
- if (Version >= ArmSbbrVersionMax) {
- return EFI_INVALID_PARAMETER;
- }
-
- IsArmSbbrViolated = FALSE;
-
- // Go through the list of mandatory tables for the input SBBR version
- for (Table = 0; Table < ArmSbbrReqs[Version].TableCount; Table++) {
- MandatoryTable = ArmSbbrReqs[Version].Tables[Table];
- SignaturePtr = (CONST UINT8 *)(UINTN)&MandatoryTable;
-
- // Locate the instance count for the table with the given signature
- Index = 0;
- while ((Index < ARRAY_SIZE (ArmSbbrTableCounts)) &&
- (ArmSbbrTableCounts[Index].Signature != MandatoryTable))
- {
- Index++;
- }
-
- if (Index >= ARRAY_SIZE (ArmSbbrTableCounts)) {
- IncrementErrorCount ();
- Print (
- L"\nERROR: SBBR v%a: Mandatory %c%c%c%c table's instance count not " \
- L"found\n",
- ArmSbbrVersions[Version],
- SignaturePtr[0],
- SignaturePtr[1],
- SignaturePtr[2],
- SignaturePtr[3]
- );
- return EFI_UNSUPPORTED;
- }
-
- if (ArmSbbrTableCounts[Index].Count == 0) {
- IsArmSbbrViolated = TRUE;
- IncrementErrorCount ();
- Print (
- L"\nERROR: SBBR v%a: Mandatory %c%c%c%c table is missing",
- ArmSbbrVersions[Version],
- SignaturePtr[0],
- SignaturePtr[1],
- SignaturePtr[2],
- SignaturePtr[3]
- );
- }
- }
-
- if (!IsArmSbbrViolated) {
- Print (
- L"\nINFO: SBBR v%a: All mandatory ACPI tables are installed",
- ArmSbbrVersions[Version]
- );
- }
-
- Print (L"\n");
-
- return IsArmSbbrViolated ? EFI_NOT_FOUND : EFI_SUCCESS;
-}
+/** @file + Arm Server Base Boot Requirements ACPI table requirement validator. + + Copyright (c) 2020, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - Sbbr or SBBR - Server Base Boot Requirements + - Sbsa or SBSA - Server Base System Architecture + + @par Reference(s): + - Arm Server Base Boot Requirements 1.2, September 2019 + - Arm Server Base Boot Requirements 1.1, May 2018 + - Arm Server Base Boot Requirements 1.0, March 2016 + - Arm Server Base System Architecture 6.0 +**/ + +#include <Library/DebugLib.h> +#include <Library/UefiLib.h> +#include "AcpiParser.h" +#include "Arm/SbbrValidator.h" + +/** + SBBR specification version strings +**/ +STATIC CONST CHAR8 *ArmSbbrVersions[ArmSbbrVersionMax] = { + "1.0", // ArmSbbrVersion_1_0 + "1.1", // ArmSbbrVersion_1_1 + "1.2" // ArmSbbrVersion_1_2 +}; + +/** + SBBR 1.0 mandatory ACPI tables +**/ +STATIC CONST UINT32 ArmSbbr10Mandatory[] = { + EFI_ACPI_6_3_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, + EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, + EFI_ACPI_6_3_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, + EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, + EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE, + EFI_ACPI_6_3_DEBUG_PORT_2_TABLE_SIGNATURE, + EFI_ACPI_6_3_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE +}; + +/** + SBBR 1.1 mandatory ACPI tables +**/ +STATIC CONST UINT32 ArmSbbr11Mandatory[] = { + EFI_ACPI_6_3_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, + EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, + EFI_ACPI_6_3_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, + EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, + EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE, + EFI_ACPI_6_3_DEBUG_PORT_2_TABLE_SIGNATURE, + EFI_ACPI_6_3_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, + EFI_ACPI_6_3_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE +}; + +/** + SBBR 1.2 mandatory ACPI tables +**/ +STATIC CONST UINT32 ArmSbbr12Mandatory[] = { + EFI_ACPI_6_3_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, + EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, + EFI_ACPI_6_3_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, + EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, + EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE, + EFI_ACPI_6_3_DEBUG_PORT_2_TABLE_SIGNATURE, + EFI_ACPI_6_3_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, + EFI_ACPI_6_3_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE, + EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE +}; + +/** + Mandatory ACPI tables for every SBBR specification version. +**/ +STATIC CONST ACPI_SBBR_REQ ArmSbbrReqs[ArmSbbrVersionMax] = { + { ArmSbbr10Mandatory, ARRAY_SIZE (ArmSbbr10Mandatory) }, // SBBR v1.0 + { ArmSbbr11Mandatory, ARRAY_SIZE (ArmSbbr11Mandatory) }, // SBBR v1.1 + { ArmSbbr12Mandatory, ARRAY_SIZE (ArmSbbr12Mandatory) } // SBBR v1.2 +}; + +/** + Data structure to track instance counts for all ACPI tables which are + defined as 'mandatory' in any SBBR version. +**/ +STATIC ACPI_TABLE_COUNTER ArmSbbrTableCounts[] = { + { EFI_ACPI_6_3_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, 0 }, + { EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, 0 }, + { EFI_ACPI_6_3_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE, 0 }, + { EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE, 0 }, + { EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE, 0 }, + { EFI_ACPI_6_3_DEBUG_PORT_2_TABLE_SIGNATURE, 0 }, + { EFI_ACPI_6_3_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE, 0 }, + { EFI_ACPI_6_3_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE, 0 }, + { EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE, 0 } +}; + +/** + Reset the platform ACPI table instance count for all SBBR-mandatory tables. +**/ +VOID +EFIAPI +ArmSbbrResetTableCounts ( + VOID + ) +{ + UINT32 Table; + + for (Table = 0; Table < ARRAY_SIZE (ArmSbbrTableCounts); Table++) { + ArmSbbrTableCounts[Table].Count = 0; + } +} + +/** + Increment instance count for SBBR-mandatory ACPI table with the given + signature. + + @param [in] Signature ACPI table signature. + + @retval TRUE Count incremented successfully. + @retval FALSE Table with the input signature not found. +**/ +BOOLEAN +EFIAPI +ArmSbbrIncrementTableCount ( + UINT32 Signature + ) +{ + UINT32 Table; + + for (Table = 0; Table < ARRAY_SIZE (ArmSbbrTableCounts); Table++) { + if (Signature == ArmSbbrTableCounts[Table].Signature) { + ArmSbbrTableCounts[Table].Count++; + return TRUE; + } + } + + return FALSE; +} + +/** + Validate that all ACPI tables required by the given SBBR specification + version are installed on the platform. + + @param [in] Version SBBR spec version to validate against. + + @retval EFI_SUCCESS All required tables are present. + @retval EFI_INVALID_PARAMETER Invalid SBBR version. + @retval EFI_NOT_FOUND One or more mandatory tables are missing. + @retval EFI_UNSUPPORTED Mandatory ACPI table does not have its + instance count tracked. +**/ +EFI_STATUS +EFIAPI +ArmSbbrReqsValidate ( + ARM_SBBR_VERSION Version + ) +{ + UINT32 Table; + UINT32 Index; + UINT32 MandatoryTable; + CONST UINT8 *SignaturePtr; + BOOLEAN IsArmSbbrViolated; + + if (Version >= ArmSbbrVersionMax) { + return EFI_INVALID_PARAMETER; + } + + IsArmSbbrViolated = FALSE; + + // Go through the list of mandatory tables for the input SBBR version + for (Table = 0; Table < ArmSbbrReqs[Version].TableCount; Table++) { + MandatoryTable = ArmSbbrReqs[Version].Tables[Table]; + SignaturePtr = (CONST UINT8 *)(UINTN)&MandatoryTable; + + // Locate the instance count for the table with the given signature + Index = 0; + while ((Index < ARRAY_SIZE (ArmSbbrTableCounts)) && + (ArmSbbrTableCounts[Index].Signature != MandatoryTable)) + { + Index++; + } + + if (Index >= ARRAY_SIZE (ArmSbbrTableCounts)) { + IncrementErrorCount (); + Print ( + L"\nERROR: SBBR v%a: Mandatory %c%c%c%c table's instance count not " \ + L"found\n", + ArmSbbrVersions[Version], + SignaturePtr[0], + SignaturePtr[1], + SignaturePtr[2], + SignaturePtr[3] + ); + return EFI_UNSUPPORTED; + } + + if (ArmSbbrTableCounts[Index].Count == 0) { + IsArmSbbrViolated = TRUE; + IncrementErrorCount (); + Print ( + L"\nERROR: SBBR v%a: Mandatory %c%c%c%c table is missing", + ArmSbbrVersions[Version], + SignaturePtr[0], + SignaturePtr[1], + SignaturePtr[2], + SignaturePtr[3] + ); + } + } + + if (!IsArmSbbrViolated) { + Print ( + L"\nINFO: SBBR v%a: All mandatory ACPI tables are installed", + ArmSbbrVersions[Version] + ); + } + + Print (L"\n"); + + return IsArmSbbrViolated ? EFI_NOT_FOUND : EFI_SUCCESS; +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Arm/SbbrValidator.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Arm/SbbrValidator.h index b6d46af776..b5f9a5baad 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Arm/SbbrValidator.h +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Arm/SbbrValidator.h @@ -1,91 +1,91 @@ -/** @file
- Header file for SbbrValidator.c
-
- Copyright (c) 2020, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Glossary:
- - Sbbr or SBBR - Server Base Boot Requirements
- - Sbsa or SBSA - Server Base System Architecture
-
- @par Reference(s):
- - Arm Server Base Boot Requirements 1.2, September 2019
- - Arm Server Base Boot Requirements 1.1, May 2018
- - Arm Server Base Boot Requirements 1.0, March 2016
- - Arm Server Base System Architecture 6.0
-**/
-
-#ifndef SBBR_VALIDATOR_H_
-#define SBBR_VALIDATOR_H_
-
-#include <IndustryStandard/Acpi.h>
-
-/**
- Arm SBBR specification versions.
-**/
-typedef enum {
- ArmSbbrVersion_1_0 = 0,
- ArmSbbrVersion_1_1 = 1,
- ArmSbbrVersion_1_2 = 2,
- ArmSbbrVersionMax = 3
-} ARM_SBBR_VERSION;
-
-/**
- The ACPI table instance counter.
-**/
-typedef struct AcpiTableCounter {
- CONST UINT32 Signature; /// ACPI table signature
- UINT32 Count; /// Instance count
-} ACPI_TABLE_COUNTER;
-
-/**
- ACPI table SBBR requirements.
-**/
-typedef struct AcpiSbbrReq {
- CONST UINT32 *Tables; /// List of required tables
- CONST UINT32 TableCount; /// Number of elements in Tables
-} ACPI_SBBR_REQ;
-
-/**
- Reset the platform ACPI table instance count for all SBBR-mandatory tables.
-**/
-VOID
-EFIAPI
-ArmSbbrResetTableCounts (
- VOID
- );
-
-/**
- Increment instance count for SBBR-mandatory ACPI table with the given
- signature.
-
- @param [in] Signature ACPI table signature.
-
- @retval TRUE Count incremented successfully.
- @retval FALSE Table with the input signature not found.
-**/
-BOOLEAN
-EFIAPI
-ArmSbbrIncrementTableCount (
- UINT32 Signature
- );
-
-/**
- Validate that all ACPI tables required by the given SBBR specification
- version are installed on the platform.
-
- @param [in] Version SBBR spec version to validate against.
-
- @retval EFI_SUCCESS All required tables are present.
- @retval EFI_INVALID_PARAMETER Invalid SBBR version.
- @retval EFI_NOT_FOUND One or more mandatory tables are missing.
- @retval EFI_UNSUPPORTED Mandatory ACPI table does not have its
- instance count tracked.
-**/
-EFI_STATUS
-EFIAPI
-ArmSbbrReqsValidate (
- ARM_SBBR_VERSION Version
- );
-
-#endif // SBBR_VALIDATOR_H_
+/** @file + Header file for SbbrValidator.c + + Copyright (c) 2020, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Glossary: + - Sbbr or SBBR - Server Base Boot Requirements + - Sbsa or SBSA - Server Base System Architecture + + @par Reference(s): + - Arm Server Base Boot Requirements 1.2, September 2019 + - Arm Server Base Boot Requirements 1.1, May 2018 + - Arm Server Base Boot Requirements 1.0, March 2016 + - Arm Server Base System Architecture 6.0 +**/ + +#ifndef SBBR_VALIDATOR_H_ +#define SBBR_VALIDATOR_H_ + +#include <IndustryStandard/Acpi.h> + +/** + Arm SBBR specification versions. +**/ +typedef enum { + ArmSbbrVersion_1_0 = 0, + ArmSbbrVersion_1_1 = 1, + ArmSbbrVersion_1_2 = 2, + ArmSbbrVersionMax = 3 +} ARM_SBBR_VERSION; + +/** + The ACPI table instance counter. +**/ +typedef struct AcpiTableCounter { + CONST UINT32 Signature; /// ACPI table signature + UINT32 Count; /// Instance count +} ACPI_TABLE_COUNTER; + +/** + ACPI table SBBR requirements. +**/ +typedef struct AcpiSbbrReq { + CONST UINT32 *Tables; /// List of required tables + CONST UINT32 TableCount; /// Number of elements in Tables +} ACPI_SBBR_REQ; + +/** + Reset the platform ACPI table instance count for all SBBR-mandatory tables. +**/ +VOID +EFIAPI +ArmSbbrResetTableCounts ( + VOID + ); + +/** + Increment instance count for SBBR-mandatory ACPI table with the given + signature. + + @param [in] Signature ACPI table signature. + + @retval TRUE Count incremented successfully. + @retval FALSE Table with the input signature not found. +**/ +BOOLEAN +EFIAPI +ArmSbbrIncrementTableCount ( + UINT32 Signature + ); + +/** + Validate that all ACPI tables required by the given SBBR specification + version are installed on the platform. + + @param [in] Version SBBR spec version to validate against. + + @retval EFI_SUCCESS All required tables are present. + @retval EFI_INVALID_PARAMETER Invalid SBBR version. + @retval EFI_NOT_FOUND One or more mandatory tables are missing. + @retval EFI_UNSUPPORTED Mandatory ACPI table does not have its + instance count tracked. +**/ +EFI_STATUS +EFIAPI +ArmSbbrReqsValidate ( + ARM_SBBR_VERSION Version + ); + +#endif // SBBR_VALIDATOR_H_ diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c index 48f71484fb..7cf82103f7 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Aest/AestParser.c @@ -1,760 +1,760 @@ -/** @file
- AEST table parser
-
- Copyright (c) 2020, Arm Limited.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Reference(s):
- - ACPI for the Armv8 RAS Extensions 1.1 Platform Design Document,
- dated 28 September 2020.
- (https://developer.arm.com/documentation/den0085/0101/)
-**/
-
-#include <Library/PrintLib.h>
-#include <Library/UefiLib.h>
-#include <IndustryStandard/ArmErrorSourceTable.h>
-#include "AcpiParser.h"
-#include "AcpiView.h"
-#include "AcpiViewConfig.h"
-
-// Local variables
-STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
-STATIC UINT8 *AestNodeType;
-STATIC UINT16 *AestNodeLength;
-STATIC UINT32 *NodeDataOffset;
-STATIC UINT32 *NodeInterfaceOffset;
-STATIC UINT32 *NodeInterruptArrayOffset;
-STATIC UINT32 *NodeInterruptCount;
-STATIC UINT32 *ProcessorId;
-STATIC UINT8 *ProcessorFlags;
-STATIC UINT8 *ProcessorResourceType;
-
-/**
- Validate Processor 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
-ValidateProcessorFlags (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- // If the global or shared node flag is set then the ACPI Processor ID
- // field must be set to 0 and ignored.
- if (((*Ptr & 0x3) != 0) && (*ProcessorId != 0)) {
- IncrementErrorCount ();
- Print (
- L"\nERROR: 'ACPI Processor ID' field must be set to 0 for global"
- L" or shared nodes."
- );
- }
-}
-
-/**
- Validate GIC Interface 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
-ValidateGicInterfaceType (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- UINT32 GicInterfaceType;
-
- GicInterfaceType = *(UINT32 *)Ptr;
- if (GicInterfaceType > 3) {
- IncrementErrorCount ();
- Print (L"\nError: Invalid GIC Interface type %d", GicInterfaceType);
- }
-}
-
-/**
- Validate Interface 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
-ValidateInterfaceType (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- if (*Ptr > 1) {
- IncrementErrorCount ();
- Print (L"\nError: Interface type should be 0 or 1");
- }
-}
-
-/**
- Validate 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 (*Ptr > 1) {
- IncrementErrorCount ();
- Print (L"\nError: Interrupt type should be 0 or 1");
- }
-}
-
-/**
- Validate interrupt 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
-ValidateInterruptFlags (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- if ((*Ptr & 0xfe) != 0) {
- IncrementErrorCount ();
- Print (L"\nError: Reserved Flag bits not set to 0");
- }
-}
-
-/**
- Dumps 16 bytes of data.
-
- @param [in] Format Optional format string for tracing the data.
- @param [in] Ptr Pointer to the start of the buffer.
-**/
-VOID
-EFIAPI
-DumpVendorSpecificData (
- IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
- )
-{
- Print (
- L"%02X %02X %02X %02X %02X %02X %02X %02X\n",
- Ptr[0],
- Ptr[1],
- Ptr[2],
- Ptr[3],
- Ptr[4],
- Ptr[5],
- Ptr[6],
- Ptr[7]
- );
-
- Print (
- L"%*a %02X %02X %02X %02X %02X %02X %02X %02X",
- OUTPUT_FIELD_COLUMN_WIDTH,
- "",
- Ptr[8],
- Ptr[9],
- Ptr[10],
- Ptr[11],
- Ptr[12],
- Ptr[13],
- Ptr[14],
- Ptr[15]
- );
-}
-
-/**
- An ACPI_PARSER array describing the ACPI AEST Table.
-**/
-STATIC CONST ACPI_PARSER AestParser[] = {
- PARSE_ACPI_HEADER (&AcpiHdrInfo)
-};
-
-/**
- An ACPI_PARSER array describing the AEST Node Header.
-**/
-STATIC CONST ACPI_PARSER AestNodeHeaderParser[] = {
- { L"Type", 1, 0, L"%d", NULL, (VOID **)&AestNodeType, NULL, NULL },
- { L"Length", 2, 1, L"%d", NULL, (VOID **)&AestNodeLength, NULL, NULL },
- { L"Reserved", 1, 3, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Node Data Offset", 4, 4, L"%d", NULL, (VOID **)&NodeDataOffset, NULL, NULL },
- { L"Node Interface Offset", 4, 8, L"%d", NULL,
- (VOID **)&NodeInterfaceOffset, NULL, NULL },
- { L"Node Interrupt Array Offset", 4, 12, L"%d", NULL,
- (VOID **)&NodeInterruptArrayOffset, NULL, NULL },
- { L"Node Interrupt Count", 4, 16, L"%d", NULL,
- (VOID **)&NodeInterruptCount, NULL, NULL },
- { L"Timestamp Rate", 8, 20, L"%ld", NULL, NULL, NULL, NULL },
- { L"Reserved1", 8, 28, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Error Injection Countdown Rate", 8, 36, L"%ld", NULL, NULL, NULL, NULL }
- // Node specific data...
- // Node interface...
- // Node interrupt array...
-};
-
-/**
- An ACPI_PARSER array describing the Processor error node specific data.
-**/
-STATIC CONST ACPI_PARSER AestProcessorStructure[] = {
- { L"ACPI Processor ID", 4, 0, L"0x%x", NULL, (VOID **)&ProcessorId, NULL, NULL },
- { L"Resource Type", 1, 4, L"%d", NULL, (VOID **)&ProcessorResourceType, NULL,
- NULL },
- { L"Reserved", 1, 5, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Flags", 1, 6, L"0x%x", NULL, (VOID **)&ProcessorFlags,
- ValidateProcessorFlags, NULL },
- { L"Revision", 1, 7, L"%d", NULL, NULL, NULL, NULL },
- { L"Processor Affinity Level Indicator", 8, 8, L"0x%lx", NULL, NULL, NULL,
- NULL },
- // Resource specific data...
-};
-
-/**
- An ACPI_PARSER array describing the processor cache resource substructure.
-**/
-STATIC CONST ACPI_PARSER AestProcessorCacheResourceSubstructure[] = {
- { L"Cache reference ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Reserved", 4, 4, L"%d", NULL, NULL, NULL, NULL }
-};
-
-/**
- An ACPI_PARSER array describing the processor TLB resource substructure.
-**/
-STATIC CONST ACPI_PARSER AestProcessorTlbResourceSubstructure[] = {
- { L"TLB reference ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Reserved", 4, 4, L"%d", NULL, NULL, NULL, NULL }
-};
-
-/**
- An ACPI_PARSER array describing the processor generic resource substructure.
-**/
-STATIC CONST ACPI_PARSER AestProcessorGenericResourceSubstructure[] = {
- { L"Vendor-defined data", 4, 0, L"%x", NULL, NULL, NULL, NULL }
-};
-
-/**
- An ACPI_PARSER array describing the memory controller structure.
-**/
-STATIC CONST ACPI_PARSER AestMemoryControllerStructure[] = {
- { L"Proximity Domain", 4, 0, L"0x%x", NULL, NULL, NULL, NULL }
-};
-
-/**
- An ACPI_PARSER array describing the SMMU structure.
-**/
-STATIC CONST ACPI_PARSER AestSmmuStructure[] = {
- { L"IORT Node reference ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL },
- { L"SubComponent reference ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL }
-};
-
-/**
- An ACPI_PARSER array describing the vendor-defined structure.
-**/
-STATIC CONST ACPI_PARSER AestVendorDefinedStructure[] = {
- { L"Hardware ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Unique ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Vendor-specific data", 16, 8, NULL, DumpVendorSpecificData, NULL, NULL }
-};
-
-/**
- An ACPI_PARSER array describing the GIC structure.
-**/
-STATIC CONST ACPI_PARSER AestGicStructure[] = {
- { L"GIC Interface Type", 4, 0, L"0x%x", NULL, NULL, ValidateGicInterfaceType,
- NULL },
- { L"GIC Interface reference ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL}
-};
-
-/**
- An ACPI_PARSER array describing the node interface.
-**/
-STATIC CONST ACPI_PARSER AestNodeInterface[] = {
- { L"Interface Type", 1, 0, L"%d", NULL, NULL, ValidateInterfaceType, NULL },
- { L"Reserved", 3, 1, L"%x %x %x", Dump3Chars, NULL, NULL, NULL },
- { L"Flags", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Start Error Record Index", 4, 16, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Number of Error Records", 4, 20, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Error Records Implemented", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Error Records Support", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Addressing mode", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL }
-};
-
-/**
- An ACPI_PARSER array describing the node interrupts.
-**/
-STATIC CONST ACPI_PARSER AestNodeInterrupt[] = {
- { L"Interrupt Type", 1, 0, L"%d", NULL, NULL, ValidateInterruptType, NULL },
- { L"Reserved", 2, 1, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Interrupt Flags", 1, 3, L"0x%x", NULL, NULL, ValidateInterruptFlags, NULL },
- { L"Interrupt GSIV", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
- { L"ID", 1, 8, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Reserved1", 3, 9, L"%x %x %x", Dump3Chars, NULL, NULL, NULL }
-};
-
-/**
- Parses the Processor Error Node structure along with its resource
- specific data.
-
- @param [in] Ptr Pointer to the start of the Processor node.
- @param [in] Length Maximum length of the Processor node.
-**/
-STATIC
-VOID
-DumpProcessorNode (
- IN UINT8 *Ptr,
- IN UINT32 Length
- )
-{
- UINT32 Offset;
-
- Offset = ParseAcpi (
- TRUE,
- 2,
- "Processor",
- Ptr,
- Length,
- PARSER_PARAMS (AestProcessorStructure)
- );
-
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if ((ProcessorId == NULL) ||
- (ProcessorResourceType == NULL) ||
- (ProcessorFlags == NULL))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient Processor Error Node length. Length = %d.\n",
- Length
- );
- return;
- }
-
- switch (*ProcessorResourceType) {
- case EFI_ACPI_AEST_PROCESSOR_RESOURCE_TYPE_CACHE:
- ParseAcpi (
- TRUE,
- 2,
- "Cache Resource",
- Ptr + Offset,
- Length - Offset,
- PARSER_PARAMS (AestProcessorCacheResourceSubstructure)
- );
- break;
- case EFI_ACPI_AEST_PROCESSOR_RESOURCE_TYPE_TLB:
- ParseAcpi (
- TRUE,
- 2,
- "TLB Resource",
- Ptr + Offset,
- Length - Offset,
- PARSER_PARAMS (AestProcessorTlbResourceSubstructure)
- );
- break;
- case EFI_ACPI_AEST_PROCESSOR_RESOURCE_TYPE_GENERIC:
- ParseAcpi (
- TRUE,
- 2,
- "Generic Resource",
- Ptr + Offset,
- Length - Offset,
- PARSER_PARAMS (AestProcessorGenericResourceSubstructure)
- );
- break;
- default:
- IncrementErrorCount ();
- Print (L"ERROR: Invalid Processor Resource Type.");
- return;
- } // switch
-}
-
-/**
- Parses the Memory Controller node.
-
- @param [in] Ptr Pointer to the start of the Memory Controller node.
- @param [in] Length Maximum length of the Memory Controller node.
-**/
-STATIC
-VOID
-DumpMemoryControllerNode (
- IN UINT8 *Ptr,
- IN UINT32 Length
- )
-{
- ParseAcpi (
- TRUE,
- 2,
- "Memory Controller",
- Ptr,
- Length,
- PARSER_PARAMS (AestMemoryControllerStructure)
- );
-}
-
-/**
- Parses the SMMU node.
-
- @param [in] Ptr Pointer to the start of the SMMU node.
- @param [in] Length Maximum length of the SMMU node.
-**/
-STATIC
-VOID
-DumpSmmuNode (
- IN UINT8 *Ptr,
- IN UINT32 Length
- )
-{
- ParseAcpi (
- TRUE,
- 2,
- "SMMU",
- Ptr,
- Length,
- PARSER_PARAMS (AestSmmuStructure)
- );
-}
-
-/**
- Parses the Vendor-defined structure.
-
- @param [in] Ptr Pointer to the start of the Vendor-defined node.
- @param [in] Length Maximum length of the Vendor-defined node.
-**/
-STATIC
-VOID
-DumpVendorDefinedNode (
- IN UINT8 *Ptr,
- IN UINT32 Length
- )
-{
- ParseAcpi (
- TRUE,
- 2,
- "Vendor-defined",
- Ptr,
- Length,
- PARSER_PARAMS (AestVendorDefinedStructure)
- );
-}
-
-/**
- Parses the GIC node.
-
- @param [in] Ptr Pointer to the start of the GIC node.
- @param [in] Length Maximum length of the GIC node.
-**/
-STATIC
-VOID
-DumpGicNode (
- IN UINT8 *Ptr,
- IN UINT32 Length
- )
-{
- ParseAcpi (
- TRUE,
- 2,
- "GIC",
- Ptr,
- Length,
- PARSER_PARAMS (AestGicStructure)
- );
-}
-
-/**
- Parses the Node Interface structure.
-
- @param [in] Ptr Pointer to the start of the Node Interface Structure.
- @param [in] Length Maximum length of the Node Interface Structure.
-**/
-STATIC
-VOID
-DumpNodeInterface (
- IN UINT8 *Ptr,
- IN UINT32 Length
- )
-{
- ParseAcpi (
- TRUE,
- 2,
- "Node Interface",
- Ptr,
- Length,
- PARSER_PARAMS (AestNodeInterface)
- );
-}
-
-/**
- Parses the Node Interrupts Structure.
-
- @param [in] Ptr Pointer to the start of the Node Interrupt array.
- @param [in] Length Maximum length of the Node Interrupt array.
- @param [in] InterruptCount Number if interrupts in the Node Interrupts array.
-**/
-STATIC
-VOID
-DumpNodeInterrupts (
- IN UINT8 *Ptr,
- IN UINT32 Length,
- IN UINT32 InterruptCount
- )
-{
- UINT32 Offset;
- UINT32 Index;
- CHAR8 Buffer[64];
-
- if (Length < (InterruptCount * sizeof (EFI_ACPI_AEST_INTERRUPT_STRUCT))) {
- IncrementErrorCount ();
- Print (
- L"ERROR: Node not long enough for Interrupt Array.\n" \
- L" Length left = %d, Required = %d, Interrupt Count = %d\n",
- Length,
- (InterruptCount * sizeof (EFI_ACPI_AEST_INTERRUPT_STRUCT)),
- InterruptCount
- );
- return;
- }
-
- Offset = 0;
- for (Index = 0; Index < InterruptCount; Index++) {
- AsciiSPrint (
- Buffer,
- sizeof (Buffer),
- "Node Interrupt [%d]",
- Index
- );
-
- Offset += ParseAcpi (
- TRUE,
- 4,
- Buffer,
- Ptr + Offset,
- Length - Offset,
- PARSER_PARAMS (AestNodeInterrupt)
- );
- } // for
-}
-
-/**
- Parses a single AEST Node Structure.
-
- @param [in] Ptr Pointer to the start of the Node.
- @param [in] Length Maximum length of the Node.
- @param [in] NodeType AEST node type.
- @param [in] DataOffset Offset to the node data.
- @param [in] InterfaceOffset Offset to the node interface data.
- @param [in] InterruptArrayOffset Offset to the node interrupt array.
- @param [in] InterruptCount Number of interrupts.
-**/
-STATIC
-VOID
-DumpAestNodeStructure (
- IN UINT8 *Ptr,
- IN UINT32 Length,
- IN UINT8 NodeType,
- IN UINT32 DataOffset,
- IN UINT32 InterfaceOffset,
- IN UINT32 InterruptArrayOffset,
- IN UINT32 InterruptCount
- )
-{
- UINT32 Offset;
- UINT32 RemainingLength;
- UINT8 *NodeDataPtr;
-
- Offset = ParseAcpi (
- TRUE,
- 2,
- "Node Structure",
- Ptr,
- Length,
- PARSER_PARAMS (AestNodeHeaderParser)
- );
-
- if ((Offset > DataOffset) || (DataOffset > Length)) {
- IncrementErrorCount ();
- Print (
- L"ERROR: Invalid Node Data Offset: %d.\n" \
- L" It should be between %d and %d.\n",
- DataOffset,
- Offset,
- Length
- );
- }
-
- if ((Offset > InterfaceOffset) || (InterfaceOffset > Length)) {
- IncrementErrorCount ();
- Print (
- L"ERROR: Invalid Node Interface Offset: %d.\n" \
- L" It should be between %d and %d.\n",
- InterfaceOffset,
- Offset,
- Length
- );
- }
-
- if ((Offset > InterruptArrayOffset) || (InterruptArrayOffset > Length)) {
- IncrementErrorCount ();
- Print (
- L"ERROR: Invalid Node Interrupt Array Offset: %d.\n" \
- L" It should be between %d and %d.\n",
- InterruptArrayOffset,
- Offset,
- Length
- );
- }
-
- // Parse Node Data Field.
- NodeDataPtr = Ptr + DataOffset;
- RemainingLength = Length - DataOffset;
- switch (NodeType) {
- case EFI_ACPI_AEST_NODE_TYPE_PROCESSOR:
- DumpProcessorNode (NodeDataPtr, RemainingLength);
- break;
- case EFI_ACPI_AEST_NODE_TYPE_MEMORY:
- DumpMemoryControllerNode (NodeDataPtr, RemainingLength);
- break;
- case EFI_ACPI_AEST_NODE_TYPE_SMMU:
- DumpSmmuNode (NodeDataPtr, RemainingLength);
- break;
- case EFI_ACPI_AEST_NODE_TYPE_VENDOR_DEFINED:
- DumpVendorDefinedNode (NodeDataPtr, RemainingLength);
- break;
- case EFI_ACPI_AEST_NODE_TYPE_GIC:
- DumpGicNode (NodeDataPtr, RemainingLength);
- break;
- default:
- IncrementErrorCount ();
- Print (L"ERROR: Invalid Error Node Type.\n");
- return;
- } // switch
-
- // Parse the Interface Field.
- DumpNodeInterface (
- Ptr + InterfaceOffset,
- Length - InterfaceOffset
- );
-
- // Parse the Node Interrupt Array.
- DumpNodeInterrupts (
- Ptr + InterruptArrayOffset,
- Length - InterruptArrayOffset,
- InterruptCount
- );
-
- return;
-}
-
-/**
- This function parses the ACPI AEST table.
- When trace is enabled this function parses the AEST 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
-ParseAcpiAest (
- IN BOOLEAN Trace,
- IN UINT8 *Ptr,
- IN UINT32 AcpiTableLength,
- IN UINT8 AcpiTableRevision
- )
-{
- UINT32 Offset;
- UINT8 *NodePtr;
-
- if (!Trace) {
- return;
- }
-
- Offset = ParseAcpi (
- TRUE,
- 0,
- "AEST",
- Ptr,
- AcpiTableLength,
- PARSER_PARAMS (AestParser)
- );
-
- while (Offset < AcpiTableLength) {
- NodePtr = Ptr + Offset;
-
- ParseAcpi (
- FALSE,
- 0,
- NULL,
- NodePtr,
- AcpiTableLength - Offset,
- PARSER_PARAMS (AestNodeHeaderParser)
- );
-
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if ((AestNodeType == NULL) ||
- (AestNodeLength == NULL) ||
- (NodeDataOffset == NULL) ||
- (NodeInterfaceOffset == NULL) ||
- (NodeInterruptArrayOffset == NULL) ||
- (NodeInterruptCount == NULL))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient length left for Node Structure.\n" \
- L" Length left = %d.\n",
- AcpiTableLength - Offset
- );
- return;
- }
-
- // Validate AEST Node length
- if ((*AestNodeLength == 0) ||
- ((Offset + (*AestNodeLength)) > AcpiTableLength))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Invalid AEST Node length. " \
- L"Length = %d. Offset = %d. AcpiTableLength = %d.\n",
- *AestNodeLength,
- Offset,
- AcpiTableLength
- );
- return;
- }
-
- DumpAestNodeStructure (
- NodePtr,
- *AestNodeLength,
- *AestNodeType,
- *NodeDataOffset,
- *NodeInterfaceOffset,
- *NodeInterruptArrayOffset,
- *NodeInterruptCount
- );
-
- Offset += *AestNodeLength;
- } // while
-}
+/** @file + AEST table parser + + Copyright (c) 2020, Arm Limited. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI for the Armv8 RAS Extensions 1.1 Platform Design Document, + dated 28 September 2020. + (https://developer.arm.com/documentation/den0085/0101/) +**/ + +#include <Library/PrintLib.h> +#include <Library/UefiLib.h> +#include <IndustryStandard/ArmErrorSourceTable.h> +#include "AcpiParser.h" +#include "AcpiView.h" +#include "AcpiViewConfig.h" + +// Local variables +STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; +STATIC UINT8 *AestNodeType; +STATIC UINT16 *AestNodeLength; +STATIC UINT32 *NodeDataOffset; +STATIC UINT32 *NodeInterfaceOffset; +STATIC UINT32 *NodeInterruptArrayOffset; +STATIC UINT32 *NodeInterruptCount; +STATIC UINT32 *ProcessorId; +STATIC UINT8 *ProcessorFlags; +STATIC UINT8 *ProcessorResourceType; + +/** + Validate Processor 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 +ValidateProcessorFlags ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + // If the global or shared node flag is set then the ACPI Processor ID + // field must be set to 0 and ignored. + if (((*Ptr & 0x3) != 0) && (*ProcessorId != 0)) { + IncrementErrorCount (); + Print ( + L"\nERROR: 'ACPI Processor ID' field must be set to 0 for global" + L" or shared nodes." + ); + } +} + +/** + Validate GIC Interface 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 +ValidateGicInterfaceType ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + UINT32 GicInterfaceType; + + GicInterfaceType = *(UINT32 *)Ptr; + if (GicInterfaceType > 3) { + IncrementErrorCount (); + Print (L"\nError: Invalid GIC Interface type %d", GicInterfaceType); + } +} + +/** + Validate Interface 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 +ValidateInterfaceType ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + if (*Ptr > 1) { + IncrementErrorCount (); + Print (L"\nError: Interface type should be 0 or 1"); + } +} + +/** + Validate 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 (*Ptr > 1) { + IncrementErrorCount (); + Print (L"\nError: Interrupt type should be 0 or 1"); + } +} + +/** + Validate interrupt 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 +ValidateInterruptFlags ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + if ((*Ptr & 0xfe) != 0) { + IncrementErrorCount (); + Print (L"\nError: Reserved Flag bits not set to 0"); + } +} + +/** + Dumps 16 bytes of data. + + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. +**/ +VOID +EFIAPI +DumpVendorSpecificData ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + Print ( + L"%02X %02X %02X %02X %02X %02X %02X %02X\n", + Ptr[0], + Ptr[1], + Ptr[2], + Ptr[3], + Ptr[4], + Ptr[5], + Ptr[6], + Ptr[7] + ); + + Print ( + L"%*a %02X %02X %02X %02X %02X %02X %02X %02X", + OUTPUT_FIELD_COLUMN_WIDTH, + "", + Ptr[8], + Ptr[9], + Ptr[10], + Ptr[11], + Ptr[12], + Ptr[13], + Ptr[14], + Ptr[15] + ); +} + +/** + An ACPI_PARSER array describing the ACPI AEST Table. +**/ +STATIC CONST ACPI_PARSER AestParser[] = { + PARSE_ACPI_HEADER (&AcpiHdrInfo) +}; + +/** + An ACPI_PARSER array describing the AEST Node Header. +**/ +STATIC CONST ACPI_PARSER AestNodeHeaderParser[] = { + { L"Type", 1, 0, L"%d", NULL, (VOID **)&AestNodeType, NULL, NULL }, + { L"Length", 2, 1, L"%d", NULL, (VOID **)&AestNodeLength, NULL, NULL }, + { L"Reserved", 1, 3, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Node Data Offset", 4, 4, L"%d", NULL, (VOID **)&NodeDataOffset, NULL, NULL }, + { L"Node Interface Offset", 4, 8, L"%d", NULL, + (VOID **)&NodeInterfaceOffset, NULL, NULL }, + { L"Node Interrupt Array Offset", 4, 12, L"%d", NULL, + (VOID **)&NodeInterruptArrayOffset, NULL, NULL }, + { L"Node Interrupt Count", 4, 16, L"%d", NULL, + (VOID **)&NodeInterruptCount, NULL, NULL }, + { L"Timestamp Rate", 8, 20, L"%ld", NULL, NULL, NULL, NULL }, + { L"Reserved1", 8, 28, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Error Injection Countdown Rate", 8, 36, L"%ld", NULL, NULL, NULL, NULL } + // Node specific data... + // Node interface... + // Node interrupt array... +}; + +/** + An ACPI_PARSER array describing the Processor error node specific data. +**/ +STATIC CONST ACPI_PARSER AestProcessorStructure[] = { + { L"ACPI Processor ID", 4, 0, L"0x%x", NULL, (VOID **)&ProcessorId, NULL, NULL }, + { L"Resource Type", 1, 4, L"%d", NULL, (VOID **)&ProcessorResourceType, NULL, + NULL }, + { L"Reserved", 1, 5, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Flags", 1, 6, L"0x%x", NULL, (VOID **)&ProcessorFlags, + ValidateProcessorFlags, NULL }, + { L"Revision", 1, 7, L"%d", NULL, NULL, NULL, NULL }, + { L"Processor Affinity Level Indicator", 8, 8, L"0x%lx", NULL, NULL, NULL, + NULL }, + // Resource specific data... +}; + +/** + An ACPI_PARSER array describing the processor cache resource substructure. +**/ +STATIC CONST ACPI_PARSER AestProcessorCacheResourceSubstructure[] = { + { L"Cache reference ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Reserved", 4, 4, L"%d", NULL, NULL, NULL, NULL } +}; + +/** + An ACPI_PARSER array describing the processor TLB resource substructure. +**/ +STATIC CONST ACPI_PARSER AestProcessorTlbResourceSubstructure[] = { + { L"TLB reference ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Reserved", 4, 4, L"%d", NULL, NULL, NULL, NULL } +}; + +/** + An ACPI_PARSER array describing the processor generic resource substructure. +**/ +STATIC CONST ACPI_PARSER AestProcessorGenericResourceSubstructure[] = { + { L"Vendor-defined data", 4, 0, L"%x", NULL, NULL, NULL, NULL } +}; + +/** + An ACPI_PARSER array describing the memory controller structure. +**/ +STATIC CONST ACPI_PARSER AestMemoryControllerStructure[] = { + { L"Proximity Domain", 4, 0, L"0x%x", NULL, NULL, NULL, NULL } +}; + +/** + An ACPI_PARSER array describing the SMMU structure. +**/ +STATIC CONST ACPI_PARSER AestSmmuStructure[] = { + { L"IORT Node reference ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL }, + { L"SubComponent reference ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL } +}; + +/** + An ACPI_PARSER array describing the vendor-defined structure. +**/ +STATIC CONST ACPI_PARSER AestVendorDefinedStructure[] = { + { L"Hardware ID", 4, 0, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Unique ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Vendor-specific data", 16, 8, NULL, DumpVendorSpecificData, NULL, NULL } +}; + +/** + An ACPI_PARSER array describing the GIC structure. +**/ +STATIC CONST ACPI_PARSER AestGicStructure[] = { + { L"GIC Interface Type", 4, 0, L"0x%x", NULL, NULL, ValidateGicInterfaceType, + NULL }, + { L"GIC Interface reference ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL} +}; + +/** + An ACPI_PARSER array describing the node interface. +**/ +STATIC CONST ACPI_PARSER AestNodeInterface[] = { + { L"Interface Type", 1, 0, L"%d", NULL, NULL, ValidateInterfaceType, NULL }, + { L"Reserved", 3, 1, L"%x %x %x", Dump3Chars, NULL, NULL, NULL }, + { L"Flags", 4, 4, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Start Error Record Index", 4, 16, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Number of Error Records", 4, 20, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Error Records Implemented", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Error Records Support", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Addressing mode", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL } +}; + +/** + An ACPI_PARSER array describing the node interrupts. +**/ +STATIC CONST ACPI_PARSER AestNodeInterrupt[] = { + { L"Interrupt Type", 1, 0, L"%d", NULL, NULL, ValidateInterruptType, NULL }, + { L"Reserved", 2, 1, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Interrupt Flags", 1, 3, L"0x%x", NULL, NULL, ValidateInterruptFlags, NULL }, + { L"Interrupt GSIV", 4, 4, L"0x%x", NULL, NULL, NULL, NULL }, + { L"ID", 1, 8, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Reserved1", 3, 9, L"%x %x %x", Dump3Chars, NULL, NULL, NULL } +}; + +/** + Parses the Processor Error Node structure along with its resource + specific data. + + @param [in] Ptr Pointer to the start of the Processor node. + @param [in] Length Maximum length of the Processor node. +**/ +STATIC +VOID +DumpProcessorNode ( + IN UINT8 *Ptr, + IN UINT32 Length + ) +{ + UINT32 Offset; + + Offset = ParseAcpi ( + TRUE, + 2, + "Processor", + Ptr, + Length, + PARSER_PARAMS (AestProcessorStructure) + ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if ((ProcessorId == NULL) || + (ProcessorResourceType == NULL) || + (ProcessorFlags == NULL)) + { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient Processor Error Node length. Length = %d.\n", + Length + ); + return; + } + + switch (*ProcessorResourceType) { + case EFI_ACPI_AEST_PROCESSOR_RESOURCE_TYPE_CACHE: + ParseAcpi ( + TRUE, + 2, + "Cache Resource", + Ptr + Offset, + Length - Offset, + PARSER_PARAMS (AestProcessorCacheResourceSubstructure) + ); + break; + case EFI_ACPI_AEST_PROCESSOR_RESOURCE_TYPE_TLB: + ParseAcpi ( + TRUE, + 2, + "TLB Resource", + Ptr + Offset, + Length - Offset, + PARSER_PARAMS (AestProcessorTlbResourceSubstructure) + ); + break; + case EFI_ACPI_AEST_PROCESSOR_RESOURCE_TYPE_GENERIC: + ParseAcpi ( + TRUE, + 2, + "Generic Resource", + Ptr + Offset, + Length - Offset, + PARSER_PARAMS (AestProcessorGenericResourceSubstructure) + ); + break; + default: + IncrementErrorCount (); + Print (L"ERROR: Invalid Processor Resource Type."); + return; + } // switch +} + +/** + Parses the Memory Controller node. + + @param [in] Ptr Pointer to the start of the Memory Controller node. + @param [in] Length Maximum length of the Memory Controller node. +**/ +STATIC +VOID +DumpMemoryControllerNode ( + IN UINT8 *Ptr, + IN UINT32 Length + ) +{ + ParseAcpi ( + TRUE, + 2, + "Memory Controller", + Ptr, + Length, + PARSER_PARAMS (AestMemoryControllerStructure) + ); +} + +/** + Parses the SMMU node. + + @param [in] Ptr Pointer to the start of the SMMU node. + @param [in] Length Maximum length of the SMMU node. +**/ +STATIC +VOID +DumpSmmuNode ( + IN UINT8 *Ptr, + IN UINT32 Length + ) +{ + ParseAcpi ( + TRUE, + 2, + "SMMU", + Ptr, + Length, + PARSER_PARAMS (AestSmmuStructure) + ); +} + +/** + Parses the Vendor-defined structure. + + @param [in] Ptr Pointer to the start of the Vendor-defined node. + @param [in] Length Maximum length of the Vendor-defined node. +**/ +STATIC +VOID +DumpVendorDefinedNode ( + IN UINT8 *Ptr, + IN UINT32 Length + ) +{ + ParseAcpi ( + TRUE, + 2, + "Vendor-defined", + Ptr, + Length, + PARSER_PARAMS (AestVendorDefinedStructure) + ); +} + +/** + Parses the GIC node. + + @param [in] Ptr Pointer to the start of the GIC node. + @param [in] Length Maximum length of the GIC node. +**/ +STATIC +VOID +DumpGicNode ( + IN UINT8 *Ptr, + IN UINT32 Length + ) +{ + ParseAcpi ( + TRUE, + 2, + "GIC", + Ptr, + Length, + PARSER_PARAMS (AestGicStructure) + ); +} + +/** + Parses the Node Interface structure. + + @param [in] Ptr Pointer to the start of the Node Interface Structure. + @param [in] Length Maximum length of the Node Interface Structure. +**/ +STATIC +VOID +DumpNodeInterface ( + IN UINT8 *Ptr, + IN UINT32 Length + ) +{ + ParseAcpi ( + TRUE, + 2, + "Node Interface", + Ptr, + Length, + PARSER_PARAMS (AestNodeInterface) + ); +} + +/** + Parses the Node Interrupts Structure. + + @param [in] Ptr Pointer to the start of the Node Interrupt array. + @param [in] Length Maximum length of the Node Interrupt array. + @param [in] InterruptCount Number if interrupts in the Node Interrupts array. +**/ +STATIC +VOID +DumpNodeInterrupts ( + IN UINT8 *Ptr, + IN UINT32 Length, + IN UINT32 InterruptCount + ) +{ + UINT32 Offset; + UINT32 Index; + CHAR8 Buffer[64]; + + if (Length < (InterruptCount * sizeof (EFI_ACPI_AEST_INTERRUPT_STRUCT))) { + IncrementErrorCount (); + Print ( + L"ERROR: Node not long enough for Interrupt Array.\n" \ + L" Length left = %d, Required = %d, Interrupt Count = %d\n", + Length, + (InterruptCount * sizeof (EFI_ACPI_AEST_INTERRUPT_STRUCT)), + InterruptCount + ); + return; + } + + Offset = 0; + for (Index = 0; Index < InterruptCount; Index++) { + AsciiSPrint ( + Buffer, + sizeof (Buffer), + "Node Interrupt [%d]", + Index + ); + + Offset += ParseAcpi ( + TRUE, + 4, + Buffer, + Ptr + Offset, + Length - Offset, + PARSER_PARAMS (AestNodeInterrupt) + ); + } // for +} + +/** + Parses a single AEST Node Structure. + + @param [in] Ptr Pointer to the start of the Node. + @param [in] Length Maximum length of the Node. + @param [in] NodeType AEST node type. + @param [in] DataOffset Offset to the node data. + @param [in] InterfaceOffset Offset to the node interface data. + @param [in] InterruptArrayOffset Offset to the node interrupt array. + @param [in] InterruptCount Number of interrupts. +**/ +STATIC +VOID +DumpAestNodeStructure ( + IN UINT8 *Ptr, + IN UINT32 Length, + IN UINT8 NodeType, + IN UINT32 DataOffset, + IN UINT32 InterfaceOffset, + IN UINT32 InterruptArrayOffset, + IN UINT32 InterruptCount + ) +{ + UINT32 Offset; + UINT32 RemainingLength; + UINT8 *NodeDataPtr; + + Offset = ParseAcpi ( + TRUE, + 2, + "Node Structure", + Ptr, + Length, + PARSER_PARAMS (AestNodeHeaderParser) + ); + + if ((Offset > DataOffset) || (DataOffset > Length)) { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid Node Data Offset: %d.\n" \ + L" It should be between %d and %d.\n", + DataOffset, + Offset, + Length + ); + } + + if ((Offset > InterfaceOffset) || (InterfaceOffset > Length)) { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid Node Interface Offset: %d.\n" \ + L" It should be between %d and %d.\n", + InterfaceOffset, + Offset, + Length + ); + } + + if ((Offset > InterruptArrayOffset) || (InterruptArrayOffset > Length)) { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid Node Interrupt Array Offset: %d.\n" \ + L" It should be between %d and %d.\n", + InterruptArrayOffset, + Offset, + Length + ); + } + + // Parse Node Data Field. + NodeDataPtr = Ptr + DataOffset; + RemainingLength = Length - DataOffset; + switch (NodeType) { + case EFI_ACPI_AEST_NODE_TYPE_PROCESSOR: + DumpProcessorNode (NodeDataPtr, RemainingLength); + break; + case EFI_ACPI_AEST_NODE_TYPE_MEMORY: + DumpMemoryControllerNode (NodeDataPtr, RemainingLength); + break; + case EFI_ACPI_AEST_NODE_TYPE_SMMU: + DumpSmmuNode (NodeDataPtr, RemainingLength); + break; + case EFI_ACPI_AEST_NODE_TYPE_VENDOR_DEFINED: + DumpVendorDefinedNode (NodeDataPtr, RemainingLength); + break; + case EFI_ACPI_AEST_NODE_TYPE_GIC: + DumpGicNode (NodeDataPtr, RemainingLength); + break; + default: + IncrementErrorCount (); + Print (L"ERROR: Invalid Error Node Type.\n"); + return; + } // switch + + // Parse the Interface Field. + DumpNodeInterface ( + Ptr + InterfaceOffset, + Length - InterfaceOffset + ); + + // Parse the Node Interrupt Array. + DumpNodeInterrupts ( + Ptr + InterruptArrayOffset, + Length - InterruptArrayOffset, + InterruptCount + ); + + return; +} + +/** + This function parses the ACPI AEST table. + When trace is enabled this function parses the AEST 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 +ParseAcpiAest ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ) +{ + UINT32 Offset; + UINT8 *NodePtr; + + if (!Trace) { + return; + } + + Offset = ParseAcpi ( + TRUE, + 0, + "AEST", + Ptr, + AcpiTableLength, + PARSER_PARAMS (AestParser) + ); + + while (Offset < AcpiTableLength) { + NodePtr = Ptr + Offset; + + ParseAcpi ( + FALSE, + 0, + NULL, + NodePtr, + AcpiTableLength - Offset, + PARSER_PARAMS (AestNodeHeaderParser) + ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if ((AestNodeType == NULL) || + (AestNodeLength == NULL) || + (NodeDataOffset == NULL) || + (NodeInterfaceOffset == NULL) || + (NodeInterruptArrayOffset == NULL) || + (NodeInterruptCount == NULL)) + { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient length left for Node Structure.\n" \ + L" Length left = %d.\n", + AcpiTableLength - Offset + ); + return; + } + + // Validate AEST Node length + if ((*AestNodeLength == 0) || + ((Offset + (*AestNodeLength)) > AcpiTableLength)) + { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid AEST Node length. " \ + L"Length = %d. Offset = %d. AcpiTableLength = %d.\n", + *AestNodeLength, + Offset, + AcpiTableLength + ); + return; + } + + DumpAestNodeStructure ( + NodePtr, + *AestNodeLength, + *AestNodeType, + *NodeDataOffset, + *NodeInterfaceOffset, + *NodeInterruptArrayOffset, + *NodeInterruptCount + ); + + Offset += *AestNodeLength; + } // while +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Apmt/ApmtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Apmt/ApmtParser.c index ad64adbb0a..e464761cec 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Apmt/ApmtParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Apmt/ApmtParser.c @@ -1,106 +1,106 @@ -/** @file
- APMT table parser
-
- Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
- Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Reference(s):
- - ACPI 6.2 Specification - Errata A, September 2017
-**/
-
-#include <IndustryStandard/Acpi.h>
-#include <IndustryStandard/ArmPerformanceMonitoringUnitTable.h>
-#include <Library/UefiLib.h>
-#include "AcpiParser.h"
-#include "AcpiTableParser.h"
-
-// Local variables
-STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
-STATIC CONST UINT16 *NodeLength;
-
-/**
- An ACPI_PARSER array describing the ACPI APMT Table.
-**/
-STATIC CONST ACPI_PARSER ApmtParser[] = {
- PARSE_ACPI_HEADER (&AcpiHdrInfo)
-};
-
-/**
- An ACPI_PARSER array describing the ACPI Arm PMU Node.
-**/
-STATIC CONST ACPI_PARSER ArmPmuNodeParser[] = {
- { L"Length", 2, 0, L"0x%x", NULL, (VOID **)&NodeLength, NULL, NULL },
- { L"Node flags", 1, 2, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Node type", 1, 3, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Identifier", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Node Instance primary", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Node Instance secondary", 4, 16, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Base address 0", 8, 20, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Base address 1", 8, 28, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Overflow interrupt", 4, 36, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Reserved1", 4, 40, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Overflow interrupt flags", 4, 44, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Processor affinity", 4, 48, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Implementation ID", 4, 52, L"0x%x", NULL, NULL, NULL, NULL }
-};
-
-/**
- This function parses the ACPI APMT table.
- When trace is enabled this function parses the APMT 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
-ParseAcpiApmt (
- IN BOOLEAN Trace,
- IN UINT8 *Ptr,
- IN UINT32 AcpiTableLength,
- IN UINT8 AcpiTableRevision
- )
-{
- UINT32 Offset;
-
- if (!Trace) {
- return;
- }
-
- ParseAcpi (
- Trace,
- 0,
- "APMT",
- Ptr,
- AcpiTableLength,
- PARSER_PARAMS (ApmtParser)
- );
- Offset = sizeof (EFI_ACPI_DESCRIPTION_HEADER);
-
- while (Offset < AcpiTableLength) {
- ParseAcpi (
- Trace,
- 2,
- "Arm PMU node",
- Ptr + Offset,
- (AcpiTableLength - Offset),
- PARSER_PARAMS (ArmPmuNodeParser)
- );
- if (NodeLength == NULL) {
- Print (
- L"ERROR: Insufficient remaining table buffer length to read the " \
- L"Node structure. Length = %d.\n",
- (AcpiTableLength - Offset)
- );
- IncrementErrorCount ();
- break;
- }
-
- Offset += *NodeLength;
- }
-}
+/** @file + APMT table parser + + Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.2 Specification - Errata A, September 2017 +**/ + +#include <IndustryStandard/Acpi.h> +#include <IndustryStandard/ArmPerformanceMonitoringUnitTable.h> +#include <Library/UefiLib.h> +#include "AcpiParser.h" +#include "AcpiTableParser.h" + +// Local variables +STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; +STATIC CONST UINT16 *NodeLength; + +/** + An ACPI_PARSER array describing the ACPI APMT Table. +**/ +STATIC CONST ACPI_PARSER ApmtParser[] = { + PARSE_ACPI_HEADER (&AcpiHdrInfo) +}; + +/** + An ACPI_PARSER array describing the ACPI Arm PMU Node. +**/ +STATIC CONST ACPI_PARSER ArmPmuNodeParser[] = { + { L"Length", 2, 0, L"0x%x", NULL, (VOID **)&NodeLength, NULL, NULL }, + { L"Node flags", 1, 2, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Node type", 1, 3, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Identifier", 4, 4, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Node Instance primary", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Node Instance secondary", 4, 16, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Base address 0", 8, 20, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Base address 1", 8, 28, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Overflow interrupt", 4, 36, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Reserved1", 4, 40, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Overflow interrupt flags", 4, 44, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Processor affinity", 4, 48, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Implementation ID", 4, 52, L"0x%x", NULL, NULL, NULL, NULL } +}; + +/** + This function parses the ACPI APMT table. + When trace is enabled this function parses the APMT 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 +ParseAcpiApmt ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ) +{ + UINT32 Offset; + + if (!Trace) { + return; + } + + ParseAcpi ( + Trace, + 0, + "APMT", + Ptr, + AcpiTableLength, + PARSER_PARAMS (ApmtParser) + ); + Offset = sizeof (EFI_ACPI_DESCRIPTION_HEADER); + + while (Offset < AcpiTableLength) { + ParseAcpi ( + Trace, + 2, + "Arm PMU node", + Ptr + Offset, + (AcpiTableLength - Offset), + PARSER_PARAMS (ArmPmuNodeParser) + ); + if (NodeLength == NULL) { + Print ( + L"ERROR: Insufficient remaining table buffer length to read the " \ + L"Node structure. Length = %d.\n", + (AcpiTableLength - Offset) + ); + IncrementErrorCount (); + break; + } + + Offset += *NodeLength; + } +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Bgrt/BgrtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Bgrt/BgrtParser.c index afadde2aae..7a88d6eefb 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Bgrt/BgrtParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Bgrt/BgrtParser.c @@ -1,65 +1,65 @@ -/** @file
- BGRT table parser
-
- Copyright (c) 2017 - 2018, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Reference(s):
- - ACPI 6.2 Specification - Errata A, September 2017
-**/
-
-#include <IndustryStandard/Acpi.h>
-#include <Library/UefiLib.h>
-#include "AcpiParser.h"
-#include "AcpiTableParser.h"
-
-// Local variables
-STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
-
-/**
- An ACPI_PARSER array describing the ACPI BDRT Table.
-**/
-STATIC CONST ACPI_PARSER BgrtParser[] = {
- PARSE_ACPI_HEADER (&AcpiHdrInfo),
- { L"Version", 2, 36, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Status", 1, 38, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Image Type", 1, 39, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Image Address", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Image Offset X", 4, 48, L"%d", NULL, NULL, NULL, NULL },
- { L"Image Offset Y", 4, 52, L"%d", NULL, NULL, NULL, NULL }
-};
-
-/**
- This function parses the ACPI BGRT table.
- When trace is enabled this function parses the BGRT table and
- traces the ACPI table fields.
-
- This function also performs validation of the ACPI table fields.
-
- @param [in] Trace If TRUE, trace the ACPI fields.
- @param [in] Ptr Pointer to the start of the buffer.
- @param [in] AcpiTableLength Length of the ACPI table.
- @param [in] AcpiTableRevision Revision of the ACPI table.
-**/
-VOID
-EFIAPI
-ParseAcpiBgrt (
- IN BOOLEAN Trace,
- IN UINT8 *Ptr,
- IN UINT32 AcpiTableLength,
- IN UINT8 AcpiTableRevision
- )
-{
- if (!Trace) {
- return;
- }
-
- ParseAcpi (
- Trace,
- 0,
- "BGRT",
- Ptr,
- AcpiTableLength,
- PARSER_PARAMS (BgrtParser)
- );
-}
+/** @file + BGRT table parser + + Copyright (c) 2017 - 2018, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.2 Specification - Errata A, September 2017 +**/ + +#include <IndustryStandard/Acpi.h> +#include <Library/UefiLib.h> +#include "AcpiParser.h" +#include "AcpiTableParser.h" + +// Local variables +STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; + +/** + An ACPI_PARSER array describing the ACPI BDRT Table. +**/ +STATIC CONST ACPI_PARSER BgrtParser[] = { + PARSE_ACPI_HEADER (&AcpiHdrInfo), + { L"Version", 2, 36, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Status", 1, 38, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Image Type", 1, 39, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Image Address", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Image Offset X", 4, 48, L"%d", NULL, NULL, NULL, NULL }, + { L"Image Offset Y", 4, 52, L"%d", NULL, NULL, NULL, NULL } +}; + +/** + This function parses the ACPI BGRT table. + When trace is enabled this function parses the BGRT table and + traces the ACPI table fields. + + This function also performs validation of the ACPI table fields. + + @param [in] Trace If TRUE, trace the ACPI fields. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] AcpiTableLength Length of the ACPI table. + @param [in] AcpiTableRevision Revision of the ACPI table. +**/ +VOID +EFIAPI +ParseAcpiBgrt ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ) +{ + if (!Trace) { + return; + } + + ParseAcpi ( + Trace, + 0, + "BGRT", + Ptr, + AcpiTableLength, + PARSER_PARAMS (BgrtParser) + ); +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c index d25d4d84f8..1ad6ae130c 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dbg2/Dbg2Parser.c @@ -1,311 +1,311 @@ -/** @file
- DBG2 table parser
-
- Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Reference(s):
- - Microsoft Debug Port Table 2 (DBG2) Specification - December 10, 2015.
-**/
-
-#include <IndustryStandard/DebugPort2Table.h>
-#include <Library/UefiLib.h>
-#include "AcpiParser.h"
-#include "AcpiTableParser.h"
-
-// Local variables pointing to the table fields
-STATIC CONST UINT32 *OffsetDbgDeviceInfo;
-STATIC CONST UINT32 *NumberDbgDeviceInfo;
-STATIC CONST UINT16 *DbgDevInfoLen;
-STATIC CONST UINT8 *GasCount;
-STATIC CONST UINT16 *NameSpaceStringLength;
-STATIC CONST UINT16 *NameSpaceStringOffset;
-STATIC CONST UINT16 *OEMDataLength;
-STATIC CONST UINT16 *OEMDataOffset;
-STATIC CONST UINT16 *BaseAddrRegOffset;
-STATIC CONST UINT16 *AddrSizeOffset;
-STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
-
-/**
- This function validates the NameSpace string length.
-
- @param [in] Ptr Pointer to the start of the buffer.
- @param [in] Context Pointer to context specific information e.g. this
- could be a pointer to the ACPI table header.
-**/
-STATIC
-VOID
-EFIAPI
-ValidateNameSpaceStrLen (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- UINT16 NameSpaceStrLen;
-
- NameSpaceStrLen = *(UINT16 *)Ptr;
-
- if (NameSpaceStrLen < 2) {
- IncrementErrorCount ();
- Print (
- L"\nERROR: NamespaceString Length = %d. If no Namespace device exists, " \
- L"NamespaceString[] must contain a period '.'",
- NameSpaceStrLen
- );
- }
-}
-
-/// 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 structure
-/// header.
-STATIC CONST ACPI_PARSER DbgDevInfoHeaderParser[] = {
- { L"Revision", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Length", 2, 1, L"%d", NULL, (VOID **)&DbgDevInfoLen, 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, NULL, 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 parses the debug device information structure.
-
- @param [in] Ptr Pointer to the start of the buffer.
- @param [in] Length Length of the debug device information structure.
-**/
-STATIC
-VOID
-EFIAPI
-DumpDbgDeviceInfo (
- IN UINT8 *Ptr,
- IN UINT16 Length
- )
-{
- UINT16 Index;
- UINT16 Offset;
-
- ParseAcpi (
- TRUE,
- 2,
- "Debug Device Info",
- Ptr,
- Length,
- PARSER_PARAMS (DbgDevInfoParser)
- );
-
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if ((GasCount == NULL) ||
- (NameSpaceStringLength == NULL) ||
- (NameSpaceStringOffset == NULL) ||
- (OEMDataLength == NULL) ||
- (OEMDataOffset == NULL) ||
- (BaseAddrRegOffset == NULL) ||
- (AddrSizeOffset == NULL))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient Debug Device Information Structure length. " \
- L"Length = %d.\n",
- Length
- );
- return;
- }
-
- // GAS
- Index = 0;
- Offset = *BaseAddrRegOffset;
- while ((Index++ < *GasCount) &&
- (Offset < Length))
- {
- PrintFieldName (4, L"BaseAddressRegister");
- Offset += (UINT16)DumpGasStruct (
- Ptr + Offset,
- 4,
- Length - Offset
- );
- }
-
- // Make sure the array of address sizes corresponding to each GAS fit in the
- // Debug Device Information structure
- if ((*AddrSizeOffset + (*GasCount * sizeof (UINT32))) > Length) {
- IncrementErrorCount ();
- Print (
- L"ERROR: Invalid GAS count. GasCount = %d. RemainingBufferLength = %d. " \
- L"Parsing of the Debug Device Information structure aborted.\n",
- *GasCount,
- Length - *AddrSizeOffset
- );
- return;
- }
-
- // Address Size
- Index = 0;
- Offset = *AddrSizeOffset;
- while ((Index++ < *GasCount) &&
- (Offset < Length))
- {
- PrintFieldName (4, L"Address Size");
- Print (L"0x%x\n", *((UINT32 *)(Ptr + Offset)));
- Offset += sizeof (UINT32);
- }
-
- // NameSpace String
- Index = 0;
- Offset = *NameSpaceStringOffset;
- PrintFieldName (4, L"NameSpace String");
- while ((Index++ < *NameSpaceStringLength) &&
- (Offset < Length))
- {
- Print (L"%c", *(Ptr + Offset));
- Offset++;
- }
-
- Print (L"\n");
-
- // OEM Data
- if (*OEMDataOffset != 0) {
- Index = 0;
- Offset = *OEMDataOffset;
- PrintFieldName (4, L"OEM Data");
- while ((Index++ < *OEMDataLength) &&
- (Offset < Length))
- {
- Print (L"%x ", *(Ptr + Offset));
- if ((Index & 7) == 0) {
- Print (L"\n%-*s ", OUTPUT_FIELD_COLUMN_WIDTH, L"");
- }
-
- Offset++;
- }
-
- Print (L"\n");
- }
-}
-
-/**
- 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 Index;
-
- if (!Trace) {
- return;
- }
-
- Offset = ParseAcpi (
- TRUE,
- 0,
- "DBG2",
- Ptr,
- AcpiTableLength,
- PARSER_PARAMS (Dbg2Parser)
- );
-
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if ((OffsetDbgDeviceInfo == NULL) ||
- (NumberDbgDeviceInfo == NULL))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient table length. AcpiTableLength = %d\n",
- AcpiTableLength
- );
- return;
- }
-
- Offset = *OffsetDbgDeviceInfo;
- Index = 0;
-
- while (Index++ < *NumberDbgDeviceInfo) {
- // Parse the Debug Device Information Structure header to obtain Length
- ParseAcpi (
- FALSE,
- 0,
- NULL,
- Ptr + Offset,
- AcpiTableLength - Offset,
- PARSER_PARAMS (DbgDevInfoHeaderParser)
- );
-
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if (DbgDevInfoLen == NULL) {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient remaining table buffer length to read the " \
- L"Debug Device Information structure's 'Length' field. " \
- L"RemainingTableBufferLength = %d.\n",
- AcpiTableLength - Offset
- );
- return;
- }
-
- // Validate Debug Device Information Structure length
- if ((*DbgDevInfoLen == 0) ||
- ((Offset + (*DbgDevInfoLen)) > AcpiTableLength))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Invalid Debug Device Information Structure length. " \
- L"Length = %d. Offset = %d. AcpiTableLength = %d.\n",
- *DbgDevInfoLen,
- Offset,
- AcpiTableLength
- );
- return;
- }
-
- DumpDbgDeviceInfo (Ptr + Offset, (*DbgDevInfoLen));
- Offset += (*DbgDevInfoLen);
- }
-}
+/** @file + DBG2 table parser + + Copyright (c) 2016 - 2020, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - Microsoft Debug Port Table 2 (DBG2) Specification - December 10, 2015. +**/ + +#include <IndustryStandard/DebugPort2Table.h> +#include <Library/UefiLib.h> +#include "AcpiParser.h" +#include "AcpiTableParser.h" + +// Local variables pointing to the table fields +STATIC CONST UINT32 *OffsetDbgDeviceInfo; +STATIC CONST UINT32 *NumberDbgDeviceInfo; +STATIC CONST UINT16 *DbgDevInfoLen; +STATIC CONST UINT8 *GasCount; +STATIC CONST UINT16 *NameSpaceStringLength; +STATIC CONST UINT16 *NameSpaceStringOffset; +STATIC CONST UINT16 *OEMDataLength; +STATIC CONST UINT16 *OEMDataOffset; +STATIC CONST UINT16 *BaseAddrRegOffset; +STATIC CONST UINT16 *AddrSizeOffset; +STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; + +/** + This function validates the NameSpace string length. + + @param [in] Ptr Pointer to the start of the buffer. + @param [in] Context Pointer to context specific information e.g. this + could be a pointer to the ACPI table header. +**/ +STATIC +VOID +EFIAPI +ValidateNameSpaceStrLen ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + UINT16 NameSpaceStrLen; + + NameSpaceStrLen = *(UINT16 *)Ptr; + + if (NameSpaceStrLen < 2) { + IncrementErrorCount (); + Print ( + L"\nERROR: NamespaceString Length = %d. If no Namespace device exists, " \ + L"NamespaceString[] must contain a period '.'", + NameSpaceStrLen + ); + } +} + +/// 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 structure +/// header. +STATIC CONST ACPI_PARSER DbgDevInfoHeaderParser[] = { + { L"Revision", 1, 0, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Length", 2, 1, L"%d", NULL, (VOID **)&DbgDevInfoLen, 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, NULL, 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 parses the debug device information structure. + + @param [in] Ptr Pointer to the start of the buffer. + @param [in] Length Length of the debug device information structure. +**/ +STATIC +VOID +EFIAPI +DumpDbgDeviceInfo ( + IN UINT8 *Ptr, + IN UINT16 Length + ) +{ + UINT16 Index; + UINT16 Offset; + + ParseAcpi ( + TRUE, + 2, + "Debug Device Info", + Ptr, + Length, + PARSER_PARAMS (DbgDevInfoParser) + ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if ((GasCount == NULL) || + (NameSpaceStringLength == NULL) || + (NameSpaceStringOffset == NULL) || + (OEMDataLength == NULL) || + (OEMDataOffset == NULL) || + (BaseAddrRegOffset == NULL) || + (AddrSizeOffset == NULL)) + { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient Debug Device Information Structure length. " \ + L"Length = %d.\n", + Length + ); + return; + } + + // GAS + Index = 0; + Offset = *BaseAddrRegOffset; + while ((Index++ < *GasCount) && + (Offset < Length)) + { + PrintFieldName (4, L"BaseAddressRegister"); + Offset += (UINT16)DumpGasStruct ( + Ptr + Offset, + 4, + Length - Offset + ); + } + + // Make sure the array of address sizes corresponding to each GAS fit in the + // Debug Device Information structure + if ((*AddrSizeOffset + (*GasCount * sizeof (UINT32))) > Length) { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid GAS count. GasCount = %d. RemainingBufferLength = %d. " \ + L"Parsing of the Debug Device Information structure aborted.\n", + *GasCount, + Length - *AddrSizeOffset + ); + return; + } + + // Address Size + Index = 0; + Offset = *AddrSizeOffset; + while ((Index++ < *GasCount) && + (Offset < Length)) + { + PrintFieldName (4, L"Address Size"); + Print (L"0x%x\n", *((UINT32 *)(Ptr + Offset))); + Offset += sizeof (UINT32); + } + + // NameSpace String + Index = 0; + Offset = *NameSpaceStringOffset; + PrintFieldName (4, L"NameSpace String"); + while ((Index++ < *NameSpaceStringLength) && + (Offset < Length)) + { + Print (L"%c", *(Ptr + Offset)); + Offset++; + } + + Print (L"\n"); + + // OEM Data + if (*OEMDataOffset != 0) { + Index = 0; + Offset = *OEMDataOffset; + PrintFieldName (4, L"OEM Data"); + while ((Index++ < *OEMDataLength) && + (Offset < Length)) + { + Print (L"%x ", *(Ptr + Offset)); + if ((Index & 7) == 0) { + Print (L"\n%-*s ", OUTPUT_FIELD_COLUMN_WIDTH, L""); + } + + Offset++; + } + + Print (L"\n"); + } +} + +/** + 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 Index; + + if (!Trace) { + return; + } + + Offset = ParseAcpi ( + TRUE, + 0, + "DBG2", + Ptr, + AcpiTableLength, + PARSER_PARAMS (Dbg2Parser) + ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if ((OffsetDbgDeviceInfo == NULL) || + (NumberDbgDeviceInfo == NULL)) + { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient table length. AcpiTableLength = %d\n", + AcpiTableLength + ); + return; + } + + Offset = *OffsetDbgDeviceInfo; + Index = 0; + + while (Index++ < *NumberDbgDeviceInfo) { + // Parse the Debug Device Information Structure header to obtain Length + ParseAcpi ( + FALSE, + 0, + NULL, + Ptr + Offset, + AcpiTableLength - Offset, + PARSER_PARAMS (DbgDevInfoHeaderParser) + ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if (DbgDevInfoLen == NULL) { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient remaining table buffer length to read the " \ + L"Debug Device Information structure's 'Length' field. " \ + L"RemainingTableBufferLength = %d.\n", + AcpiTableLength - Offset + ); + return; + } + + // Validate Debug Device Information Structure length + if ((*DbgDevInfoLen == 0) || + ((Offset + (*DbgDevInfoLen)) > AcpiTableLength)) + { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid Debug Device Information Structure length. " \ + L"Length = %d. Offset = %d. AcpiTableLength = %d.\n", + *DbgDevInfoLen, + Offset, + AcpiTableLength + ); + return; + } + + DumpDbgDeviceInfo (Ptr + Offset, (*DbgDevInfoLen)); + Offset += (*DbgDevInfoLen); + } +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dsdt/DsdtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dsdt/DsdtParser.c index 7f30a8409b..761211d07c 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dsdt/DsdtParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Dsdt/DsdtParser.c @@ -1,58 +1,58 @@ -/** @file
- DSDT table parser
-
- Copyright (c) 2016 - 2022, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Reference(s):
- - ACPI 6.2 Specification - Errata A, September 2017
-**/
-
-#include <IndustryStandard/Acpi.h>
-#include <Library/UefiLib.h>
-#include "AcpiParser.h"
-#include "AcpiTableParser.h"
-
-/**
- This function parses the ACPI DSDT table.
- When trace is enabled this function parses the DSDT table and
- traces the ACPI table fields.
- For the DSDT table only the ACPI header fields are parsed and
- traced.
-
- @param [in] Trace If TRUE, trace the ACPI fields.
- @param [in] Ptr Pointer to the start of the buffer.
- @param [in] AcpiTableLength Length of the ACPI table.
- @param [in] AcpiTableRevision Revision of the ACPI table.
-**/
-VOID
-EFIAPI
-ParseAcpiDsdt (
- IN BOOLEAN Trace,
- IN UINT8 *Ptr,
- IN UINT32 AcpiTableLength,
- IN UINT8 AcpiTableRevision
- )
-{
- if (!Trace) {
- return;
- }
-
- DumpAcpiHeader (Ptr);
-
- // As per 19.6.29 in the version 6.4 of the ACPI spec, a revision less than 2
- // restricts integers to 32 bit width. This may not be intended, raise a
- // warning
- #if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_ARM)
- if (AcpiTableRevision < 2) {
- IncrementWarningCount ();
- Print (
- L"WARNING: DSDT Table Revision less than 2. Integer width restricted to "
- L"32 bits. Table Revision = %d.\n",
- AcpiTableRevision
- );
- return;
- }
-
- #endif
-}
+/** @file + DSDT table parser + + Copyright (c) 2016 - 2022, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.2 Specification - Errata A, September 2017 +**/ + +#include <IndustryStandard/Acpi.h> +#include <Library/UefiLib.h> +#include "AcpiParser.h" +#include "AcpiTableParser.h" + +/** + This function parses the ACPI DSDT table. + When trace is enabled this function parses the DSDT table and + traces the ACPI table fields. + For the DSDT table only the ACPI header fields are parsed and + traced. + + @param [in] Trace If TRUE, trace the ACPI fields. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] AcpiTableLength Length of the ACPI table. + @param [in] AcpiTableRevision Revision of the ACPI table. +**/ +VOID +EFIAPI +ParseAcpiDsdt ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ) +{ + if (!Trace) { + return; + } + + DumpAcpiHeader (Ptr); + + // As per 19.6.29 in the version 6.4 of the ACPI spec, a revision less than 2 + // restricts integers to 32 bit width. This may not be intended, raise a + // warning + #if defined (MDE_CPU_AARCH64) || defined (MDE_CPU_ARM) + if (AcpiTableRevision < 2) { + IncrementWarningCount (); + Print ( + L"WARNING: DSDT Table Revision less than 2. Integer width restricted to " + L"32 bits. Table Revision = %d.\n", + AcpiTableRevision + ); + return; + } + + #endif +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Erst/ErstParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Erst/ErstParser.c index f3ae09309c..6fd0f5abfc 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Erst/ErstParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Erst/ErstParser.c @@ -1,278 +1,278 @@ -/** @file
- ERST table parser
-
- Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
- Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Reference(s):
- - ACPI 6.5 Specification - August 2022
-**/
-
-#include <IndustryStandard/Acpi.h>
-#include <Library/UefiLib.h>
-#include "AcpiParser.h"
-#include "AcpiTableParser.h"
-
-// Local variables
-STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
-STATIC UINT32 *InstructionEntryCount;
-
-/**
- An array of strings describing the Erst actions
-**/
-STATIC CONST CHAR16 *ErstActionTable[] = {
- L"BEGIN_WRITE_OPERATION",
- L"BEGIN_READ_OPERATION",
- L"BEGIN_CLEAR_OPERATION",
- L"END_OPERATION",
- L"SET_RECORD_OFFSET",
- L"EXECUTE_OPERATION",
- L"CHECK_BUSY_STATUS",
- L"GET_COMMAND_STATUS",
- L"GET_RECORD_IDENTIFIER",
- L"SET_RECORD_IDENTIFIER",
- L"GET_RECORD_COUNT",
- L"BEGIN_DUMMY_WRITE_OPERATION",
- L"RESERVED",
- L"GET_ERROR_LOG_ADDRESS_RANGE",
- L"GET_ERROR_LOG_ADDRESS_RANGE_LENGTH",
- L"GET_ERROR_LOG_ADDRESS_RANGE_ATTRIBUTES",
- L"GET_EXECUTE_OPERATION_TIMINGS"
-};
-
-/**
- An array of strings describing the Erst instructions
-**/
-STATIC CONST CHAR16 *ErstInstructionTable[] = {
- L"READ_REGISTER",
- L"READ_REGISTER_VALUE",
- L"WRITE_REGISTER",
- L"WRITE_REGISTER_VALUE",
- L"NOOP",
- L"LOAD_VAR1",
- L"LOAD_VAR2",
- L"STORE_VAR1",
- L"ADD",
- L"SUBTRACT",
- L"ADD_VALUE",
- L"SUBTRACT_VALUE",
- L"STALL",
- L"STALL_WHILE_TRUE",
- L"SKIP_NEXT_INSTRUCTION_IF_TRUE",
- L"GOTO",
- L"SET_SRC_ADDRESS_BASE",
- L"SET_DST_ADDRESS_BASE",
- L"MOVE_DATA"
-};
-
-/**
- Validate Erst action.
-
- @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
-ValidateErstAction (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- if (*Ptr > EFI_ACPI_6_4_ERST_GET_EXECUTE_OPERATION_TIMINGS) {
- IncrementErrorCount ();
- Print (L"\nError: 0x%02x is not a valid action encoding", *Ptr);
- }
-}
-
-/**
- Validate Erst instruction.
-
- @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
-ValidateErstInstruction (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- if (*Ptr > EFI_ACPI_6_4_ERST_MOVE_DATA) {
- IncrementErrorCount ();
- Print (L"\nError: 0x%02x is not a valid instruction encoding", *Ptr);
- }
-}
-
-/**
- Validate Erst 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
-ValidateErstFlags (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- if ((*Ptr & 0xfe) != 0) {
- IncrementErrorCount ();
- Print (L"\nError: Reserved Flag bits not set to 0");
- }
-}
-
-/**
- Looks up and prints the string corresponding to the index.
-
- @param [in] Table Lookup table.
- @param [in] Index Entry to print.
- @param [in] NumEntries Number of valid entries in the table.
-**/
-STATIC
-VOID
-EFIAPI
-FormatByte (
- IN CONST CHAR16 *Table[],
- IN UINT8 Index,
- IN UINT8 NumEntries
- )
-{
- CONST CHAR16 *String;
-
- if (Index < NumEntries) {
- String = Table[Index];
- } else {
- String = L"**INVALID**";
- }
-
- Print (
- L"0x%02x (%s)",
- Index,
- String
- );
-}
-
-/**
- Prints the Erst Action.
-
- @param [in] Format Optional format string for tracing the data.
- @param [in] Ptr Pointer to the Action byte.
-**/
-STATIC
-VOID
-EFIAPI
-DumpErstAction (
- IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
- )
-{
- FormatByte (ErstActionTable, *Ptr, ARRAY_SIZE (ErstActionTable));
-}
-
-/**
- Prints the Erst Instruction.
-
- @param [in] Format Optional format string for tracing the data.
- @param [in] Ptr Pointer to the Instruction byte.
-**/
-STATIC
-VOID
-EFIAPI
-DumpErstInstruction (
- IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
- )
-{
- FormatByte (ErstInstructionTable, *Ptr, ARRAY_SIZE (ErstInstructionTable));
-}
-
-/**
- An ACPI_PARSER array describing the ACPI ERST Table.
-**/
-STATIC CONST ACPI_PARSER ErstParser[] = {
- PARSE_ACPI_HEADER (&AcpiHdrInfo),
- { L"Serialization Header Size", 4, 36, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Reserved", 4, 40, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Instruction Entry Count", 4, 44, L"0x%x", NULL, (VOID **)&InstructionEntryCount, NULL, NULL }
-};
-
-/**
- An ACPI_PARSER array describing the Serialization Instruction Entry structure.
-**/
-STATIC CONST ACPI_PARSER SerializationInstructionEntryParser[] = {
- { L"Serialization Action", 1, 0, L"0x%x", DumpErstAction, NULL, ValidateErstAction, NULL },
- { L"Instruction", 1, 1, L"0x%x", DumpErstInstruction, NULL, ValidateErstInstruction, NULL },
- { L"Flags", 1, 2, L"0x%x", NULL, NULL, ValidateErstFlags, NULL },
- { L"Reserved", 1, 3, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Register Region", 12, 4, NULL, DumpGas, NULL, NULL, NULL },
- { L"Value", 8, 16, L"0x%llx", NULL, NULL, NULL, NULL },
- { L"Mask", 8, 24, L"0x%llx", NULL, NULL, NULL, NULL }
-};
-
-/**
- This function parses the ACPI ERST table.
- When trace is enabled this function parses the ERST 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
-ParseAcpiErst (
- IN BOOLEAN Trace,
- IN UINT8 *Ptr,
- IN UINT32 AcpiTableLength,
- IN UINT8 AcpiTableRevision
- )
-{
- UINT32 Offset;
-
- if (!Trace) {
- return;
- }
-
- Offset = ParseAcpi (
- Trace,
- 0,
- "ERST",
- Ptr,
- AcpiTableLength,
- PARSER_PARAMS (ErstParser)
- );
-
- if (sizeof (EFI_ACPI_6_4_ERST_SERIALIZATION_INSTRUCTION_ENTRY)*(*InstructionEntryCount) != (AcpiTableLength - Offset)) {
- IncrementErrorCount ();
- Print (
- L"ERROR: Invalid InstructionEntryCount. " \
- L"Count = %d. Offset = %d. AcpiTableLength = %d.\n",
- *InstructionEntryCount,
- Offset,
- AcpiTableLength
- );
- return;
- }
-
- while (Offset < AcpiTableLength) {
- Offset += ParseAcpi (
- Trace,
- 2,
- "Serialization Action",
- Ptr + Offset,
- (AcpiTableLength - Offset),
- PARSER_PARAMS (SerializationInstructionEntryParser)
- );
- }
-}
+/** @file + ERST table parser + + Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + Copyright (c) 2016 - 2018, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.5 Specification - August 2022 +**/ + +#include <IndustryStandard/Acpi.h> +#include <Library/UefiLib.h> +#include "AcpiParser.h" +#include "AcpiTableParser.h" + +// Local variables +STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; +STATIC UINT32 *InstructionEntryCount; + +/** + An array of strings describing the Erst actions +**/ +STATIC CONST CHAR16 *ErstActionTable[] = { + L"BEGIN_WRITE_OPERATION", + L"BEGIN_READ_OPERATION", + L"BEGIN_CLEAR_OPERATION", + L"END_OPERATION", + L"SET_RECORD_OFFSET", + L"EXECUTE_OPERATION", + L"CHECK_BUSY_STATUS", + L"GET_COMMAND_STATUS", + L"GET_RECORD_IDENTIFIER", + L"SET_RECORD_IDENTIFIER", + L"GET_RECORD_COUNT", + L"BEGIN_DUMMY_WRITE_OPERATION", + L"RESERVED", + L"GET_ERROR_LOG_ADDRESS_RANGE", + L"GET_ERROR_LOG_ADDRESS_RANGE_LENGTH", + L"GET_ERROR_LOG_ADDRESS_RANGE_ATTRIBUTES", + L"GET_EXECUTE_OPERATION_TIMINGS" +}; + +/** + An array of strings describing the Erst instructions +**/ +STATIC CONST CHAR16 *ErstInstructionTable[] = { + L"READ_REGISTER", + L"READ_REGISTER_VALUE", + L"WRITE_REGISTER", + L"WRITE_REGISTER_VALUE", + L"NOOP", + L"LOAD_VAR1", + L"LOAD_VAR2", + L"STORE_VAR1", + L"ADD", + L"SUBTRACT", + L"ADD_VALUE", + L"SUBTRACT_VALUE", + L"STALL", + L"STALL_WHILE_TRUE", + L"SKIP_NEXT_INSTRUCTION_IF_TRUE", + L"GOTO", + L"SET_SRC_ADDRESS_BASE", + L"SET_DST_ADDRESS_BASE", + L"MOVE_DATA" +}; + +/** + Validate Erst action. + + @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 +ValidateErstAction ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + if (*Ptr > EFI_ACPI_6_4_ERST_GET_EXECUTE_OPERATION_TIMINGS) { + IncrementErrorCount (); + Print (L"\nError: 0x%02x is not a valid action encoding", *Ptr); + } +} + +/** + Validate Erst instruction. + + @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 +ValidateErstInstruction ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + if (*Ptr > EFI_ACPI_6_4_ERST_MOVE_DATA) { + IncrementErrorCount (); + Print (L"\nError: 0x%02x is not a valid instruction encoding", *Ptr); + } +} + +/** + Validate Erst 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 +ValidateErstFlags ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + if ((*Ptr & 0xfe) != 0) { + IncrementErrorCount (); + Print (L"\nError: Reserved Flag bits not set to 0"); + } +} + +/** + Looks up and prints the string corresponding to the index. + + @param [in] Table Lookup table. + @param [in] Index Entry to print. + @param [in] NumEntries Number of valid entries in the table. +**/ +STATIC +VOID +EFIAPI +FormatByte ( + IN CONST CHAR16 *Table[], + IN UINT8 Index, + IN UINT8 NumEntries + ) +{ + CONST CHAR16 *String; + + if (Index < NumEntries) { + String = Table[Index]; + } else { + String = L"**INVALID**"; + } + + Print ( + L"0x%02x (%s)", + Index, + String + ); +} + +/** + Prints the Erst Action. + + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the Action byte. +**/ +STATIC +VOID +EFIAPI +DumpErstAction ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + FormatByte (ErstActionTable, *Ptr, ARRAY_SIZE (ErstActionTable)); +} + +/** + Prints the Erst Instruction. + + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the Instruction byte. +**/ +STATIC +VOID +EFIAPI +DumpErstInstruction ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + FormatByte (ErstInstructionTable, *Ptr, ARRAY_SIZE (ErstInstructionTable)); +} + +/** + An ACPI_PARSER array describing the ACPI ERST Table. +**/ +STATIC CONST ACPI_PARSER ErstParser[] = { + PARSE_ACPI_HEADER (&AcpiHdrInfo), + { L"Serialization Header Size", 4, 36, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Reserved", 4, 40, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Instruction Entry Count", 4, 44, L"0x%x", NULL, (VOID **)&InstructionEntryCount, NULL, NULL } +}; + +/** + An ACPI_PARSER array describing the Serialization Instruction Entry structure. +**/ +STATIC CONST ACPI_PARSER SerializationInstructionEntryParser[] = { + { L"Serialization Action", 1, 0, L"0x%x", DumpErstAction, NULL, ValidateErstAction, NULL }, + { L"Instruction", 1, 1, L"0x%x", DumpErstInstruction, NULL, ValidateErstInstruction, NULL }, + { L"Flags", 1, 2, L"0x%x", NULL, NULL, ValidateErstFlags, NULL }, + { L"Reserved", 1, 3, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Register Region", 12, 4, NULL, DumpGas, NULL, NULL, NULL }, + { L"Value", 8, 16, L"0x%llx", NULL, NULL, NULL, NULL }, + { L"Mask", 8, 24, L"0x%llx", NULL, NULL, NULL, NULL } +}; + +/** + This function parses the ACPI ERST table. + When trace is enabled this function parses the ERST 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 +ParseAcpiErst ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ) +{ + UINT32 Offset; + + if (!Trace) { + return; + } + + Offset = ParseAcpi ( + Trace, + 0, + "ERST", + Ptr, + AcpiTableLength, + PARSER_PARAMS (ErstParser) + ); + + if (sizeof (EFI_ACPI_6_4_ERST_SERIALIZATION_INSTRUCTION_ENTRY)*(*InstructionEntryCount) != (AcpiTableLength - Offset)) { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid InstructionEntryCount. " \ + L"Count = %d. Offset = %d. AcpiTableLength = %d.\n", + *InstructionEntryCount, + Offset, + AcpiTableLength + ); + return; + } + + while (Offset < AcpiTableLength) { + Offset += ParseAcpi ( + Trace, + 2, + "Serialization Action", + Ptr + Offset, + (AcpiTableLength - Offset), + PARSER_PARAMS (SerializationInstructionEntryParser) + ); + } +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Facs/FacsParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Facs/FacsParser.c index d4c00ba891..a911b01fa2 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Facs/FacsParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Facs/FacsParser.c @@ -1,71 +1,71 @@ -/** @file
- FACS table parser
-
- Copyright (c) 2019, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Reference(s):
- - ACPI 6.3 Specification - January 2019
-**/
-
-#include <IndustryStandard/Acpi.h>
-#include <Library/UefiLib.h>
-#include "AcpiParser.h"
-#include "AcpiTableParser.h"
-
-/**
- An ACPI_PARSER array describing the ACPI FACS Table.
-**/
-STATIC CONST ACPI_PARSER FacsParser[] = {
- { L"Signature", 4, 0, L"%c%c%c%c", Dump4Chars, NULL, NULL, NULL },
- { L"Length", 4, 4, L"%d", NULL, NULL, NULL, NULL },
- { L"Hardware Signature", 4, 8, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Firmware Waking Vector", 4, 12, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Global Lock", 4, 16, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Flags", 4, 20, L"0x%x", NULL, NULL, NULL, NULL },
- { L"X Firmware Walking Vector", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Version", 1, 32, L"%d", NULL, NULL, NULL, NULL },
- { L"Reserved", 3, 33, L"%x %x %x", Dump3Chars, NULL, NULL, NULL },
- { L"OSPM Flags", 4, 36, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Reserved", 8, 40, L"%x %x %x %x %x %x %x %x", Dump8Chars, NULL, NULL,
- NULL },
- { L"Reserved", 8, 48, L"%x %x %x %x %x %x %x %x", Dump8Chars, NULL, NULL,
- NULL },
- { L"Reserved", 8, 56, L"%x %x %x %x %x %x %x %x", Dump8Chars, NULL, NULL,
- NULL }
-};
-
-/**
- This function parses the ACPI FACS table.
- When trace is enabled this function parses the FACS 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
-ParseAcpiFacs (
- IN BOOLEAN Trace,
- IN UINT8 *Ptr,
- IN UINT32 AcpiTableLength,
- IN UINT8 AcpiTableRevision
- )
-{
- if (!Trace) {
- return;
- }
-
- ParseAcpi (
- Trace,
- 0,
- "FACS",
- Ptr,
- AcpiTableLength,
- PARSER_PARAMS (FacsParser)
- );
-}
+/** @file + FACS table parser + + Copyright (c) 2019, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.3 Specification - January 2019 +**/ + +#include <IndustryStandard/Acpi.h> +#include <Library/UefiLib.h> +#include "AcpiParser.h" +#include "AcpiTableParser.h" + +/** + An ACPI_PARSER array describing the ACPI FACS Table. +**/ +STATIC CONST ACPI_PARSER FacsParser[] = { + { L"Signature", 4, 0, L"%c%c%c%c", Dump4Chars, NULL, NULL, NULL }, + { L"Length", 4, 4, L"%d", NULL, NULL, NULL, NULL }, + { L"Hardware Signature", 4, 8, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Firmware Waking Vector", 4, 12, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Global Lock", 4, 16, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Flags", 4, 20, L"0x%x", NULL, NULL, NULL, NULL }, + { L"X Firmware Walking Vector", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Version", 1, 32, L"%d", NULL, NULL, NULL, NULL }, + { L"Reserved", 3, 33, L"%x %x %x", Dump3Chars, NULL, NULL, NULL }, + { L"OSPM Flags", 4, 36, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Reserved", 8, 40, L"%x %x %x %x %x %x %x %x", Dump8Chars, NULL, NULL, + NULL }, + { L"Reserved", 8, 48, L"%x %x %x %x %x %x %x %x", Dump8Chars, NULL, NULL, + NULL }, + { L"Reserved", 8, 56, L"%x %x %x %x %x %x %x %x", Dump8Chars, NULL, NULL, + NULL } +}; + +/** + This function parses the ACPI FACS table. + When trace is enabled this function parses the FACS 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 +ParseAcpiFacs ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ) +{ + if (!Trace) { + return; + } + + ParseAcpi ( + Trace, + 0, + "FACS", + Ptr, + AcpiTableLength, + PARSER_PARAMS (FacsParser) + ); +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c index abc58d6552..a260007d18 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c @@ -1,383 +1,383 @@ -/** @file
- FADT table parser
-
- Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
- Copyright (c) 2022, AMD Incorporated. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Reference(s):
- - ACPI 6.3 Specification - January 2019
-**/
-
-#include <IndustryStandard/Acpi.h>
-#include <Library/UefiLib.h>
-#include "AcpiParser.h"
-#include "AcpiTableParser.h"
-#include "AcpiView.h"
-
-// Local variables
-STATIC CONST UINT32 *DsdtAddress;
-STATIC CONST UINT64 *X_DsdtAddress;
-STATIC CONST UINT32 *Flags;
-STATIC CONST UINT32 *FirmwareCtrl;
-STATIC CONST UINT64 *X_FirmwareCtrl;
-STATIC CONST UINT8 *FadtMinorRevision;
-STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
-
-/**
- A macro defining the Hardware reduced ACPI flag
-**/
-#define HW_REDUCED_ACPI BIT20
-
-/**
- Offset to the FACS signature from the start of the FACS.
-**/
-#define FACS_SIGNATURE_OFFSET 0
-
-/**
- Offset to the FACS revision from the start of the FACS.
-**/
-#define FACS_VERSION_OFFSET 32
-
-/**
- Offset to the FACS length from the start of the FACS.
-**/
-#define FACS_LENGTH_OFFSET 4
-
-/**
- Get the ACPI XSDT header info.
-**/
-CONST ACPI_DESCRIPTION_HEADER_INFO *
-EFIAPI
-GetAcpiXsdtHeaderInfo (
- VOID
- );
-
-/**
- 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
-}
-
-STATIC CONST ACPI_PARSER FadtFlagParser[] = {
- { L"WBINVD", 1, 0, L"%d", NULL, NULL, NULL, NULL },
- { L"WBINVD_FLUSH", 1, 1, L"%d", NULL, NULL, NULL, NULL },
- { L"PROC_C1", 1, 2, L"%d", NULL, NULL, NULL, NULL },
- { L"P_LVL2_UP", 1, 3, L"%d", NULL, NULL, NULL, NULL },
- { L"PWR_BUTTON", 1, 4, L"%d", NULL, NULL, NULL, NULL },
- { L"SLP_BUTTON", 1, 5, L"%d", NULL, NULL, NULL, NULL },
- { L"FIX_RTC", 1, 6, L"%d", NULL, NULL, NULL, NULL },
- { L"RTC_S4", 1, 7, L"%d", NULL, NULL, NULL, NULL },
- { L"TMR_VAL_EXT", 1, 8, L"%d", NULL, NULL, NULL, NULL },
- { L"DCK_CAP", 1, 9, L"%d", NULL, NULL, NULL, NULL },
- { L"RESET_REG_SUP", 1, 10, L"%d", NULL, NULL, NULL, NULL },
- { L"SEALED_CASE", 1, 11, L"%d", NULL, NULL, NULL, NULL },
- { L"HEADLESS", 1, 12, L"%d", NULL, NULL, NULL, NULL },
- { L"CPU_SW_SLP", 1, 13, L"%d", NULL, NULL, NULL, NULL },
- { L"PCI_EXP_WAK", 1, 14, L"%d", NULL, NULL, NULL, NULL },
- { L"USE_PLATFORM_CLOCK", 1, 15, L"%d", NULL, NULL, NULL, NULL },
- { L"S4_RTC_STS_VALID", 1, 16, L"%d", NULL, NULL, NULL, NULL },
- { L"REMOTE_POWER_ON_CAPABLE", 1, 17, L"%d", NULL, NULL, NULL, NULL },
- { L"FORCE_APIC_CLUSTER_MODEL", 1, 18, L"%d", NULL, NULL, NULL, NULL },
- { L"FORCE_APIC_PHYSICAL_DESTINATION_MODE", 1, 19, L"%d", NULL, NULL, NULL, NULL },
- { L"HW_REDUCED_ACPI", 1, 20, L"%d", NULL, NULL, NULL, NULL },
- { L"LOW_POWER_S0_IDLE_CAPABLE", 1, 21, L"%d", NULL, NULL, NULL, NULL },
- { L"Reserved", 10, 22, L"%d", NULL, NULL, NULL, NULL }
-};
-
-/**
- This function traces FADT Flags fields.
- 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
-DumpFadtFlags (
- IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
- )
-{
- if (Format != NULL) {
- Print (Format, *(UINT32 *)Ptr);
- return;
- }
-
- Print (L"0x%X\n", *(UINT32 *)Ptr);
- ParseAcpiBitFields (
- TRUE,
- 2,
- NULL,
- Ptr,
- 4,
- PARSER_PARAMS (FadtFlagParser)
- );
-}
-
-/**
- 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, (VOID **)&FirmwareCtrl,
- 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, NULL, DumpFadtFlags, (VOID **)&Flags, 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, (VOID **)&X_FirmwareCtrl,
- 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 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
- )
-{
- EFI_STATUS Status;
- UINT8 *DsdtPtr;
- UINT8 *FirmwareCtrlPtr;
- UINT32 FacsSignature;
- UINT32 FacsLength;
- UINT8 FacsRevision;
- PARSE_ACPI_TABLE_PROC FacsParserProc;
-
- ParseAcpi (
- Trace,
- 0,
- "FADT",
- Ptr,
- AcpiTableLength,
- PARSER_PARAMS (FadtParser)
- );
-
- if (Trace) {
- if (FadtMinorRevision != NULL) {
- 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_FIRMWARE_CTRL is not zero then use X_FIRMWARE_CTRL and ignore
- // FIRMWARE_CTRL, else use FIRMWARE_CTRL.
- if ((X_FirmwareCtrl != NULL) && (*X_FirmwareCtrl != 0)) {
- FirmwareCtrlPtr = (UINT8 *)(UINTN)(*X_FirmwareCtrl);
- } else if ((FirmwareCtrl != NULL) && (*FirmwareCtrl != 0)) {
- FirmwareCtrlPtr = (UINT8 *)(UINTN)(*FirmwareCtrl);
- } else {
- FirmwareCtrlPtr = NULL;
- // if HW_REDUCED_ACPI flag is not set, both FIRMWARE_CTRL and
- // X_FIRMWARE_CTRL cannot be zero, and the FACS Table must be
- // present.
- if ((Trace) &&
- (Flags != NULL) &&
- ((*Flags & EFI_ACPI_6_3_HW_REDUCED_ACPI) != EFI_ACPI_6_3_HW_REDUCED_ACPI))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: No FACS table found, "
- L"both X_FIRMWARE_CTRL and FIRMWARE_CTRL are zero.\n"
- );
- }
- }
-
- if (FirmwareCtrlPtr != NULL) {
- // The FACS table does not have a standard ACPI table header. Therefore,
- // the signature, length and version needs to be initially parsed.
- // The FACS signature is 4 bytes starting at offset 0.
- FacsSignature = *(UINT32 *)(FirmwareCtrlPtr + FACS_SIGNATURE_OFFSET);
-
- // The FACS length is 4 bytes starting at offset 4.
- FacsLength = *(UINT32 *)(FirmwareCtrlPtr + FACS_LENGTH_OFFSET);
-
- // The FACS version is 1 byte starting at offset 32.
- FacsRevision = *(UINT8 *)(FirmwareCtrlPtr + FACS_VERSION_OFFSET);
-
- Trace = ProcessTableReportOptions (
- FacsSignature,
- FirmwareCtrlPtr,
- FacsLength
- );
-
- Status = GetParser (FacsSignature, &FacsParserProc);
- if (EFI_ERROR (Status)) {
- Print (
- L"ERROR: No registered parser found for FACS.\n"
- );
- return;
- }
-
- FacsParserProc (
- Trace,
- FirmwareCtrlPtr,
- FacsLength,
- FacsRevision
- );
- }
-
- // If X_DSDT is valid then use X_DSDT and ignore DSDT, else use DSDT.
- if ((X_DsdtAddress != NULL) && (*X_DsdtAddress != 0)) {
- DsdtPtr = (UINT8 *)(UINTN)(*X_DsdtAddress);
- } else if ((DsdtAddress != NULL) && (*DsdtAddress != 0)) {
- DsdtPtr = (UINT8 *)(UINTN)(*DsdtAddress);
- } else {
- // Both DSDT and X_DSDT cannot be invalid.
- #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 invalid.\n");
- }
-
- #endif
- return;
- }
-
- ProcessAcpiTable (DsdtPtr);
-}
+/** @file + FADT table parser + + Copyright (c) 2016 - 2020, ARM Limited. All rights reserved. + Copyright (c) 2022, AMD Incorporated. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.3 Specification - January 2019 +**/ + +#include <IndustryStandard/Acpi.h> +#include <Library/UefiLib.h> +#include "AcpiParser.h" +#include "AcpiTableParser.h" +#include "AcpiView.h" + +// Local variables +STATIC CONST UINT32 *DsdtAddress; +STATIC CONST UINT64 *X_DsdtAddress; +STATIC CONST UINT32 *Flags; +STATIC CONST UINT32 *FirmwareCtrl; +STATIC CONST UINT64 *X_FirmwareCtrl; +STATIC CONST UINT8 *FadtMinorRevision; +STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; + +/** + A macro defining the Hardware reduced ACPI flag +**/ +#define HW_REDUCED_ACPI BIT20 + +/** + Offset to the FACS signature from the start of the FACS. +**/ +#define FACS_SIGNATURE_OFFSET 0 + +/** + Offset to the FACS revision from the start of the FACS. +**/ +#define FACS_VERSION_OFFSET 32 + +/** + Offset to the FACS length from the start of the FACS. +**/ +#define FACS_LENGTH_OFFSET 4 + +/** + Get the ACPI XSDT header info. +**/ +CONST ACPI_DESCRIPTION_HEADER_INFO * +EFIAPI +GetAcpiXsdtHeaderInfo ( + VOID + ); + +/** + 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 +} + +STATIC CONST ACPI_PARSER FadtFlagParser[] = { + { L"WBINVD", 1, 0, L"%d", NULL, NULL, NULL, NULL }, + { L"WBINVD_FLUSH", 1, 1, L"%d", NULL, NULL, NULL, NULL }, + { L"PROC_C1", 1, 2, L"%d", NULL, NULL, NULL, NULL }, + { L"P_LVL2_UP", 1, 3, L"%d", NULL, NULL, NULL, NULL }, + { L"PWR_BUTTON", 1, 4, L"%d", NULL, NULL, NULL, NULL }, + { L"SLP_BUTTON", 1, 5, L"%d", NULL, NULL, NULL, NULL }, + { L"FIX_RTC", 1, 6, L"%d", NULL, NULL, NULL, NULL }, + { L"RTC_S4", 1, 7, L"%d", NULL, NULL, NULL, NULL }, + { L"TMR_VAL_EXT", 1, 8, L"%d", NULL, NULL, NULL, NULL }, + { L"DCK_CAP", 1, 9, L"%d", NULL, NULL, NULL, NULL }, + { L"RESET_REG_SUP", 1, 10, L"%d", NULL, NULL, NULL, NULL }, + { L"SEALED_CASE", 1, 11, L"%d", NULL, NULL, NULL, NULL }, + { L"HEADLESS", 1, 12, L"%d", NULL, NULL, NULL, NULL }, + { L"CPU_SW_SLP", 1, 13, L"%d", NULL, NULL, NULL, NULL }, + { L"PCI_EXP_WAK", 1, 14, L"%d", NULL, NULL, NULL, NULL }, + { L"USE_PLATFORM_CLOCK", 1, 15, L"%d", NULL, NULL, NULL, NULL }, + { L"S4_RTC_STS_VALID", 1, 16, L"%d", NULL, NULL, NULL, NULL }, + { L"REMOTE_POWER_ON_CAPABLE", 1, 17, L"%d", NULL, NULL, NULL, NULL }, + { L"FORCE_APIC_CLUSTER_MODEL", 1, 18, L"%d", NULL, NULL, NULL, NULL }, + { L"FORCE_APIC_PHYSICAL_DESTINATION_MODE", 1, 19, L"%d", NULL, NULL, NULL, NULL }, + { L"HW_REDUCED_ACPI", 1, 20, L"%d", NULL, NULL, NULL, NULL }, + { L"LOW_POWER_S0_IDLE_CAPABLE", 1, 21, L"%d", NULL, NULL, NULL, NULL }, + { L"Reserved", 10, 22, L"%d", NULL, NULL, NULL, NULL } +}; + +/** + This function traces FADT Flags fields. + 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 +DumpFadtFlags ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + if (Format != NULL) { + Print (Format, *(UINT32 *)Ptr); + return; + } + + Print (L"0x%X\n", *(UINT32 *)Ptr); + ParseAcpiBitFields ( + TRUE, + 2, + NULL, + Ptr, + 4, + PARSER_PARAMS (FadtFlagParser) + ); +} + +/** + 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, (VOID **)&FirmwareCtrl, + 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, NULL, DumpFadtFlags, (VOID **)&Flags, 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, (VOID **)&X_FirmwareCtrl, + 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 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 + ) +{ + EFI_STATUS Status; + UINT8 *DsdtPtr; + UINT8 *FirmwareCtrlPtr; + UINT32 FacsSignature; + UINT32 FacsLength; + UINT8 FacsRevision; + PARSE_ACPI_TABLE_PROC FacsParserProc; + + ParseAcpi ( + Trace, + 0, + "FADT", + Ptr, + AcpiTableLength, + PARSER_PARAMS (FadtParser) + ); + + if (Trace) { + if (FadtMinorRevision != NULL) { + 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_FIRMWARE_CTRL is not zero then use X_FIRMWARE_CTRL and ignore + // FIRMWARE_CTRL, else use FIRMWARE_CTRL. + if ((X_FirmwareCtrl != NULL) && (*X_FirmwareCtrl != 0)) { + FirmwareCtrlPtr = (UINT8 *)(UINTN)(*X_FirmwareCtrl); + } else if ((FirmwareCtrl != NULL) && (*FirmwareCtrl != 0)) { + FirmwareCtrlPtr = (UINT8 *)(UINTN)(*FirmwareCtrl); + } else { + FirmwareCtrlPtr = NULL; + // if HW_REDUCED_ACPI flag is not set, both FIRMWARE_CTRL and + // X_FIRMWARE_CTRL cannot be zero, and the FACS Table must be + // present. + if ((Trace) && + (Flags != NULL) && + ((*Flags & EFI_ACPI_6_3_HW_REDUCED_ACPI) != EFI_ACPI_6_3_HW_REDUCED_ACPI)) + { + IncrementErrorCount (); + Print ( + L"ERROR: No FACS table found, " + L"both X_FIRMWARE_CTRL and FIRMWARE_CTRL are zero.\n" + ); + } + } + + if (FirmwareCtrlPtr != NULL) { + // The FACS table does not have a standard ACPI table header. Therefore, + // the signature, length and version needs to be initially parsed. + // The FACS signature is 4 bytes starting at offset 0. + FacsSignature = *(UINT32 *)(FirmwareCtrlPtr + FACS_SIGNATURE_OFFSET); + + // The FACS length is 4 bytes starting at offset 4. + FacsLength = *(UINT32 *)(FirmwareCtrlPtr + FACS_LENGTH_OFFSET); + + // The FACS version is 1 byte starting at offset 32. + FacsRevision = *(UINT8 *)(FirmwareCtrlPtr + FACS_VERSION_OFFSET); + + Trace = ProcessTableReportOptions ( + FacsSignature, + FirmwareCtrlPtr, + FacsLength + ); + + Status = GetParser (FacsSignature, &FacsParserProc); + if (EFI_ERROR (Status)) { + Print ( + L"ERROR: No registered parser found for FACS.\n" + ); + return; + } + + FacsParserProc ( + Trace, + FirmwareCtrlPtr, + FacsLength, + FacsRevision + ); + } + + // If X_DSDT is valid then use X_DSDT and ignore DSDT, else use DSDT. + if ((X_DsdtAddress != NULL) && (*X_DsdtAddress != 0)) { + DsdtPtr = (UINT8 *)(UINTN)(*X_DsdtAddress); + } else if ((DsdtAddress != NULL) && (*DsdtAddress != 0)) { + DsdtPtr = (UINT8 *)(UINTN)(*DsdtAddress); + } else { + // Both DSDT and X_DSDT cannot be invalid. + #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 invalid.\n"); + } + + #endif + return; + } + + ProcessAcpiTable (DsdtPtr); +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Gtdt/GtdtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Gtdt/GtdtParser.c index e62927098a..21f4ec99f8 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Gtdt/GtdtParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Gtdt/GtdtParser.c @@ -1,370 +1,370 @@ -/** @file
- GTDT table parser
-
- Copyright (c) 2016 - 2021, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Reference(s):
- - ACPI 6.4 Specification - January 2021
- **/
-
-#include <IndustryStandard/Acpi.h>
-#include <Library/UefiLib.h>
-#include "AcpiParser.h"
-#include "AcpiTableParser.h"
-#include "AcpiViewConfig.h"
-
-// "The number of GT Block Timers must be less than or equal to 8"
-#define GT_BLOCK_TIMER_COUNT_MAX 8
-
-// 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 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
- )
-{
- UINT32 BlockTimerCount;
-
- BlockTimerCount = *(UINT32 *)Ptr;
-
- if (BlockTimerCount > GT_BLOCK_TIMER_COUNT_MAX) {
- IncrementErrorCount ();
- Print (
- L"\nERROR: Timer Count = %d. Max Timer Count is %d.",
- BlockTimerCount,
- GT_BLOCK_TIMER_COUNT_MAX
- );
- }
-}
-
-/**
- This function validates the GT Frame Number.
-
- @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
-ValidateGtFrameNumber (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- UINT8 FrameNumber;
-
- FrameNumber = *(UINT8 *)Ptr;
-
- if (FrameNumber >= GT_BLOCK_TIMER_COUNT_MAX) {
- IncrementErrorCount ();
- Print (
- L"\nERROR: GT Frame Number = %d. GT Frame Number must be in range 0-%d.",
- FrameNumber,
- GT_BLOCK_TIMER_COUNT_MAX - 1
- );
- }
-}
-
-/**
- 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 },
- { L"Virtual EL2 Timer GSIV", 4, 96, L"0x%x", NULL, NULL,NULL, NULL },
- { L"Virtual EL2 Timer Flags", 4, 100, L"0x%x", NULL, NULL,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, NULL, 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, ValidateGtFrameNumber, 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 ArmGenericWatchdogParser[] = {
- { 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 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;
-
- ParseAcpi (
- TRUE,
- 2,
- "GT Block",
- Ptr,
- Length,
- PARSER_PARAMS (GtBlockParser)
- );
-
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if ((GtBlockTimerCount == NULL) ||
- (GtBlockTimerOffset == NULL))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient GT Block Structure length. Length = %d.\n",
- Length
- );
- return;
- }
-
- Offset = *GtBlockTimerOffset;
- Index = 0;
-
- // Parse the specified number of GT Block Timer Structures or the GT Block
- // Structure buffer length. Whichever is minimum.
- while ((Index++ < *GtBlockTimerCount) &&
- (Offset < Length))
- {
- Offset += ParseAcpi (
- TRUE,
- 2,
- "GT Block Timer",
- Ptr + Offset,
- Length - Offset,
- PARSER_PARAMS (GtBlockTimerParser)
- );
- }
-}
-
-/**
- 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,
- "Arm Generic Watchdog",
- Ptr,
- Length,
- PARSER_PARAMS (ArmGenericWatchdogParser)
- );
-}
-
-/**
- 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;
- UINT32 Offset;
- UINT8 *TimerPtr;
-
- if (!Trace) {
- return;
- }
-
- ParseAcpi (
- TRUE,
- 0,
- "GTDT",
- Ptr,
- AcpiTableLength,
- PARSER_PARAMS (GtdtParser)
- );
-
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if ((GtdtPlatformTimerCount == NULL) ||
- (GtdtPlatformTimerOffset == NULL))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient table length. AcpiTableLength = %d.\n",
- AcpiTableLength
- );
- return;
- }
-
- TimerPtr = Ptr + *GtdtPlatformTimerOffset;
- Offset = *GtdtPlatformTimerOffset;
- Index = 0;
-
- // Parse the specified number of Platform Timer Structures or the GTDT
- // buffer length. Whichever is minimum.
- while ((Index++ < *GtdtPlatformTimerCount) &&
- (Offset < AcpiTableLength))
- {
- // Parse the Platform Timer Header to obtain Length and Type
- ParseAcpi (
- FALSE,
- 0,
- NULL,
- TimerPtr,
- AcpiTableLength - Offset,
- PARSER_PARAMS (GtPlatformTimerHeaderParser)
- );
-
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if ((PlatformTimerType == NULL) ||
- (PlatformTimerLength == NULL))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient remaining table buffer length to read the " \
- L"Platform Timer Structure header. Length = %d.\n",
- AcpiTableLength - Offset
- );
- return;
- }
-
- // Validate Platform Timer Structure length
- if ((*PlatformTimerLength == 0) ||
- ((Offset + (*PlatformTimerLength)) > AcpiTableLength))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Invalid Platform Timer Structure length. " \
- L"Length = %d. Offset = %d. AcpiTableLength = %d.\n",
- *PlatformTimerLength,
- Offset,
- AcpiTableLength
- );
- return;
- }
-
- switch (*PlatformTimerType) {
- case EFI_ACPI_6_4_GTDT_GT_BLOCK:
- DumpGTBlock (TimerPtr, *PlatformTimerLength);
- break;
- case EFI_ACPI_6_4_GTDT_ARM_GENERIC_WATCHDOG:
- DumpWatchdogTimer (TimerPtr, *PlatformTimerLength);
- break;
- default:
- IncrementErrorCount ();
- Print (
- L"ERROR: Invalid Platform Timer Type = %d\n",
- *PlatformTimerType
- );
- break;
- } // switch
-
- TimerPtr += *PlatformTimerLength;
- Offset += *PlatformTimerLength;
- } // while
-}
+/** @file + GTDT table parser + + Copyright (c) 2016 - 2021, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.4 Specification - January 2021 + **/ + +#include <IndustryStandard/Acpi.h> +#include <Library/UefiLib.h> +#include "AcpiParser.h" +#include "AcpiTableParser.h" +#include "AcpiViewConfig.h" + +// "The number of GT Block Timers must be less than or equal to 8" +#define GT_BLOCK_TIMER_COUNT_MAX 8 + +// 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 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 + ) +{ + UINT32 BlockTimerCount; + + BlockTimerCount = *(UINT32 *)Ptr; + + if (BlockTimerCount > GT_BLOCK_TIMER_COUNT_MAX) { + IncrementErrorCount (); + Print ( + L"\nERROR: Timer Count = %d. Max Timer Count is %d.", + BlockTimerCount, + GT_BLOCK_TIMER_COUNT_MAX + ); + } +} + +/** + This function validates the GT Frame Number. + + @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 +ValidateGtFrameNumber ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + UINT8 FrameNumber; + + FrameNumber = *(UINT8 *)Ptr; + + if (FrameNumber >= GT_BLOCK_TIMER_COUNT_MAX) { + IncrementErrorCount (); + Print ( + L"\nERROR: GT Frame Number = %d. GT Frame Number must be in range 0-%d.", + FrameNumber, + GT_BLOCK_TIMER_COUNT_MAX - 1 + ); + } +} + +/** + 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 }, + { L"Virtual EL2 Timer GSIV", 4, 96, L"0x%x", NULL, NULL,NULL, NULL }, + { L"Virtual EL2 Timer Flags", 4, 100, L"0x%x", NULL, NULL,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, NULL, 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, ValidateGtFrameNumber, 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 ArmGenericWatchdogParser[] = { + { 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 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; + + ParseAcpi ( + TRUE, + 2, + "GT Block", + Ptr, + Length, + PARSER_PARAMS (GtBlockParser) + ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if ((GtBlockTimerCount == NULL) || + (GtBlockTimerOffset == NULL)) + { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient GT Block Structure length. Length = %d.\n", + Length + ); + return; + } + + Offset = *GtBlockTimerOffset; + Index = 0; + + // Parse the specified number of GT Block Timer Structures or the GT Block + // Structure buffer length. Whichever is minimum. + while ((Index++ < *GtBlockTimerCount) && + (Offset < Length)) + { + Offset += ParseAcpi ( + TRUE, + 2, + "GT Block Timer", + Ptr + Offset, + Length - Offset, + PARSER_PARAMS (GtBlockTimerParser) + ); + } +} + +/** + 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, + "Arm Generic Watchdog", + Ptr, + Length, + PARSER_PARAMS (ArmGenericWatchdogParser) + ); +} + +/** + 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; + UINT32 Offset; + UINT8 *TimerPtr; + + if (!Trace) { + return; + } + + ParseAcpi ( + TRUE, + 0, + "GTDT", + Ptr, + AcpiTableLength, + PARSER_PARAMS (GtdtParser) + ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if ((GtdtPlatformTimerCount == NULL) || + (GtdtPlatformTimerOffset == NULL)) + { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient table length. AcpiTableLength = %d.\n", + AcpiTableLength + ); + return; + } + + TimerPtr = Ptr + *GtdtPlatformTimerOffset; + Offset = *GtdtPlatformTimerOffset; + Index = 0; + + // Parse the specified number of Platform Timer Structures or the GTDT + // buffer length. Whichever is minimum. + while ((Index++ < *GtdtPlatformTimerCount) && + (Offset < AcpiTableLength)) + { + // Parse the Platform Timer Header to obtain Length and Type + ParseAcpi ( + FALSE, + 0, + NULL, + TimerPtr, + AcpiTableLength - Offset, + PARSER_PARAMS (GtPlatformTimerHeaderParser) + ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if ((PlatformTimerType == NULL) || + (PlatformTimerLength == NULL)) + { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient remaining table buffer length to read the " \ + L"Platform Timer Structure header. Length = %d.\n", + AcpiTableLength - Offset + ); + return; + } + + // Validate Platform Timer Structure length + if ((*PlatformTimerLength == 0) || + ((Offset + (*PlatformTimerLength)) > AcpiTableLength)) + { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid Platform Timer Structure length. " \ + L"Length = %d. Offset = %d. AcpiTableLength = %d.\n", + *PlatformTimerLength, + Offset, + AcpiTableLength + ); + return; + } + + switch (*PlatformTimerType) { + case EFI_ACPI_6_4_GTDT_GT_BLOCK: + DumpGTBlock (TimerPtr, *PlatformTimerLength); + break; + case EFI_ACPI_6_4_GTDT_ARM_GENERIC_WATCHDOG: + DumpWatchdogTimer (TimerPtr, *PlatformTimerLength); + break; + default: + IncrementErrorCount (); + Print ( + L"ERROR: Invalid Platform Timer Type = %d\n", + *PlatformTimerType + ); + break; + } // switch + + TimerPtr += *PlatformTimerLength; + Offset += *PlatformTimerLength; + } // while +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c index 2a1357c853..06520bb7e7 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hmat/HmatParser.c @@ -1,667 +1,667 @@ -/** @file
- HMAT table parser
-
- Copyright (c) 2020, Arm Limited.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Reference(s):
- - ACPI 6.3 Specification - January 2019
-
- @par Glossary:
- - MPDA - Memory Proximity Domain Attributes
- - SLLBI - System Locality Latency and Bandwidth Information
- - MSCI - Memory Side Cache Information
- - Dom - Domain
-**/
-
-#include <Library/PrintLib.h>
-#include <Library/BaseLib.h>
-#include <Library/UefiLib.h>
-#include "AcpiParser.h"
-#include "AcpiView.h"
-
-// Maximum Memory Domain matrix print size.
-#define MAX_MEMORY_DOMAIN_TARGET_PRINT_MATRIX 10
-
-// Local variables
-STATIC CONST UINT16 *HmatStructureType;
-STATIC CONST UINT32 *HmatStructureLength;
-
-STATIC CONST UINT32 *NumberInitiatorProximityDomain;
-STATIC CONST UINT32 *NumberTargetProximityDomain;
-STATIC CONST
-EFI_ACPI_6_4_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO_FLAGS *
- SllbiFlags;
-
-STATIC CONST UINT8 *SllbiDataType;
-STATIC CONST UINT16 *NumberSMBIOSHandles;
-
-STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
-
-/**
- Names of System Locality Latency Bandwidth Information (SLLBI) data types
-**/
-STATIC CONST CHAR16 *SllbiNames[] = {
- L"Access %sLatency%s",
- L"Read %sLatency%s",
- L"Write %sLatency%s",
- L"Access %sBandwidth%s",
- L"Read %sBandwidth%s",
- L"Write %sBandwidth%s"
-};
-
-/**
- This function validates the Cache Attributes 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
-ValidateCacheAttributes (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES *
- Attributes;
-
- Attributes =
- (EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES *)Ptr;
-
- if (Attributes->TotalCacheLevels > 0x3) {
- IncrementErrorCount ();
- Print (
- L"\nERROR: Attributes bits [3:0] have invalid value: 0x%x",
- Attributes->TotalCacheLevels
- );
- }
-
- if (Attributes->CacheLevel > 0x3) {
- IncrementErrorCount ();
- Print (
- L"\nERROR: Attributes bits [7:4] have invalid value: 0x%x",
- Attributes->CacheLevel
- );
- }
-
- if (Attributes->CacheAssociativity > 0x2) {
- IncrementErrorCount ();
- Print (
- L"\nERROR: Attributes bits [11:8] have invalid value: 0x%x",
- Attributes->CacheAssociativity
- );
- }
-
- if (Attributes->WritePolicy > 0x2) {
- IncrementErrorCount ();
- Print (
- L"\nERROR: Attributes bits [15:12] have invalid value: 0x%x",
- Attributes->WritePolicy
- );
- }
-}
-
-/**
- Dumps the cache attributes field
-
- @param [in] Format Optional format string for tracing the data.
- @param [in] Ptr Pointer to the start of the buffer.
-**/
-STATIC
-VOID
-EFIAPI
-DumpCacheAttributes (
- IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
- )
-{
- EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES *
- Attributes;
-
- Attributes =
- (EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES *)Ptr;
-
- Print (L"\n");
- PrintFieldName (4, L"Total Cache Levels");
- Print (L"%d\n", Attributes->TotalCacheLevels);
- PrintFieldName (4, L"Cache Level");
- Print (L"%d\n", Attributes->CacheLevel);
- PrintFieldName (4, L"Cache Associativity");
- Print (L"%d\n", Attributes->CacheAssociativity);
- PrintFieldName (4, L"Write Policy");
- Print (L"%d\n", Attributes->WritePolicy);
- PrintFieldName (4, L"Cache Line Size");
- Print (L"%d\n", Attributes->CacheLineSize);
-}
-
-/**
- An ACPI_PARSER array describing the ACPI HMAT Table.
-*/
-STATIC CONST ACPI_PARSER HmatParser[] = {
- PARSE_ACPI_HEADER (&AcpiHdrInfo),
- { L"Reserved", 4,36, NULL, NULL, NULL, NULL, NULL }
-};
-
-/**
- An ACPI_PARSER array describing the HMAT structure header.
-*/
-STATIC CONST ACPI_PARSER HmatStructureHeaderParser[] = {
- { L"Type", 2, 0, NULL, NULL, (VOID **)&HmatStructureType, NULL, NULL },
- { L"Reserved", 2, 2, NULL, NULL, NULL, NULL, NULL },
- { L"Length", 4, 4, NULL, NULL, (VOID **)&HmatStructureLength, NULL, NULL }
-};
-
-/**
- An ACPI PARSER array describing the Memory Proximity Domain Attributes
- Structure - Type 0.
-*/
-STATIC CONST ACPI_PARSER MemProximityDomainAttributeParser[] = {
- { L"Type", 2, 0, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Length", 4, 4, L"%d", NULL, NULL, NULL, NULL },
- { L"Flags", 2, 8, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Reserved", 2, 10, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Proximity Dom for initiator", 4, 12, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Proximity Dom for memory", 4, 16, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Reserved", 4, 20, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Reserved", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Reserved", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL }
-};
-
-/**
- An ACPI PARSER array describing the System Locality Latency and Bandwidth
- Information Structure - Type 1.
-*/
-STATIC CONST ACPI_PARSER SllbiParser[] = {
- { L"Type", 2, 0, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Length", 4, 4, L"%d", NULL, NULL, NULL, NULL },
- { L"Flags", 1, 8, L"0x%x", NULL, (VOID **)&SllbiFlags, NULL, NULL },
- { L"Data type", 1, 9, L"0x%x", NULL, (VOID **)&SllbiDataType, NULL, NULL },
- { L"Min Transfer Size", 1, 10, L"%d", NULL, NULL, NULL, NULL },
- { L"Reserved", 1, 11, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Initiator Proximity Dom Count", 4, 12, L"%d", NULL,
- (VOID **)&NumberInitiatorProximityDomain, NULL, NULL },
- { L"Target Proximity Dom Count", 4, 16, L"%d", NULL,
- (VOID **)&NumberTargetProximityDomain, NULL, NULL },
- { L"Reserved", 4, 20, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Entry Base Unit", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL }
- // initiator Proximity Domain list ...
- // target Proximity Domain list ...
- // Latency/Bandwidth matrix ...
-};
-
-/**
- An ACPI PARSER array describing the Memory Side Cache Information
- Structure - Type 2.
-*/
-STATIC CONST ACPI_PARSER MemSideCacheInfoParser[] = {
- { L"Type", 2, 0, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Length", 4, 4, L"%d", NULL, NULL, NULL, NULL },
- { L"Proximity Dom for memory", 4, 8, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Reserved", 4, 12, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Memory Side Cache Size", 8, 16, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Cache Attributes", 4, 24, NULL, DumpCacheAttributes, NULL,
- ValidateCacheAttributes, NULL },
- { L"Reserved", 2, 28, L"0x%x", NULL, NULL, NULL, NULL },
- { L"SMBIOS Handle Count", 2, 30, L"%d", NULL,
- (VOID **)&NumberSMBIOSHandles, NULL, NULL }
- // SMBIOS handles List ...
-};
-
-/**
- This function parses the Memory Proximity Domain Attributes
- Structure (Type 0).
-
- @param [in] Ptr Pointer to the start of the Memory Proximity Domain
- Attributes Structure data.
- @param [in] Length Length of the Memory Proximity Domain Attributes
- Structure.
-**/
-STATIC
-VOID
-DumpMpda (
- IN UINT8 *Ptr,
- IN UINT32 Length
- )
-{
- ParseAcpi (
- TRUE,
- 2,
- "Memory Proximity Domain Attributes Structure",
- Ptr,
- Length,
- PARSER_PARAMS (MemProximityDomainAttributeParser)
- );
-}
-
-/**
- This function parses the System Locality Latency and Bandwidth Information
- Structure (Type 1).
-
- @param [in] Ptr Pointer to the start of the System Locality Latency and
- Bandwidth Information Structure data.
- @param [in] Length Length of the System Locality Latency and Bandwidth
- Information Structure.
-**/
-STATIC
-VOID
-DumpSllbi (
- IN UINT8 *Ptr,
- IN UINT32 Length
- )
-{
- CONST UINT32 *InitiatorProximityDomainList;
- CONST UINT32 *TargetProximityDomainList;
- CONST UINT16 *LatencyBandwidthMatrix;
- UINT32 Offset;
- CHAR16 Buffer[OUTPUT_FIELD_COLUMN_WIDTH];
- CHAR16 SecondBuffer[OUTPUT_FIELD_COLUMN_WIDTH];
- UINT32 RequiredTableSize;
- UINT32 Index;
- UINT32 IndexInitiator;
- UINT32 IndexTarget;
- UINT32 TargetStartOffset;
-
- Offset = ParseAcpi (
- TRUE,
- 2,
- "System Locality Latency and Bandwidth Information Structure",
- Ptr,
- Length,
- PARSER_PARAMS (SllbiParser)
- );
-
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if ((SllbiFlags == NULL) ||
- (SllbiDataType == NULL) ||
- (NumberInitiatorProximityDomain == NULL) ||
- (NumberTargetProximityDomain == NULL))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient remaining table buffer length to read the " \
- L"SLLBI structure header. Length = %d.\n",
- Length
- );
- return;
- }
-
- RequiredTableSize = (*NumberInitiatorProximityDomain * sizeof (UINT32)) +
- (*NumberTargetProximityDomain * sizeof (UINT32)) +
- (*NumberInitiatorProximityDomain *
- *NumberTargetProximityDomain * sizeof (UINT16)) +
- Offset;
-
- if (RequiredTableSize > Length) {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient System Locality Latency and Bandwidth" \
- L"Information Structure length. TableLength = %d. " \
- L"RequiredTableLength = %d.\n",
- Length,
- RequiredTableSize
- );
- return;
- }
-
- InitiatorProximityDomainList = (UINT32 *)(Ptr + Offset);
- TargetProximityDomainList = InitiatorProximityDomainList +
- *NumberInitiatorProximityDomain;
- LatencyBandwidthMatrix = (UINT16 *)(TargetProximityDomainList +
- *NumberTargetProximityDomain);
-
- // Display each element of the Initiator Proximity Domain list
- for (Index = 0; Index < *NumberInitiatorProximityDomain; Index++) {
- UnicodeSPrint (
- Buffer,
- sizeof (Buffer),
- L"Initiator Proximity Dom [%d]",
- Index
- );
-
- PrintFieldName (4, Buffer);
- Print (
- L"0x%x\n",
- InitiatorProximityDomainList[Index]
- );
- }
-
- // Display each element of the Target Proximity Domain list
- for (Index = 0; Index < *NumberTargetProximityDomain; Index++) {
- UnicodeSPrint (
- Buffer,
- sizeof (Buffer),
- L"Target Proximity Dom [%d]",
- Index
- );
-
- PrintFieldName (4, Buffer);
- Print (
- L"0x%x\n",
- TargetProximityDomainList[Index]
- );
- }
-
- // Create base name depending on Data Type in this Structure
- if (*SllbiDataType >= ARRAY_SIZE (SllbiNames)) {
- IncrementErrorCount ();
- Print (L"Error: Unkown Data Type. DataType = 0x%x.\n", *SllbiDataType);
- return;
- }
-
- StrCpyS (Buffer, sizeof (Buffer), SllbiNames[*SllbiDataType]);
-
- // Adjust base name depending on Memory Hierarchy in this Structure
- switch (SllbiFlags->MemoryHierarchy) {
- case 0:
- UnicodeSPrint (
- SecondBuffer,
- sizeof (SecondBuffer),
- Buffer,
- L"",
- L"%s"
- );
- break;
- case 1:
- case 2:
- case 3:
- UnicodeSPrint (
- SecondBuffer,
- sizeof (SecondBuffer),
- Buffer,
- L"Hit ",
- L"%s"
- );
- break;
- default:
- IncrementErrorCount ();
- Print (
- L"Error: Invalid Memory Hierarchy. MemoryHierarchy = %d.\n",
- SllbiFlags->MemoryHierarchy
- );
- return;
- } // switch
-
- if (*NumberTargetProximityDomain <= MAX_MEMORY_DOMAIN_TARGET_PRINT_MATRIX) {
- // Display the latency/bandwidth matrix as a matrix
- UnicodeSPrint (
- Buffer,
- sizeof (Buffer),
- SecondBuffer,
- L""
- );
- PrintFieldName (4, Buffer);
-
- Print (L"\n Target : X-axis (Horizontal)");
- Print (L"\n Initiator : Y-axis (Vertical)");
- Print (L"\n |");
-
- for (IndexTarget = 0;
- IndexTarget < *NumberTargetProximityDomain;
- IndexTarget++)
- {
- Print (L" %2d", IndexTarget);
- }
-
- Print (L"\n ---+");
- for (IndexTarget = 0;
- IndexTarget < *NumberTargetProximityDomain;
- IndexTarget++)
- {
- Print (L"------");
- }
-
- Print (L"\n");
-
- TargetStartOffset = 0;
- for (IndexInitiator = 0;
- IndexInitiator < *NumberInitiatorProximityDomain;
- IndexInitiator++)
- {
- Print (L" %2d |", IndexInitiator);
- for (IndexTarget = 0;
- IndexTarget < *NumberTargetProximityDomain;
- IndexTarget++)
- {
- Print (
- L" %5d",
- LatencyBandwidthMatrix[TargetStartOffset + IndexTarget]
- );
- } // for Target
-
- Print (L"\n");
- TargetStartOffset += (*NumberTargetProximityDomain);
- } // for Initiator
-
- Print (L"\n");
- } else {
- // Display the latency/bandwidth matrix as a list
- UnicodeSPrint (
- Buffer,
- sizeof (Buffer),
- SecondBuffer,
- L" [%d][%d]"
- );
-
- TargetStartOffset = 0;
- for (IndexInitiator = 0;
- IndexInitiator < *NumberInitiatorProximityDomain;
- IndexInitiator++)
- {
- for (IndexTarget = 0;
- IndexTarget < *NumberTargetProximityDomain;
- IndexTarget++)
- {
- UnicodeSPrint (
- SecondBuffer,
- sizeof (SecondBuffer),
- Buffer,
- IndexInitiator,
- IndexTarget
- );
-
- PrintFieldName (4, SecondBuffer);
- Print (
- L"%d\n",
- LatencyBandwidthMatrix[TargetStartOffset + IndexTarget]
- );
- } // for Target
-
- TargetStartOffset += (*NumberTargetProximityDomain);
- } // for Initiator
- }
-}
-
-/**
- This function parses the Memory Side Cache Information Structure (Type 2).
-
- @param [in] Ptr Pointer to the start of the Memory Side Cache Information
- Structure data.
- @param [in] Length Length of the Memory Side Cache Information Structure.
-**/
-STATIC
-VOID
-DumpMsci (
- IN UINT8 *Ptr,
- IN UINT32 Length
- )
-{
- CONST UINT16 *SMBIOSHandlesList;
- CHAR16 Buffer[OUTPUT_FIELD_COLUMN_WIDTH];
- UINT32 Offset;
- UINT16 Index;
-
- Offset = ParseAcpi (
- TRUE,
- 2,
- "Memory Side Cache Information Structure",
- Ptr,
- Length,
- PARSER_PARAMS (MemSideCacheInfoParser)
- );
-
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if (NumberSMBIOSHandles == NULL) {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient remaining table buffer length to read the " \
- L"MSCI structure header. Length = %d.\n",
- Length
- );
- return;
- }
-
- if ((*NumberSMBIOSHandles * sizeof (UINT16)) > (Length - Offset)) {
- IncrementErrorCount ();
- Print (
- L"ERROR: Invalid Number of SMBIOS Handles. SMBIOSHandlesCount = %d." \
- L"RemainingBufferLength = %d.\n",
- *NumberSMBIOSHandles,
- Length - Offset
- );
- return;
- }
-
- SMBIOSHandlesList = (UINT16 *)(Ptr + Offset);
-
- for (Index = 0; Index < *NumberSMBIOSHandles; Index++) {
- UnicodeSPrint (
- Buffer,
- sizeof (Buffer),
- L"SMBIOS Handles [%d]",
- Index
- );
-
- PrintFieldName (4, Buffer);
- Print (
- L"0x%x\n",
- SMBIOSHandlesList[Index]
- );
- }
-}
-
-/**
- This function parses the ACPI HMAT table.
- When trace is enabled this function parses the HMAT table and
- traces the ACPI table fields.
-
- This function parses the following HMAT structures:
- - Memory Proximity Domain Attributes Structure (Type 0)
- - System Locality Latency and Bandwidth Info Structure (Type 1)
- - Memory Side Cache Info structure (Type 2)
-
- 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
-ParseAcpiHmat (
- IN BOOLEAN Trace,
- IN UINT8 *Ptr,
- IN UINT32 AcpiTableLength,
- IN UINT8 AcpiTableRevision
- )
-{
- UINT32 Offset;
- UINT8 *HmatStructurePtr;
-
- if (!Trace) {
- return;
- }
-
- Offset = ParseAcpi (
- Trace,
- 0,
- "HMAT",
- Ptr,
- AcpiTableLength,
- PARSER_PARAMS (HmatParser)
- );
-
- HmatStructurePtr = Ptr + Offset;
-
- while (Offset < AcpiTableLength) {
- // Parse HMAT Structure Header to obtain Type and Length.
- ParseAcpi (
- FALSE,
- 0,
- NULL,
- HmatStructurePtr,
- AcpiTableLength - Offset,
- PARSER_PARAMS (HmatStructureHeaderParser)
- );
-
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if ((HmatStructureType == NULL) ||
- (HmatStructureLength == NULL))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient remaining table buffer length to read the " \
- L"HMAT structure header. Length = %d.\n",
- AcpiTableLength - Offset
- );
- return;
- }
-
- // Validate HMAT Structure length.
- if ((*HmatStructureLength == 0) ||
- ((Offset + (*HmatStructureLength)) > AcpiTableLength))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Invalid HMAT Structure length. " \
- L"Length = %d. Offset = %d. AcpiTableLength = %d.\n",
- *HmatStructureLength,
- Offset,
- AcpiTableLength
- );
- return;
- }
-
- switch (*HmatStructureType) {
- case EFI_ACPI_6_4_HMAT_TYPE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES:
- DumpMpda (
- HmatStructurePtr,
- *HmatStructureLength
- );
- break;
- case EFI_ACPI_6_4_HMAT_TYPE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO:
- DumpSllbi (
- HmatStructurePtr,
- *HmatStructureLength
- );
- break;
- case EFI_ACPI_6_4_HMAT_TYPE_MEMORY_SIDE_CACHE_INFO:
- DumpMsci (
- HmatStructurePtr,
- *HmatStructureLength
- );
- break;
- default:
- IncrementErrorCount ();
- Print (
- L"ERROR: Unknown HMAT structure:"
- L" Type = %d, Length = %d\n",
- *HmatStructureType,
- *HmatStructureLength
- );
- break;
- } // switch
-
- HmatStructurePtr += *HmatStructureLength;
- Offset += *HmatStructureLength;
- } // while
-}
+/** @file + HMAT table parser + + Copyright (c) 2020, Arm Limited. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.3 Specification - January 2019 + + @par Glossary: + - MPDA - Memory Proximity Domain Attributes + - SLLBI - System Locality Latency and Bandwidth Information + - MSCI - Memory Side Cache Information + - Dom - Domain +**/ + +#include <Library/PrintLib.h> +#include <Library/BaseLib.h> +#include <Library/UefiLib.h> +#include "AcpiParser.h" +#include "AcpiView.h" + +// Maximum Memory Domain matrix print size. +#define MAX_MEMORY_DOMAIN_TARGET_PRINT_MATRIX 10 + +// Local variables +STATIC CONST UINT16 *HmatStructureType; +STATIC CONST UINT32 *HmatStructureLength; + +STATIC CONST UINT32 *NumberInitiatorProximityDomain; +STATIC CONST UINT32 *NumberTargetProximityDomain; +STATIC CONST +EFI_ACPI_6_4_HMAT_STRUCTURE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO_FLAGS * + SllbiFlags; + +STATIC CONST UINT8 *SllbiDataType; +STATIC CONST UINT16 *NumberSMBIOSHandles; + +STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; + +/** + Names of System Locality Latency Bandwidth Information (SLLBI) data types +**/ +STATIC CONST CHAR16 *SllbiNames[] = { + L"Access %sLatency%s", + L"Read %sLatency%s", + L"Write %sLatency%s", + L"Access %sBandwidth%s", + L"Read %sBandwidth%s", + L"Write %sBandwidth%s" +}; + +/** + This function validates the Cache Attributes 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 +ValidateCacheAttributes ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES * + Attributes; + + Attributes = + (EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES *)Ptr; + + if (Attributes->TotalCacheLevels > 0x3) { + IncrementErrorCount (); + Print ( + L"\nERROR: Attributes bits [3:0] have invalid value: 0x%x", + Attributes->TotalCacheLevels + ); + } + + if (Attributes->CacheLevel > 0x3) { + IncrementErrorCount (); + Print ( + L"\nERROR: Attributes bits [7:4] have invalid value: 0x%x", + Attributes->CacheLevel + ); + } + + if (Attributes->CacheAssociativity > 0x2) { + IncrementErrorCount (); + Print ( + L"\nERROR: Attributes bits [11:8] have invalid value: 0x%x", + Attributes->CacheAssociativity + ); + } + + if (Attributes->WritePolicy > 0x2) { + IncrementErrorCount (); + Print ( + L"\nERROR: Attributes bits [15:12] have invalid value: 0x%x", + Attributes->WritePolicy + ); + } +} + +/** + Dumps the cache attributes field + + @param [in] Format Optional format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. +**/ +STATIC +VOID +EFIAPI +DumpCacheAttributes ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES * + Attributes; + + Attributes = + (EFI_ACPI_6_4_HMAT_STRUCTURE_MEMORY_SIDE_CACHE_INFO_CACHE_ATTRIBUTES *)Ptr; + + Print (L"\n"); + PrintFieldName (4, L"Total Cache Levels"); + Print (L"%d\n", Attributes->TotalCacheLevels); + PrintFieldName (4, L"Cache Level"); + Print (L"%d\n", Attributes->CacheLevel); + PrintFieldName (4, L"Cache Associativity"); + Print (L"%d\n", Attributes->CacheAssociativity); + PrintFieldName (4, L"Write Policy"); + Print (L"%d\n", Attributes->WritePolicy); + PrintFieldName (4, L"Cache Line Size"); + Print (L"%d\n", Attributes->CacheLineSize); +} + +/** + An ACPI_PARSER array describing the ACPI HMAT Table. +*/ +STATIC CONST ACPI_PARSER HmatParser[] = { + PARSE_ACPI_HEADER (&AcpiHdrInfo), + { L"Reserved", 4,36, NULL, NULL, NULL, NULL, NULL } +}; + +/** + An ACPI_PARSER array describing the HMAT structure header. +*/ +STATIC CONST ACPI_PARSER HmatStructureHeaderParser[] = { + { L"Type", 2, 0, NULL, NULL, (VOID **)&HmatStructureType, NULL, NULL }, + { L"Reserved", 2, 2, NULL, NULL, NULL, NULL, NULL }, + { L"Length", 4, 4, NULL, NULL, (VOID **)&HmatStructureLength, NULL, NULL } +}; + +/** + An ACPI PARSER array describing the Memory Proximity Domain Attributes + Structure - Type 0. +*/ +STATIC CONST ACPI_PARSER MemProximityDomainAttributeParser[] = { + { L"Type", 2, 0, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Length", 4, 4, L"%d", NULL, NULL, NULL, NULL }, + { L"Flags", 2, 8, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Reserved", 2, 10, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Proximity Dom for initiator", 4, 12, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Proximity Dom for memory", 4, 16, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Reserved", 4, 20, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Reserved", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Reserved", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL } +}; + +/** + An ACPI PARSER array describing the System Locality Latency and Bandwidth + Information Structure - Type 1. +*/ +STATIC CONST ACPI_PARSER SllbiParser[] = { + { L"Type", 2, 0, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Length", 4, 4, L"%d", NULL, NULL, NULL, NULL }, + { L"Flags", 1, 8, L"0x%x", NULL, (VOID **)&SllbiFlags, NULL, NULL }, + { L"Data type", 1, 9, L"0x%x", NULL, (VOID **)&SllbiDataType, NULL, NULL }, + { L"Min Transfer Size", 1, 10, L"%d", NULL, NULL, NULL, NULL }, + { L"Reserved", 1, 11, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Initiator Proximity Dom Count", 4, 12, L"%d", NULL, + (VOID **)&NumberInitiatorProximityDomain, NULL, NULL }, + { L"Target Proximity Dom Count", 4, 16, L"%d", NULL, + (VOID **)&NumberTargetProximityDomain, NULL, NULL }, + { L"Reserved", 4, 20, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Entry Base Unit", 8, 24, L"0x%lx", NULL, NULL, NULL, NULL } + // initiator Proximity Domain list ... + // target Proximity Domain list ... + // Latency/Bandwidth matrix ... +}; + +/** + An ACPI PARSER array describing the Memory Side Cache Information + Structure - Type 2. +*/ +STATIC CONST ACPI_PARSER MemSideCacheInfoParser[] = { + { L"Type", 2, 0, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Reserved", 2, 2, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Length", 4, 4, L"%d", NULL, NULL, NULL, NULL }, + { L"Proximity Dom for memory", 4, 8, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Reserved", 4, 12, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Memory Side Cache Size", 8, 16, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Cache Attributes", 4, 24, NULL, DumpCacheAttributes, NULL, + ValidateCacheAttributes, NULL }, + { L"Reserved", 2, 28, L"0x%x", NULL, NULL, NULL, NULL }, + { L"SMBIOS Handle Count", 2, 30, L"%d", NULL, + (VOID **)&NumberSMBIOSHandles, NULL, NULL } + // SMBIOS handles List ... +}; + +/** + This function parses the Memory Proximity Domain Attributes + Structure (Type 0). + + @param [in] Ptr Pointer to the start of the Memory Proximity Domain + Attributes Structure data. + @param [in] Length Length of the Memory Proximity Domain Attributes + Structure. +**/ +STATIC +VOID +DumpMpda ( + IN UINT8 *Ptr, + IN UINT32 Length + ) +{ + ParseAcpi ( + TRUE, + 2, + "Memory Proximity Domain Attributes Structure", + Ptr, + Length, + PARSER_PARAMS (MemProximityDomainAttributeParser) + ); +} + +/** + This function parses the System Locality Latency and Bandwidth Information + Structure (Type 1). + + @param [in] Ptr Pointer to the start of the System Locality Latency and + Bandwidth Information Structure data. + @param [in] Length Length of the System Locality Latency and Bandwidth + Information Structure. +**/ +STATIC +VOID +DumpSllbi ( + IN UINT8 *Ptr, + IN UINT32 Length + ) +{ + CONST UINT32 *InitiatorProximityDomainList; + CONST UINT32 *TargetProximityDomainList; + CONST UINT16 *LatencyBandwidthMatrix; + UINT32 Offset; + CHAR16 Buffer[OUTPUT_FIELD_COLUMN_WIDTH]; + CHAR16 SecondBuffer[OUTPUT_FIELD_COLUMN_WIDTH]; + UINT32 RequiredTableSize; + UINT32 Index; + UINT32 IndexInitiator; + UINT32 IndexTarget; + UINT32 TargetStartOffset; + + Offset = ParseAcpi ( + TRUE, + 2, + "System Locality Latency and Bandwidth Information Structure", + Ptr, + Length, + PARSER_PARAMS (SllbiParser) + ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if ((SllbiFlags == NULL) || + (SllbiDataType == NULL) || + (NumberInitiatorProximityDomain == NULL) || + (NumberTargetProximityDomain == NULL)) + { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient remaining table buffer length to read the " \ + L"SLLBI structure header. Length = %d.\n", + Length + ); + return; + } + + RequiredTableSize = (*NumberInitiatorProximityDomain * sizeof (UINT32)) + + (*NumberTargetProximityDomain * sizeof (UINT32)) + + (*NumberInitiatorProximityDomain * + *NumberTargetProximityDomain * sizeof (UINT16)) + + Offset; + + if (RequiredTableSize > Length) { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient System Locality Latency and Bandwidth" \ + L"Information Structure length. TableLength = %d. " \ + L"RequiredTableLength = %d.\n", + Length, + RequiredTableSize + ); + return; + } + + InitiatorProximityDomainList = (UINT32 *)(Ptr + Offset); + TargetProximityDomainList = InitiatorProximityDomainList + + *NumberInitiatorProximityDomain; + LatencyBandwidthMatrix = (UINT16 *)(TargetProximityDomainList + + *NumberTargetProximityDomain); + + // Display each element of the Initiator Proximity Domain list + for (Index = 0; Index < *NumberInitiatorProximityDomain; Index++) { + UnicodeSPrint ( + Buffer, + sizeof (Buffer), + L"Initiator Proximity Dom [%d]", + Index + ); + + PrintFieldName (4, Buffer); + Print ( + L"0x%x\n", + InitiatorProximityDomainList[Index] + ); + } + + // Display each element of the Target Proximity Domain list + for (Index = 0; Index < *NumberTargetProximityDomain; Index++) { + UnicodeSPrint ( + Buffer, + sizeof (Buffer), + L"Target Proximity Dom [%d]", + Index + ); + + PrintFieldName (4, Buffer); + Print ( + L"0x%x\n", + TargetProximityDomainList[Index] + ); + } + + // Create base name depending on Data Type in this Structure + if (*SllbiDataType >= ARRAY_SIZE (SllbiNames)) { + IncrementErrorCount (); + Print (L"Error: Unkown Data Type. DataType = 0x%x.\n", *SllbiDataType); + return; + } + + StrCpyS (Buffer, sizeof (Buffer), SllbiNames[*SllbiDataType]); + + // Adjust base name depending on Memory Hierarchy in this Structure + switch (SllbiFlags->MemoryHierarchy) { + case 0: + UnicodeSPrint ( + SecondBuffer, + sizeof (SecondBuffer), + Buffer, + L"", + L"%s" + ); + break; + case 1: + case 2: + case 3: + UnicodeSPrint ( + SecondBuffer, + sizeof (SecondBuffer), + Buffer, + L"Hit ", + L"%s" + ); + break; + default: + IncrementErrorCount (); + Print ( + L"Error: Invalid Memory Hierarchy. MemoryHierarchy = %d.\n", + SllbiFlags->MemoryHierarchy + ); + return; + } // switch + + if (*NumberTargetProximityDomain <= MAX_MEMORY_DOMAIN_TARGET_PRINT_MATRIX) { + // Display the latency/bandwidth matrix as a matrix + UnicodeSPrint ( + Buffer, + sizeof (Buffer), + SecondBuffer, + L"" + ); + PrintFieldName (4, Buffer); + + Print (L"\n Target : X-axis (Horizontal)"); + Print (L"\n Initiator : Y-axis (Vertical)"); + Print (L"\n |"); + + for (IndexTarget = 0; + IndexTarget < *NumberTargetProximityDomain; + IndexTarget++) + { + Print (L" %2d", IndexTarget); + } + + Print (L"\n ---+"); + for (IndexTarget = 0; + IndexTarget < *NumberTargetProximityDomain; + IndexTarget++) + { + Print (L"------"); + } + + Print (L"\n"); + + TargetStartOffset = 0; + for (IndexInitiator = 0; + IndexInitiator < *NumberInitiatorProximityDomain; + IndexInitiator++) + { + Print (L" %2d |", IndexInitiator); + for (IndexTarget = 0; + IndexTarget < *NumberTargetProximityDomain; + IndexTarget++) + { + Print ( + L" %5d", + LatencyBandwidthMatrix[TargetStartOffset + IndexTarget] + ); + } // for Target + + Print (L"\n"); + TargetStartOffset += (*NumberTargetProximityDomain); + } // for Initiator + + Print (L"\n"); + } else { + // Display the latency/bandwidth matrix as a list + UnicodeSPrint ( + Buffer, + sizeof (Buffer), + SecondBuffer, + L" [%d][%d]" + ); + + TargetStartOffset = 0; + for (IndexInitiator = 0; + IndexInitiator < *NumberInitiatorProximityDomain; + IndexInitiator++) + { + for (IndexTarget = 0; + IndexTarget < *NumberTargetProximityDomain; + IndexTarget++) + { + UnicodeSPrint ( + SecondBuffer, + sizeof (SecondBuffer), + Buffer, + IndexInitiator, + IndexTarget + ); + + PrintFieldName (4, SecondBuffer); + Print ( + L"%d\n", + LatencyBandwidthMatrix[TargetStartOffset + IndexTarget] + ); + } // for Target + + TargetStartOffset += (*NumberTargetProximityDomain); + } // for Initiator + } +} + +/** + This function parses the Memory Side Cache Information Structure (Type 2). + + @param [in] Ptr Pointer to the start of the Memory Side Cache Information + Structure data. + @param [in] Length Length of the Memory Side Cache Information Structure. +**/ +STATIC +VOID +DumpMsci ( + IN UINT8 *Ptr, + IN UINT32 Length + ) +{ + CONST UINT16 *SMBIOSHandlesList; + CHAR16 Buffer[OUTPUT_FIELD_COLUMN_WIDTH]; + UINT32 Offset; + UINT16 Index; + + Offset = ParseAcpi ( + TRUE, + 2, + "Memory Side Cache Information Structure", + Ptr, + Length, + PARSER_PARAMS (MemSideCacheInfoParser) + ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if (NumberSMBIOSHandles == NULL) { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient remaining table buffer length to read the " \ + L"MSCI structure header. Length = %d.\n", + Length + ); + return; + } + + if ((*NumberSMBIOSHandles * sizeof (UINT16)) > (Length - Offset)) { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid Number of SMBIOS Handles. SMBIOSHandlesCount = %d." \ + L"RemainingBufferLength = %d.\n", + *NumberSMBIOSHandles, + Length - Offset + ); + return; + } + + SMBIOSHandlesList = (UINT16 *)(Ptr + Offset); + + for (Index = 0; Index < *NumberSMBIOSHandles; Index++) { + UnicodeSPrint ( + Buffer, + sizeof (Buffer), + L"SMBIOS Handles [%d]", + Index + ); + + PrintFieldName (4, Buffer); + Print ( + L"0x%x\n", + SMBIOSHandlesList[Index] + ); + } +} + +/** + This function parses the ACPI HMAT table. + When trace is enabled this function parses the HMAT table and + traces the ACPI table fields. + + This function parses the following HMAT structures: + - Memory Proximity Domain Attributes Structure (Type 0) + - System Locality Latency and Bandwidth Info Structure (Type 1) + - Memory Side Cache Info structure (Type 2) + + 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 +ParseAcpiHmat ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ) +{ + UINT32 Offset; + UINT8 *HmatStructurePtr; + + if (!Trace) { + return; + } + + Offset = ParseAcpi ( + Trace, + 0, + "HMAT", + Ptr, + AcpiTableLength, + PARSER_PARAMS (HmatParser) + ); + + HmatStructurePtr = Ptr + Offset; + + while (Offset < AcpiTableLength) { + // Parse HMAT Structure Header to obtain Type and Length. + ParseAcpi ( + FALSE, + 0, + NULL, + HmatStructurePtr, + AcpiTableLength - Offset, + PARSER_PARAMS (HmatStructureHeaderParser) + ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if ((HmatStructureType == NULL) || + (HmatStructureLength == NULL)) + { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient remaining table buffer length to read the " \ + L"HMAT structure header. Length = %d.\n", + AcpiTableLength - Offset + ); + return; + } + + // Validate HMAT Structure length. + if ((*HmatStructureLength == 0) || + ((Offset + (*HmatStructureLength)) > AcpiTableLength)) + { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid HMAT Structure length. " \ + L"Length = %d. Offset = %d. AcpiTableLength = %d.\n", + *HmatStructureLength, + Offset, + AcpiTableLength + ); + return; + } + + switch (*HmatStructureType) { + case EFI_ACPI_6_4_HMAT_TYPE_MEMORY_PROXIMITY_DOMAIN_ATTRIBUTES: + DumpMpda ( + HmatStructurePtr, + *HmatStructureLength + ); + break; + case EFI_ACPI_6_4_HMAT_TYPE_SYSTEM_LOCALITY_LATENCY_AND_BANDWIDTH_INFO: + DumpSllbi ( + HmatStructurePtr, + *HmatStructureLength + ); + break; + case EFI_ACPI_6_4_HMAT_TYPE_MEMORY_SIDE_CACHE_INFO: + DumpMsci ( + HmatStructurePtr, + *HmatStructureLength + ); + break; + default: + IncrementErrorCount (); + Print ( + L"ERROR: Unknown HMAT structure:" + L" Type = %d, Length = %d\n", + *HmatStructureType, + *HmatStructureLength + ); + break; + } // switch + + HmatStructurePtr += *HmatStructureLength; + Offset += *HmatStructureLength; + } // while +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hpet/HpetParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hpet/HpetParser.c index 1b4c38f2af..a4b030bfd6 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hpet/HpetParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hpet/HpetParser.c @@ -1,222 +1,222 @@ -/** @file
- HPET table parser
-
- Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Reference(s):
- - HPET spec, version 1.0a
-**/
-
-#include <Library/UefiLib.h>
-#include "AcpiParser.h"
-
-STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
-
-/**
- This function prints HPET page protection flags.
- 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
-DumpHpetPageProtectionFlag (
- IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
- )
-{
- if (Format != NULL) {
- Print (Format, *(UINT8 *)Ptr);
- return;
- }
-
- Print (L"0x%X ", *(UINT8 *)Ptr);
- switch (*Ptr) {
- case 0:
- Print (L"(no guarantee for page protection)");
- break;
- case 1:
- Print (L"(4K page protection)");
- break;
- case 2:
- Print (L"(64K page protection)");
- break;
- default:
- IncrementErrorCount ();
- Print (L"(OEM Reserved)");
- break;
- }
-
- return;
-}
-
-/**
- An ACPI_PARSER array describing the ACPI HPET flags.
-**/
-STATIC CONST ACPI_PARSER DumpHpetFlagParser[] = {
- { L"Page Protection Flag", 4, 0, NULL, DumpHpetPageProtectionFlag, NULL, NULL, NULL },
- { L"OEM Attributes", 4, 4, L"0x%x", NULL, NULL, NULL, NULL }
-};
-
-/**
- This function prints HPET Flags fields.
- 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
-DumpHpetFlag (
- IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
- )
-{
- if (Format != NULL) {
- Print (Format, *(UINT8 *)Ptr);
- return;
- }
-
- Print (L"0x%X\n", *(UINT8 *)Ptr);
- ParseAcpiBitFields (
- TRUE,
- 2,
- NULL,
- Ptr,
- 4,
- PARSER_PARAMS (DumpHpetFlagParser)
- );
-}
-
-/**
- This function prints HPET Counter size fields.
- 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
-DumpCounterSize (
- IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
- )
-{
- if (Format != NULL) {
- Print (Format, *(UINT32 *)Ptr);
- return;
- }
-
- Print (L"0x%X ", *(UINT32 *)Ptr);
- if (*Ptr == 0) {
- Print (L"(Max 32-bit counter size)");
- } else {
- Print (L"(Max 64-bit counter size)");
- }
-}
-
-/**
- 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
-ValidateHpetRevId (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- if ((*(UINT8 *)Ptr) == 0) {
- IncrementErrorCount ();
- Print (
- L"\nERROR: HPET Hardware Rev ID must be set."
- );
- }
-}
-
-/**
- An ACPI_PARSER array describing the ACPI HPET Event Timer Block ID.
-**/
-STATIC CONST ACPI_PARSER HpetEventTimerBlockIdFlagParser[] = {
- { L"Hardware Rev ID", 8, 0, L"0x%x", NULL, NULL, ValidateHpetRevId, NULL },
- { L"Comparators in 1st Timer Block", 5, 8, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Counter max size", 1, 13, NULL, DumpCounterSize, NULL, NULL, NULL },
- { L"Reserved", 1, 14, L"%d", NULL, NULL, NULL, NULL },
- { L"LegacyReplacement IRQ Routing", 1, 15, L"%d", NULL, NULL, NULL, NULL },
- { L"PCI Vendor ID of 1st Timer Block", 16, 16, L"0x%x", NULL, NULL, NULL, NULL }
-};
-
-/**
- This function prints Hardware ID of HPET Event timer block.
- 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
-DumpHpetEventTimerBlockId (
- IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
- )
-{
- if (Format != NULL) {
- Print (Format, *(UINT32 *)Ptr);
- return;
- }
-
- Print (L"0x%X\n", *(UINT32 *)Ptr);
- ParseAcpiBitFields (
- TRUE,
- 2,
- NULL,
- Ptr,
- 4,
- PARSER_PARAMS (HpetEventTimerBlockIdFlagParser)
- );
-}
-
-/**
- An ACPI_PARSER array describing the ACPI HPET Table.
-**/
-STATIC CONST ACPI_PARSER HpetParser[] = {
- PARSE_ACPI_HEADER (&AcpiHdrInfo),
- { L"Event Timer Block ID", 4, 36, NULL, DumpHpetEventTimerBlockId, NULL, NULL, NULL },
- { L"Base Address", 12, 40, NULL, DumpGas, NULL, NULL, NULL },
- { L"HPET Number", 1, 52, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Minimum Clock Ticks", 2, 53, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Page Protection and OEM Attributes",1, 55, NULL, DumpHpetFlag, NULL, NULL, NULL }
-};
-
-/**
- This function parses the ACPI HPET 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
-ParseAcpiHpet (
- IN BOOLEAN Trace,
- IN UINT8 *Ptr,
- IN UINT32 AcpiTableLength,
- IN UINT8 AcpiTableRevision
- )
-{
- ParseAcpi (
- Trace,
- 0,
- "HPET",
- Ptr,
- AcpiTableLength,
- PARSER_PARAMS (HpetParser)
- );
-}
+/** @file + HPET table parser + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - HPET spec, version 1.0a +**/ + +#include <Library/UefiLib.h> +#include "AcpiParser.h" + +STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; + +/** + This function prints HPET page protection flags. + 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 +DumpHpetPageProtectionFlag ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + if (Format != NULL) { + Print (Format, *(UINT8 *)Ptr); + return; + } + + Print (L"0x%X ", *(UINT8 *)Ptr); + switch (*Ptr) { + case 0: + Print (L"(no guarantee for page protection)"); + break; + case 1: + Print (L"(4K page protection)"); + break; + case 2: + Print (L"(64K page protection)"); + break; + default: + IncrementErrorCount (); + Print (L"(OEM Reserved)"); + break; + } + + return; +} + +/** + An ACPI_PARSER array describing the ACPI HPET flags. +**/ +STATIC CONST ACPI_PARSER DumpHpetFlagParser[] = { + { L"Page Protection Flag", 4, 0, NULL, DumpHpetPageProtectionFlag, NULL, NULL, NULL }, + { L"OEM Attributes", 4, 4, L"0x%x", NULL, NULL, NULL, NULL } +}; + +/** + This function prints HPET Flags fields. + 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 +DumpHpetFlag ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + if (Format != NULL) { + Print (Format, *(UINT8 *)Ptr); + return; + } + + Print (L"0x%X\n", *(UINT8 *)Ptr); + ParseAcpiBitFields ( + TRUE, + 2, + NULL, + Ptr, + 4, + PARSER_PARAMS (DumpHpetFlagParser) + ); +} + +/** + This function prints HPET Counter size fields. + 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 +DumpCounterSize ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + if (Format != NULL) { + Print (Format, *(UINT32 *)Ptr); + return; + } + + Print (L"0x%X ", *(UINT32 *)Ptr); + if (*Ptr == 0) { + Print (L"(Max 32-bit counter size)"); + } else { + Print (L"(Max 64-bit counter size)"); + } +} + +/** + 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 +ValidateHpetRevId ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + if ((*(UINT8 *)Ptr) == 0) { + IncrementErrorCount (); + Print ( + L"\nERROR: HPET Hardware Rev ID must be set." + ); + } +} + +/** + An ACPI_PARSER array describing the ACPI HPET Event Timer Block ID. +**/ +STATIC CONST ACPI_PARSER HpetEventTimerBlockIdFlagParser[] = { + { L"Hardware Rev ID", 8, 0, L"0x%x", NULL, NULL, ValidateHpetRevId, NULL }, + { L"Comparators in 1st Timer Block", 5, 8, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Counter max size", 1, 13, NULL, DumpCounterSize, NULL, NULL, NULL }, + { L"Reserved", 1, 14, L"%d", NULL, NULL, NULL, NULL }, + { L"LegacyReplacement IRQ Routing", 1, 15, L"%d", NULL, NULL, NULL, NULL }, + { L"PCI Vendor ID of 1st Timer Block", 16, 16, L"0x%x", NULL, NULL, NULL, NULL } +}; + +/** + This function prints Hardware ID of HPET Event timer block. + 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 +DumpHpetEventTimerBlockId ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + if (Format != NULL) { + Print (Format, *(UINT32 *)Ptr); + return; + } + + Print (L"0x%X\n", *(UINT32 *)Ptr); + ParseAcpiBitFields ( + TRUE, + 2, + NULL, + Ptr, + 4, + PARSER_PARAMS (HpetEventTimerBlockIdFlagParser) + ); +} + +/** + An ACPI_PARSER array describing the ACPI HPET Table. +**/ +STATIC CONST ACPI_PARSER HpetParser[] = { + PARSE_ACPI_HEADER (&AcpiHdrInfo), + { L"Event Timer Block ID", 4, 36, NULL, DumpHpetEventTimerBlockId, NULL, NULL, NULL }, + { L"Base Address", 12, 40, NULL, DumpGas, NULL, NULL, NULL }, + { L"HPET Number", 1, 52, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Minimum Clock Ticks", 2, 53, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Page Protection and OEM Attributes",1, 55, NULL, DumpHpetFlag, NULL, NULL, NULL } +}; + +/** + This function parses the ACPI HPET 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 +ParseAcpiHpet ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ) +{ + ParseAcpi ( + Trace, + 0, + "HPET", + Ptr, + AcpiTableLength, + PARSER_PARAMS (HpetParser) + ); +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c index 599cf0ee8f..6468b818c2 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Iort/IortParser.c @@ -1,971 +1,971 @@ -/** @file
- IORT table parser
-
- Copyright (c) 2016 - 2022, Arm Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Reference(s):
- - IO Remapping Table, Platform Design Document, Revision E.d, Feb 2022
- (https://developer.arm.com/documentation/den0049/)
-
- @par Glossary:
- - Ref - Reference
- - Desc - Descriptor
-**/
-
-#include <IndustryStandard/IoRemappingTable.h>
-#include <Library/PrintLib.h>
-#include <Library/UefiLib.h>
-#include "AcpiParser.h"
-#include "AcpiTableParser.h"
-#include "AcpiViewConfig.h"
-
-// Local variables
-STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
-
-STATIC CONST UINT32 *IortNodeCount;
-STATIC CONST UINT32 *IortNodeOffset;
-
-STATIC CONST UINT8 *IortNodeType;
-STATIC CONST UINT16 *IortNodeLength;
-STATIC CONST UINT8 *IortNodeRevision;
-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;
-
-STATIC CONST UINT32 *RmrMemDescCount;
-STATIC CONST UINT32 *RmrMemDescOffset;
-
-/**
- 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
- )
-{
- if (*(UINT32 *)Ptr != 0) {
- IncrementErrorCount ();
- Print (L"\nERROR: IORT ID Mapping count must be zero.");
- }
-}
-
-/**
- This function validates the ID Mapping array count for the Performance
- Monitoring Counter Group (PMCG) 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
-ValidatePmcgIdMappingCount (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- if (*(UINT32 *)Ptr > 1) {
- IncrementErrorCount ();
- Print (L"\nERROR: IORT ID Mapping count must not be greater than 1.");
- }
-}
-
-/**
- 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 validates that the Physical Range address or length is not zero
- and is 64K aligned.
-
- @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
-ValidatePhysicalRange (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- UINT64 Value;
-
- Value = *(UINT64 *)Ptr;
- if ((Value == 0) || ((Value & (SIZE_64KB - 1)) != 0)) {
- IncrementErrorCount ();
- Print (L"\nERROR: Physical Range must be 64K aligned and cannot be zero.");
- }
-}
-
-/**
- This function validates that the RMR memory range descriptor 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
-ValidateRmrMemDescCount (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- if (*(UINT32 *)Ptr == 0) {
- IncrementErrorCount ();
- Print (L"\nERROR: Memory Range Descriptor count must be >=1.");
- }
-}
-
-/**
- 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, (VOID**)&IortNodeRevision, NULL, NULL }, \
- { L"Identifier", 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"Global Interrupt Array Ref", 4, 40, L"0x%x", NULL, NULL, NULL,
- NULL },
- { L"Number of context interrupts", 4, 44, L"%d", NULL,
- (VOID **)&InterruptContextCount, NULL, NULL },
- { L"Context Interrupt Array Ref", 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"PMU Interrupt Array Ref", 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 },
- { L"Proximity domain", 4, 60, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Device ID mapping index", 4, 64, L"%d", 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 },
- { L"Memory access size limit",1, 32, L"0x%x", NULL, NULL, NULL, NULL },
- { L"PASID capabilities", 2, 33, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Reserved", 1, 35, L"%x", NULL, NULL, NULL, NULL },
- { L"Flags", 4, 36, 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 (ValidatePmcgIdMappingCount, NULL),
- { L"Page 0 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 },
- { L"Page 1 Base Address", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL }
-};
-
-/**
- An ACPI_PARSER array describing the IORT RMR node.
-**/
-STATIC CONST ACPI_PARSER IortNodeRmrParser[] = {
- PARSE_IORT_NODE_HEADER (NULL, NULL),
- { L"Flags", 4, 16, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Memory Range Desc count", 4, 20, L"%d", NULL,
- (VOID **)&RmrMemDescCount, ValidateRmrMemDescCount,NULL },
- { L"Memory Range Desc Ref", 4, 24, L"0x%x", NULL,
- (VOID **)&RmrMemDescOffset, NULL, NULL }
-};
-
-/**
- An ACPI_PARSER array describing the IORT RMR Memory Range Descriptor.
-**/
-STATIC CONST ACPI_PARSER IortNodeRmrMemRangeDescParser[] = {
- { L"Physical Range offset", 8, 0, L"0x%lx", NULL, NULL, ValidatePhysicalRange,
- NULL },
- { L"Physical Range length", 8, 8, L"0x%lx", NULL, NULL, ValidatePhysicalRange,
- NULL },
- { L"Reserved", 4, 16, L"0x%x", NULL, NULL, NULL, NULL}
-};
-
-/**
- This function parses the IORT Node Id Mapping array.
-
- @param [in] Ptr Pointer to the start of the ID mapping array.
- @param [in] Length Length of the buffer.
- @param [in] MappingCount The ID Mapping count.
-**/
-STATIC
-VOID
-DumpIortNodeIdMappings (
- IN UINT8 *Ptr,
- IN UINT32 Length,
- IN UINT32 MappingCount
- )
-{
- UINT32 Index;
- UINT32 Offset;
- CHAR8 Buffer[40]; // Used for AsciiName param of ParseAcpi
-
- Index = 0;
- Offset = 0;
-
- while ((Index < MappingCount) &&
- (Offset < Length))
- {
- AsciiSPrint (
- Buffer,
- sizeof (Buffer),
- "ID Mapping [%d]",
- Index
- );
- Offset += ParseAcpi (
- TRUE,
- 4,
- Buffer,
- Ptr + Offset,
- Length - Offset,
- PARSER_PARAMS (IortNodeIdMappingParser)
- );
- 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
-
- ParseAcpi (
- TRUE,
- 2,
- "SMMUv1 or SMMUv2 Node",
- Ptr,
- Length,
- PARSER_PARAMS (IortNodeSmmuV1V2Parser)
- );
-
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if ((InterruptContextCount == NULL) ||
- (InterruptContextOffset == NULL) ||
- (PmuInterruptCount == NULL) ||
- (PmuInterruptOffset == NULL))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient SMMUv1/2 node length. Length = %d\n",
- Length
- );
- return;
- }
-
- Offset = *InterruptContextOffset;
- Index = 0;
-
- while ((Index < *InterruptContextCount) &&
- (Offset < Length))
- {
- AsciiSPrint (
- Buffer,
- sizeof (Buffer),
- "Context Interrupts Array [%d]",
- Index
- );
- Offset += ParseAcpi (
- TRUE,
- 4,
- Buffer,
- Ptr + Offset,
- Length - Offset,
- PARSER_PARAMS (InterruptArrayParser)
- );
- Index++;
- }
-
- Offset = *PmuInterruptOffset;
- Index = 0;
-
- while ((Index < *PmuInterruptCount) &&
- (Offset < Length))
- {
- AsciiSPrint (
- Buffer,
- sizeof (Buffer),
- "PMU Interrupts Array [%d]",
- Index
- );
- Offset += ParseAcpi (
- TRUE,
- 4,
- Buffer,
- Ptr + Offset,
- Length - Offset,
- PARSER_PARAMS (InterruptArrayParser)
- );
- Index++;
- }
-
- DumpIortNodeIdMappings (
- Ptr + MappingOffset,
- Length - MappingOffset,
- MappingCount
- );
-}
-
-/**
- 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)
- );
-
- DumpIortNodeIdMappings (
- Ptr + MappingOffset,
- Length - MappingOffset,
- MappingCount
- );
-}
-
-/**
- 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;
- CHAR8 Buffer[80]; // Used for AsciiName param of ParseAcpi
-
- Offset = ParseAcpi (
- TRUE,
- 2,
- "ITS Node",
- Ptr,
- Length,
- PARSER_PARAMS (IortNodeItsParser)
- );
-
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if (ItsCount == NULL) {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient ITS group length. Length = %d.\n",
- Length
- );
- return;
- }
-
- Index = 0;
-
- while ((Index < *ItsCount) &&
- (Offset < Length))
- {
- AsciiSPrint (
- Buffer,
- sizeof (Buffer),
- "GIC ITS Identifier Array [%d]",
- Index
- );
- Offset += ParseAcpi (
- TRUE,
- 4,
- Buffer,
- Ptr + Offset,
- Length - Offset,
- PARSER_PARAMS (ItsIdParser)
- );
- 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;
-
- Offset = ParseAcpi (
- TRUE,
- 2,
- "Named Component Node",
- Ptr,
- Length,
- PARSER_PARAMS (IortNodeNamedComponentParser)
- );
-
- // Estimate the Device Name length
- PrintFieldName (2, L"Device Object Name");
-
- while ((*(Ptr + Offset) != 0) &&
- (Offset < Length))
- {
- Print (L"%c", *(Ptr + Offset));
- Offset++;
- }
-
- Print (L"\n");
-
- DumpIortNodeIdMappings (
- Ptr + MappingOffset,
- Length - MappingOffset,
- MappingCount
- );
-}
-
-/**
- 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)
- );
-
- DumpIortNodeIdMappings (
- Ptr + MappingOffset,
- Length - MappingOffset,
- MappingCount
- );
-}
-
-/**
- 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)
- );
-
- DumpIortNodeIdMappings (
- Ptr + MappingOffset,
- Length - MappingOffset,
- MappingCount
- );
-}
-
-/**
- This function parses the IORT RMR Node Memory Range Descriptor array.
-
- @param [in] Ptr Pointer to the start of the Memory Range Descriptor
- array.
- @param [in] Length Length of the buffer.
- @param [in] DescCount Memory Range Descriptor count.
-**/
-STATIC
-VOID
-DumpIortNodeRmrMemRangeDesc (
- IN UINT8 *Ptr,
- IN UINT32 Length,
- IN UINT32 DescCount
- )
-{
- UINT32 Index;
- UINT32 Offset;
- CHAR8 Buffer[40]; // Used for AsciiName param of ParseAcpi
-
- Index = 0;
- Offset = 0;
-
- while ((Index < DescCount) &&
- (Offset < Length))
- {
- AsciiSPrint (
- Buffer,
- sizeof (Buffer),
- "Mem range Descriptor [%d]",
- Index
- );
- Offset += ParseAcpi (
- TRUE,
- 4,
- Buffer,
- Ptr + Offset,
- Length - Offset,
- PARSER_PARAMS (IortNodeRmrMemRangeDescParser)
- );
- Index++;
- }
-}
-
-/**
- This function parses the IORT RMR 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
-DumpIortNodeRmr (
- IN UINT8 *Ptr,
- IN UINT16 Length,
- IN UINT32 MappingCount,
- IN UINT32 MappingOffset
- )
-{
- ParseAcpi (
- TRUE,
- 2,
- "RMR Node",
- Ptr,
- Length,
- PARSER_PARAMS (IortNodeRmrParser)
- );
-
- if (*IortNodeRevision == EFI_ACPI_IORT_RMR_NODE_REVISION_02) {
- IncrementErrorCount ();
- Print (
- L"ERROR: RMR node Rev 2 (defined in IORT Rev E.c) must not be used."
- L" IORT tabe Revision E.c is deprecated and must not be used.\n"
- );
- }
-
- DumpIortNodeIdMappings (
- Ptr + MappingOffset,
- Length - MappingOffset,
- MappingCount
- );
-
- DumpIortNodeRmrMemRangeDesc (
- Ptr + (*RmrMemDescOffset),
- Length - (*RmrMemDescOffset),
- *RmrMemDescCount
- );
-}
-
-/**
- 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
- - RMR
-
- 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;
- }
-
- if ((AcpiTableRevision > EFI_ACPI_IO_REMAPPING_TABLE_REVISION_00) &&
- (AcpiTableRevision < EFI_ACPI_IO_REMAPPING_TABLE_REVISION_05))
- {
- Print (
- L"ERROR: Parsing not supported for IORT tabe Revision E, E.<a,b,c>.\n"
- );
- if (AcpiTableRevision == EFI_ACPI_IO_REMAPPING_TABLE_REVISION_04) {
- IncrementErrorCount ();
- Print (
- L"ERROR: IORT tabe Revision E.c is deprecated and must not be used.\n"
- );
- }
-
- return;
- }
-
- ParseAcpi (
- TRUE,
- 0,
- "IORT",
- Ptr,
- AcpiTableLength,
- PARSER_PARAMS (IortParser)
- );
-
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if ((IortNodeCount == NULL) ||
- (IortNodeOffset == NULL))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient table length. AcpiTableLength = %d.\n",
- AcpiTableLength
- );
- return;
- }
-
- Offset = *IortNodeOffset;
- NodePtr = Ptr + Offset;
- Index = 0;
-
- // Parse the specified number of IORT nodes or the IORT table buffer length.
- // Whichever is minimum.
- while ((Index++ < *IortNodeCount) &&
- (Offset < AcpiTableLength))
- {
- // Parse the IORT Node Header
- ParseAcpi (
- FALSE,
- 0,
- "IORT Node Header",
- NodePtr,
- AcpiTableLength - Offset,
- PARSER_PARAMS (IortNodeHeaderParser)
- );
-
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if ((IortNodeType == NULL) ||
- (IortNodeLength == NULL) ||
- (IortIdMappingCount == NULL) ||
- (IortIdMappingOffset == NULL))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient remaining table buffer length to read the " \
- L"IORT node header. Length = %d.\n",
- AcpiTableLength - Offset
- );
- return;
- }
-
- // Validate IORT Node length
- if ((*IortNodeLength == 0) ||
- ((Offset + (*IortNodeLength)) > AcpiTableLength))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Invalid IORT Node length. " \
- L"Length = %d. Offset = %d. AcpiTableLength = %d.\n",
- *IortNodeLength,
- Offset,
- AcpiTableLength
- );
- return;
- }
-
- PrintFieldName (2, L"* Node Offset *");
- Print (L"0x%x\n", Offset);
-
- switch (*IortNodeType) {
- case EFI_ACPI_IORT_TYPE_ITS_GROUP:
- DumpIortNodeIts (
- NodePtr,
- *IortNodeLength
- );
- break;
- case EFI_ACPI_IORT_TYPE_NAMED_COMP:
- DumpIortNodeNamedComponent (
- NodePtr,
- *IortNodeLength,
- *IortIdMappingCount,
- *IortIdMappingOffset
- );
- break;
- case EFI_ACPI_IORT_TYPE_ROOT_COMPLEX:
- DumpIortNodeRootComplex (
- NodePtr,
- *IortNodeLength,
- *IortIdMappingCount,
- *IortIdMappingOffset
- );
- break;
- case EFI_ACPI_IORT_TYPE_SMMUv1v2:
- DumpIortNodeSmmuV1V2 (
- NodePtr,
- *IortNodeLength,
- *IortIdMappingCount,
- *IortIdMappingOffset
- );
- break;
- case EFI_ACPI_IORT_TYPE_SMMUv3:
- DumpIortNodeSmmuV3 (
- NodePtr,
- *IortNodeLength,
- *IortIdMappingCount,
- *IortIdMappingOffset
- );
- break;
- case EFI_ACPI_IORT_TYPE_PMCG:
- DumpIortNodePmcg (
- NodePtr,
- *IortNodeLength,
- *IortIdMappingCount,
- *IortIdMappingOffset
- );
- break;
- case EFI_ACPI_IORT_TYPE_RMR:
- DumpIortNodeRmr (
- NodePtr,
- *IortNodeLength,
- *IortIdMappingCount,
- *IortIdMappingOffset
- );
- break;
- default:
- IncrementErrorCount ();
- Print (L"ERROR: Unsupported IORT Node type = %d\n", *IortNodeType);
- } // switch
-
- NodePtr += (*IortNodeLength);
- Offset += (*IortNodeLength);
- } // while
-}
+/** @file + IORT table parser + + Copyright (c) 2016 - 2022, Arm Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - IO Remapping Table, Platform Design Document, Revision E.d, Feb 2022 + (https://developer.arm.com/documentation/den0049/) + + @par Glossary: + - Ref - Reference + - Desc - Descriptor +**/ + +#include <IndustryStandard/IoRemappingTable.h> +#include <Library/PrintLib.h> +#include <Library/UefiLib.h> +#include "AcpiParser.h" +#include "AcpiTableParser.h" +#include "AcpiViewConfig.h" + +// Local variables +STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; + +STATIC CONST UINT32 *IortNodeCount; +STATIC CONST UINT32 *IortNodeOffset; + +STATIC CONST UINT8 *IortNodeType; +STATIC CONST UINT16 *IortNodeLength; +STATIC CONST UINT8 *IortNodeRevision; +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; + +STATIC CONST UINT32 *RmrMemDescCount; +STATIC CONST UINT32 *RmrMemDescOffset; + +/** + 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 + ) +{ + if (*(UINT32 *)Ptr != 0) { + IncrementErrorCount (); + Print (L"\nERROR: IORT ID Mapping count must be zero."); + } +} + +/** + This function validates the ID Mapping array count for the Performance + Monitoring Counter Group (PMCG) 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 +ValidatePmcgIdMappingCount ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + if (*(UINT32 *)Ptr > 1) { + IncrementErrorCount (); + Print (L"\nERROR: IORT ID Mapping count must not be greater than 1."); + } +} + +/** + 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 validates that the Physical Range address or length is not zero + and is 64K aligned. + + @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 +ValidatePhysicalRange ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + UINT64 Value; + + Value = *(UINT64 *)Ptr; + if ((Value == 0) || ((Value & (SIZE_64KB - 1)) != 0)) { + IncrementErrorCount (); + Print (L"\nERROR: Physical Range must be 64K aligned and cannot be zero."); + } +} + +/** + This function validates that the RMR memory range descriptor 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 +ValidateRmrMemDescCount ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + if (*(UINT32 *)Ptr == 0) { + IncrementErrorCount (); + Print (L"\nERROR: Memory Range Descriptor count must be >=1."); + } +} + +/** + 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, (VOID**)&IortNodeRevision, NULL, NULL }, \ + { L"Identifier", 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"Global Interrupt Array Ref", 4, 40, L"0x%x", NULL, NULL, NULL, + NULL }, + { L"Number of context interrupts", 4, 44, L"%d", NULL, + (VOID **)&InterruptContextCount, NULL, NULL }, + { L"Context Interrupt Array Ref", 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"PMU Interrupt Array Ref", 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 }, + { L"Proximity domain", 4, 60, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Device ID mapping index", 4, 64, L"%d", 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 }, + { L"Memory access size limit",1, 32, L"0x%x", NULL, NULL, NULL, NULL }, + { L"PASID capabilities", 2, 33, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Reserved", 1, 35, L"%x", NULL, NULL, NULL, NULL }, + { L"Flags", 4, 36, 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 (ValidatePmcgIdMappingCount, NULL), + { L"Page 0 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 }, + { L"Page 1 Base Address", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL } +}; + +/** + An ACPI_PARSER array describing the IORT RMR node. +**/ +STATIC CONST ACPI_PARSER IortNodeRmrParser[] = { + PARSE_IORT_NODE_HEADER (NULL, NULL), + { L"Flags", 4, 16, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Memory Range Desc count", 4, 20, L"%d", NULL, + (VOID **)&RmrMemDescCount, ValidateRmrMemDescCount,NULL }, + { L"Memory Range Desc Ref", 4, 24, L"0x%x", NULL, + (VOID **)&RmrMemDescOffset, NULL, NULL } +}; + +/** + An ACPI_PARSER array describing the IORT RMR Memory Range Descriptor. +**/ +STATIC CONST ACPI_PARSER IortNodeRmrMemRangeDescParser[] = { + { L"Physical Range offset", 8, 0, L"0x%lx", NULL, NULL, ValidatePhysicalRange, + NULL }, + { L"Physical Range length", 8, 8, L"0x%lx", NULL, NULL, ValidatePhysicalRange, + NULL }, + { L"Reserved", 4, 16, L"0x%x", NULL, NULL, NULL, NULL} +}; + +/** + This function parses the IORT Node Id Mapping array. + + @param [in] Ptr Pointer to the start of the ID mapping array. + @param [in] Length Length of the buffer. + @param [in] MappingCount The ID Mapping count. +**/ +STATIC +VOID +DumpIortNodeIdMappings ( + IN UINT8 *Ptr, + IN UINT32 Length, + IN UINT32 MappingCount + ) +{ + UINT32 Index; + UINT32 Offset; + CHAR8 Buffer[40]; // Used for AsciiName param of ParseAcpi + + Index = 0; + Offset = 0; + + while ((Index < MappingCount) && + (Offset < Length)) + { + AsciiSPrint ( + Buffer, + sizeof (Buffer), + "ID Mapping [%d]", + Index + ); + Offset += ParseAcpi ( + TRUE, + 4, + Buffer, + Ptr + Offset, + Length - Offset, + PARSER_PARAMS (IortNodeIdMappingParser) + ); + 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 + + ParseAcpi ( + TRUE, + 2, + "SMMUv1 or SMMUv2 Node", + Ptr, + Length, + PARSER_PARAMS (IortNodeSmmuV1V2Parser) + ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if ((InterruptContextCount == NULL) || + (InterruptContextOffset == NULL) || + (PmuInterruptCount == NULL) || + (PmuInterruptOffset == NULL)) + { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient SMMUv1/2 node length. Length = %d\n", + Length + ); + return; + } + + Offset = *InterruptContextOffset; + Index = 0; + + while ((Index < *InterruptContextCount) && + (Offset < Length)) + { + AsciiSPrint ( + Buffer, + sizeof (Buffer), + "Context Interrupts Array [%d]", + Index + ); + Offset += ParseAcpi ( + TRUE, + 4, + Buffer, + Ptr + Offset, + Length - Offset, + PARSER_PARAMS (InterruptArrayParser) + ); + Index++; + } + + Offset = *PmuInterruptOffset; + Index = 0; + + while ((Index < *PmuInterruptCount) && + (Offset < Length)) + { + AsciiSPrint ( + Buffer, + sizeof (Buffer), + "PMU Interrupts Array [%d]", + Index + ); + Offset += ParseAcpi ( + TRUE, + 4, + Buffer, + Ptr + Offset, + Length - Offset, + PARSER_PARAMS (InterruptArrayParser) + ); + Index++; + } + + DumpIortNodeIdMappings ( + Ptr + MappingOffset, + Length - MappingOffset, + MappingCount + ); +} + +/** + 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) + ); + + DumpIortNodeIdMappings ( + Ptr + MappingOffset, + Length - MappingOffset, + MappingCount + ); +} + +/** + 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; + CHAR8 Buffer[80]; // Used for AsciiName param of ParseAcpi + + Offset = ParseAcpi ( + TRUE, + 2, + "ITS Node", + Ptr, + Length, + PARSER_PARAMS (IortNodeItsParser) + ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if (ItsCount == NULL) { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient ITS group length. Length = %d.\n", + Length + ); + return; + } + + Index = 0; + + while ((Index < *ItsCount) && + (Offset < Length)) + { + AsciiSPrint ( + Buffer, + sizeof (Buffer), + "GIC ITS Identifier Array [%d]", + Index + ); + Offset += ParseAcpi ( + TRUE, + 4, + Buffer, + Ptr + Offset, + Length - Offset, + PARSER_PARAMS (ItsIdParser) + ); + 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; + + Offset = ParseAcpi ( + TRUE, + 2, + "Named Component Node", + Ptr, + Length, + PARSER_PARAMS (IortNodeNamedComponentParser) + ); + + // Estimate the Device Name length + PrintFieldName (2, L"Device Object Name"); + + while ((*(Ptr + Offset) != 0) && + (Offset < Length)) + { + Print (L"%c", *(Ptr + Offset)); + Offset++; + } + + Print (L"\n"); + + DumpIortNodeIdMappings ( + Ptr + MappingOffset, + Length - MappingOffset, + MappingCount + ); +} + +/** + 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) + ); + + DumpIortNodeIdMappings ( + Ptr + MappingOffset, + Length - MappingOffset, + MappingCount + ); +} + +/** + 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) + ); + + DumpIortNodeIdMappings ( + Ptr + MappingOffset, + Length - MappingOffset, + MappingCount + ); +} + +/** + This function parses the IORT RMR Node Memory Range Descriptor array. + + @param [in] Ptr Pointer to the start of the Memory Range Descriptor + array. + @param [in] Length Length of the buffer. + @param [in] DescCount Memory Range Descriptor count. +**/ +STATIC +VOID +DumpIortNodeRmrMemRangeDesc ( + IN UINT8 *Ptr, + IN UINT32 Length, + IN UINT32 DescCount + ) +{ + UINT32 Index; + UINT32 Offset; + CHAR8 Buffer[40]; // Used for AsciiName param of ParseAcpi + + Index = 0; + Offset = 0; + + while ((Index < DescCount) && + (Offset < Length)) + { + AsciiSPrint ( + Buffer, + sizeof (Buffer), + "Mem range Descriptor [%d]", + Index + ); + Offset += ParseAcpi ( + TRUE, + 4, + Buffer, + Ptr + Offset, + Length - Offset, + PARSER_PARAMS (IortNodeRmrMemRangeDescParser) + ); + Index++; + } +} + +/** + This function parses the IORT RMR 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 +DumpIortNodeRmr ( + IN UINT8 *Ptr, + IN UINT16 Length, + IN UINT32 MappingCount, + IN UINT32 MappingOffset + ) +{ + ParseAcpi ( + TRUE, + 2, + "RMR Node", + Ptr, + Length, + PARSER_PARAMS (IortNodeRmrParser) + ); + + if (*IortNodeRevision == EFI_ACPI_IORT_RMR_NODE_REVISION_02) { + IncrementErrorCount (); + Print ( + L"ERROR: RMR node Rev 2 (defined in IORT Rev E.c) must not be used." + L" IORT tabe Revision E.c is deprecated and must not be used.\n" + ); + } + + DumpIortNodeIdMappings ( + Ptr + MappingOffset, + Length - MappingOffset, + MappingCount + ); + + DumpIortNodeRmrMemRangeDesc ( + Ptr + (*RmrMemDescOffset), + Length - (*RmrMemDescOffset), + *RmrMemDescCount + ); +} + +/** + 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 + - RMR + + 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; + } + + if ((AcpiTableRevision > EFI_ACPI_IO_REMAPPING_TABLE_REVISION_00) && + (AcpiTableRevision < EFI_ACPI_IO_REMAPPING_TABLE_REVISION_05)) + { + Print ( + L"ERROR: Parsing not supported for IORT tabe Revision E, E.<a,b,c>.\n" + ); + if (AcpiTableRevision == EFI_ACPI_IO_REMAPPING_TABLE_REVISION_04) { + IncrementErrorCount (); + Print ( + L"ERROR: IORT tabe Revision E.c is deprecated and must not be used.\n" + ); + } + + return; + } + + ParseAcpi ( + TRUE, + 0, + "IORT", + Ptr, + AcpiTableLength, + PARSER_PARAMS (IortParser) + ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if ((IortNodeCount == NULL) || + (IortNodeOffset == NULL)) + { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient table length. AcpiTableLength = %d.\n", + AcpiTableLength + ); + return; + } + + Offset = *IortNodeOffset; + NodePtr = Ptr + Offset; + Index = 0; + + // Parse the specified number of IORT nodes or the IORT table buffer length. + // Whichever is minimum. + while ((Index++ < *IortNodeCount) && + (Offset < AcpiTableLength)) + { + // Parse the IORT Node Header + ParseAcpi ( + FALSE, + 0, + "IORT Node Header", + NodePtr, + AcpiTableLength - Offset, + PARSER_PARAMS (IortNodeHeaderParser) + ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if ((IortNodeType == NULL) || + (IortNodeLength == NULL) || + (IortIdMappingCount == NULL) || + (IortIdMappingOffset == NULL)) + { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient remaining table buffer length to read the " \ + L"IORT node header. Length = %d.\n", + AcpiTableLength - Offset + ); + return; + } + + // Validate IORT Node length + if ((*IortNodeLength == 0) || + ((Offset + (*IortNodeLength)) > AcpiTableLength)) + { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid IORT Node length. " \ + L"Length = %d. Offset = %d. AcpiTableLength = %d.\n", + *IortNodeLength, + Offset, + AcpiTableLength + ); + return; + } + + PrintFieldName (2, L"* Node Offset *"); + Print (L"0x%x\n", Offset); + + switch (*IortNodeType) { + case EFI_ACPI_IORT_TYPE_ITS_GROUP: + DumpIortNodeIts ( + NodePtr, + *IortNodeLength + ); + break; + case EFI_ACPI_IORT_TYPE_NAMED_COMP: + DumpIortNodeNamedComponent ( + NodePtr, + *IortNodeLength, + *IortIdMappingCount, + *IortIdMappingOffset + ); + break; + case EFI_ACPI_IORT_TYPE_ROOT_COMPLEX: + DumpIortNodeRootComplex ( + NodePtr, + *IortNodeLength, + *IortIdMappingCount, + *IortIdMappingOffset + ); + break; + case EFI_ACPI_IORT_TYPE_SMMUv1v2: + DumpIortNodeSmmuV1V2 ( + NodePtr, + *IortNodeLength, + *IortIdMappingCount, + *IortIdMappingOffset + ); + break; + case EFI_ACPI_IORT_TYPE_SMMUv3: + DumpIortNodeSmmuV3 ( + NodePtr, + *IortNodeLength, + *IortIdMappingCount, + *IortIdMappingOffset + ); + break; + case EFI_ACPI_IORT_TYPE_PMCG: + DumpIortNodePmcg ( + NodePtr, + *IortNodeLength, + *IortIdMappingCount, + *IortIdMappingOffset + ); + break; + case EFI_ACPI_IORT_TYPE_RMR: + DumpIortNodeRmr ( + 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 index 3a4f246347..5f7b7e764e 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.c @@ -1,590 +1,590 @@ -/** @file
- MADT table parser
-
- Copyright (c) 2016 - 2023, ARM Limited. All rights reserved.
- Copyright (c) 2022, AMD Incorporated. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Reference(s):
- - ACPI 6.3 Specification - January 2019
- - Arm Generic Interrupt Controller Architecture Specification,
- GIC architecture version 3 and version 4, issue E
- - Arm Server Base System Architecture 5.0
-**/
-
-#include <IndustryStandard/Acpi.h>
-#include <Library/UefiLib.h>
-#include "AcpiParser.h"
-#include "AcpiTableParser.h"
-#include "AcpiViewConfig.h"
-#include "MadtParser.h"
-
-// Local Variables
-STATIC CONST UINT8 *MadtInterruptControllerType;
-STATIC CONST UINT8 *MadtInterruptControllerLength;
-STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
-
-/**
- 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 validates the SPE Overflow Interrupt in the GICC.
-
- @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
-ValidateSpeOverflowInterrupt (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- UINT16 SpeOverflowInterrupt;
-
- SpeOverflowInterrupt = *(UINT16 *)Ptr;
-
- // SPE not supported by this processor
- if (SpeOverflowInterrupt == 0) {
- return;
- }
-
- if ((SpeOverflowInterrupt < ARM_PPI_ID_MIN) ||
- ((SpeOverflowInterrupt > ARM_PPI_ID_MAX) &&
- (SpeOverflowInterrupt < ARM_PPI_ID_EXTENDED_MIN)) ||
- (SpeOverflowInterrupt > ARM_PPI_ID_EXTENDED_MAX))
- {
- IncrementErrorCount ();
- Print (
- L"\nERROR: SPE Overflow Interrupt ID of %d is not in the allowed PPI ID "
- L"ranges of %d-%d or %d-%d (for GICv3.1 or later).",
- SpeOverflowInterrupt,
- ARM_PPI_ID_MIN,
- ARM_PPI_ID_MAX,
- ARM_PPI_ID_EXTENDED_MIN,
- ARM_PPI_ID_EXTENDED_MAX
- );
- } else if (SpeOverflowInterrupt != ARM_PPI_ID_PMBIRQ) {
- IncrementWarningCount ();
- Print (
- L"\nWARNING: SPE Overflow Interrupt ID of %d is not compliant with SBSA "
- L"Level 3 PPI ID assignment: %d.",
- SpeOverflowInterrupt,
- ARM_PPI_ID_PMBIRQ
- );
- }
-}
-
-/**
- This function validates the TRBE Interrupt in the GICC.
-
- @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
-ValidateTrbeInterrupt (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- UINT16 TrbeInterrupt;
-
- TrbeInterrupt = *(UINT16 *)Ptr;
-
- // SPE not supported by this processor
- if (TrbeInterrupt == 0) {
- return;
- }
-
- if ((TrbeInterrupt < ARM_PPI_ID_MIN) ||
- ((TrbeInterrupt > ARM_PPI_ID_MAX) &&
- (TrbeInterrupt < ARM_PPI_ID_EXTENDED_MIN)) ||
- (TrbeInterrupt > ARM_PPI_ID_EXTENDED_MAX))
- {
- IncrementErrorCount ();
- Print (
- L"\nERROR: TRBE Interrupt ID of %d is not in the allowed PPI ID "
- L"ranges of %d-%d or %d-%d (for GICv3.1 or later).",
- TrbeInterrupt,
- ARM_PPI_ID_MIN,
- ARM_PPI_ID_MAX,
- ARM_PPI_ID_EXTENDED_MIN,
- ARM_PPI_ID_EXTENDED_MAX
- );
- }
-}
-
-/**
- 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", 1, 77, L"0x%x", NULL, NULL, NULL, NULL },
- { L"SPE overflow Interrupt", 2, 78, L"0x%x", NULL, NULL,
- ValidateSpeOverflowInterrupt, NULL },
- { L"TRBE Interrupt", 2, 80, L"0x%x", NULL, NULL,
- ValidateTrbeInterrupt, 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 IO APIC Structure.
-**/
-STATIC CONST ACPI_PARSER IoApic[] = {
- { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },
- { L"I/O APIC ID", 1, 2, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Reserved", 1, 3, L"0x%x", NULL, NULL, NULL, NULL },
- { L"I/O APIC Address", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Global System Interrupt Base", 4, 8, L"0x%x", NULL, NULL, NULL, NULL }
-};
-
-/**
- An ACPI_PARSER array describing the Interrupt Source Override Structure.
-**/
-STATIC CONST ACPI_PARSER InterruptSourceOverride[] = {
- { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },
- { L"Bus", 1, 2, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Source", 1, 3, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Global System Interrupt", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Flags", 2, 8, L"0x%x", NULL, NULL, NULL, NULL }
-};
-
-STATIC CONST ACPI_PARSER LocalApicFlags[] = {
- { L"Enabled", 1, 0, L"%d", NULL, NULL, NULL, NULL },
- { L"Online Capable", 1, 1, L"%d", NULL, NULL, NULL, NULL },
- { L"Reserved", 30, 2, L"%d", NULL, NULL, NULL, NULL }
-};
-
-/**
- This function traces Bit Flags fields.
- 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
-DumpLocalApicBitFlags (
- IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
- )
-{
- if (Format != NULL) {
- Print (Format, *(UINT32 *)Ptr);
- return;
- }
-
- Print (L"0x%X\n", *(UINT32 *)Ptr);
- ParseAcpiBitFields (
- TRUE,
- 2,
- NULL,
- Ptr,
- 4,
- PARSER_PARAMS (LocalApicFlags)
- );
-}
-
-/**
- An ACPI_PARSER array describing the Processor Local APIC Structure.
- **/
-STATIC CONST ACPI_PARSER ProcessorLocalApic[] = {
- { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },
-
- { L"ACPI Processor UID", 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, NULL, DumpLocalApicBitFlags, NULL, NULL, NULL }
-};
-
-/**
- An ACPI_PARSER array describing the Processor Local x2APIC Structure.
-**/
-STATIC CONST ACPI_PARSER ProcessorLocalX2Apic[] = {
- { 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"X2APIC ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Flags", 4, 8, NULL, DumpLocalApicBitFlags, NULL, NULL, NULL },
- { L"ACPI Processor UID", 4, 12, L"0x%x", NULL, NULL, NULL, NULL }
-};
-
-/**
- An ACPI_PARSER array describing the Local x2APIC NMI Structure.
-**/
-STATIC CONST ACPI_PARSER LocalX2ApicNmi[] = {
- { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL },
- { L"Flags", 2, 2, L"0x%x", NULL, NULL, NULL, NULL },
-
- { L"ACPI Processor UID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Local x2APIC LINT#", 1, 8, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Reserved", 3, 9, L"0x%x%x%x", Dump3Chars, 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 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;
-
- 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,
- AcpiTableLength - Offset,
- PARSER_PARAMS (MadtInterruptControllerHeaderParser)
- );
-
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if ((MadtInterruptControllerType == NULL) ||
- (MadtInterruptControllerLength == NULL))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient remaining table buffer length to read the " \
- L"Interrupt Controller Structure header. Length = %d.\n",
- AcpiTableLength - Offset
- );
- return;
- }
-
- // Validate Interrupt Controller Structure length
- if ((*MadtInterruptControllerLength == 0) ||
- ((Offset + (*MadtInterruptControllerLength)) > AcpiTableLength))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Invalid Interrupt Controller Structure length. " \
- L"Length = %d. Offset = %d. AcpiTableLength = %d.\n",
- *MadtInterruptControllerLength,
- Offset,
- AcpiTableLength
- );
- return;
- }
-
- switch (*MadtInterruptControllerType) {
- case EFI_ACPI_6_3_GIC:
- {
- ParseAcpi (
- TRUE,
- 2,
- "GICC",
- InterruptContollerPtr,
- *MadtInterruptControllerLength,
- PARSER_PARAMS (GicCParser)
- );
- break;
- }
-
- case EFI_ACPI_6_3_GICD:
- {
- if (++GICDCount > 1) {
- IncrementErrorCount ();
- Print (
- L"ERROR: Only one GICD must be present,"
- L" GICDCount = %d\n",
- GICDCount
- );
- }
-
- ParseAcpi (
- TRUE,
- 2,
- "GICD",
- InterruptContollerPtr,
- *MadtInterruptControllerLength,
- PARSER_PARAMS (GicDParser)
- );
- break;
- }
-
- case EFI_ACPI_6_3_GIC_MSI_FRAME:
- {
- ParseAcpi (
- TRUE,
- 2,
- "GIC MSI Frame",
- InterruptContollerPtr,
- *MadtInterruptControllerLength,
- PARSER_PARAMS (GicMSIFrameParser)
- );
- break;
- }
-
- case EFI_ACPI_6_3_GICR:
- {
- ParseAcpi (
- TRUE,
- 2,
- "GICR",
- InterruptContollerPtr,
- *MadtInterruptControllerLength,
- PARSER_PARAMS (GicRParser)
- );
- break;
- }
-
- case EFI_ACPI_6_3_GIC_ITS:
- {
- ParseAcpi (
- TRUE,
- 2,
- "GIC ITS",
- InterruptContollerPtr,
- *MadtInterruptControllerLength,
- PARSER_PARAMS (GicITSParser)
- );
- break;
- }
-
- case EFI_ACPI_6_3_IO_APIC:
- {
- ParseAcpi (
- TRUE,
- 2,
- "IO APIC",
- InterruptContollerPtr,
- *MadtInterruptControllerLength,
- PARSER_PARAMS (IoApic)
- );
- break;
- }
-
- case EFI_ACPI_6_3_INTERRUPT_SOURCE_OVERRIDE:
- {
- ParseAcpi (
- TRUE,
- 2,
- "INTERRUPT SOURCE OVERRIDE",
- InterruptContollerPtr,
- *MadtInterruptControllerLength,
- PARSER_PARAMS (InterruptSourceOverride)
- );
- break;
- }
- case EFI_ACPI_6_3_PROCESSOR_LOCAL_APIC:
- {
- ParseAcpi (
- TRUE,
- 2,
- "PROCESSOR LOCAL APIC",
- InterruptContollerPtr,
- *MadtInterruptControllerLength,
- PARSER_PARAMS (ProcessorLocalApic)
- );
- break;
- }
- case EFI_ACPI_6_3_PROCESSOR_LOCAL_X2APIC:
- {
- ParseAcpi (
- TRUE,
- 2,
- "PROCESSOR LOCAL X2APIC",
- InterruptContollerPtr,
- *MadtInterruptControllerLength,
- PARSER_PARAMS (ProcessorLocalX2Apic)
- );
- break;
- }
-
- case EFI_ACPI_6_3_LOCAL_X2APIC_NMI:
- {
- ParseAcpi (
- TRUE,
- 2,
- "LOCAL x2APIC NMI",
- InterruptContollerPtr,
- *MadtInterruptControllerLength,
- PARSER_PARAMS (LocalX2ApicNmi)
- );
- break;
- }
-
- default:
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Unknown Interrupt Controller Structure,"
- L" Type = %d, Length = %d\n",
- *MadtInterruptControllerType,
- *MadtInterruptControllerLength
- );
- }
- } // switch
-
- InterruptContollerPtr += *MadtInterruptControllerLength;
- Offset += *MadtInterruptControllerLength;
- } // while
-}
+/** @file + MADT table parser + + Copyright (c) 2016 - 2023, ARM Limited. All rights reserved. + Copyright (c) 2022, AMD Incorporated. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.3 Specification - January 2019 + - Arm Generic Interrupt Controller Architecture Specification, + GIC architecture version 3 and version 4, issue E + - Arm Server Base System Architecture 5.0 +**/ + +#include <IndustryStandard/Acpi.h> +#include <Library/UefiLib.h> +#include "AcpiParser.h" +#include "AcpiTableParser.h" +#include "AcpiViewConfig.h" +#include "MadtParser.h" + +// Local Variables +STATIC CONST UINT8 *MadtInterruptControllerType; +STATIC CONST UINT8 *MadtInterruptControllerLength; +STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; + +/** + 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 validates the SPE Overflow Interrupt in the GICC. + + @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 +ValidateSpeOverflowInterrupt ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + UINT16 SpeOverflowInterrupt; + + SpeOverflowInterrupt = *(UINT16 *)Ptr; + + // SPE not supported by this processor + if (SpeOverflowInterrupt == 0) { + return; + } + + if ((SpeOverflowInterrupt < ARM_PPI_ID_MIN) || + ((SpeOverflowInterrupt > ARM_PPI_ID_MAX) && + (SpeOverflowInterrupt < ARM_PPI_ID_EXTENDED_MIN)) || + (SpeOverflowInterrupt > ARM_PPI_ID_EXTENDED_MAX)) + { + IncrementErrorCount (); + Print ( + L"\nERROR: SPE Overflow Interrupt ID of %d is not in the allowed PPI ID " + L"ranges of %d-%d or %d-%d (for GICv3.1 or later).", + SpeOverflowInterrupt, + ARM_PPI_ID_MIN, + ARM_PPI_ID_MAX, + ARM_PPI_ID_EXTENDED_MIN, + ARM_PPI_ID_EXTENDED_MAX + ); + } else if (SpeOverflowInterrupt != ARM_PPI_ID_PMBIRQ) { + IncrementWarningCount (); + Print ( + L"\nWARNING: SPE Overflow Interrupt ID of %d is not compliant with SBSA " + L"Level 3 PPI ID assignment: %d.", + SpeOverflowInterrupt, + ARM_PPI_ID_PMBIRQ + ); + } +} + +/** + This function validates the TRBE Interrupt in the GICC. + + @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 +ValidateTrbeInterrupt ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + UINT16 TrbeInterrupt; + + TrbeInterrupt = *(UINT16 *)Ptr; + + // SPE not supported by this processor + if (TrbeInterrupt == 0) { + return; + } + + if ((TrbeInterrupt < ARM_PPI_ID_MIN) || + ((TrbeInterrupt > ARM_PPI_ID_MAX) && + (TrbeInterrupt < ARM_PPI_ID_EXTENDED_MIN)) || + (TrbeInterrupt > ARM_PPI_ID_EXTENDED_MAX)) + { + IncrementErrorCount (); + Print ( + L"\nERROR: TRBE Interrupt ID of %d is not in the allowed PPI ID " + L"ranges of %d-%d or %d-%d (for GICv3.1 or later).", + TrbeInterrupt, + ARM_PPI_ID_MIN, + ARM_PPI_ID_MAX, + ARM_PPI_ID_EXTENDED_MIN, + ARM_PPI_ID_EXTENDED_MAX + ); + } +} + +/** + 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", 1, 77, L"0x%x", NULL, NULL, NULL, NULL }, + { L"SPE overflow Interrupt", 2, 78, L"0x%x", NULL, NULL, + ValidateSpeOverflowInterrupt, NULL }, + { L"TRBE Interrupt", 2, 80, L"0x%x", NULL, NULL, + ValidateTrbeInterrupt, 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 IO APIC Structure. +**/ +STATIC CONST ACPI_PARSER IoApic[] = { + { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL }, + { L"I/O APIC ID", 1, 2, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Reserved", 1, 3, L"0x%x", NULL, NULL, NULL, NULL }, + { L"I/O APIC Address", 4, 4, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Global System Interrupt Base", 4, 8, L"0x%x", NULL, NULL, NULL, NULL } +}; + +/** + An ACPI_PARSER array describing the Interrupt Source Override Structure. +**/ +STATIC CONST ACPI_PARSER InterruptSourceOverride[] = { + { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL }, + { L"Bus", 1, 2, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Source", 1, 3, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Global System Interrupt", 4, 4, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Flags", 2, 8, L"0x%x", NULL, NULL, NULL, NULL } +}; + +STATIC CONST ACPI_PARSER LocalApicFlags[] = { + { L"Enabled", 1, 0, L"%d", NULL, NULL, NULL, NULL }, + { L"Online Capable", 1, 1, L"%d", NULL, NULL, NULL, NULL }, + { L"Reserved", 30, 2, L"%d", NULL, NULL, NULL, NULL } +}; + +/** + This function traces Bit Flags fields. + 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 +DumpLocalApicBitFlags ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + if (Format != NULL) { + Print (Format, *(UINT32 *)Ptr); + return; + } + + Print (L"0x%X\n", *(UINT32 *)Ptr); + ParseAcpiBitFields ( + TRUE, + 2, + NULL, + Ptr, + 4, + PARSER_PARAMS (LocalApicFlags) + ); +} + +/** + An ACPI_PARSER array describing the Processor Local APIC Structure. + **/ +STATIC CONST ACPI_PARSER ProcessorLocalApic[] = { + { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL }, + + { L"ACPI Processor UID", 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, NULL, DumpLocalApicBitFlags, NULL, NULL, NULL } +}; + +/** + An ACPI_PARSER array describing the Processor Local x2APIC Structure. +**/ +STATIC CONST ACPI_PARSER ProcessorLocalX2Apic[] = { + { 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"X2APIC ID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Flags", 4, 8, NULL, DumpLocalApicBitFlags, NULL, NULL, NULL }, + { L"ACPI Processor UID", 4, 12, L"0x%x", NULL, NULL, NULL, NULL } +}; + +/** + An ACPI_PARSER array describing the Local x2APIC NMI Structure. +**/ +STATIC CONST ACPI_PARSER LocalX2ApicNmi[] = { + { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Length", 1, 1, L"%d", NULL, NULL, NULL, NULL }, + { L"Flags", 2, 2, L"0x%x", NULL, NULL, NULL, NULL }, + + { L"ACPI Processor UID", 4, 4, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Local x2APIC LINT#", 1, 8, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Reserved", 3, 9, L"0x%x%x%x", Dump3Chars, 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 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; + + 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, + AcpiTableLength - Offset, + PARSER_PARAMS (MadtInterruptControllerHeaderParser) + ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if ((MadtInterruptControllerType == NULL) || + (MadtInterruptControllerLength == NULL)) + { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient remaining table buffer length to read the " \ + L"Interrupt Controller Structure header. Length = %d.\n", + AcpiTableLength - Offset + ); + return; + } + + // Validate Interrupt Controller Structure length + if ((*MadtInterruptControllerLength == 0) || + ((Offset + (*MadtInterruptControllerLength)) > AcpiTableLength)) + { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid Interrupt Controller Structure length. " \ + L"Length = %d. Offset = %d. AcpiTableLength = %d.\n", + *MadtInterruptControllerLength, + Offset, + AcpiTableLength + ); + return; + } + + switch (*MadtInterruptControllerType) { + case EFI_ACPI_6_3_GIC: + { + ParseAcpi ( + TRUE, + 2, + "GICC", + InterruptContollerPtr, + *MadtInterruptControllerLength, + PARSER_PARAMS (GicCParser) + ); + break; + } + + case EFI_ACPI_6_3_GICD: + { + if (++GICDCount > 1) { + IncrementErrorCount (); + Print ( + L"ERROR: Only one GICD must be present," + L" GICDCount = %d\n", + GICDCount + ); + } + + ParseAcpi ( + TRUE, + 2, + "GICD", + InterruptContollerPtr, + *MadtInterruptControllerLength, + PARSER_PARAMS (GicDParser) + ); + break; + } + + case EFI_ACPI_6_3_GIC_MSI_FRAME: + { + ParseAcpi ( + TRUE, + 2, + "GIC MSI Frame", + InterruptContollerPtr, + *MadtInterruptControllerLength, + PARSER_PARAMS (GicMSIFrameParser) + ); + break; + } + + case EFI_ACPI_6_3_GICR: + { + ParseAcpi ( + TRUE, + 2, + "GICR", + InterruptContollerPtr, + *MadtInterruptControllerLength, + PARSER_PARAMS (GicRParser) + ); + break; + } + + case EFI_ACPI_6_3_GIC_ITS: + { + ParseAcpi ( + TRUE, + 2, + "GIC ITS", + InterruptContollerPtr, + *MadtInterruptControllerLength, + PARSER_PARAMS (GicITSParser) + ); + break; + } + + case EFI_ACPI_6_3_IO_APIC: + { + ParseAcpi ( + TRUE, + 2, + "IO APIC", + InterruptContollerPtr, + *MadtInterruptControllerLength, + PARSER_PARAMS (IoApic) + ); + break; + } + + case EFI_ACPI_6_3_INTERRUPT_SOURCE_OVERRIDE: + { + ParseAcpi ( + TRUE, + 2, + "INTERRUPT SOURCE OVERRIDE", + InterruptContollerPtr, + *MadtInterruptControllerLength, + PARSER_PARAMS (InterruptSourceOverride) + ); + break; + } + case EFI_ACPI_6_3_PROCESSOR_LOCAL_APIC: + { + ParseAcpi ( + TRUE, + 2, + "PROCESSOR LOCAL APIC", + InterruptContollerPtr, + *MadtInterruptControllerLength, + PARSER_PARAMS (ProcessorLocalApic) + ); + break; + } + case EFI_ACPI_6_3_PROCESSOR_LOCAL_X2APIC: + { + ParseAcpi ( + TRUE, + 2, + "PROCESSOR LOCAL X2APIC", + InterruptContollerPtr, + *MadtInterruptControllerLength, + PARSER_PARAMS (ProcessorLocalX2Apic) + ); + break; + } + + case EFI_ACPI_6_3_LOCAL_X2APIC_NMI: + { + ParseAcpi ( + TRUE, + 2, + "LOCAL x2APIC NMI", + InterruptContollerPtr, + *MadtInterruptControllerLength, + PARSER_PARAMS (LocalX2ApicNmi) + ); + break; + } + + default: + { + IncrementErrorCount (); + Print ( + L"ERROR: Unknown Interrupt Controller Structure," + L" Type = %d, Length = %d\n", + *MadtInterruptControllerType, + *MadtInterruptControllerLength + ); + } + } // switch + + InterruptContollerPtr += *MadtInterruptControllerLength; + Offset += *MadtInterruptControllerLength; + } // while +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.h index 33ed85821b..f6857d65c7 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.h +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Madt/MadtParser.h @@ -1,40 +1,40 @@ -/** @file
- Header file for MADT table parser
-
- Copyright (c) 2019, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Reference(s):
- - Arm Generic Interrupt Controller Architecture Specification,
- GIC architecture version 3 and version 4, issue E
- - Arm Server Base System Architecture 5.0
-**/
-
-#ifndef MADT_PARSER_H_
-#define MADT_PARSER_H_
-
-///
-/// Level 3 base server system Private Peripheral Inerrupt (PPI) ID assignments
-///
-#define ARM_PPI_ID_OVERFLOW_INTERRUPT_FROM_CNTP 30
-#define ARM_PPI_ID_OVERFLOW_INTERRUPT_FROM_CNTPS 29
-#define ARM_PPI_ID_OVERFLOW_INTERRUPT_FROM_CNTHV 28
-#define ARM_PPI_ID_OVERFLOW_INTERRUPT_FROM_CNTV 27
-#define ARM_PPI_ID_OVERFLOW_INTERRUPT_FROM_CNTHP 26
-#define ARM_PPI_ID_GIC_MAINTENANCE_INTERRUPT 25
-#define ARM_PPI_ID_CTIIRQ 24
-#define ARM_PPI_ID_PERFORMANCE_MONITORS_INTERRUPT 23
-#define ARM_PPI_ID_COMMIRQ 22
-#define ARM_PPI_ID_PMBIRQ 21
-#define ARM_PPI_ID_CNTHPS 20
-#define ARM_PPI_ID_CNTHVS 19
-
-///
-/// PPI ID allowed ranges
-///
-#define ARM_PPI_ID_MAX 31
-#define ARM_PPI_ID_MIN 16
-#define ARM_PPI_ID_EXTENDED_MAX 1119
-#define ARM_PPI_ID_EXTENDED_MIN 1056
-
-#endif // MADT_PARSER_H_
+/** @file + Header file for MADT table parser + + Copyright (c) 2019, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - Arm Generic Interrupt Controller Architecture Specification, + GIC architecture version 3 and version 4, issue E + - Arm Server Base System Architecture 5.0 +**/ + +#ifndef MADT_PARSER_H_ +#define MADT_PARSER_H_ + +/// +/// Level 3 base server system Private Peripheral Inerrupt (PPI) ID assignments +/// +#define ARM_PPI_ID_OVERFLOW_INTERRUPT_FROM_CNTP 30 +#define ARM_PPI_ID_OVERFLOW_INTERRUPT_FROM_CNTPS 29 +#define ARM_PPI_ID_OVERFLOW_INTERRUPT_FROM_CNTHV 28 +#define ARM_PPI_ID_OVERFLOW_INTERRUPT_FROM_CNTV 27 +#define ARM_PPI_ID_OVERFLOW_INTERRUPT_FROM_CNTHP 26 +#define ARM_PPI_ID_GIC_MAINTENANCE_INTERRUPT 25 +#define ARM_PPI_ID_CTIIRQ 24 +#define ARM_PPI_ID_PERFORMANCE_MONITORS_INTERRUPT 23 +#define ARM_PPI_ID_COMMIRQ 22 +#define ARM_PPI_ID_PMBIRQ 21 +#define ARM_PPI_ID_CNTHPS 20 +#define ARM_PPI_ID_CNTHVS 19 + +/// +/// PPI ID allowed ranges +/// +#define ARM_PPI_ID_MAX 31 +#define ARM_PPI_ID_MIN 16 +#define ARM_PPI_ID_EXTENDED_MAX 1119 +#define ARM_PPI_ID_EXTENDED_MIN 1056 + +#endif // MADT_PARSER_H_ diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Mcfg/McfgParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Mcfg/McfgParser.c index 16e99c25de..151a1069b7 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Mcfg/McfgParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Mcfg/McfgParser.c @@ -1,90 +1,90 @@ -/** @file
- MCFG table parser
-
- Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Reference(s):
- - PCI Firmware Specification - Revision 3.2, January 26, 2015.
-**/
-
-#include <IndustryStandard/Acpi.h>
-#include <Library/UefiLib.h>
-#include "AcpiParser.h"
-#include "AcpiTableParser.h"
-
-// Local variables
-STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
-
-/**
- An ACPI_PARSER array describing the ACPI MCFG Table.
-**/
-STATIC CONST ACPI_PARSER McfgParser[] = {
- PARSE_ACPI_HEADER (&AcpiHdrInfo),
- { L"Reserved", 8,36, L"0x%lx", NULL, NULL, NULL, NULL },
-};
-
-/**
- An ACPI_PARSER array describing the PCI configuration Space Base Address structure.
-**/
-STATIC CONST ACPI_PARSER PciCfgSpaceBaseAddrParser[] = {
- { L"Base Address", 8, 0, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"PCI Segment Group No.", 2, 8, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Start Bus No.", 1, 10, L"0x%x", NULL, NULL, NULL, NULL },
- { L"End Bus No.", 1, 11, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Reserved", 4, 12, L"0x%x", NULL, NULL, NULL, NULL }
-};
-
-/**
- This function parses the ACPI MCFG table.
- When trace is enabled this function parses the MCFG table and
- traces the ACPI table fields.
-
- This function also performs validation of the ACPI table fields.
-
- @param [in] Trace If TRUE, trace the ACPI fields.
- @param [in] Ptr Pointer to the start of the buffer.
- @param [in] AcpiTableLength Length of the ACPI table.
- @param [in] AcpiTableRevision Revision of the ACPI table.
-**/
-VOID
-EFIAPI
-ParseAcpiMcfg (
- IN BOOLEAN Trace,
- IN UINT8 *Ptr,
- IN UINT32 AcpiTableLength,
- IN UINT8 AcpiTableRevision
- )
-{
- UINT32 Offset;
- UINT32 PciCfgOffset;
- UINT8 *PciCfgSpacePtr;
-
- if (!Trace) {
- return;
- }
-
- Offset = ParseAcpi (
- TRUE,
- 0,
- "MCFG",
- Ptr,
- AcpiTableLength,
- PARSER_PARAMS (McfgParser)
- );
-
- PciCfgSpacePtr = Ptr + Offset;
-
- while (Offset < AcpiTableLength) {
- PciCfgOffset = ParseAcpi (
- TRUE,
- 2,
- "PCI Configuration Space",
- PciCfgSpacePtr,
- (AcpiTableLength - Offset),
- PARSER_PARAMS (PciCfgSpaceBaseAddrParser)
- );
- PciCfgSpacePtr += PciCfgOffset;
- Offset += PciCfgOffset;
- }
-}
+/** @file + MCFG table parser + + Copyright (c) 2016 - 2018, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - PCI Firmware Specification - Revision 3.2, January 26, 2015. +**/ + +#include <IndustryStandard/Acpi.h> +#include <Library/UefiLib.h> +#include "AcpiParser.h" +#include "AcpiTableParser.h" + +// Local variables +STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; + +/** + An ACPI_PARSER array describing the ACPI MCFG Table. +**/ +STATIC CONST ACPI_PARSER McfgParser[] = { + PARSE_ACPI_HEADER (&AcpiHdrInfo), + { L"Reserved", 8,36, L"0x%lx", NULL, NULL, NULL, NULL }, +}; + +/** + An ACPI_PARSER array describing the PCI configuration Space Base Address structure. +**/ +STATIC CONST ACPI_PARSER PciCfgSpaceBaseAddrParser[] = { + { L"Base Address", 8, 0, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"PCI Segment Group No.", 2, 8, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Start Bus No.", 1, 10, L"0x%x", NULL, NULL, NULL, NULL }, + { L"End Bus No.", 1, 11, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Reserved", 4, 12, L"0x%x", NULL, NULL, NULL, NULL } +}; + +/** + This function parses the ACPI MCFG table. + When trace is enabled this function parses the MCFG table and + traces the ACPI table fields. + + This function also performs validation of the ACPI table fields. + + @param [in] Trace If TRUE, trace the ACPI fields. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] AcpiTableLength Length of the ACPI table. + @param [in] AcpiTableRevision Revision of the ACPI table. +**/ +VOID +EFIAPI +ParseAcpiMcfg ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ) +{ + UINT32 Offset; + UINT32 PciCfgOffset; + UINT8 *PciCfgSpacePtr; + + if (!Trace) { + return; + } + + Offset = ParseAcpi ( + TRUE, + 0, + "MCFG", + Ptr, + AcpiTableLength, + PARSER_PARAMS (McfgParser) + ); + + PciCfgSpacePtr = Ptr + Offset; + + while (Offset < AcpiTableLength) { + PciCfgOffset = ParseAcpi ( + TRUE, + 2, + "PCI Configuration Space", + PciCfgSpacePtr, + (AcpiTableLength - Offset), + PARSER_PARAMS (PciCfgSpaceBaseAddrParser) + ); + PciCfgSpacePtr += PciCfgOffset; + Offset += PciCfgOffset; + } +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c index 8ad39090af..20757f902c 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.c @@ -1,673 +1,673 @@ -/** @file
- PCCT table parser
-
- Copyright (c) 2021, Arm Limited.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Reference(s):
- - ACPI 6.4 Specification - January 2021
-**/
-
-#include <Library/BaseMemoryLib.h>
-#include <Library/PrintLib.h>
-#include <Library/UefiLib.h>
-#include "AcpiParser.h"
-#include "AcpiView.h"
-#include "AcpiViewConfig.h"
-#include "PcctParser.h"
-
-// Local variables
-STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
-
-STATIC UINT32 *PccGlobalFlags;
-STATIC UINT8 *PccSubspaceLength;
-STATIC UINT8 *PccSubspaceType;
-STATIC UINT8 *ExtendedPccSubspaceInterruptFlags;
-
-/**
- This function validates the length coded on 4 bytes of a shared memory range
-
- @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
-ValidateRangeLength4 (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- if (*(UINT32 *)Ptr < MIN_EXT_PCC_SUBSPACE_MEM_RANGE_LEN) {
- IncrementErrorCount ();
- Print (
- L"\nError: Shared memory range length is too short.\n"
- L"Length is %u when it should be greater than or equal to %u",
- *(UINT32 *)Ptr,
- MIN_EXT_PCC_SUBSPACE_MEM_RANGE_LEN
- );
- }
-}
-
-/**
- This function validates the length coded on 8 bytes of a shared memory range
-
- @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
-ValidateRangeLength8 (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- if (*(UINT64 *)Ptr <= MIN_MEMORY_RANGE_LENGTH) {
- IncrementErrorCount ();
- Print (
- L"\nError: Shared memory range length is too short.\n"
- L"Length is %u when it should be greater than %u",
- *(UINT64 *)Ptr,
- MIN_MEMORY_RANGE_LENGTH
- );
- }
-}
-
-/**
- This function validates address space for Memory/IO GAS.
-
- @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
-ValidatePccMemoryIoGas (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- switch (*(UINT8 *)Ptr) {
- #if !(defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
- case EFI_ACPI_6_4_SYSTEM_IO:
- #endif //if not (defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
- case EFI_ACPI_6_4_SYSTEM_MEMORY:
- return;
- default:
- IncrementErrorCount ();
- Print (L"\nError: Invalid address space");
- }
-}
-
-/**
- This function validates address space for structures of types other than 0.
-
- @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
-ValidatePccGas (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- switch (*(UINT8 *)Ptr) {
- #if !(defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
- case EFI_ACPI_6_4_SYSTEM_IO:
- #endif //if not (defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64))
- case EFI_ACPI_6_4_FUNCTIONAL_FIXED_HARDWARE:
- case EFI_ACPI_6_4_SYSTEM_MEMORY:
- return;
- default:
- IncrementErrorCount ();
- Print (L"\nError: Invalid address space");
- }
-}
-
-/**
- This function validates doorbell address space for type 4 structure.
-
- @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
-ValidatePccDoorbellGas (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- // For responder subspaces this field is optional, if not present the field
- // should just contain zeros.
- if (*PccSubspaceType == EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC) {
- if (IsZeroBuffer (
- Ptr,
- sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE)
- ))
- {
- return;
- }
- }
-
- ValidatePccGas (Ptr, Context);
-}
-
-/**
- This function validates interrupt acknowledge address space for
- type 4 structure.
-
- @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
-ValidatePccIntAckGas (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- // If the subspace does not support interrupts or the interrupt is
- // edge driven the register may be omitted. A value of 0x0 on all
- // 12 bytes of the GAS structure indicates the register is not
- // present.
- if (((*PccGlobalFlags & EFI_ACPI_6_4_PCCT_FLAGS_PLATFORM_INTERRUPT) !=
- EFI_ACPI_6_4_PCCT_FLAGS_PLATFORM_INTERRUPT) ||
- ((*ExtendedPccSubspaceInterruptFlags &
- EFI_ACPI_6_4_PCCT_SUBSPACE_PLATFORM_INTERRUPT_FLAGS_MODE) ==
- EFI_ACPI_6_4_PCCT_SUBSPACE_PLATFORM_INTERRUPT_FLAGS_MODE))
- {
- if (IsZeroBuffer (
- Ptr,
- sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE)
- ))
- {
- return;
- }
- }
-
- ValidatePccGas (Ptr, Context);
-}
-
-/**
- This function validates error status address space for type 4 structure.
-
- @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
-ValidatePccErrStatusGas (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- // This field is ignored by the OSPM on responder channels.
- if (*PccSubspaceType == EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC) {
- return;
- }
-
- ValidatePccGas (Ptr, Context);
-}
-
-/**
- This function validates platform interrupt flags for type 4 structure.
-
- @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
-ValidatePlatInterrupt (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- // If a responder subspace is present in the PCCT, then the global Platform
- // Interrupt flag must be set to 1.
- if ((*PccSubspaceType == EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC) &&
- ((*PccGlobalFlags & EFI_ACPI_6_4_PCCT_FLAGS_PLATFORM_INTERRUPT) !=
- EFI_ACPI_6_4_PCCT_FLAGS_PLATFORM_INTERRUPT))
- {
- IncrementErrorCount ();
- Print (
- L"\nError: Global Platform interrupt flag must be set to 1" \
- L" if a PCC type 4 structure is present in PCCT."
- );
- }
-}
-
-/**
- An ACPI_PARSER array describing the ACPI PCCT Table.
-*/
-STATIC CONST ACPI_PARSER PcctParser[] = {
- PARSE_ACPI_HEADER (&AcpiHdrInfo),
- { L"Flags", 4, 36, NULL, NULL, (VOID **)&PccGlobalFlags, NULL, NULL },
- { L"Reserved", 8, 40, NULL, NULL, NULL, NULL, NULL }
-};
-
-/**
- An ACPI_PARSER array describing the platform communications channel subspace
- structure header.
-*/
-STATIC CONST ACPI_PARSER PccSubspaceHeaderParser[] = {
- PCC_SUBSPACE_HEADER ()
- // ... Type Specific Fields ...
-};
-
-/**
- An ACPI_PARSER array describing the Generic Communications Subspace - Type 0
-*/
-STATIC CONST ACPI_PARSER PccSubspaceType0Parser[] = {
- PCC_SUBSPACE_HEADER (),
- { L"Reserved", 6, 2, L"%x %x %x %x %x %x", Dump6Chars, NULL, NULL, NULL },
- { L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Memory Range Length",8, 16, L"0x%lx", NULL, NULL, ValidateRangeLength8,
- NULL },
- { L"Doorbell Register",12, 24, NULL, DumpGas, NULL, ValidatePccMemoryIoGas,
- NULL },
- { L"Doorbell Preserve",8, 36, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Doorbell Write", 8, 44, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Nominal Latency", 4, 52, L"%u", NULL, NULL, NULL, NULL },
- { L"Maximum Periodic Access Rate",4, 56, L"%u", NULL, NULL, NULL, NULL },
- { L"Minimum Request Turnaround Time",2, 60, L"%u", NULL, NULL, NULL, NULL }
-};
-
-/**
- An ACPI_PARSER array describing the HW-Reduced Communications Subspace
- - Type 1
-*/
-STATIC CONST ACPI_PARSER PccSubspaceType1Parser[] = {
- PCC_SUBSPACE_HEADER (),
- { L"Platform Interrupt",4, 2, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Platform Interrupt Flags",1, 6, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Reserved", 1, 7, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Memory Range Length",8, 16, L"0x%lx", NULL, NULL, ValidateRangeLength8,
- NULL },
- { L"Doorbell Register",12, 24, NULL, DumpGas, NULL,
- ValidatePccGas, NULL },
- { L"Doorbell Preserve",8, 36, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Doorbell Write", 8, 44, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Nominal Latency", 4, 52, L"%u", NULL, NULL, NULL, NULL },
- { L"Maximum Periodic Access Rate",4, 56, L"%u", NULL, NULL, NULL, NULL },
- { L"Minimum Request Turnaround Time",2, 60, L"%u", NULL, NULL, NULL, NULL }
-};
-
-/**
- An ACPI_PARSER array describing the HW-Reduced Communications Subspace
- - Type 2
-*/
-STATIC CONST ACPI_PARSER PccSubspaceType2Parser[] = {
- PCC_SUBSPACE_HEADER (),
- { L"Platform Interrupt",4, 2, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Platform Interrupt Flags",1, 6, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Reserved", 1, 7, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Memory Range Length",8, 16, L"0x%lx", NULL, NULL, ValidateRangeLength8,
- NULL },
- { L"Doorbell Register",12, 24, NULL, DumpGas, NULL,
- ValidatePccGas, NULL },
- { L"Doorbell Preserve",8, 36, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Doorbell Write", 8, 44, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Nominal Latency", 4, 52, L"%u", NULL, NULL, NULL, NULL },
- { L"Maximum Periodic Access Rate",4, 56, L"%u", NULL, NULL, NULL, NULL },
- { L"Minimum Request Turnaround Time",2, 60, L"%u", NULL, NULL, NULL, NULL },
- { L"Platform Interrupt Ack Register",12, 62, NULL, DumpGas, NULL,
- ValidatePccGas, NULL },
- { L"Platform Interrupt Ack Preserve",8, 74, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Platform Interrupt Ack Write",8, 82, L"0x%lx", NULL, NULL,
- NULL, NULL },
-};
-
-/**
- An ACPI_PARSER array describing the Extended PCC Subspaces - Type 3/4
-*/
-STATIC CONST ACPI_PARSER PccSubspaceType3Parser[] = {
- PCC_SUBSPACE_HEADER (),
- { L"Platform Interrupt", 4, 2, L"0x%x", NULL, NULL,
- ValidatePlatInterrupt, NULL },
- { L"Platform Interrupt Flags", 1, 6, L"0x%x", NULL,
- (VOID **)&ExtendedPccSubspaceInterruptFlags,NULL, NULL },
- { L"Reserved", 1, 7, L"0x%x", NULL, NULL,NULL, NULL },
- { L"Base Address", 8, 8, L"0x%lx", NULL, NULL,NULL, NULL },
- { L"Memory Range Length", 4, 16, L"0x%x", NULL, NULL,ValidateRangeLength4,
- NULL },
- { L"Doorbell Register", 12, 20, NULL, DumpGas, NULL,
- ValidatePccDoorbellGas, NULL },
- { L"Doorbell Preserve", 8, 32, L"0x%lx", NULL, NULL,NULL, NULL },
- { L"Doorbell Write", 8, 40, L"0x%lx", NULL, NULL,NULL, NULL },
- { L"Nominal Latency", 4, 48, L"%u", NULL, NULL,NULL, NULL },
- { L"Maximum Periodic Access Rate", 4, 52, L"%u", NULL, NULL,NULL, NULL },
- { L"Minimum Request Turnaround Time", 4, 56, L"%u", NULL, NULL,NULL, NULL },
- { L"Platform Interrupt Ack Register", 12, 60, NULL, DumpGas, NULL,
- ValidatePccIntAckGas, NULL },
- { L"Platform Interrupt Ack Preserve", 8, 72, L"0x%lx", NULL, NULL,NULL, NULL },
- { L"Platform Interrupt Ack Set", 8, 80, L"0x%lx", NULL, NULL,NULL, NULL },
- { L"Reserved", 8, 88, L"0x%lx", NULL, NULL,NULL, NULL },
- { L"Cmd Complete Check Reg Addr", 12, 96, NULL, DumpGas, NULL,
- ValidatePccGas, NULL },
- { L"Cmd Complete Check Mask", 8, 108, L"0x%lx", NULL, NULL,NULL, NULL },
- { L"Cmd Update Reg Addr", 12, 116, NULL, DumpGas, NULL,
- ValidatePccGas, NULL },
- { L"Cmd Update Preserve mask", 8, 128, L"0x%lx", NULL, NULL,NULL, NULL },
- { L"Cmd Update Set mask", 8, 136, L"0x%lx", NULL, NULL,NULL, NULL },
- { L"Error Status Register", 12, 144, NULL, DumpGas, NULL,
- ValidatePccErrStatusGas, NULL },
- { L"Error Status Mask", 8, 156, L"0x%lx", NULL, NULL,NULL, NULL },
-};
-
-/**
- An ACPI_PARSER array describing the HW Registers based Communications
- Subspace Structure - Type 5
-*/
-STATIC CONST ACPI_PARSER PccSubspaceType5Parser[] = {
- PCC_SUBSPACE_HEADER (),
- { L"Version", 2, 2, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Base Address", 8, 4, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Shared Memory Range Length",8, 12, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Doorbell Register", 12, 20, NULL, DumpGas, NULL,
- ValidatePccMemoryIoGas,NULL },
- { L"Doorbell Preserve", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Doorbell Write", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Command Complete Check Register",12, 48, NULL, DumpGas, NULL,
- ValidatePccMemoryIoGas,NULL },
- { L"Command Complete Check Mask",8, 60, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Error Status Register",12, 68, NULL, DumpGas, NULL,
- ValidatePccMemoryIoGas,NULL },
- { L"Error Status Mask", 8, 80, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"Nominal Latency", 4, 88, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Minimum Request Turnaround Time",4, 92, L"0x%x", NULL, NULL, NULL, NULL }
-};
-
-/**
- This function parses the PCC Subspace type 0.
-
- @param [in] Ptr Pointer to the start of Subspace Structure.
- @param [in] Length Length of the Subspace Structure.
-**/
-STATIC
-VOID
-DumpPccSubspaceType0 (
- IN UINT8 *Ptr,
- IN UINT8 Length
- )
-{
- ParseAcpi (
- TRUE,
- 2,
- "Subspace Type 0",
- Ptr,
- Length,
- PARSER_PARAMS (PccSubspaceType0Parser)
- );
-}
-
-/**
- This function parses the PCC Subspace type 1.
-
- @param [in] Ptr Pointer to the start of the Subspace Structure.
- @param [in] Length Length of the Subspace Structure.
-**/
-STATIC
-VOID
-DumpPccSubspaceType1 (
- IN UINT8 *Ptr,
- IN UINT8 Length
- )
-{
- ParseAcpi (
- TRUE,
- 2,
- "Subspace Type 1",
- Ptr,
- Length,
- PARSER_PARAMS (PccSubspaceType1Parser)
- );
-}
-
-/**
- This function parses the PCC Subspace type 2.
-
- @param [in] Ptr Pointer to the start of the Subspace Structure.
- @param [in] Length Length of the Subspace Structure.
-**/
-STATIC
-VOID
-DumpPccSubspaceType2 (
- IN UINT8 *Ptr,
- IN UINT8 Length
- )
-{
- ParseAcpi (
- TRUE,
- 2,
- "Subspace Type 2",
- Ptr,
- Length,
- PARSER_PARAMS (PccSubspaceType2Parser)
- );
-}
-
-/**
- This function parses the PCC Subspace type 3.
-
- @param [in] Ptr Pointer to the start of the Subspace Structure.
- @param [in] Length Length of the Subspace Structure.
-**/
-STATIC
-VOID
-DumpPccSubspaceType3 (
- IN UINT8 *Ptr,
- IN UINT8 Length
- )
-{
- ParseAcpi (
- TRUE,
- 2,
- "Subspace Type 3",
- Ptr,
- Length,
- PARSER_PARAMS (PccSubspaceType3Parser)
- );
-}
-
-/**
- This function parses the PCC Subspace type 4.
-
- @param [in] Ptr Pointer to the start of the Subspace Structure.
- @param [in] Length Length of the Subspace Structure.
-**/
-STATIC
-VOID
-DumpPccSubspaceType4 (
- IN UINT8 *Ptr,
- IN UINT8 Length
- )
-{
- ParseAcpi (
- TRUE,
- 2,
- "Subspace Type 4",
- Ptr,
- Length,
- PARSER_PARAMS (PccSubspaceType3Parser)
- );
-}
-
-/**
- This function parses the PCC Subspace type 5.
-
- @param [in] Ptr Pointer to the start of the Subspace Structure.
- @param [in] Length Length of the Subspace Structure.
-**/
-STATIC
-VOID
-DumpPccSubspaceType5 (
- IN UINT8 *Ptr,
- IN UINT8 Length
- )
-{
- ParseAcpi (
- TRUE,
- 2,
- "Subspace Type 5",
- Ptr,
- Length,
- PARSER_PARAMS (PccSubspaceType5Parser)
- );
-}
-
-/**
- This function parses the ACPI PCCT table including its sub-structures
- of type 0 through 4.
- When trace is enabled this function parses the PCCT 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
-ParseAcpiPcct (
- IN BOOLEAN Trace,
- IN UINT8 *Ptr,
- IN UINT32 AcpiTableLength,
- IN UINT8 AcpiTableRevision
- )
-{
- UINT32 Offset;
- UINT8 *PccSubspacePtr;
- UINTN SubspaceCount;
-
- if (!Trace) {
- return;
- }
-
- Offset = ParseAcpi (
- TRUE,
- 0,
- "PCCT",
- Ptr,
- AcpiTableLength,
- PARSER_PARAMS (PcctParser)
- );
-
- PccSubspacePtr = Ptr + Offset;
-
- SubspaceCount = 0;
- while (Offset < AcpiTableLength) {
- // Parse common structure header to obtain Type and Length.
- ParseAcpi (
- FALSE,
- 0,
- NULL,
- PccSubspacePtr,
- AcpiTableLength - Offset,
- PARSER_PARAMS (PccSubspaceHeaderParser)
- );
-
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if ((PccSubspaceType == NULL) ||
- (PccSubspaceLength == NULL))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient remaining table buffer length to read the " \
- L"structure header. Length = %u.\n",
- AcpiTableLength - Offset
- );
- return;
- }
-
- // Validate Structure length
- if ((*PccSubspaceLength == 0) ||
- ((Offset + (*PccSubspaceLength)) > AcpiTableLength))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Invalid Structure length. " \
- L"Length = %u. Offset = %u. AcpiTableLength = %u.\n",
- *PccSubspaceLength,
- Offset,
- AcpiTableLength
- );
- return;
- }
-
- switch (*PccSubspaceType) {
- case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_GENERIC:
- DumpPccSubspaceType0 (
- PccSubspacePtr,
- *PccSubspaceLength
- );
- break;
- case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS:
- DumpPccSubspaceType1 (
- PccSubspacePtr,
- *PccSubspaceLength
- );
- break;
- case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS:
- DumpPccSubspaceType2 (
- PccSubspacePtr,
- *PccSubspaceLength
- );
- break;
- case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC:
- DumpPccSubspaceType3 (
- PccSubspacePtr,
- *PccSubspaceLength
- );
- break;
- case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC:
- DumpPccSubspaceType4 (
- PccSubspacePtr,
- *PccSubspaceLength
- );
- break;
- case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_5_HW_REGISTERS_COMMUNICATIONS:
- DumpPccSubspaceType5 (
- PccSubspacePtr,
- *PccSubspaceLength
- );
- break;
- default:
- IncrementErrorCount ();
- Print (
- L"ERROR: Unknown PCC subspace structure:"
- L" Type = %u, Length = %u\n",
- PccSubspaceType,
- *PccSubspaceLength
- );
- }
-
- PccSubspacePtr += *PccSubspaceLength;
- Offset += *PccSubspaceLength;
- SubspaceCount++;
- } // while
-
- if (SubspaceCount > MAX_PCC_SUBSPACES) {
- IncrementErrorCount ();
- Print (L"ERROR: Too many PCC subspaces.");
- }
-}
+/** @file + PCCT table parser + + Copyright (c) 2021, Arm Limited. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.4 Specification - January 2021 +**/ + +#include <Library/BaseMemoryLib.h> +#include <Library/PrintLib.h> +#include <Library/UefiLib.h> +#include "AcpiParser.h" +#include "AcpiView.h" +#include "AcpiViewConfig.h" +#include "PcctParser.h" + +// Local variables +STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; + +STATIC UINT32 *PccGlobalFlags; +STATIC UINT8 *PccSubspaceLength; +STATIC UINT8 *PccSubspaceType; +STATIC UINT8 *ExtendedPccSubspaceInterruptFlags; + +/** + This function validates the length coded on 4 bytes of a shared memory range + + @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 +ValidateRangeLength4 ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + if (*(UINT32 *)Ptr < MIN_EXT_PCC_SUBSPACE_MEM_RANGE_LEN) { + IncrementErrorCount (); + Print ( + L"\nError: Shared memory range length is too short.\n" + L"Length is %u when it should be greater than or equal to %u", + *(UINT32 *)Ptr, + MIN_EXT_PCC_SUBSPACE_MEM_RANGE_LEN + ); + } +} + +/** + This function validates the length coded on 8 bytes of a shared memory range + + @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 +ValidateRangeLength8 ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + if (*(UINT64 *)Ptr <= MIN_MEMORY_RANGE_LENGTH) { + IncrementErrorCount (); + Print ( + L"\nError: Shared memory range length is too short.\n" + L"Length is %u when it should be greater than %u", + *(UINT64 *)Ptr, + MIN_MEMORY_RANGE_LENGTH + ); + } +} + +/** + This function validates address space for Memory/IO GAS. + + @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 +ValidatePccMemoryIoGas ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + switch (*(UINT8 *)Ptr) { + #if !(defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)) + case EFI_ACPI_6_4_SYSTEM_IO: + #endif //if not (defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)) + case EFI_ACPI_6_4_SYSTEM_MEMORY: + return; + default: + IncrementErrorCount (); + Print (L"\nError: Invalid address space"); + } +} + +/** + This function validates address space for structures of types other than 0. + + @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 +ValidatePccGas ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + switch (*(UINT8 *)Ptr) { + #if !(defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)) + case EFI_ACPI_6_4_SYSTEM_IO: + #endif //if not (defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)) + case EFI_ACPI_6_4_FUNCTIONAL_FIXED_HARDWARE: + case EFI_ACPI_6_4_SYSTEM_MEMORY: + return; + default: + IncrementErrorCount (); + Print (L"\nError: Invalid address space"); + } +} + +/** + This function validates doorbell address space for type 4 structure. + + @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 +ValidatePccDoorbellGas ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + // For responder subspaces this field is optional, if not present the field + // should just contain zeros. + if (*PccSubspaceType == EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC) { + if (IsZeroBuffer ( + Ptr, + sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE) + )) + { + return; + } + } + + ValidatePccGas (Ptr, Context); +} + +/** + This function validates interrupt acknowledge address space for + type 4 structure. + + @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 +ValidatePccIntAckGas ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + // If the subspace does not support interrupts or the interrupt is + // edge driven the register may be omitted. A value of 0x0 on all + // 12 bytes of the GAS structure indicates the register is not + // present. + if (((*PccGlobalFlags & EFI_ACPI_6_4_PCCT_FLAGS_PLATFORM_INTERRUPT) != + EFI_ACPI_6_4_PCCT_FLAGS_PLATFORM_INTERRUPT) || + ((*ExtendedPccSubspaceInterruptFlags & + EFI_ACPI_6_4_PCCT_SUBSPACE_PLATFORM_INTERRUPT_FLAGS_MODE) == + EFI_ACPI_6_4_PCCT_SUBSPACE_PLATFORM_INTERRUPT_FLAGS_MODE)) + { + if (IsZeroBuffer ( + Ptr, + sizeof (EFI_ACPI_6_4_GENERIC_ADDRESS_STRUCTURE) + )) + { + return; + } + } + + ValidatePccGas (Ptr, Context); +} + +/** + This function validates error status address space for type 4 structure. + + @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 +ValidatePccErrStatusGas ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + // This field is ignored by the OSPM on responder channels. + if (*PccSubspaceType == EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC) { + return; + } + + ValidatePccGas (Ptr, Context); +} + +/** + This function validates platform interrupt flags for type 4 structure. + + @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 +ValidatePlatInterrupt ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + // If a responder subspace is present in the PCCT, then the global Platform + // Interrupt flag must be set to 1. + if ((*PccSubspaceType == EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC) && + ((*PccGlobalFlags & EFI_ACPI_6_4_PCCT_FLAGS_PLATFORM_INTERRUPT) != + EFI_ACPI_6_4_PCCT_FLAGS_PLATFORM_INTERRUPT)) + { + IncrementErrorCount (); + Print ( + L"\nError: Global Platform interrupt flag must be set to 1" \ + L" if a PCC type 4 structure is present in PCCT." + ); + } +} + +/** + An ACPI_PARSER array describing the ACPI PCCT Table. +*/ +STATIC CONST ACPI_PARSER PcctParser[] = { + PARSE_ACPI_HEADER (&AcpiHdrInfo), + { L"Flags", 4, 36, NULL, NULL, (VOID **)&PccGlobalFlags, NULL, NULL }, + { L"Reserved", 8, 40, NULL, NULL, NULL, NULL, NULL } +}; + +/** + An ACPI_PARSER array describing the platform communications channel subspace + structure header. +*/ +STATIC CONST ACPI_PARSER PccSubspaceHeaderParser[] = { + PCC_SUBSPACE_HEADER () + // ... Type Specific Fields ... +}; + +/** + An ACPI_PARSER array describing the Generic Communications Subspace - Type 0 +*/ +STATIC CONST ACPI_PARSER PccSubspaceType0Parser[] = { + PCC_SUBSPACE_HEADER (), + { L"Reserved", 6, 2, L"%x %x %x %x %x %x", Dump6Chars, NULL, NULL, NULL }, + { L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Memory Range Length",8, 16, L"0x%lx", NULL, NULL, ValidateRangeLength8, + NULL }, + { L"Doorbell Register",12, 24, NULL, DumpGas, NULL, ValidatePccMemoryIoGas, + NULL }, + { L"Doorbell Preserve",8, 36, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Doorbell Write", 8, 44, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Nominal Latency", 4, 52, L"%u", NULL, NULL, NULL, NULL }, + { L"Maximum Periodic Access Rate",4, 56, L"%u", NULL, NULL, NULL, NULL }, + { L"Minimum Request Turnaround Time",2, 60, L"%u", NULL, NULL, NULL, NULL } +}; + +/** + An ACPI_PARSER array describing the HW-Reduced Communications Subspace + - Type 1 +*/ +STATIC CONST ACPI_PARSER PccSubspaceType1Parser[] = { + PCC_SUBSPACE_HEADER (), + { L"Platform Interrupt",4, 2, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Platform Interrupt Flags",1, 6, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Reserved", 1, 7, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Memory Range Length",8, 16, L"0x%lx", NULL, NULL, ValidateRangeLength8, + NULL }, + { L"Doorbell Register",12, 24, NULL, DumpGas, NULL, + ValidatePccGas, NULL }, + { L"Doorbell Preserve",8, 36, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Doorbell Write", 8, 44, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Nominal Latency", 4, 52, L"%u", NULL, NULL, NULL, NULL }, + { L"Maximum Periodic Access Rate",4, 56, L"%u", NULL, NULL, NULL, NULL }, + { L"Minimum Request Turnaround Time",2, 60, L"%u", NULL, NULL, NULL, NULL } +}; + +/** + An ACPI_PARSER array describing the HW-Reduced Communications Subspace + - Type 2 +*/ +STATIC CONST ACPI_PARSER PccSubspaceType2Parser[] = { + PCC_SUBSPACE_HEADER (), + { L"Platform Interrupt",4, 2, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Platform Interrupt Flags",1, 6, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Reserved", 1, 7, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Base Address", 8, 8, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Memory Range Length",8, 16, L"0x%lx", NULL, NULL, ValidateRangeLength8, + NULL }, + { L"Doorbell Register",12, 24, NULL, DumpGas, NULL, + ValidatePccGas, NULL }, + { L"Doorbell Preserve",8, 36, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Doorbell Write", 8, 44, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Nominal Latency", 4, 52, L"%u", NULL, NULL, NULL, NULL }, + { L"Maximum Periodic Access Rate",4, 56, L"%u", NULL, NULL, NULL, NULL }, + { L"Minimum Request Turnaround Time",2, 60, L"%u", NULL, NULL, NULL, NULL }, + { L"Platform Interrupt Ack Register",12, 62, NULL, DumpGas, NULL, + ValidatePccGas, NULL }, + { L"Platform Interrupt Ack Preserve",8, 74, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Platform Interrupt Ack Write",8, 82, L"0x%lx", NULL, NULL, + NULL, NULL }, +}; + +/** + An ACPI_PARSER array describing the Extended PCC Subspaces - Type 3/4 +*/ +STATIC CONST ACPI_PARSER PccSubspaceType3Parser[] = { + PCC_SUBSPACE_HEADER (), + { L"Platform Interrupt", 4, 2, L"0x%x", NULL, NULL, + ValidatePlatInterrupt, NULL }, + { L"Platform Interrupt Flags", 1, 6, L"0x%x", NULL, + (VOID **)&ExtendedPccSubspaceInterruptFlags,NULL, NULL }, + { L"Reserved", 1, 7, L"0x%x", NULL, NULL,NULL, NULL }, + { L"Base Address", 8, 8, L"0x%lx", NULL, NULL,NULL, NULL }, + { L"Memory Range Length", 4, 16, L"0x%x", NULL, NULL,ValidateRangeLength4, + NULL }, + { L"Doorbell Register", 12, 20, NULL, DumpGas, NULL, + ValidatePccDoorbellGas, NULL }, + { L"Doorbell Preserve", 8, 32, L"0x%lx", NULL, NULL,NULL, NULL }, + { L"Doorbell Write", 8, 40, L"0x%lx", NULL, NULL,NULL, NULL }, + { L"Nominal Latency", 4, 48, L"%u", NULL, NULL,NULL, NULL }, + { L"Maximum Periodic Access Rate", 4, 52, L"%u", NULL, NULL,NULL, NULL }, + { L"Minimum Request Turnaround Time", 4, 56, L"%u", NULL, NULL,NULL, NULL }, + { L"Platform Interrupt Ack Register", 12, 60, NULL, DumpGas, NULL, + ValidatePccIntAckGas, NULL }, + { L"Platform Interrupt Ack Preserve", 8, 72, L"0x%lx", NULL, NULL,NULL, NULL }, + { L"Platform Interrupt Ack Set", 8, 80, L"0x%lx", NULL, NULL,NULL, NULL }, + { L"Reserved", 8, 88, L"0x%lx", NULL, NULL,NULL, NULL }, + { L"Cmd Complete Check Reg Addr", 12, 96, NULL, DumpGas, NULL, + ValidatePccGas, NULL }, + { L"Cmd Complete Check Mask", 8, 108, L"0x%lx", NULL, NULL,NULL, NULL }, + { L"Cmd Update Reg Addr", 12, 116, NULL, DumpGas, NULL, + ValidatePccGas, NULL }, + { L"Cmd Update Preserve mask", 8, 128, L"0x%lx", NULL, NULL,NULL, NULL }, + { L"Cmd Update Set mask", 8, 136, L"0x%lx", NULL, NULL,NULL, NULL }, + { L"Error Status Register", 12, 144, NULL, DumpGas, NULL, + ValidatePccErrStatusGas, NULL }, + { L"Error Status Mask", 8, 156, L"0x%lx", NULL, NULL,NULL, NULL }, +}; + +/** + An ACPI_PARSER array describing the HW Registers based Communications + Subspace Structure - Type 5 +*/ +STATIC CONST ACPI_PARSER PccSubspaceType5Parser[] = { + PCC_SUBSPACE_HEADER (), + { L"Version", 2, 2, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Base Address", 8, 4, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Shared Memory Range Length",8, 12, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Doorbell Register", 12, 20, NULL, DumpGas, NULL, + ValidatePccMemoryIoGas,NULL }, + { L"Doorbell Preserve", 8, 32, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Doorbell Write", 8, 40, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Command Complete Check Register",12, 48, NULL, DumpGas, NULL, + ValidatePccMemoryIoGas,NULL }, + { L"Command Complete Check Mask",8, 60, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Error Status Register",12, 68, NULL, DumpGas, NULL, + ValidatePccMemoryIoGas,NULL }, + { L"Error Status Mask", 8, 80, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"Nominal Latency", 4, 88, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Minimum Request Turnaround Time",4, 92, L"0x%x", NULL, NULL, NULL, NULL } +}; + +/** + This function parses the PCC Subspace type 0. + + @param [in] Ptr Pointer to the start of Subspace Structure. + @param [in] Length Length of the Subspace Structure. +**/ +STATIC +VOID +DumpPccSubspaceType0 ( + IN UINT8 *Ptr, + IN UINT8 Length + ) +{ + ParseAcpi ( + TRUE, + 2, + "Subspace Type 0", + Ptr, + Length, + PARSER_PARAMS (PccSubspaceType0Parser) + ); +} + +/** + This function parses the PCC Subspace type 1. + + @param [in] Ptr Pointer to the start of the Subspace Structure. + @param [in] Length Length of the Subspace Structure. +**/ +STATIC +VOID +DumpPccSubspaceType1 ( + IN UINT8 *Ptr, + IN UINT8 Length + ) +{ + ParseAcpi ( + TRUE, + 2, + "Subspace Type 1", + Ptr, + Length, + PARSER_PARAMS (PccSubspaceType1Parser) + ); +} + +/** + This function parses the PCC Subspace type 2. + + @param [in] Ptr Pointer to the start of the Subspace Structure. + @param [in] Length Length of the Subspace Structure. +**/ +STATIC +VOID +DumpPccSubspaceType2 ( + IN UINT8 *Ptr, + IN UINT8 Length + ) +{ + ParseAcpi ( + TRUE, + 2, + "Subspace Type 2", + Ptr, + Length, + PARSER_PARAMS (PccSubspaceType2Parser) + ); +} + +/** + This function parses the PCC Subspace type 3. + + @param [in] Ptr Pointer to the start of the Subspace Structure. + @param [in] Length Length of the Subspace Structure. +**/ +STATIC +VOID +DumpPccSubspaceType3 ( + IN UINT8 *Ptr, + IN UINT8 Length + ) +{ + ParseAcpi ( + TRUE, + 2, + "Subspace Type 3", + Ptr, + Length, + PARSER_PARAMS (PccSubspaceType3Parser) + ); +} + +/** + This function parses the PCC Subspace type 4. + + @param [in] Ptr Pointer to the start of the Subspace Structure. + @param [in] Length Length of the Subspace Structure. +**/ +STATIC +VOID +DumpPccSubspaceType4 ( + IN UINT8 *Ptr, + IN UINT8 Length + ) +{ + ParseAcpi ( + TRUE, + 2, + "Subspace Type 4", + Ptr, + Length, + PARSER_PARAMS (PccSubspaceType3Parser) + ); +} + +/** + This function parses the PCC Subspace type 5. + + @param [in] Ptr Pointer to the start of the Subspace Structure. + @param [in] Length Length of the Subspace Structure. +**/ +STATIC +VOID +DumpPccSubspaceType5 ( + IN UINT8 *Ptr, + IN UINT8 Length + ) +{ + ParseAcpi ( + TRUE, + 2, + "Subspace Type 5", + Ptr, + Length, + PARSER_PARAMS (PccSubspaceType5Parser) + ); +} + +/** + This function parses the ACPI PCCT table including its sub-structures + of type 0 through 4. + When trace is enabled this function parses the PCCT 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 +ParseAcpiPcct ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ) +{ + UINT32 Offset; + UINT8 *PccSubspacePtr; + UINTN SubspaceCount; + + if (!Trace) { + return; + } + + Offset = ParseAcpi ( + TRUE, + 0, + "PCCT", + Ptr, + AcpiTableLength, + PARSER_PARAMS (PcctParser) + ); + + PccSubspacePtr = Ptr + Offset; + + SubspaceCount = 0; + while (Offset < AcpiTableLength) { + // Parse common structure header to obtain Type and Length. + ParseAcpi ( + FALSE, + 0, + NULL, + PccSubspacePtr, + AcpiTableLength - Offset, + PARSER_PARAMS (PccSubspaceHeaderParser) + ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if ((PccSubspaceType == NULL) || + (PccSubspaceLength == NULL)) + { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient remaining table buffer length to read the " \ + L"structure header. Length = %u.\n", + AcpiTableLength - Offset + ); + return; + } + + // Validate Structure length + if ((*PccSubspaceLength == 0) || + ((Offset + (*PccSubspaceLength)) > AcpiTableLength)) + { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid Structure length. " \ + L"Length = %u. Offset = %u. AcpiTableLength = %u.\n", + *PccSubspaceLength, + Offset, + AcpiTableLength + ); + return; + } + + switch (*PccSubspaceType) { + case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_GENERIC: + DumpPccSubspaceType0 ( + PccSubspacePtr, + *PccSubspaceLength + ); + break; + case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_1_HW_REDUCED_COMMUNICATIONS: + DumpPccSubspaceType1 ( + PccSubspacePtr, + *PccSubspaceLength + ); + break; + case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS: + DumpPccSubspaceType2 ( + PccSubspacePtr, + *PccSubspaceLength + ); + break; + case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_3_EXTENDED_PCC: + DumpPccSubspaceType3 ( + PccSubspacePtr, + *PccSubspaceLength + ); + break; + case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_4_EXTENDED_PCC: + DumpPccSubspaceType4 ( + PccSubspacePtr, + *PccSubspaceLength + ); + break; + case EFI_ACPI_6_4_PCCT_SUBSPACE_TYPE_5_HW_REGISTERS_COMMUNICATIONS: + DumpPccSubspaceType5 ( + PccSubspacePtr, + *PccSubspaceLength + ); + break; + default: + IncrementErrorCount (); + Print ( + L"ERROR: Unknown PCC subspace structure:" + L" Type = %u, Length = %u\n", + PccSubspaceType, + *PccSubspaceLength + ); + } + + PccSubspacePtr += *PccSubspaceLength; + Offset += *PccSubspaceLength; + SubspaceCount++; + } // while + + if (SubspaceCount > MAX_PCC_SUBSPACES) { + IncrementErrorCount (); + Print (L"ERROR: Too many PCC subspaces."); + } +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.h index 5b92ffee3f..aa3e0a1b16 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.h +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pcct/PcctParser.h @@ -1,33 +1,33 @@ -/** @file
- Header file for PCCT parser
-
- Copyright (c) 2020, Arm Limited.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#ifndef PCCT_PARSER_H_
-#define PCCT_PARSER_H_
-
-/**
- Minimum value for the 'length' field in subspaces of types 0, 1 and 2.
-*/
-#define MIN_MEMORY_RANGE_LENGTH 8
-
-/**
- Minimum value for the 'length' field in subspaces of types 3 and 4.
-*/
-#define MIN_EXT_PCC_SUBSPACE_MEM_RANGE_LEN 16
-
-/**
- Maximum number of PCC subspaces.
-*/
-#define MAX_PCC_SUBSPACES 256
-
-/**
- Parser for the header of any type of PCC subspace.
-*/
-#define PCC_SUBSPACE_HEADER() \
- {L"Type", 1, 0, L"0x%x", NULL, (VOID**)&PccSubspaceType, NULL, NULL}, \
- {L"Length", 1, 1, L"%u", NULL, (VOID**)&PccSubspaceLength, NULL, NULL}
-
-#endif // PCCT_PARSER_H_
+/** @file + Header file for PCCT parser + + Copyright (c) 2020, Arm Limited. + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#ifndef PCCT_PARSER_H_ +#define PCCT_PARSER_H_ + +/** + Minimum value for the 'length' field in subspaces of types 0, 1 and 2. +*/ +#define MIN_MEMORY_RANGE_LENGTH 8 + +/** + Minimum value for the 'length' field in subspaces of types 3 and 4. +*/ +#define MIN_EXT_PCC_SUBSPACE_MEM_RANGE_LEN 16 + +/** + Maximum number of PCC subspaces. +*/ +#define MAX_PCC_SUBSPACES 256 + +/** + Parser for the header of any type of PCC subspace. +*/ +#define PCC_SUBSPACE_HEADER() \ + {L"Type", 1, 0, L"0x%x", NULL, (VOID**)&PccSubspaceType, NULL, NULL}, \ + {L"Length", 1, 1, L"%u", NULL, (VOID**)&PccSubspaceLength, NULL, NULL} + +#endif // PCCT_PARSER_H_ diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c index 5377764458..df8d347c75 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.c @@ -1,575 +1,575 @@ -/** @file
- PPTT table parser
-
- Copyright (c) 2019 - 2021, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Reference(s):
- - ACPI 6.4 Specification - January 2021
- - ARM Architecture Reference Manual ARMv8 (D.a)
-**/
-
-#include <Library/PrintLib.h>
-#include <Library/UefiLib.h>
-#include "AcpiParser.h"
-#include "AcpiView.h"
-#include "AcpiViewConfig.h"
-#include "PpttParser.h"
-
-// Local variables
-STATIC CONST UINT8 *ProcessorTopologyStructureType;
-STATIC CONST UINT8 *ProcessorTopologyStructureLength;
-STATIC CONST UINT32 *NumberOfPrivateResources;
-STATIC CONST EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE_FLAGS *CacheFlags;
-STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
-
-#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
-
-/**
- Increment the error count and print an error that a required flag is missing.
-
- @param [in] FlagName Name of the missing flag.
-**/
-STATIC
-VOID
-EFIAPI
-LogCacheFlagError (
- IN CONST CHAR16 *FlagName
- )
-{
- IncrementErrorCount ();
- Print (
- L"\nERROR: On Arm based systems, all cache properties must be"
- L" provided in the cache type structure."
- L" Missing '%s' flag.",
- FlagName
- );
-}
-
-#endif
-
-/**
- This function validates the Cache Type Structure (Type 1) Cache Flags 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
-ValidateCacheFlags (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
- CacheFlags = (EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE_FLAGS *)Ptr;
-
- if (CacheFlags == NULL) {
- IncrementErrorCount ();
- Print (L"\nERROR: Cache Structure Flags were not successfully read.");
- return;
- }
-
- if (CacheFlags->SizePropertyValid == EFI_ACPI_6_4_PPTT_CACHE_SIZE_INVALID) {
- LogCacheFlagError (L"Size Property Valid");
- }
-
- if (CacheFlags->NumberOfSetsValid == EFI_ACPI_6_4_PPTT_NUMBER_OF_SETS_INVALID) {
- LogCacheFlagError (L"Number Of Sets Valid");
- }
-
- if (CacheFlags->AssociativityValid == EFI_ACPI_6_4_PPTT_ASSOCIATIVITY_INVALID) {
- LogCacheFlagError (L"Associativity Valid");
- }
-
- if (CacheFlags->AllocationTypeValid == EFI_ACPI_6_4_PPTT_ALLOCATION_TYPE_INVALID) {
- LogCacheFlagError (L"Allocation Type Valid");
- }
-
- if (CacheFlags->CacheTypeValid == EFI_ACPI_6_4_PPTT_CACHE_TYPE_INVALID) {
- LogCacheFlagError (L"Cache Type Valid");
- }
-
- if (CacheFlags->WritePolicyValid == EFI_ACPI_6_4_PPTT_WRITE_POLICY_INVALID) {
- LogCacheFlagError (L"Write Policy Valid");
- }
-
- if (CacheFlags->LineSizeValid == EFI_ACPI_6_4_PPTT_LINE_SIZE_INVALID) {
- LogCacheFlagError (L"Line Size Valid");
- }
-
- // Cache ID was only introduced in revision 3
- if (*(AcpiHdrInfo.Revision) >= 3) {
- if (CacheFlags->CacheIdValid == EFI_ACPI_6_4_PPTT_CACHE_ID_INVALID) {
- LogCacheFlagError (L"Cache Id Valid");
- }
- }
-
- #endif
-}
-
-/**
- This function validates the Cache Type Structure (Type 1) 'Number of sets'
- 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
-ValidateCacheNumberOfSets (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- UINT32 NumberOfSets;
-
- NumberOfSets = *(UINT32 *)Ptr;
-
- if (NumberOfSets == 0) {
- IncrementErrorCount ();
- Print (L"\nERROR: Cache number of sets must be greater than 0");
- return;
- }
-
- #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
- if (NumberOfSets > PPTT_ARM_CCIDX_CACHE_NUMBER_OF_SETS_MAX) {
- IncrementErrorCount ();
- Print (
- L"\nERROR: When ARMv8.3-CCIDX is implemented the maximum cache number of "
- L"sets must be less than or equal to %d",
- PPTT_ARM_CCIDX_CACHE_NUMBER_OF_SETS_MAX
- );
- return;
- }
-
- if (NumberOfSets > PPTT_ARM_CACHE_NUMBER_OF_SETS_MAX) {
- IncrementWarningCount ();
- Print (
- L"\nWARNING: Without ARMv8.3-CCIDX, the maximum cache number of sets "
- L"must be less than or equal to %d. Ignore this message if "
- L"ARMv8.3-CCIDX is implemented",
- PPTT_ARM_CACHE_NUMBER_OF_SETS_MAX
- );
- return;
- }
-
- #endif
-}
-
-/**
- This function validates the Cache Type Structure (Type 1) 'Associativity'
- 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
-ValidateCacheAssociativity (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- UINT8 Associativity;
-
- Associativity = *(UINT8 *)Ptr;
-
- if (Associativity == 0) {
- IncrementErrorCount ();
- Print (L"\nERROR: Cache associativity must be greater than 0");
- return;
- }
-}
-
-/**
- This function validates the Cache Type Structure (Type 1) Line size 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
-ValidateCacheLineSize (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
- // Reference: ARM Architecture Reference Manual ARMv8 (D.a)
- // Section D12.2.25: CCSIDR_EL1, Current Cache Size ID Register
- // LineSize, bits [2:0]
- // (Log2(Number of bytes in cache line)) - 4.
-
- UINT16 LineSize;
- LineSize = *(UINT16 *)Ptr;
-
- if ((LineSize < PPTT_ARM_CACHE_LINE_SIZE_MIN) ||
- (LineSize > PPTT_ARM_CACHE_LINE_SIZE_MAX))
- {
- IncrementErrorCount ();
- Print (
- L"\nERROR: The cache line size must be between %d and %d bytes"
- L" on ARM Platforms.",
- PPTT_ARM_CACHE_LINE_SIZE_MIN,
- PPTT_ARM_CACHE_LINE_SIZE_MAX
- );
- return;
- }
-
- if ((LineSize & (LineSize - 1)) != 0) {
- IncrementErrorCount ();
- Print (L"\nERROR: The cache line size is not a power of 2.");
- }
-
- #endif
-}
-
-/**
- This function validates the Cache Type Structure (Type 1) Cache ID 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
-ValidateCacheId (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- UINT32 CacheId;
-
- CacheId = *(UINT32 *)Ptr;
-
- // Cache ID was only introduced in revision 3
- if (*(AcpiHdrInfo.Revision) < 3) {
- return;
- }
-
- if (CacheFlags == NULL) {
- IncrementErrorCount ();
- Print (L"\nERROR: Cache Structure Flags were not successfully read.");
- return;
- }
-
- if (CacheFlags->CacheIdValid == EFI_ACPI_6_4_PPTT_CACHE_ID_VALID) {
- if (CacheId == 0) {
- IncrementErrorCount ();
- Print (L"\nERROR: 0 is not a valid Cache ID.");
- return;
- }
- }
-}
-
-/**
- This function validates the Cache Type Structure (Type 1) Attributes 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
-ValidateCacheAttributes (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- // Reference: Advanced Configuration and Power Interface (ACPI) Specification
- // Version 6.4, January 2021
- // Table 5-140: Cache Type Structure
- UINT8 Attributes;
-
- Attributes = *(UINT8 *)Ptr;
-
- if ((Attributes & 0xE0) != 0) {
- IncrementErrorCount ();
- Print (
- L"\nERROR: Attributes bits [7:5] are reserved and must be zero.",
- Attributes
- );
- return;
- }
-}
-
-/**
- An ACPI_PARSER array describing the ACPI PPTT Table.
-**/
-STATIC CONST ACPI_PARSER PpttParser[] = {
- PARSE_ACPI_HEADER (&AcpiHdrInfo)
-};
-
-/**
- An ACPI_PARSER array describing the processor topology structure header.
-**/
-STATIC CONST ACPI_PARSER ProcessorTopologyStructureHeaderParser[] = {
- { L"Type", 1, 0, NULL, NULL, (VOID **)&ProcessorTopologyStructureType,
- NULL, NULL },
- { L"Length", 1, 1, NULL, NULL, (VOID **)&ProcessorTopologyStructureLength,
- NULL, NULL },
- { L"Reserved", 2, 2, NULL, NULL, NULL, NULL,NULL }
-};
-
-/**
- An ACPI_PARSER array describing the Processor Hierarchy Node Structure - Type 0.
-**/
-STATIC CONST ACPI_PARSER ProcessorHierarchyNodeStructureParser[] = {
- { 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"Flags", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Parent", 4, 8, L"0x%x", NULL, NULL, NULL, NULL },
- { L"ACPI Processor ID", 4, 12, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Number of private resources", 4, 16, L"%d", NULL,
- (VOID **)&NumberOfPrivateResources, NULL, NULL }
-};
-
-/**
- An ACPI_PARSER array describing the Cache Type Structure - Type 1.
-**/
-STATIC CONST ACPI_PARSER CacheTypeStructureParser[] = {
- { 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"Flags", 4, 4, L"0x%x", NULL, (VOID **)&CacheFlags, ValidateCacheFlags,
- NULL },
- { L"Next Level of Cache", 4, 8, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Size", 4, 12, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Number of sets", 4, 16, L"%d", NULL, NULL, ValidateCacheNumberOfSets, NULL },
- { L"Associativity", 1, 20, L"%d", NULL, NULL, ValidateCacheAssociativity, NULL },
- { L"Attributes", 1, 21, L"0x%x", NULL, NULL, ValidateCacheAttributes, NULL },
- { L"Line size", 2, 22, L"%d", NULL, NULL, ValidateCacheLineSize, NULL },
- { L"Cache ID", 4, 24, L"%d", NULL, NULL, ValidateCacheId, NULL }
-};
-
-/**
- This function parses the Processor Hierarchy Node Structure (Type 0).
-
- @param [in] Ptr Pointer to the start of the Processor Hierarchy Node
- Structure data.
- @param [in] Length Length of the Processor Hierarchy Node Structure.
-**/
-STATIC
-VOID
-DumpProcessorHierarchyNodeStructure (
- IN UINT8 *Ptr,
- IN UINT8 Length
- )
-{
- UINT32 Offset;
- UINT32 Index;
- CHAR16 Buffer[OUTPUT_FIELD_COLUMN_WIDTH];
-
- Offset = ParseAcpi (
- TRUE,
- 2,
- "Processor Hierarchy Node Structure",
- Ptr,
- Length,
- PARSER_PARAMS (ProcessorHierarchyNodeStructureParser)
- );
-
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if (NumberOfPrivateResources == NULL) {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient Processor Hierarchy Node length. Length = %d.\n",
- Length
- );
- return;
- }
-
- // Make sure the Private Resource array lies inside this structure
- if (Offset + (*NumberOfPrivateResources * sizeof (UINT32)) > Length) {
- IncrementErrorCount ();
- Print (
- L"ERROR: Invalid Number of Private Resources. " \
- L"PrivateResourceCount = %d. RemainingBufferLength = %d. " \
- L"Parsing of this structure aborted.\n",
- *NumberOfPrivateResources,
- Length - Offset
- );
- return;
- }
-
- Index = 0;
-
- // Parse the specified number of private resource references or the Processor
- // Hierarchy Node length. Whichever is minimum.
- while (Index < *NumberOfPrivateResources) {
- UnicodeSPrint (
- Buffer,
- sizeof (Buffer),
- L"Private resources [%d]",
- Index
- );
-
- PrintFieldName (4, Buffer);
- Print (
- L"0x%x\n",
- *((UINT32 *)(Ptr + Offset))
- );
-
- Offset += sizeof (UINT32);
- Index++;
- }
-}
-
-/**
- This function parses the Cache Type Structure (Type 1).
-
- @param [in] Ptr Pointer to the start of the Cache Type Structure data.
- @param [in] Length Length of the Cache Type Structure.
-**/
-STATIC
-VOID
-DumpCacheTypeStructure (
- IN UINT8 *Ptr,
- IN UINT8 Length
- )
-{
- ParseAcpi (
- TRUE,
- 2,
- "Cache Type Structure",
- Ptr,
- Length,
- PARSER_PARAMS (CacheTypeStructureParser)
- );
-}
-
-/**
- This function parses the ACPI PPTT table.
- When trace is enabled this function parses the PPTT table and
- traces the ACPI table fields.
-
- This function parses the following processor topology structures:
- - Processor hierarchy node structure (Type 0)
- - Cache Type Structure (Type 1)
-
- 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
-ParseAcpiPptt (
- IN BOOLEAN Trace,
- IN UINT8 *Ptr,
- IN UINT32 AcpiTableLength,
- IN UINT8 AcpiTableRevision
- )
-{
- UINT32 Offset;
- UINT8 *ProcessorTopologyStructurePtr;
-
- if (!Trace) {
- return;
- }
-
- Offset = ParseAcpi (
- TRUE,
- 0,
- "PPTT",
- Ptr,
- AcpiTableLength,
- PARSER_PARAMS (PpttParser)
- );
-
- ProcessorTopologyStructurePtr = Ptr + Offset;
-
- while (Offset < AcpiTableLength) {
- // Parse Processor Hierarchy Node Structure to obtain Type and Length.
- ParseAcpi (
- FALSE,
- 0,
- NULL,
- ProcessorTopologyStructurePtr,
- AcpiTableLength - Offset,
- PARSER_PARAMS (ProcessorTopologyStructureHeaderParser)
- );
-
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if ((ProcessorTopologyStructureType == NULL) ||
- (ProcessorTopologyStructureLength == NULL))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient remaining table buffer length to read the " \
- L"processor topology structure header. Length = %d.\n",
- AcpiTableLength - Offset
- );
- return;
- }
-
- // Validate Processor Topology Structure length
- if ((*ProcessorTopologyStructureLength == 0) ||
- ((Offset + (*ProcessorTopologyStructureLength)) > AcpiTableLength))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Invalid Processor Topology Structure length. " \
- L"Length = %d. Offset = %d. AcpiTableLength = %d.\n",
- *ProcessorTopologyStructureLength,
- Offset,
- AcpiTableLength
- );
- return;
- }
-
- PrintFieldName (2, L"* Structure Offset *");
- Print (L"0x%x\n", Offset);
-
- switch (*ProcessorTopologyStructureType) {
- case EFI_ACPI_6_4_PPTT_TYPE_PROCESSOR:
- DumpProcessorHierarchyNodeStructure (
- ProcessorTopologyStructurePtr,
- *ProcessorTopologyStructureLength
- );
- break;
- case EFI_ACPI_6_4_PPTT_TYPE_CACHE:
- DumpCacheTypeStructure (
- ProcessorTopologyStructurePtr,
- *ProcessorTopologyStructureLength
- );
- break;
- case EFI_ACPI_6_3_PPTT_TYPE_ID:
- IncrementErrorCount ();
- Print (
- L"ERROR: PPTT Type 2 - Processor ID has been removed and must not be"
- L"used.\n"
- );
- break;
- default:
- IncrementErrorCount ();
- Print (
- L"ERROR: Unknown processor topology structure:"
- L" Type = %d, Length = %d\n",
- *ProcessorTopologyStructureType,
- *ProcessorTopologyStructureLength
- );
- }
-
- ProcessorTopologyStructurePtr += *ProcessorTopologyStructureLength;
- Offset += *ProcessorTopologyStructureLength;
- } // while
-}
+/** @file + PPTT table parser + + Copyright (c) 2019 - 2021, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.4 Specification - January 2021 + - ARM Architecture Reference Manual ARMv8 (D.a) +**/ + +#include <Library/PrintLib.h> +#include <Library/UefiLib.h> +#include "AcpiParser.h" +#include "AcpiView.h" +#include "AcpiViewConfig.h" +#include "PpttParser.h" + +// Local variables +STATIC CONST UINT8 *ProcessorTopologyStructureType; +STATIC CONST UINT8 *ProcessorTopologyStructureLength; +STATIC CONST UINT32 *NumberOfPrivateResources; +STATIC CONST EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE_FLAGS *CacheFlags; +STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; + +#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64) + +/** + Increment the error count and print an error that a required flag is missing. + + @param [in] FlagName Name of the missing flag. +**/ +STATIC +VOID +EFIAPI +LogCacheFlagError ( + IN CONST CHAR16 *FlagName + ) +{ + IncrementErrorCount (); + Print ( + L"\nERROR: On Arm based systems, all cache properties must be" + L" provided in the cache type structure." + L" Missing '%s' flag.", + FlagName + ); +} + +#endif + +/** + This function validates the Cache Type Structure (Type 1) Cache Flags 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 +ValidateCacheFlags ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64) + CacheFlags = (EFI_ACPI_6_4_PPTT_STRUCTURE_CACHE_FLAGS *)Ptr; + + if (CacheFlags == NULL) { + IncrementErrorCount (); + Print (L"\nERROR: Cache Structure Flags were not successfully read."); + return; + } + + if (CacheFlags->SizePropertyValid == EFI_ACPI_6_4_PPTT_CACHE_SIZE_INVALID) { + LogCacheFlagError (L"Size Property Valid"); + } + + if (CacheFlags->NumberOfSetsValid == EFI_ACPI_6_4_PPTT_NUMBER_OF_SETS_INVALID) { + LogCacheFlagError (L"Number Of Sets Valid"); + } + + if (CacheFlags->AssociativityValid == EFI_ACPI_6_4_PPTT_ASSOCIATIVITY_INVALID) { + LogCacheFlagError (L"Associativity Valid"); + } + + if (CacheFlags->AllocationTypeValid == EFI_ACPI_6_4_PPTT_ALLOCATION_TYPE_INVALID) { + LogCacheFlagError (L"Allocation Type Valid"); + } + + if (CacheFlags->CacheTypeValid == EFI_ACPI_6_4_PPTT_CACHE_TYPE_INVALID) { + LogCacheFlagError (L"Cache Type Valid"); + } + + if (CacheFlags->WritePolicyValid == EFI_ACPI_6_4_PPTT_WRITE_POLICY_INVALID) { + LogCacheFlagError (L"Write Policy Valid"); + } + + if (CacheFlags->LineSizeValid == EFI_ACPI_6_4_PPTT_LINE_SIZE_INVALID) { + LogCacheFlagError (L"Line Size Valid"); + } + + // Cache ID was only introduced in revision 3 + if (*(AcpiHdrInfo.Revision) >= 3) { + if (CacheFlags->CacheIdValid == EFI_ACPI_6_4_PPTT_CACHE_ID_INVALID) { + LogCacheFlagError (L"Cache Id Valid"); + } + } + + #endif +} + +/** + This function validates the Cache Type Structure (Type 1) 'Number of sets' + 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 +ValidateCacheNumberOfSets ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + UINT32 NumberOfSets; + + NumberOfSets = *(UINT32 *)Ptr; + + if (NumberOfSets == 0) { + IncrementErrorCount (); + Print (L"\nERROR: Cache number of sets must be greater than 0"); + return; + } + + #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64) + if (NumberOfSets > PPTT_ARM_CCIDX_CACHE_NUMBER_OF_SETS_MAX) { + IncrementErrorCount (); + Print ( + L"\nERROR: When ARMv8.3-CCIDX is implemented the maximum cache number of " + L"sets must be less than or equal to %d", + PPTT_ARM_CCIDX_CACHE_NUMBER_OF_SETS_MAX + ); + return; + } + + if (NumberOfSets > PPTT_ARM_CACHE_NUMBER_OF_SETS_MAX) { + IncrementWarningCount (); + Print ( + L"\nWARNING: Without ARMv8.3-CCIDX, the maximum cache number of sets " + L"must be less than or equal to %d. Ignore this message if " + L"ARMv8.3-CCIDX is implemented", + PPTT_ARM_CACHE_NUMBER_OF_SETS_MAX + ); + return; + } + + #endif +} + +/** + This function validates the Cache Type Structure (Type 1) 'Associativity' + 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 +ValidateCacheAssociativity ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + UINT8 Associativity; + + Associativity = *(UINT8 *)Ptr; + + if (Associativity == 0) { + IncrementErrorCount (); + Print (L"\nERROR: Cache associativity must be greater than 0"); + return; + } +} + +/** + This function validates the Cache Type Structure (Type 1) Line size 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 +ValidateCacheLineSize ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64) + // Reference: ARM Architecture Reference Manual ARMv8 (D.a) + // Section D12.2.25: CCSIDR_EL1, Current Cache Size ID Register + // LineSize, bits [2:0] + // (Log2(Number of bytes in cache line)) - 4. + + UINT16 LineSize; + LineSize = *(UINT16 *)Ptr; + + if ((LineSize < PPTT_ARM_CACHE_LINE_SIZE_MIN) || + (LineSize > PPTT_ARM_CACHE_LINE_SIZE_MAX)) + { + IncrementErrorCount (); + Print ( + L"\nERROR: The cache line size must be between %d and %d bytes" + L" on ARM Platforms.", + PPTT_ARM_CACHE_LINE_SIZE_MIN, + PPTT_ARM_CACHE_LINE_SIZE_MAX + ); + return; + } + + if ((LineSize & (LineSize - 1)) != 0) { + IncrementErrorCount (); + Print (L"\nERROR: The cache line size is not a power of 2."); + } + + #endif +} + +/** + This function validates the Cache Type Structure (Type 1) Cache ID 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 +ValidateCacheId ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + UINT32 CacheId; + + CacheId = *(UINT32 *)Ptr; + + // Cache ID was only introduced in revision 3 + if (*(AcpiHdrInfo.Revision) < 3) { + return; + } + + if (CacheFlags == NULL) { + IncrementErrorCount (); + Print (L"\nERROR: Cache Structure Flags were not successfully read."); + return; + } + + if (CacheFlags->CacheIdValid == EFI_ACPI_6_4_PPTT_CACHE_ID_VALID) { + if (CacheId == 0) { + IncrementErrorCount (); + Print (L"\nERROR: 0 is not a valid Cache ID."); + return; + } + } +} + +/** + This function validates the Cache Type Structure (Type 1) Attributes 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 +ValidateCacheAttributes ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + // Reference: Advanced Configuration and Power Interface (ACPI) Specification + // Version 6.4, January 2021 + // Table 5-140: Cache Type Structure + UINT8 Attributes; + + Attributes = *(UINT8 *)Ptr; + + if ((Attributes & 0xE0) != 0) { + IncrementErrorCount (); + Print ( + L"\nERROR: Attributes bits [7:5] are reserved and must be zero.", + Attributes + ); + return; + } +} + +/** + An ACPI_PARSER array describing the ACPI PPTT Table. +**/ +STATIC CONST ACPI_PARSER PpttParser[] = { + PARSE_ACPI_HEADER (&AcpiHdrInfo) +}; + +/** + An ACPI_PARSER array describing the processor topology structure header. +**/ +STATIC CONST ACPI_PARSER ProcessorTopologyStructureHeaderParser[] = { + { L"Type", 1, 0, NULL, NULL, (VOID **)&ProcessorTopologyStructureType, + NULL, NULL }, + { L"Length", 1, 1, NULL, NULL, (VOID **)&ProcessorTopologyStructureLength, + NULL, NULL }, + { L"Reserved", 2, 2, NULL, NULL, NULL, NULL,NULL } +}; + +/** + An ACPI_PARSER array describing the Processor Hierarchy Node Structure - Type 0. +**/ +STATIC CONST ACPI_PARSER ProcessorHierarchyNodeStructureParser[] = { + { 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"Flags", 4, 4, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Parent", 4, 8, L"0x%x", NULL, NULL, NULL, NULL }, + { L"ACPI Processor ID", 4, 12, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Number of private resources", 4, 16, L"%d", NULL, + (VOID **)&NumberOfPrivateResources, NULL, NULL } +}; + +/** + An ACPI_PARSER array describing the Cache Type Structure - Type 1. +**/ +STATIC CONST ACPI_PARSER CacheTypeStructureParser[] = { + { 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"Flags", 4, 4, L"0x%x", NULL, (VOID **)&CacheFlags, ValidateCacheFlags, + NULL }, + { L"Next Level of Cache", 4, 8, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Size", 4, 12, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Number of sets", 4, 16, L"%d", NULL, NULL, ValidateCacheNumberOfSets, NULL }, + { L"Associativity", 1, 20, L"%d", NULL, NULL, ValidateCacheAssociativity, NULL }, + { L"Attributes", 1, 21, L"0x%x", NULL, NULL, ValidateCacheAttributes, NULL }, + { L"Line size", 2, 22, L"%d", NULL, NULL, ValidateCacheLineSize, NULL }, + { L"Cache ID", 4, 24, L"%d", NULL, NULL, ValidateCacheId, NULL } +}; + +/** + This function parses the Processor Hierarchy Node Structure (Type 0). + + @param [in] Ptr Pointer to the start of the Processor Hierarchy Node + Structure data. + @param [in] Length Length of the Processor Hierarchy Node Structure. +**/ +STATIC +VOID +DumpProcessorHierarchyNodeStructure ( + IN UINT8 *Ptr, + IN UINT8 Length + ) +{ + UINT32 Offset; + UINT32 Index; + CHAR16 Buffer[OUTPUT_FIELD_COLUMN_WIDTH]; + + Offset = ParseAcpi ( + TRUE, + 2, + "Processor Hierarchy Node Structure", + Ptr, + Length, + PARSER_PARAMS (ProcessorHierarchyNodeStructureParser) + ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if (NumberOfPrivateResources == NULL) { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient Processor Hierarchy Node length. Length = %d.\n", + Length + ); + return; + } + + // Make sure the Private Resource array lies inside this structure + if (Offset + (*NumberOfPrivateResources * sizeof (UINT32)) > Length) { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid Number of Private Resources. " \ + L"PrivateResourceCount = %d. RemainingBufferLength = %d. " \ + L"Parsing of this structure aborted.\n", + *NumberOfPrivateResources, + Length - Offset + ); + return; + } + + Index = 0; + + // Parse the specified number of private resource references or the Processor + // Hierarchy Node length. Whichever is minimum. + while (Index < *NumberOfPrivateResources) { + UnicodeSPrint ( + Buffer, + sizeof (Buffer), + L"Private resources [%d]", + Index + ); + + PrintFieldName (4, Buffer); + Print ( + L"0x%x\n", + *((UINT32 *)(Ptr + Offset)) + ); + + Offset += sizeof (UINT32); + Index++; + } +} + +/** + This function parses the Cache Type Structure (Type 1). + + @param [in] Ptr Pointer to the start of the Cache Type Structure data. + @param [in] Length Length of the Cache Type Structure. +**/ +STATIC +VOID +DumpCacheTypeStructure ( + IN UINT8 *Ptr, + IN UINT8 Length + ) +{ + ParseAcpi ( + TRUE, + 2, + "Cache Type Structure", + Ptr, + Length, + PARSER_PARAMS (CacheTypeStructureParser) + ); +} + +/** + This function parses the ACPI PPTT table. + When trace is enabled this function parses the PPTT table and + traces the ACPI table fields. + + This function parses the following processor topology structures: + - Processor hierarchy node structure (Type 0) + - Cache Type Structure (Type 1) + + 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 +ParseAcpiPptt ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ) +{ + UINT32 Offset; + UINT8 *ProcessorTopologyStructurePtr; + + if (!Trace) { + return; + } + + Offset = ParseAcpi ( + TRUE, + 0, + "PPTT", + Ptr, + AcpiTableLength, + PARSER_PARAMS (PpttParser) + ); + + ProcessorTopologyStructurePtr = Ptr + Offset; + + while (Offset < AcpiTableLength) { + // Parse Processor Hierarchy Node Structure to obtain Type and Length. + ParseAcpi ( + FALSE, + 0, + NULL, + ProcessorTopologyStructurePtr, + AcpiTableLength - Offset, + PARSER_PARAMS (ProcessorTopologyStructureHeaderParser) + ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if ((ProcessorTopologyStructureType == NULL) || + (ProcessorTopologyStructureLength == NULL)) + { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient remaining table buffer length to read the " \ + L"processor topology structure header. Length = %d.\n", + AcpiTableLength - Offset + ); + return; + } + + // Validate Processor Topology Structure length + if ((*ProcessorTopologyStructureLength == 0) || + ((Offset + (*ProcessorTopologyStructureLength)) > AcpiTableLength)) + { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid Processor Topology Structure length. " \ + L"Length = %d. Offset = %d. AcpiTableLength = %d.\n", + *ProcessorTopologyStructureLength, + Offset, + AcpiTableLength + ); + return; + } + + PrintFieldName (2, L"* Structure Offset *"); + Print (L"0x%x\n", Offset); + + switch (*ProcessorTopologyStructureType) { + case EFI_ACPI_6_4_PPTT_TYPE_PROCESSOR: + DumpProcessorHierarchyNodeStructure ( + ProcessorTopologyStructurePtr, + *ProcessorTopologyStructureLength + ); + break; + case EFI_ACPI_6_4_PPTT_TYPE_CACHE: + DumpCacheTypeStructure ( + ProcessorTopologyStructurePtr, + *ProcessorTopologyStructureLength + ); + break; + case EFI_ACPI_6_3_PPTT_TYPE_ID: + IncrementErrorCount (); + Print ( + L"ERROR: PPTT Type 2 - Processor ID has been removed and must not be" + L"used.\n" + ); + break; + default: + IncrementErrorCount (); + Print ( + L"ERROR: Unknown processor topology structure:" + L" Type = %d, Length = %d\n", + *ProcessorTopologyStructureType, + *ProcessorTopologyStructureLength + ); + } + + ProcessorTopologyStructurePtr += *ProcessorTopologyStructureLength; + Offset += *ProcessorTopologyStructureLength; + } // while +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.h index 6bee88084c..65040855e2 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.h +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Pptt/PpttParser.h @@ -1,38 +1,38 @@ -/** @file
- Header file for PPTT parser
-
- Copyright (c) 2019, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Reference(s):
- - ARM Architecture Reference Manual ARMv8 (D.a)
-**/
-
-#ifndef PPTT_PARSER_H_
-#define PPTT_PARSER_H_
-
-#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
-
-/// Cache parameters allowed by the architecture with
-/// ARMv8.3-CCIDX (Cache extended number of sets)
-/// Derived from CCSIDR_EL1 when ID_AA64MMFR2_EL1.CCIDX==0001
-#define PPTT_ARM_CCIDX_CACHE_NUMBER_OF_SETS_MAX (1 << 24)
-#define PPTT_ARM_CCIDX_CACHE_ASSOCIATIVITY_MAX (1 << 21)
-
-/// Cache parameters allowed by the architecture without
-/// ARMv8.3-CCIDX (Cache extended number of sets)
-/// Derived from CCSIDR_EL1 when ID_AA64MMFR2_EL1.CCIDX==0000
-#define PPTT_ARM_CACHE_NUMBER_OF_SETS_MAX (1 << 15)
-#define PPTT_ARM_CACHE_ASSOCIATIVITY_MAX (1 << 10)
-
-/// Common cache parameters
-/// Derived from CCSIDR_EL1
-/// The LineSize is represented by bits 2:0
-/// (Log2(Number of bytes in cache line)) - 4 is used to represent
-/// the LineSize bits.
-#define PPTT_ARM_CACHE_LINE_SIZE_MAX (1 << 11)
-#define PPTT_ARM_CACHE_LINE_SIZE_MIN (1 << 4)
-
-#endif // if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
-
-#endif // PPTT_PARSER_H_
+/** @file + Header file for PPTT parser + + Copyright (c) 2019, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ARM Architecture Reference Manual ARMv8 (D.a) +**/ + +#ifndef PPTT_PARSER_H_ +#define PPTT_PARSER_H_ + +#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64) + +/// Cache parameters allowed by the architecture with +/// ARMv8.3-CCIDX (Cache extended number of sets) +/// Derived from CCSIDR_EL1 when ID_AA64MMFR2_EL1.CCIDX==0001 +#define PPTT_ARM_CCIDX_CACHE_NUMBER_OF_SETS_MAX (1 << 24) +#define PPTT_ARM_CCIDX_CACHE_ASSOCIATIVITY_MAX (1 << 21) + +/// Cache parameters allowed by the architecture without +/// ARMv8.3-CCIDX (Cache extended number of sets) +/// Derived from CCSIDR_EL1 when ID_AA64MMFR2_EL1.CCIDX==0000 +#define PPTT_ARM_CACHE_NUMBER_OF_SETS_MAX (1 << 15) +#define PPTT_ARM_CACHE_ASSOCIATIVITY_MAX (1 << 10) + +/// Common cache parameters +/// Derived from CCSIDR_EL1 +/// The LineSize is represented by bits 2:0 +/// (Log2(Number of bytes in cache line)) - 4 is used to represent +/// the LineSize bits. +#define PPTT_ARM_CACHE_LINE_SIZE_MAX (1 << 11) +#define PPTT_ARM_CACHE_LINE_SIZE_MIN (1 << 4) + +#endif // if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64) + +#endif // PPTT_PARSER_H_ diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rsdp/RsdpParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rsdp/RsdpParser.c index bddf276356..ba0d58b20a 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rsdp/RsdpParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Rsdp/RsdpParser.c @@ -1,166 +1,166 @@ -/** @file
- RSDP table parser
-
- Copyright (c) 2016 - 2019, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Reference(s):
- - ACPI 6.2 Specification - Errata A, September 2017
-**/
-
-#include <Library/UefiLib.h>
-#include "AcpiParser.h"
-#include "AcpiTableParser.h"
-
-// Local Variables
-STATIC CONST UINT64 *XsdtAddress;
-
-/**
- This function validates the RSDT Address.
-
- @param [in] Ptr Pointer to the start of the field data.
- @param [in] Context Pointer to context specific information e.g. this
- could be a pointer to the ACPI table header.
-**/
-STATIC
-VOID
-EFIAPI
-ValidateRsdtAddress (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- #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;
-
- 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;
-
- XsdtAddr = *(UINT64 *)Ptr;
-
- if (XsdtAddr == 0) {
- IncrementErrorCount ();
- Print (
- L"\nERROR: Xsdt Address = 0x%p. This must not be NULL on ARM Platforms.",
- XsdtAddr
- );
- }
-
- #endif
-}
-
-/**
- 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 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)
- );
-
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if (XsdtAddress == NULL) {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient table length. AcpiTableLength = %d." \
- L"RSDP parsing aborted.\n",
- AcpiTableLength
- );
- return;
- }
-
- // 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. RSDP parsing aborted.\n");
- return;
- }
-
- ProcessAcpiTable ((UINT8 *)(UINTN)(*XsdtAddress));
-}
+/** @file + RSDP table parser + + Copyright (c) 2016 - 2019, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.2 Specification - Errata A, September 2017 +**/ + +#include <Library/UefiLib.h> +#include "AcpiParser.h" +#include "AcpiTableParser.h" + +// Local Variables +STATIC CONST UINT64 *XsdtAddress; + +/** + This function validates the RSDT Address. + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Context Pointer to context specific information e.g. this + could be a pointer to the ACPI table header. +**/ +STATIC +VOID +EFIAPI +ValidateRsdtAddress ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + #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; + + 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; + + XsdtAddr = *(UINT64 *)Ptr; + + if (XsdtAddr == 0) { + IncrementErrorCount (); + Print ( + L"\nERROR: Xsdt Address = 0x%p. This must not be NULL on ARM Platforms.", + XsdtAddr + ); + } + + #endif +} + +/** + 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 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) + ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if (XsdtAddress == NULL) { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient table length. AcpiTableLength = %d." \ + L"RSDP parsing aborted.\n", + AcpiTableLength + ); + return; + } + + // 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. RSDP parsing aborted.\n"); + return; + } + + ProcessAcpiTable ((UINT8 *)(UINTN)(*XsdtAddress)); +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Slit/SlitParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Slit/SlitParser.c index 71cc12cc2b..7e65f81cd6 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Slit/SlitParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Slit/SlitParser.c @@ -1,192 +1,192 @@ -/** @file
- SLIT table parser
-
- Copyright (c) 2016 - 2019, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Reference(s):
- - ACPI 6.2 Specification - Errata A, September 2017
-**/
-
-#include <IndustryStandard/Acpi.h>
-#include <Library/PrintLib.h>
-#include <Library/UefiLib.h>
-#include "AcpiParser.h"
-#include "AcpiTableParser.h"
-
-// Local Variables
-STATIC CONST UINT64 *SlitSystemLocalityCount;
-STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
-
-/**
- An ACPI_PARSER array describing the ACPI SLIT table.
-**/
-STATIC CONST ACPI_PARSER SlitParser[] = {
- PARSE_ACPI_HEADER (&AcpiHdrInfo),
- { L"Number of System Localities", 8, 36, L"0x%lx", NULL,
- (VOID **)&SlitSystemLocalityCount,NULL, NULL }
-};
-
-/**
- Macro to get the value of a System Locality
-**/
-#define SLIT_ELEMENT(Ptr, i, j) *(Ptr + (i * LocalityCount) + j)
-
-/**
- This function parses the ACPI SLIT table.
- When trace is enabled this function parses the SLIT table and
- traces the ACPI table fields.
-
- This function also validates System Localities for the following:
- - Diagonal elements have a normalized value of 10
- - Relative distance from System Locality at i*N+j is same as
- j*N+i
-
- @param [in] Trace If TRUE, trace the ACPI fields.
- @param [in] Ptr Pointer to the start of the buffer.
- @param [in] AcpiTableLength Length of the ACPI table.
- @param [in] AcpiTableRevision Revision of the ACPI table.
-**/
-VOID
-EFIAPI
-ParseAcpiSlit (
- IN BOOLEAN Trace,
- IN UINT8 *Ptr,
- IN UINT32 AcpiTableLength,
- IN UINT8 AcpiTableRevision
- )
-{
- UINT32 Offset;
- UINT32 Count;
- UINT32 Index;
- UINT32 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)
- );
-
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if (SlitSystemLocalityCount == NULL) {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient table length. AcpiTableLength = %d.\n",
- AcpiTableLength
- );
- return;
- }
-
- /*
- Despite the 'Number of System Localities' being a 64-bit field in SLIT,
- the maximum number of localities that can be represented in SLIT is limited
- by the 'Length' field of the ACPI table.
-
- Since the ACPI table length field is 32-bit wide. The maximum number of
- localities that can be represented in SLIT can be calculated as:
-
- MaxLocality = sqrt (MAX_UINT32 - sizeof (EFI_ACPI_6_3_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER))
- = 65535
- = MAX_UINT16
- */
- if (*SlitSystemLocalityCount > MAX_UINT16) {
- IncrementErrorCount ();
- Print (
- L"ERROR: The Number of System Localities provided can't be represented " \
- L"in the SLIT table. SlitSystemLocalityCount = %ld. " \
- L"MaxLocalityCountAllowed = %d.\n",
- *SlitSystemLocalityCount,
- MAX_UINT16
- );
- return;
- }
-
- LocalityCount = (UINT32)*SlitSystemLocalityCount;
-
- // Make sure system localities fit in the table buffer provided
- if (Offset + (LocalityCount * LocalityCount) > AcpiTableLength) {
- IncrementErrorCount ();
- Print (
- L"ERROR: Invalid Number of System Localities. " \
- L"SlitSystemLocalityCount = %ld. AcpiTableLength = %d.\n",
- *SlitSystemLocalityCount,
- AcpiTableLength
- );
- return;
- }
-
- LocalityPtr = Ptr + Offset;
-
- // 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 (Index = 0; Index < LocalityCount; Index++) {
- Print (L" (%3d) ", Index);
- }
-
- Print (L"\n");
- for (Count = 0; Count < LocalityCount; Count++) {
- Print (L" (%3d) ", Count);
- for (Index = 0; Index < LocalityCount; Index++) {
- Print (L" %3d ", SLIT_ELEMENT (LocalityPtr, Count, Index));
- }
-
- Print (L"\n");
- }
- }
-
- // Validate
- for (Count = 0; Count < LocalityCount; Count++) {
- for (Index = 0; Index < LocalityCount; Index++) {
- // Element[x][x] must be equal to 10
- if ((Count == Index) && (SLIT_ELEMENT (LocalityPtr, Count, Index) != 10)) {
- IncrementErrorCount ();
- Print (
- L"ERROR: Diagonal Element[0x%lx][0x%lx] (%3d)."
- L" Normalized Value is not 10\n",
- Count,
- Index,
- SLIT_ELEMENT (LocalityPtr, Count, Index)
- );
- }
-
- // Element[i][j] must be equal to Element[j][i]
- if (SLIT_ELEMENT (LocalityPtr, Count, Index) !=
- SLIT_ELEMENT (LocalityPtr, Index, Count))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Relative distances for Element[0x%lx][0x%lx] (%3d) and \n"
- L"Element[0x%lx][0x%lx] (%3d) do not match.\n",
- Count,
- Index,
- SLIT_ELEMENT (LocalityPtr, Count, Index),
- Index,
- Count,
- SLIT_ELEMENT (LocalityPtr, Index, Count)
- );
- }
- }
- }
-}
+/** @file + SLIT table parser + + Copyright (c) 2016 - 2019, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.2 Specification - Errata A, September 2017 +**/ + +#include <IndustryStandard/Acpi.h> +#include <Library/PrintLib.h> +#include <Library/UefiLib.h> +#include "AcpiParser.h" +#include "AcpiTableParser.h" + +// Local Variables +STATIC CONST UINT64 *SlitSystemLocalityCount; +STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; + +/** + An ACPI_PARSER array describing the ACPI SLIT table. +**/ +STATIC CONST ACPI_PARSER SlitParser[] = { + PARSE_ACPI_HEADER (&AcpiHdrInfo), + { L"Number of System Localities", 8, 36, L"0x%lx", NULL, + (VOID **)&SlitSystemLocalityCount,NULL, NULL } +}; + +/** + Macro to get the value of a System Locality +**/ +#define SLIT_ELEMENT(Ptr, i, j) *(Ptr + (i * LocalityCount) + j) + +/** + This function parses the ACPI SLIT table. + When trace is enabled this function parses the SLIT table and + traces the ACPI table fields. + + This function also validates System Localities for the following: + - Diagonal elements have a normalized value of 10 + - Relative distance from System Locality at i*N+j is same as + j*N+i + + @param [in] Trace If TRUE, trace the ACPI fields. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] AcpiTableLength Length of the ACPI table. + @param [in] AcpiTableRevision Revision of the ACPI table. +**/ +VOID +EFIAPI +ParseAcpiSlit ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ) +{ + UINT32 Offset; + UINT32 Count; + UINT32 Index; + UINT32 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) + ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if (SlitSystemLocalityCount == NULL) { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient table length. AcpiTableLength = %d.\n", + AcpiTableLength + ); + return; + } + + /* + Despite the 'Number of System Localities' being a 64-bit field in SLIT, + the maximum number of localities that can be represented in SLIT is limited + by the 'Length' field of the ACPI table. + + Since the ACPI table length field is 32-bit wide. The maximum number of + localities that can be represented in SLIT can be calculated as: + + MaxLocality = sqrt (MAX_UINT32 - sizeof (EFI_ACPI_6_3_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER)) + = 65535 + = MAX_UINT16 + */ + if (*SlitSystemLocalityCount > MAX_UINT16) { + IncrementErrorCount (); + Print ( + L"ERROR: The Number of System Localities provided can't be represented " \ + L"in the SLIT table. SlitSystemLocalityCount = %ld. " \ + L"MaxLocalityCountAllowed = %d.\n", + *SlitSystemLocalityCount, + MAX_UINT16 + ); + return; + } + + LocalityCount = (UINT32)*SlitSystemLocalityCount; + + // Make sure system localities fit in the table buffer provided + if (Offset + (LocalityCount * LocalityCount) > AcpiTableLength) { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid Number of System Localities. " \ + L"SlitSystemLocalityCount = %ld. AcpiTableLength = %d.\n", + *SlitSystemLocalityCount, + AcpiTableLength + ); + return; + } + + LocalityPtr = Ptr + Offset; + + // 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 (Index = 0; Index < LocalityCount; Index++) { + Print (L" (%3d) ", Index); + } + + Print (L"\n"); + for (Count = 0; Count < LocalityCount; Count++) { + Print (L" (%3d) ", Count); + for (Index = 0; Index < LocalityCount; Index++) { + Print (L" %3d ", SLIT_ELEMENT (LocalityPtr, Count, Index)); + } + + Print (L"\n"); + } + } + + // Validate + for (Count = 0; Count < LocalityCount; Count++) { + for (Index = 0; Index < LocalityCount; Index++) { + // Element[x][x] must be equal to 10 + if ((Count == Index) && (SLIT_ELEMENT (LocalityPtr, Count, Index) != 10)) { + IncrementErrorCount (); + Print ( + L"ERROR: Diagonal Element[0x%lx][0x%lx] (%3d)." + L" Normalized Value is not 10\n", + Count, + Index, + SLIT_ELEMENT (LocalityPtr, Count, Index) + ); + } + + // Element[i][j] must be equal to Element[j][i] + if (SLIT_ELEMENT (LocalityPtr, Count, Index) != + SLIT_ELEMENT (LocalityPtr, Index, Count)) + { + IncrementErrorCount (); + Print ( + L"ERROR: Relative distances for Element[0x%lx][0x%lx] (%3d) and \n" + L"Element[0x%lx][0x%lx] (%3d) do not match.\n", + Count, + Index, + SLIT_ELEMENT (LocalityPtr, Count, Index), + Index, + Count, + SLIT_ELEMENT (LocalityPtr, Index, Count) + ); + } + } + } +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Spcr/SpcrParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Spcr/SpcrParser.c index e5267b1d04..72dda11a03 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Spcr/SpcrParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Spcr/SpcrParser.c @@ -1,147 +1,147 @@ -/** @file
- SPCR table parser
-
- Copyright (c) 2016 - 2019, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Reference(s):
- - Microsoft Serial Port Console Redirection Table
- Specification - Version 1.03 - August 10, 2015.
-**/
-
-#include <IndustryStandard/Acpi.h>
-#include <IndustryStandard/SerialPortConsoleRedirectionTable.h>
-#include <Library/UefiLib.h>
-#include "AcpiParser.h"
-#include "AcpiTableParser.h"
-
-// Local variables
-STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
-
-/**
- This function validates the Interrupt Type.
-
- @param [in] Ptr Pointer to the start of the field data.
- @param [in] Context Pointer to context specific information e.g. this
- could be a pointer to the ACPI table header.
-**/
-STATIC
-VOID
-EFIAPI
-ValidateInterruptType (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
- UINT8 InterruptType;
-
- 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;
-
- Irq = *Ptr;
-
- if (Irq != 0) {
- IncrementErrorCount ();
- Print (
- L"\nERROR: Irq = %d. This must be zero on ARM Platforms\n",
- Irq
- );
- }
-
- #endif
-}
-
-/**
- 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 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)
- );
-}
+/** @file + SPCR table parser + + Copyright (c) 2016 - 2019, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - Microsoft Serial Port Console Redirection Table + Specification - Version 1.03 - August 10, 2015. +**/ + +#include <IndustryStandard/Acpi.h> +#include <IndustryStandard/SerialPortConsoleRedirectionTable.h> +#include <Library/UefiLib.h> +#include "AcpiParser.h" +#include "AcpiTableParser.h" + +// Local variables +STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; + +/** + This function validates the Interrupt Type. + + @param [in] Ptr Pointer to the start of the field data. + @param [in] Context Pointer to context specific information e.g. this + could be a pointer to the ACPI table header. +**/ +STATIC +VOID +EFIAPI +ValidateInterruptType ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64) + UINT8 InterruptType; + + 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; + + Irq = *Ptr; + + if (Irq != 0) { + IncrementErrorCount (); + Print ( + L"\nERROR: Irq = %d. This must be zero on ARM Platforms\n", + Irq + ); + } + + #endif +} + +/** + 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 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 index 2980704479..9bc40b70f7 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Srat/SratParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Srat/SratParser.c @@ -1,544 +1,544 @@ -/** @file
- SRAT table parser
-
- Copyright (c) 2016 - 2020, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Reference(s):
- - ACPI 6.3 Specification - January 2019
-**/
-
-#include <IndustryStandard/Acpi.h>
-#include <Library/PrintLib.h>
-#include <Library/UefiLib.h>
-#include "AcpiParser.h"
-#include "AcpiTableParser.h"
-#include "AcpiViewConfig.h"
-
-// Local Variables
-STATIC CONST UINT8 *SratRAType;
-STATIC CONST UINT8 *SratRALength;
-STATIC CONST UINT8 *SratDeviceHandleType;
-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
- )
-{
- if (*(UINT32 *)Ptr != 1) {
- IncrementErrorCount ();
- Print (L"\nERROR: Reserved should be 1 for backward compatibility.\n");
- }
-}
-
-/**
- This function validates the Device Handle Type field in the Generic Initiator
- Affinity Structure.
-
- @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
-ValidateSratDeviceHandleType (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- UINT8 DeviceHandleType;
-
- DeviceHandleType = *Ptr;
-
- if (DeviceHandleType > EFI_ACPI_6_3_PCI_DEVICE_HANDLE) {
- IncrementErrorCount ();
- Print (
- L"\nERROR: Invalid Device Handle Type: %d. Must be between 0 and %d.",
- DeviceHandleType,
- EFI_ACPI_6_3_PCI_DEVICE_HANDLE
- );
- }
-}
-
-/**
- This function traces the PCI BDF Number field inside Device Handle - PCI
-
- @param [in] Format Format string for tracing the data.
- @param [in] Ptr Pointer to the start of the buffer.
-**/
-STATIC
-VOID
-EFIAPI
-DumpSratPciBdfNumber (
- IN CONST CHAR16 *Format,
- IN UINT8 *Ptr
- )
-{
- CHAR16 Buffer[OUTPUT_FIELD_COLUMN_WIDTH];
-
- Print (L"\n");
-
- /*
- The PCI BDF Number subfields are printed in the order specified in the ACPI
- specification. The format of the 16-bit PCI BDF Number field is as follows:
-
- +-----+------+------+
- |DEV | FUNC | BUS |
- +-----+------+------+
- |15:11| 10:8 | 7:0 |
- +-----+------+------+
- */
-
- // Print PCI Bus Number (Bits 7:0 of Byte 2)
- UnicodeSPrint (
- Buffer,
- sizeof (Buffer),
- L"PCI Bus Number"
- );
- PrintFieldName (4, Buffer);
- Print (
- L"0x%x\n",
- *Ptr
- );
-
- Ptr++;
-
- // Print PCI Device Number (Bits 7:3 of Byte 3)
- UnicodeSPrint (
- Buffer,
- sizeof (Buffer),
- L"PCI Device Number"
- );
- PrintFieldName (4, Buffer);
- Print (
- L"0x%x\n",
- (*Ptr & (BIT7 | BIT6 | BIT5 | BIT4 | BIT3)) >> 3
- );
-
- // PCI Function Number (Bits 2:0 of Byte 3)
- UnicodeSPrint (
- Buffer,
- sizeof (Buffer),
- L"PCI Function Number"
- );
- PrintFieldName (4, Buffer);
- Print (
- L"0x%x\n",
- *Ptr & (BIT2 | BIT1 | BIT0)
- );
-}
-
-/**
- An ACPI_PARSER array describing the Device Handle - ACPI
-**/
-STATIC CONST ACPI_PARSER SratDeviceHandleAcpiParser[] = {
- { L"ACPI_HID", 8, 0, L"0x%lx", NULL, NULL, NULL, NULL },
- { L"ACPI_UID", 4, 8, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Reserved", 4, 12, L"0x%x", NULL, NULL, NULL, NULL }
-};
-
-/**
- An ACPI_PARSER array describing the Device Handle - PCI
-**/
-STATIC CONST ACPI_PARSER SratDeviceHandlePciParser[] = {
- { L"PCI Segment", 2, 0, L"0x%x", NULL, NULL, NULL, NULL },
- { L"PCI BDF Number", 2, 2, NULL, DumpSratPciBdfNumber, NULL, NULL, NULL },
- { L"Reserved", 12, 4, L"%x %x %x %x - %x %x %x %x - %x %x %x %x", Dump12Chars,
- NULL, NULL, NULL }
-};
-
-/**
- This function traces the Device Handle field inside Generic Initiator
- Affinity Structure.
-
- @param [in] Format Format string for tracing the data.
- @param [in] Ptr Pointer to the start of the buffer.
-**/
-STATIC
-VOID
-EFIAPI
-DumpSratDeviceHandle (
- IN CONST CHAR16 *Format,
- IN UINT8 *Ptr
- )
-{
- if (SratDeviceHandleType == NULL) {
- IncrementErrorCount ();
- Print (L"\nERROR: Device Handle Type read incorrectly.\n");
- return;
- }
-
- Print (L"\n");
-
- if (*SratDeviceHandleType == EFI_ACPI_6_3_ACPI_DEVICE_HANDLE) {
- ParseAcpi (
- TRUE,
- 2,
- NULL,
- Ptr,
- sizeof (EFI_ACPI_6_3_DEVICE_HANDLE_ACPI),
- PARSER_PARAMS (SratDeviceHandleAcpiParser)
- );
- } else if (*SratDeviceHandleType == EFI_ACPI_6_3_PCI_DEVICE_HANDLE) {
- ParseAcpi (
- TRUE,
- 2,
- NULL,
- Ptr,
- sizeof (EFI_ACPI_6_3_DEVICE_HANDLE_PCI),
- PARSER_PARAMS (SratDeviceHandlePciParser)
- );
- }
-}
-
-/**
- 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
-EFIAPI
-DumpSratApicProximity (
- IN CONST CHAR16 *Format,
- IN UINT8 *Ptr
- )
-{
- UINT32 ProximityDomain;
-
- ProximityDomain = Ptr[0] | (Ptr[1] << 8) | (Ptr[2] << 16);
-
- Print (Format, ProximityDomain);
-}
-
-/**
- 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 Generic Initiator Affinity Structure
-**/
-STATIC CONST ACPI_PARSER SratGenericInitiatorAffinityParser[] = {
- { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Length", 1, 1, L"0x%x", NULL, NULL, NULL, NULL },
-
- { L"Reserved", 1, 2, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Device Handle Type", 1, 3, L"%d", NULL, (VOID **)&SratDeviceHandleType,
- ValidateSratDeviceHandleType, NULL },
- { L"Proximity Domain", 4, 4, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Device Handle", 16, 8, L"%s", DumpSratDeviceHandle, 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 }
-};
-
-/**
- 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 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;
- UINT32 GicITSAffinityIndex;
- UINT32 GenericInitiatorAffinityIndex;
- UINT32 MemoryAffinityIndex;
- UINT32 ApicSapicAffinityIndex;
- UINT32 X2ApicAffinityIndex;
- CHAR8 Buffer[80]; // Used for AsciiName param of ParseAcpi
-
- GicCAffinityIndex = 0;
- GicITSAffinityIndex = 0;
- GenericInitiatorAffinityIndex = 0;
- MemoryAffinityIndex = 0;
- ApicSapicAffinityIndex = 0;
- X2ApicAffinityIndex = 0;
-
- if (!Trace) {
- return;
- }
-
- Offset = ParseAcpi (
- TRUE,
- 0,
- "SRAT",
- Ptr,
- AcpiTableLength,
- PARSER_PARAMS (SratParser)
- );
-
- ResourcePtr = Ptr + Offset;
-
- while (Offset < AcpiTableLength) {
- ParseAcpi (
- FALSE,
- 0,
- NULL,
- ResourcePtr,
- AcpiTableLength - Offset,
- PARSER_PARAMS (SratResourceAllocationParser)
- );
-
- // Check if the values used to control the parsing logic have been
- // successfully read.
- if ((SratRAType == NULL) ||
- (SratRALength == NULL))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Insufficient remaining table buffer length to read the " \
- L"Static Resource Allocation structure header. Length = %d.\n",
- AcpiTableLength - Offset
- );
- return;
- }
-
- // Validate Static Resource Allocation Structure length
- if ((*SratRALength == 0) ||
- ((Offset + (*SratRALength)) > AcpiTableLength))
- {
- IncrementErrorCount ();
- Print (
- L"ERROR: Invalid Static Resource Allocation Structure length. " \
- L"Length = %d. Offset = %d. AcpiTableLength = %d.\n",
- *SratRALength,
- Offset,
- AcpiTableLength
- );
- return;
- }
-
- switch (*SratRAType) {
- case EFI_ACPI_6_3_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_3_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_3_GENERIC_INITIATOR_AFFINITY:
- AsciiSPrint (
- Buffer,
- sizeof (Buffer),
- "Generic Initiator Affinity Structure [%d]",
- GenericInitiatorAffinityIndex++
- );
- ParseAcpi (
- TRUE,
- 2,
- Buffer,
- ResourcePtr,
- *SratRALength,
- PARSER_PARAMS (SratGenericInitiatorAffinityParser)
- );
- break;
-
- case EFI_ACPI_6_3_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_3_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_3_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);
- }
-}
+/** @file + SRAT table parser + + Copyright (c) 2016 - 2020, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.3 Specification - January 2019 +**/ + +#include <IndustryStandard/Acpi.h> +#include <Library/PrintLib.h> +#include <Library/UefiLib.h> +#include "AcpiParser.h" +#include "AcpiTableParser.h" +#include "AcpiViewConfig.h" + +// Local Variables +STATIC CONST UINT8 *SratRAType; +STATIC CONST UINT8 *SratRALength; +STATIC CONST UINT8 *SratDeviceHandleType; +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 + ) +{ + if (*(UINT32 *)Ptr != 1) { + IncrementErrorCount (); + Print (L"\nERROR: Reserved should be 1 for backward compatibility.\n"); + } +} + +/** + This function validates the Device Handle Type field in the Generic Initiator + Affinity Structure. + + @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 +ValidateSratDeviceHandleType ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + UINT8 DeviceHandleType; + + DeviceHandleType = *Ptr; + + if (DeviceHandleType > EFI_ACPI_6_3_PCI_DEVICE_HANDLE) { + IncrementErrorCount (); + Print ( + L"\nERROR: Invalid Device Handle Type: %d. Must be between 0 and %d.", + DeviceHandleType, + EFI_ACPI_6_3_PCI_DEVICE_HANDLE + ); + } +} + +/** + This function traces the PCI BDF Number field inside Device Handle - PCI + + @param [in] Format Format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. +**/ +STATIC +VOID +EFIAPI +DumpSratPciBdfNumber ( + IN CONST CHAR16 *Format, + IN UINT8 *Ptr + ) +{ + CHAR16 Buffer[OUTPUT_FIELD_COLUMN_WIDTH]; + + Print (L"\n"); + + /* + The PCI BDF Number subfields are printed in the order specified in the ACPI + specification. The format of the 16-bit PCI BDF Number field is as follows: + + +-----+------+------+ + |DEV | FUNC | BUS | + +-----+------+------+ + |15:11| 10:8 | 7:0 | + +-----+------+------+ + */ + + // Print PCI Bus Number (Bits 7:0 of Byte 2) + UnicodeSPrint ( + Buffer, + sizeof (Buffer), + L"PCI Bus Number" + ); + PrintFieldName (4, Buffer); + Print ( + L"0x%x\n", + *Ptr + ); + + Ptr++; + + // Print PCI Device Number (Bits 7:3 of Byte 3) + UnicodeSPrint ( + Buffer, + sizeof (Buffer), + L"PCI Device Number" + ); + PrintFieldName (4, Buffer); + Print ( + L"0x%x\n", + (*Ptr & (BIT7 | BIT6 | BIT5 | BIT4 | BIT3)) >> 3 + ); + + // PCI Function Number (Bits 2:0 of Byte 3) + UnicodeSPrint ( + Buffer, + sizeof (Buffer), + L"PCI Function Number" + ); + PrintFieldName (4, Buffer); + Print ( + L"0x%x\n", + *Ptr & (BIT2 | BIT1 | BIT0) + ); +} + +/** + An ACPI_PARSER array describing the Device Handle - ACPI +**/ +STATIC CONST ACPI_PARSER SratDeviceHandleAcpiParser[] = { + { L"ACPI_HID", 8, 0, L"0x%lx", NULL, NULL, NULL, NULL }, + { L"ACPI_UID", 4, 8, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Reserved", 4, 12, L"0x%x", NULL, NULL, NULL, NULL } +}; + +/** + An ACPI_PARSER array describing the Device Handle - PCI +**/ +STATIC CONST ACPI_PARSER SratDeviceHandlePciParser[] = { + { L"PCI Segment", 2, 0, L"0x%x", NULL, NULL, NULL, NULL }, + { L"PCI BDF Number", 2, 2, NULL, DumpSratPciBdfNumber, NULL, NULL, NULL }, + { L"Reserved", 12, 4, L"%x %x %x %x - %x %x %x %x - %x %x %x %x", Dump12Chars, + NULL, NULL, NULL } +}; + +/** + This function traces the Device Handle field inside Generic Initiator + Affinity Structure. + + @param [in] Format Format string for tracing the data. + @param [in] Ptr Pointer to the start of the buffer. +**/ +STATIC +VOID +EFIAPI +DumpSratDeviceHandle ( + IN CONST CHAR16 *Format, + IN UINT8 *Ptr + ) +{ + if (SratDeviceHandleType == NULL) { + IncrementErrorCount (); + Print (L"\nERROR: Device Handle Type read incorrectly.\n"); + return; + } + + Print (L"\n"); + + if (*SratDeviceHandleType == EFI_ACPI_6_3_ACPI_DEVICE_HANDLE) { + ParseAcpi ( + TRUE, + 2, + NULL, + Ptr, + sizeof (EFI_ACPI_6_3_DEVICE_HANDLE_ACPI), + PARSER_PARAMS (SratDeviceHandleAcpiParser) + ); + } else if (*SratDeviceHandleType == EFI_ACPI_6_3_PCI_DEVICE_HANDLE) { + ParseAcpi ( + TRUE, + 2, + NULL, + Ptr, + sizeof (EFI_ACPI_6_3_DEVICE_HANDLE_PCI), + PARSER_PARAMS (SratDeviceHandlePciParser) + ); + } +} + +/** + 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 +EFIAPI +DumpSratApicProximity ( + IN CONST CHAR16 *Format, + IN UINT8 *Ptr + ) +{ + UINT32 ProximityDomain; + + ProximityDomain = Ptr[0] | (Ptr[1] << 8) | (Ptr[2] << 16); + + Print (Format, ProximityDomain); +} + +/** + 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 Generic Initiator Affinity Structure +**/ +STATIC CONST ACPI_PARSER SratGenericInitiatorAffinityParser[] = { + { L"Type", 1, 0, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Length", 1, 1, L"0x%x", NULL, NULL, NULL, NULL }, + + { L"Reserved", 1, 2, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Device Handle Type", 1, 3, L"%d", NULL, (VOID **)&SratDeviceHandleType, + ValidateSratDeviceHandleType, NULL }, + { L"Proximity Domain", 4, 4, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Device Handle", 16, 8, L"%s", DumpSratDeviceHandle, 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 } +}; + +/** + 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 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; + UINT32 GicITSAffinityIndex; + UINT32 GenericInitiatorAffinityIndex; + UINT32 MemoryAffinityIndex; + UINT32 ApicSapicAffinityIndex; + UINT32 X2ApicAffinityIndex; + CHAR8 Buffer[80]; // Used for AsciiName param of ParseAcpi + + GicCAffinityIndex = 0; + GicITSAffinityIndex = 0; + GenericInitiatorAffinityIndex = 0; + MemoryAffinityIndex = 0; + ApicSapicAffinityIndex = 0; + X2ApicAffinityIndex = 0; + + if (!Trace) { + return; + } + + Offset = ParseAcpi ( + TRUE, + 0, + "SRAT", + Ptr, + AcpiTableLength, + PARSER_PARAMS (SratParser) + ); + + ResourcePtr = Ptr + Offset; + + while (Offset < AcpiTableLength) { + ParseAcpi ( + FALSE, + 0, + NULL, + ResourcePtr, + AcpiTableLength - Offset, + PARSER_PARAMS (SratResourceAllocationParser) + ); + + // Check if the values used to control the parsing logic have been + // successfully read. + if ((SratRAType == NULL) || + (SratRALength == NULL)) + { + IncrementErrorCount (); + Print ( + L"ERROR: Insufficient remaining table buffer length to read the " \ + L"Static Resource Allocation structure header. Length = %d.\n", + AcpiTableLength - Offset + ); + return; + } + + // Validate Static Resource Allocation Structure length + if ((*SratRALength == 0) || + ((Offset + (*SratRALength)) > AcpiTableLength)) + { + IncrementErrorCount (); + Print ( + L"ERROR: Invalid Static Resource Allocation Structure length. " \ + L"Length = %d. Offset = %d. AcpiTableLength = %d.\n", + *SratRALength, + Offset, + AcpiTableLength + ); + return; + } + + switch (*SratRAType) { + case EFI_ACPI_6_3_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_3_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_3_GENERIC_INITIATOR_AFFINITY: + AsciiSPrint ( + Buffer, + sizeof (Buffer), + "Generic Initiator Affinity Structure [%d]", + GenericInitiatorAffinityIndex++ + ); + ParseAcpi ( + TRUE, + 2, + Buffer, + ResourcePtr, + *SratRALength, + PARSER_PARAMS (SratGenericInitiatorAffinityParser) + ); + break; + + case EFI_ACPI_6_3_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_3_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_3_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 index 1fc8f2f4a6..57151420be 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Ssdt/SsdtParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Ssdt/SsdtParser.c @@ -1,42 +1,42 @@ -/** @file
- SSDT table parser
-
- Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Reference(s):
- - ACPI 6.2 Specification - Errata A, September 2017
-**/
-
-#include <IndustryStandard/Acpi.h>
-#include <Library/UefiLib.h>
-#include "AcpiParser.h"
-#include "AcpiTableParser.h"
-
-/**
- This function parses the ACPI SSDT table.
- When trace is enabled this function parses the SSDT table and
- traces the ACPI table fields.
- For the SSDT table only the ACPI header fields are
- parsed and traced.
-
- @param [in] Trace If TRUE, trace the ACPI fields.
- @param [in] Ptr Pointer to the start of the buffer.
- @param [in] AcpiTableLength Length of the ACPI table.
- @param [in] AcpiTableRevision Revision of the ACPI table.
-**/
-VOID
-EFIAPI
-ParseAcpiSsdt (
- IN BOOLEAN Trace,
- IN UINT8 *Ptr,
- IN UINT32 AcpiTableLength,
- IN UINT8 AcpiTableRevision
- )
-{
- if (!Trace) {
- return;
- }
-
- DumpAcpiHeader (Ptr);
-}
+/** @file + SSDT table parser + + Copyright (c) 2016 - 2018, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.2 Specification - Errata A, September 2017 +**/ + +#include <IndustryStandard/Acpi.h> +#include <Library/UefiLib.h> +#include "AcpiParser.h" +#include "AcpiTableParser.h" + +/** + This function parses the ACPI SSDT table. + When trace is enabled this function parses the SSDT table and + traces the ACPI table fields. + For the SSDT table only the ACPI header fields are + parsed and traced. + + @param [in] Trace If TRUE, trace the ACPI fields. + @param [in] Ptr Pointer to the start of the buffer. + @param [in] AcpiTableLength Length of the ACPI table. + @param [in] AcpiTableRevision Revision of the ACPI table. +**/ +VOID +EFIAPI +ParseAcpiSsdt ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ) +{ + if (!Trace) { + return; + } + + DumpAcpiHeader (Ptr); +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Wsmt/WsmtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Wsmt/WsmtParser.c index 3c7252b0bf..de877011b7 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Wsmt/WsmtParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Wsmt/WsmtParser.c @@ -1,147 +1,147 @@ -/** @file
- WSMT table parser
-
- Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Reference(s):
- - Windows SMM Security Mitigation Table spec, version 1.0
-**/
-
-#include <Library/UefiLib.h>
-#include <IndustryStandard/WindowsSmmSecurityMitigationTable.h>
-#include "AcpiParser.h"
-
-STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
-
-/**
- This function validates the WSMT Protection flag.
-
- @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
-ValidateWsmtProtectionFlag (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- UINT32 ProtectionFlag;
-
- ProtectionFlag = *(UINT32 *)Ptr;
-
- if ((ProtectionFlag & EFI_WSMT_PROTECTION_FLAGS_COMM_BUFFER_NESTED_PTR_PROTECTION) \
- == EFI_WSMT_PROTECTION_FLAGS_COMM_BUFFER_NESTED_PTR_PROTECTION)
- {
- if ((ProtectionFlag & EFI_WSMT_PROTECTION_FLAGS_FIXED_COMM_BUFFERS) \
- != EFI_WSMT_PROTECTION_FLAGS_FIXED_COMM_BUFFERS)
- {
- IncrementErrorCount ();
- Print (L"ERROR: COMM_BUFFER_NESTED_PTR_PROTECTION is set but FIXED_COMM_BUFFERS is not set.\n");
- }
- }
-}
-
-/**
- This function validates the reserved bits in the WSMT Protection flag.
-
- @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
-ValidateReserved (
- IN UINT8 *Ptr,
- IN VOID *Context
- )
-{
- UINT32 ProtectionFlag;
-
- ProtectionFlag = *(UINT32 *)Ptr;
-
- if ((ProtectionFlag & 0xFFFFFFF8) != 0) {
- IncrementErrorCount ();
- Print (L"ERROR: Reserved bits are not zero.\n");
- }
-}
-
-/**
- An ACPI_PARSER array describing the WSMT Protection flag .
-**/
-STATIC CONST ACPI_PARSER WsmtProtectionFlagParser[] = {
- { L"FIXED_COMM_BUFFERS ", 1, 0, L"0x%x", NULL, NULL, NULL, NULL },
- { L"COMM_BUFFER_NESTED_PTR_PROTECTION ", 1, 1, L"0x%x", NULL, NULL, NULL, NULL },
- { L"SYSTEM_RESOURCE_PROTECTION ", 1, 2, L"0x%x", NULL, NULL, NULL, NULL },
- { L"Reserved ", 29, 3, L"0x%x", NULL, NULL, ValidateReserved, NULL },
-};
-
-/**
- This function prints WSMT Protection flag.
- 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
-DumpWsmtProtectionFlag (
- IN CONST CHAR16 *Format OPTIONAL,
- IN UINT8 *Ptr
- )
-{
- if (Format != NULL) {
- Print (Format, *(UINT32 *)Ptr);
- return;
- }
-
- Print (L"0x%X\n", *(UINT32 *)Ptr);
- ParseAcpiBitFields (
- TRUE,
- 2,
- NULL,
- Ptr,
- 4,
- PARSER_PARAMS (WsmtProtectionFlagParser)
- );
-}
-
-/**
- An ACPI_PARSER array describing the ACPI WSMT Table.
-**/
-STATIC CONST ACPI_PARSER WsmtParser[] = {
- PARSE_ACPI_HEADER (&AcpiHdrInfo),
- { L"Protection Flag", 4,36, NULL, DumpWsmtProtectionFlag, NULL, ValidateWsmtProtectionFlag, NULL }
-};
-
-/**
- This function parses the ACPI WSMT 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
-ParseAcpiWsmt (
- IN BOOLEAN Trace,
- IN UINT8 *Ptr,
- IN UINT32 AcpiTableLength,
- IN UINT8 AcpiTableRevision
- )
-{
- ParseAcpi (
- Trace,
- 0,
- "WSMT",
- Ptr,
- AcpiTableLength,
- PARSER_PARAMS (WsmtParser)
- );
-}
+/** @file + WSMT table parser + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - Windows SMM Security Mitigation Table spec, version 1.0 +**/ + +#include <Library/UefiLib.h> +#include <IndustryStandard/WindowsSmmSecurityMitigationTable.h> +#include "AcpiParser.h" + +STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; + +/** + This function validates the WSMT Protection flag. + + @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 +ValidateWsmtProtectionFlag ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + UINT32 ProtectionFlag; + + ProtectionFlag = *(UINT32 *)Ptr; + + if ((ProtectionFlag & EFI_WSMT_PROTECTION_FLAGS_COMM_BUFFER_NESTED_PTR_PROTECTION) \ + == EFI_WSMT_PROTECTION_FLAGS_COMM_BUFFER_NESTED_PTR_PROTECTION) + { + if ((ProtectionFlag & EFI_WSMT_PROTECTION_FLAGS_FIXED_COMM_BUFFERS) \ + != EFI_WSMT_PROTECTION_FLAGS_FIXED_COMM_BUFFERS) + { + IncrementErrorCount (); + Print (L"ERROR: COMM_BUFFER_NESTED_PTR_PROTECTION is set but FIXED_COMM_BUFFERS is not set.\n"); + } + } +} + +/** + This function validates the reserved bits in the WSMT Protection flag. + + @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 +ValidateReserved ( + IN UINT8 *Ptr, + IN VOID *Context + ) +{ + UINT32 ProtectionFlag; + + ProtectionFlag = *(UINT32 *)Ptr; + + if ((ProtectionFlag & 0xFFFFFFF8) != 0) { + IncrementErrorCount (); + Print (L"ERROR: Reserved bits are not zero.\n"); + } +} + +/** + An ACPI_PARSER array describing the WSMT Protection flag . +**/ +STATIC CONST ACPI_PARSER WsmtProtectionFlagParser[] = { + { L"FIXED_COMM_BUFFERS ", 1, 0, L"0x%x", NULL, NULL, NULL, NULL }, + { L"COMM_BUFFER_NESTED_PTR_PROTECTION ", 1, 1, L"0x%x", NULL, NULL, NULL, NULL }, + { L"SYSTEM_RESOURCE_PROTECTION ", 1, 2, L"0x%x", NULL, NULL, NULL, NULL }, + { L"Reserved ", 29, 3, L"0x%x", NULL, NULL, ValidateReserved, NULL }, +}; + +/** + This function prints WSMT Protection flag. + 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 +DumpWsmtProtectionFlag ( + IN CONST CHAR16 *Format OPTIONAL, + IN UINT8 *Ptr + ) +{ + if (Format != NULL) { + Print (Format, *(UINT32 *)Ptr); + return; + } + + Print (L"0x%X\n", *(UINT32 *)Ptr); + ParseAcpiBitFields ( + TRUE, + 2, + NULL, + Ptr, + 4, + PARSER_PARAMS (WsmtProtectionFlagParser) + ); +} + +/** + An ACPI_PARSER array describing the ACPI WSMT Table. +**/ +STATIC CONST ACPI_PARSER WsmtParser[] = { + PARSE_ACPI_HEADER (&AcpiHdrInfo), + { L"Protection Flag", 4,36, NULL, DumpWsmtProtectionFlag, NULL, ValidateWsmtProtectionFlag, NULL } +}; + +/** + This function parses the ACPI WSMT 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 +ParseAcpiWsmt ( + IN BOOLEAN Trace, + IN UINT8 *Ptr, + IN UINT32 AcpiTableLength, + IN UINT8 AcpiTableRevision + ) +{ + ParseAcpi ( + Trace, + 0, + "WSMT", + Ptr, + AcpiTableLength, + PARSER_PARAMS (WsmtParser) + ); +} diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Xsdt/XsdtParser.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Xsdt/XsdtParser.c index ff09f3ca7f..84cc897fdf 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Xsdt/XsdtParser.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Xsdt/XsdtParser.c @@ -1,142 +1,142 @@ -/** @file
- XSDT table parser
-
- Copyright (c) 2016 - 2019, ARM Limited. All rights reserved.
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
- @par Reference(s):
- - ACPI 6.2 Specification - Errata A, September 2017
-**/
-
-#include <IndustryStandard/Acpi.h>
-#include <Library/UefiLib.h>
-#include <Library/PrintLib.h>
-#include "AcpiParser.h"
-#include "AcpiTableParser.h"
-
-// Local variables
-STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;
-
-/** An ACPI_PARSER array describing the ACPI XSDT table.
-*/
-STATIC CONST ACPI_PARSER XsdtParser[] = {
- PARSE_ACPI_HEADER (&AcpiHdrInfo)
-};
-
-/**
- Get the ACPI XSDT header info.
-**/
-CONST ACPI_DESCRIPTION_HEADER_INFO *
-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];
-
- Offset = ParseAcpi (
- Trace,
- 0,
- "XSDT",
- Ptr,
- AcpiTableLength,
- PARSER_PARAMS (XsdtParser)
- );
-
- TableOffset = Offset;
-
- if (Trace) {
- EntryIndex = 0;
- TablePointer = (UINT64 *)(Ptr + TableOffset);
- while (Offset < AcpiTableLength) {
- CONST UINT32 *Signature;
- CONST UINT32 *Length;
- CONST UINT8 *Revision;
-
- if ((UINT64 *)(UINTN)(*TablePointer) != NULL) {
- UINT8 *SignaturePtr;
-
- ParseAcpiHeader (
- (UINT8 *)(UINTN)(*TablePointer),
- &Signature,
- &Length,
- &Revision
- );
-
- SignaturePtr = (UINT8 *)Signature;
-
- UnicodeSPrint (
- Buffer,
- sizeof (Buffer),
- L"Entry[%d] - %c%c%c%c",
- EntryIndex++,
- SignaturePtr[0],
- SignaturePtr[1],
- SignaturePtr[2],
- SignaturePtr[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 < AcpiTableLength) {
- if ((UINT64 *)(UINTN)(*TablePointer) != NULL) {
- ProcessAcpiTable ((UINT8 *)(UINTN)(*TablePointer));
- }
-
- Offset += sizeof (UINT64);
- TablePointer++;
- } // while
-}
+/** @file + XSDT table parser + + Copyright (c) 2016 - 2019, ARM Limited. All rights reserved. + SPDX-License-Identifier: BSD-2-Clause-Patent + + @par Reference(s): + - ACPI 6.2 Specification - Errata A, September 2017 +**/ + +#include <IndustryStandard/Acpi.h> +#include <Library/UefiLib.h> +#include <Library/PrintLib.h> +#include "AcpiParser.h" +#include "AcpiTableParser.h" + +// Local variables +STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo; + +/** An ACPI_PARSER array describing the ACPI XSDT table. +*/ +STATIC CONST ACPI_PARSER XsdtParser[] = { + PARSE_ACPI_HEADER (&AcpiHdrInfo) +}; + +/** + Get the ACPI XSDT header info. +**/ +CONST ACPI_DESCRIPTION_HEADER_INFO * +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]; + + Offset = ParseAcpi ( + Trace, + 0, + "XSDT", + Ptr, + AcpiTableLength, + PARSER_PARAMS (XsdtParser) + ); + + TableOffset = Offset; + + if (Trace) { + EntryIndex = 0; + TablePointer = (UINT64 *)(Ptr + TableOffset); + while (Offset < AcpiTableLength) { + CONST UINT32 *Signature; + CONST UINT32 *Length; + CONST UINT8 *Revision; + + if ((UINT64 *)(UINTN)(*TablePointer) != NULL) { + UINT8 *SignaturePtr; + + ParseAcpiHeader ( + (UINT8 *)(UINTN)(*TablePointer), + &Signature, + &Length, + &Revision + ); + + SignaturePtr = (UINT8 *)Signature; + + UnicodeSPrint ( + Buffer, + sizeof (Buffer), + L"Entry[%d] - %c%c%c%c", + EntryIndex++, + SignaturePtr[0], + SignaturePtr[1], + SignaturePtr[2], + SignaturePtr[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 < AcpiTableLength) { + 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 index 0bdf068fe0..ad6819934b 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.c @@ -1,463 +1,463 @@ -/** @file
- Main file for 'acpiview' Shell command function.
-
- Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
- Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-**/
-
-#include <Guid/ShellLibHiiGuid.h>
-#include <IndustryStandard/Acpi.h>
-#include <IndustryStandard/ArmErrorSourceTable.h>
-
-#include <Library/BaseMemoryLib.h>
-#include <Library/HiiLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/PrintLib.h>
-#include <Library/ShellCommandLib.h>
-#include <Library/ShellLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiLib.h>
-#include <Library/AcpiViewCommandLib.h>
-#include <Uefi.h>
-
-#include "AcpiParser.h"
-#include "AcpiTableParser.h"
-#include "AcpiView.h"
-#include "AcpiViewConfig.h"
-
-CONST CHAR16 gShellAcpiViewFileName[] = L"ShellCommand";
-EFI_HII_HANDLE gShellAcpiViewHiiHandle = NULL;
-
-/**
- An array of acpiview command line parameters.
-**/
-STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
- { L"-q", TypeFlag },
- { L"-d", TypeFlag },
- { L"-h", TypeFlag },
- { L"-l", TypeFlag },
- { L"-s", TypeValue },
- { L"-r", TypeValue },
- { NULL, TypeMax }
-};
-
-/**
- A list of available table parsers.
-*/
-STATIC
-CONST
-ACPI_TABLE_PARSER ParserList[] = {
- { EFI_ACPI_6_3_ARM_ERROR_SOURCE_TABLE_SIGNATURE, ParseAcpiAest },
- { EFI_ACPI_6_4_ARM_PERFORMANCE_MONITORING_UNIT_TABLE_SIGNATURE, ParseAcpiApmt },
- { 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_4_ERROR_RECORD_SERIALIZATION_TABLE_SIGNATURE, ParseAcpiErst },
- { EFI_ACPI_6_3_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE, ParseAcpiFacs },
- { EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiFadt },
- { EFI_ACPI_6_4_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiGtdt },
- { EFI_ACPI_6_4_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_SIGNATURE, ParseAcpiHmat },
- { EFI_ACPI_6_5_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE, ParseAcpiHpet },
- { 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 },
- { EFI_ACPI_6_4_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE,
- ParseAcpiPcct },
- { EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE,
- ParseAcpiPptt },
- { 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_5_WINDOWS_SMM_SECURITY_MITIGATION_TABLE_SIGNATURE, ParseAcpiWsmt },
- { 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;
-
- Status = EFI_SUCCESS;
- 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;
-}
-
-/**
- Dump a buffer to a file. Print error message if a file cannot be created.
-
- @param[in] FileName The filename that shall be created to contain the buffer.
- @param[in] Buffer Pointer to buffer that shall be dumped.
- @param[in] BufferSize The size of buffer to be dumped in bytes.
-
- @return The number of bytes that were written
-**/
-UINTN
-EFIAPI
-ShellDumpBufferToFile (
- IN CONST CHAR16 *FileNameBuffer,
- IN CONST VOID *Buffer,
- IN CONST UINTN BufferSize
- )
-{
- EFI_STATUS Status;
- SHELL_FILE_HANDLE DumpFileHandle;
- UINTN TransferBytes;
-
- 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 0;
- }
-
- TransferBytes = BufferSize;
- Status = ShellWriteFile (
- DumpFileHandle,
- &TransferBytes,
- (VOID *)Buffer
- );
-
- if (EFI_ERROR (Status)) {
- Print (L"ERROR: Failed to write binary file.\n");
- TransferBytes = 0;
- } else {
- Print (L"DONE.\n");
- }
-
- ShellCloseFile (&DumpFileHandle);
- return TransferBytes;
-}
-
-/**
- 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;
-}
-
-/**
- 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).
-
- @retval SHELL_INVALID_PARAMETER The command line invocation could not be parsed
- @retval SHELL_NOT_FOUND The command failed
- @retval SHELL_SUCCESS The command was successful
-**/
-SHELL_STATUS
-EFIAPI
-ShellCommandRunAcpiView (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- SHELL_STATUS ShellStatus;
- LIST_ENTRY *Package;
- CHAR16 *ProblemParam;
- SHELL_FILE_HANDLE TmpDumpFileHandle;
- CONST CHAR16 *MandatoryTableSpecStr;
- CONST CHAR16 *SelectedTableName;
-
- // Set configuration defaults
- AcpiConfigSetDefaults ();
-
- ShellStatus = SHELL_SUCCESS;
- Package = NULL;
- TmpDumpFileHandle = NULL;
-
- 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"-r") &&
- (ShellCommandLineGetValue (Package, L"-r") == NULL))
- {
- ShellPrintHiiEx (
- -1,
- -1,
- NULL,
- STRING_TOKEN (STR_GEN_NO_VALUE),
- gShellAcpiViewHiiHandle,
- L"acpiview",
- L"-r"
- );
- 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"-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 {
- // Turn on colour highlighting if requested
- SetColourHighlighting (ShellCommandLineGetFlag (Package, L"-h"));
-
- // Surpress consistency checking if requested
- SetConsistencyChecking (!ShellCommandLineGetFlag (Package, L"-q"));
-
- // Evaluate the parameters for mandatory ACPI table presence checks
- SetMandatoryTableValidate (ShellCommandLineGetFlag (Package, L"-r"));
- MandatoryTableSpecStr = ShellCommandLineGetValue (Package, L"-r");
-
- if (MandatoryTableSpecStr != NULL) {
- SetMandatoryTableSpec (ShellHexStrToUintn (MandatoryTableSpecStr));
- }
-
- if (ShellCommandLineGetFlag (Package, L"-l")) {
- SetReportOption (ReportTableList);
- } else {
- SelectedTableName = ShellCommandLineGetValue (Package, L"-s");
- if (SelectedTableName != NULL) {
- SelectAcpiTable (SelectedTableName);
- SetReportOption (ReportSelected);
-
- if (ShellCommandLineGetFlag (Package, L"-d")) {
- // Create a temporary file to check if the media is writable.
- CHAR16 FileNameBuffer[MAX_FILE_NAME_LEN];
- SetReportOption (ReportDumpBinFile);
-
- UnicodeSPrint (
- FileNameBuffer,
- sizeof (FileNameBuffer),
- L".\\%s0000.tmp",
- SelectedTableName
- );
-
- 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;
-}
-
-/**
- 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 ((PcdGet8 (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;
-}
+/** @file + Main file for 'acpiview' Shell command function. + + Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include <Guid/ShellLibHiiGuid.h> +#include <IndustryStandard/Acpi.h> +#include <IndustryStandard/ArmErrorSourceTable.h> + +#include <Library/BaseMemoryLib.h> +#include <Library/HiiLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/PrintLib.h> +#include <Library/ShellCommandLib.h> +#include <Library/ShellLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiLib.h> +#include <Library/AcpiViewCommandLib.h> +#include <Uefi.h> + +#include "AcpiParser.h" +#include "AcpiTableParser.h" +#include "AcpiView.h" +#include "AcpiViewConfig.h" + +CONST CHAR16 gShellAcpiViewFileName[] = L"ShellCommand"; +EFI_HII_HANDLE gShellAcpiViewHiiHandle = NULL; + +/** + An array of acpiview command line parameters. +**/ +STATIC CONST SHELL_PARAM_ITEM ParamList[] = { + { L"-q", TypeFlag }, + { L"-d", TypeFlag }, + { L"-h", TypeFlag }, + { L"-l", TypeFlag }, + { L"-s", TypeValue }, + { L"-r", TypeValue }, + { NULL, TypeMax } +}; + +/** + A list of available table parsers. +*/ +STATIC +CONST +ACPI_TABLE_PARSER ParserList[] = { + { EFI_ACPI_6_3_ARM_ERROR_SOURCE_TABLE_SIGNATURE, ParseAcpiAest }, + { EFI_ACPI_6_4_ARM_PERFORMANCE_MONITORING_UNIT_TABLE_SIGNATURE, ParseAcpiApmt }, + { 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_4_ERROR_RECORD_SERIALIZATION_TABLE_SIGNATURE, ParseAcpiErst }, + { EFI_ACPI_6_3_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE, ParseAcpiFacs }, + { EFI_ACPI_6_2_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiFadt }, + { EFI_ACPI_6_4_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE, ParseAcpiGtdt }, + { EFI_ACPI_6_4_HETEROGENEOUS_MEMORY_ATTRIBUTE_TABLE_SIGNATURE, ParseAcpiHmat }, + { EFI_ACPI_6_5_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE, ParseAcpiHpet }, + { 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 }, + { EFI_ACPI_6_4_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE, + ParseAcpiPcct }, + { EFI_ACPI_6_4_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE, + ParseAcpiPptt }, + { 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_5_WINDOWS_SMM_SECURITY_MITIGATION_TABLE_SIGNATURE, ParseAcpiWsmt }, + { 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; + + Status = EFI_SUCCESS; + 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; +} + +/** + Dump a buffer to a file. Print error message if a file cannot be created. + + @param[in] FileName The filename that shall be created to contain the buffer. + @param[in] Buffer Pointer to buffer that shall be dumped. + @param[in] BufferSize The size of buffer to be dumped in bytes. + + @return The number of bytes that were written +**/ +UINTN +EFIAPI +ShellDumpBufferToFile ( + IN CONST CHAR16 *FileNameBuffer, + IN CONST VOID *Buffer, + IN CONST UINTN BufferSize + ) +{ + EFI_STATUS Status; + SHELL_FILE_HANDLE DumpFileHandle; + UINTN TransferBytes; + + 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 0; + } + + TransferBytes = BufferSize; + Status = ShellWriteFile ( + DumpFileHandle, + &TransferBytes, + (VOID *)Buffer + ); + + if (EFI_ERROR (Status)) { + Print (L"ERROR: Failed to write binary file.\n"); + TransferBytes = 0; + } else { + Print (L"DONE.\n"); + } + + ShellCloseFile (&DumpFileHandle); + return TransferBytes; +} + +/** + 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; +} + +/** + 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). + + @retval SHELL_INVALID_PARAMETER The command line invocation could not be parsed + @retval SHELL_NOT_FOUND The command failed + @retval SHELL_SUCCESS The command was successful +**/ +SHELL_STATUS +EFIAPI +ShellCommandRunAcpiView ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + SHELL_STATUS ShellStatus; + LIST_ENTRY *Package; + CHAR16 *ProblemParam; + SHELL_FILE_HANDLE TmpDumpFileHandle; + CONST CHAR16 *MandatoryTableSpecStr; + CONST CHAR16 *SelectedTableName; + + // Set configuration defaults + AcpiConfigSetDefaults (); + + ShellStatus = SHELL_SUCCESS; + Package = NULL; + TmpDumpFileHandle = NULL; + + 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"-r") && + (ShellCommandLineGetValue (Package, L"-r") == NULL)) + { + ShellPrintHiiEx ( + -1, + -1, + NULL, + STRING_TOKEN (STR_GEN_NO_VALUE), + gShellAcpiViewHiiHandle, + L"acpiview", + L"-r" + ); + 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"-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 { + // Turn on colour highlighting if requested + SetColourHighlighting (ShellCommandLineGetFlag (Package, L"-h")); + + // Surpress consistency checking if requested + SetConsistencyChecking (!ShellCommandLineGetFlag (Package, L"-q")); + + // Evaluate the parameters for mandatory ACPI table presence checks + SetMandatoryTableValidate (ShellCommandLineGetFlag (Package, L"-r")); + MandatoryTableSpecStr = ShellCommandLineGetValue (Package, L"-r"); + + if (MandatoryTableSpecStr != NULL) { + SetMandatoryTableSpec (ShellHexStrToUintn (MandatoryTableSpecStr)); + } + + if (ShellCommandLineGetFlag (Package, L"-l")) { + SetReportOption (ReportTableList); + } else { + SelectedTableName = ShellCommandLineGetValue (Package, L"-s"); + if (SelectedTableName != NULL) { + SelectAcpiTable (SelectedTableName); + SetReportOption (ReportSelected); + + if (ShellCommandLineGetFlag (Package, L"-d")) { + // Create a temporary file to check if the media is writable. + CHAR16 FileNameBuffer[MAX_FILE_NAME_LEN]; + SetReportOption (ReportDumpBinFile); + + UnicodeSPrint ( + FileNameBuffer, + sizeof (FileNameBuffer), + L".\\%s0000.tmp", + SelectedTableName + ); + + 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; +} + +/** + 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 ((PcdGet8 (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.inf b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf index e62366116c..af0b1643db 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf @@ -1,90 +1,90 @@ -## @file
-# Provides Shell 'acpiview' command functions
-#
-# Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
-# Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010019
- BASE_NAME = UefiShellAcpiViewCommandLib
- FILE_GUID = FB5B305E-84F5-461F-940D-82D345757AFA
- MODULE_TYPE = UEFI_APPLICATION
- VERSION_STRING = 1.0
- LIBRARY_CLASS = AcpiViewCommandLib|UEFI_APPLICATION UEFI_DRIVER
- CONSTRUCTOR = UefiShellAcpiViewCommandLibConstructor
- DESTRUCTOR = UefiShellAcpiViewCommandLibDestructor
-
-[Sources.common]
- AcpiParser.c
- AcpiParser.h
- AcpiTableParser.c
- AcpiTableParser.h
- AcpiView.c
- AcpiView.h
- AcpiViewConfig.c
- AcpiViewConfig.h
- Parsers/Aest/AestParser.c
- Parsers/Apmt/ApmtParser.c
- Parsers/Bgrt/BgrtParser.c
- Parsers/Dbg2/Dbg2Parser.c
- Parsers/Dsdt/DsdtParser.c
- Parsers/Erst/ErstParser.c
- Parsers/Facs/FacsParser.c
- Parsers/Fadt/FadtParser.c
- Parsers/Gtdt/GtdtParser.c
- Parsers/Hmat/HmatParser.c
- Parsers/Hpet/HpetParser.c
- Parsers/Iort/IortParser.c
- Parsers/Madt/MadtParser.c
- Parsers/Madt/MadtParser.h
- Parsers/Mcfg/McfgParser.c
- Parsers/Pcct/PcctParser.c
- Parsers/Pcct/PcctParser.h
- Parsers/Pptt/PpttParser.c
- Parsers/Pptt/PpttParser.h
- Parsers/Rsdp/RsdpParser.c
- Parsers/Slit/SlitParser.c
- Parsers/Spcr/SpcrParser.c
- Parsers/Srat/SratParser.c
- Parsers/Ssdt/SsdtParser.c
- Parsers/Wsmt/WsmtParser.c
- Parsers/Xsdt/XsdtParser.c
- UefiShellAcpiViewCommandLib.c
- UefiShellAcpiViewCommandLib.uni
-
-[Sources.ARM, Sources.AARCH64]
- Arm/SbbrValidator.h
- Arm/SbbrValidator.c
-
-[Packages]
- MdeModulePkg/MdeModulePkg.dec
- MdePkg/MdePkg.dec
- ShellPkg/ShellPkg.dec
-
-[LibraryClasses]
- BaseLib
- BaseMemoryLib
- DebugLib
- FileHandleLib
- HiiLib
- MemoryAllocationLib
- PcdLib
- PrintLib
- ShellCommandLib
- ShellLib
- UefiBootServicesTableLib
- UefiLib
- UefiRuntimeServicesTableLib
-
-
-[FixedPcd]
- gEfiShellPkgTokenSpaceGuid.PcdShellProfileMask ## CONSUMES
-
-[Guids]
- gShellAcpiViewHiiGuid ## CONSUMES ## HII
- gEfiAcpiTableGuid ## SOMETIMES_CONSUMES ## SystemTable
+## @file +# Provides Shell 'acpiview' command functions +# +# Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. +# Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010019 + BASE_NAME = UefiShellAcpiViewCommandLib + FILE_GUID = FB5B305E-84F5-461F-940D-82D345757AFA + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + LIBRARY_CLASS = AcpiViewCommandLib|UEFI_APPLICATION UEFI_DRIVER + CONSTRUCTOR = UefiShellAcpiViewCommandLibConstructor + DESTRUCTOR = UefiShellAcpiViewCommandLibDestructor + +[Sources.common] + AcpiParser.c + AcpiParser.h + AcpiTableParser.c + AcpiTableParser.h + AcpiView.c + AcpiView.h + AcpiViewConfig.c + AcpiViewConfig.h + Parsers/Aest/AestParser.c + Parsers/Apmt/ApmtParser.c + Parsers/Bgrt/BgrtParser.c + Parsers/Dbg2/Dbg2Parser.c + Parsers/Dsdt/DsdtParser.c + Parsers/Erst/ErstParser.c + Parsers/Facs/FacsParser.c + Parsers/Fadt/FadtParser.c + Parsers/Gtdt/GtdtParser.c + Parsers/Hmat/HmatParser.c + Parsers/Hpet/HpetParser.c + Parsers/Iort/IortParser.c + Parsers/Madt/MadtParser.c + Parsers/Madt/MadtParser.h + Parsers/Mcfg/McfgParser.c + Parsers/Pcct/PcctParser.c + Parsers/Pcct/PcctParser.h + Parsers/Pptt/PpttParser.c + Parsers/Pptt/PpttParser.h + Parsers/Rsdp/RsdpParser.c + Parsers/Slit/SlitParser.c + Parsers/Spcr/SpcrParser.c + Parsers/Srat/SratParser.c + Parsers/Ssdt/SsdtParser.c + Parsers/Wsmt/WsmtParser.c + Parsers/Xsdt/XsdtParser.c + UefiShellAcpiViewCommandLib.c + UefiShellAcpiViewCommandLib.uni + +[Sources.ARM, Sources.AARCH64] + Arm/SbbrValidator.h + Arm/SbbrValidator.c + +[Packages] + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + ShellPkg/ShellPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + FileHandleLib + HiiLib + MemoryAllocationLib + PcdLib + PrintLib + ShellCommandLib + ShellLib + UefiBootServicesTableLib + UefiLib + UefiRuntimeServicesTableLib + + +[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 index e4a9dd5b40..c492c1f8f9 100644 --- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni +++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.uni @@ -1,140 +1,140 @@ -// /**
-//
-// Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.<BR>
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// 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]]] [-q] [-h]] [-r Spec]]]\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 and only support single\r\n"
-" invocation option.\r\n"
-" AcpiTable : The required ACPI Table type.\r\n"
-" -d - Generate a binary file dump of the specified AcpiTable.\r\n"
-" -q - Quiet. Suppress errors and warnings. Disables consistency checks.\r\n"
-" -h - Enable colour highlighting.\r\n"
-" -r - Validate that all required ACPI tables are installed\r\n"
-" Spec : Specification to validate against.\r\n"
-" For Arm, the possible values are:\r\n"
-" 0 - Server Base Boot Requirements v1.0\r\n"
-" 1 - Server Base Boot Requirements v1.1\r\n"
-" 2 - Server Base Boot Requirements v1.2\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\r\n"
-" where 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\r\n"
-" consistency 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\r\n"
-" relevant 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. -s option supports to display the specified AcpiTable type that is present\r\n"
-" in the system. For normal type AcpiTable, it would display the data of the\r\n"
-" AcpiTable and AcpiTable header. The following type may contain header type\r\n"
-" other than AcpiTable header. The actual header can refer to the ACPI spec\r\n"
-" 6.2\r\n"
-" Extra A. Particular types:\r\n"
-" AEST - Arm Error Source Table\r\n"
-" APIC - Multiple APIC Description Table (MADT)\r\n"
-" APMT - Arm Performance Monitoring Unit Table\r\n"
-" BGRT - Boot Graphics Resource Table\r\n"
-" DBG2 - Debug Port Table 2\r\n"
-" DSDT - Differentiated System Description Table\r\n"
-" FACP - Fixed ACPI Description Table (FADT)\r\n"
-" GTDT - Generic Timer Description Table\r\n"
-" HMAT - Heterogeneous Memory Attributes Table\r\n"
-" IORT - IO Remapping Table\r\n"
-" MCFG - Memory Mapped Config Space Base Address Description Table\r\n"
-" PPTT - Processor Properties Topology 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"
-" SSDT - Secondary SystemDescription 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\r\n"
-" will be 'backwards compatible' with prior version of the specification\r\n"
-" in 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"
-" * To check if all Server Base Boot Requirements (SBBR) v1.2 mandatory\r\n"
-" ACPI tables are installed (Arm only):\r\n"
-" fs0:\> acpiview -r 2\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"
-
+// /** +// +// Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.<BR> +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// 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]]] [-q] [-h]] [-r Spec]]]\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 and only support single\r\n" +" invocation option.\r\n" +" AcpiTable : The required ACPI Table type.\r\n" +" -d - Generate a binary file dump of the specified AcpiTable.\r\n" +" -q - Quiet. Suppress errors and warnings. Disables consistency checks.\r\n" +" -h - Enable colour highlighting.\r\n" +" -r - Validate that all required ACPI tables are installed\r\n" +" Spec : Specification to validate against.\r\n" +" For Arm, the possible values are:\r\n" +" 0 - Server Base Boot Requirements v1.0\r\n" +" 1 - Server Base Boot Requirements v1.1\r\n" +" 2 - Server Base Boot Requirements v1.2\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\r\n" +" where 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\r\n" +" consistency 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\r\n" +" relevant 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. -s option supports to display the specified AcpiTable type that is present\r\n" +" in the system. For normal type AcpiTable, it would display the data of the\r\n" +" AcpiTable and AcpiTable header. The following type may contain header type\r\n" +" other than AcpiTable header. The actual header can refer to the ACPI spec\r\n" +" 6.2\r\n" +" Extra A. Particular types:\r\n" +" AEST - Arm Error Source Table\r\n" +" APIC - Multiple APIC Description Table (MADT)\r\n" +" APMT - Arm Performance Monitoring Unit Table\r\n" +" BGRT - Boot Graphics Resource Table\r\n" +" DBG2 - Debug Port Table 2\r\n" +" DSDT - Differentiated System Description Table\r\n" +" FACP - Fixed ACPI Description Table (FADT)\r\n" +" GTDT - Generic Timer Description Table\r\n" +" HMAT - Heterogeneous Memory Attributes Table\r\n" +" IORT - IO Remapping Table\r\n" +" MCFG - Memory Mapped Config Space Base Address Description Table\r\n" +" PPTT - Processor Properties Topology 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" +" SSDT - Secondary SystemDescription 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\r\n" +" will be 'backwards compatible' with prior version of the specification\r\n" +" in 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" +" * To check if all Server Base Boot Requirements (SBBR) v1.2 mandatory\r\n" +" ACPI tables are installed (Arm only):\r\n" +" fs0:\> acpiview -r 2\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" + |
