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