ShellPkg: Add acpiview tool to dump ACPI tables
[mirror_edk2.git] / ShellPkg / Library / UefiShellAcpiViewCommandLib / Parsers / Xsdt / XsdtParser.c
1 /**\r
2   XSDT table parser\r
3 \r
4   Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.\r
5   This program and the accompanying materials\r
6   are licensed and made available under the terms and conditions of the BSD License\r
7   which accompanies this distribution.  The full text of the license may be found at\r
8   http://opensource.org/licenses/bsd-license.php\r
9 \r
10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12 \r
13   @par Reference(s):\r
14     - ACPI 6.2 Specification - Errata A, September 2017\r
15 **/\r
16 \r
17 #include <IndustryStandard/Acpi.h>\r
18 #include <Library/UefiLib.h>\r
19 #include <Library/PrintLib.h>\r
20 #include "AcpiParser.h"\r
21 #include "AcpiTableParser.h"\r
22 \r
23 // Local variables\r
24 STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;\r
25 \r
26 /** An ACPI_PARSER array describing the ACPI XSDT table.\r
27 */\r
28 STATIC CONST ACPI_PARSER XsdtParser[] = {\r
29   PARSE_ACPI_HEADER (&AcpiHdrInfo)\r
30 };\r
31 \r
32 CONST ACPI_DESCRIPTION_HEADER_INFO* CONST\r
33 EFIAPI\r
34 GetAcpiXsdtHeaderInfo (\r
35   VOID\r
36 )\r
37 {\r
38   return &AcpiHdrInfo;\r
39 }\r
40 \r
41 /** This function parses the ACPI XSDT table\r
42   and optionally traces the ACPI table fields.\r
43 \r
44   This function also performs validation of the XSDT table.\r
45 \r
46   @param [in] Trace              If TRUE, trace the ACPI fields.\r
47   @param [in] Ptr                Pointer to the start of the buffer.\r
48   @param [in] AcpiTableLength    Length of the ACPI table.\r
49   @param [in] AcpiTableRevision  Revision of the ACPI table.\r
50 */\r
51 VOID\r
52 EFIAPI\r
53 ParseAcpiXsdt (\r
54   IN BOOLEAN Trace,\r
55   IN UINT8*  Ptr,\r
56   IN UINT32  AcpiTableLength,\r
57   IN UINT8   AcpiTableRevision\r
58   )\r
59 {\r
60   UINT32        Offset;\r
61   UINT32        TableOffset;\r
62   UINT64*       TablePointer;\r
63   UINTN         EntryIndex;\r
64   CHAR16        Buffer[32];\r
65 \r
66   // Parse the ACPI header to get the length\r
67   ParseAcpi (\r
68     FALSE,\r
69     0,\r
70     "XSDT",\r
71     Ptr,\r
72     ACPI_DESCRIPTION_HEADER_LENGTH,\r
73     PARSER_PARAMS (XsdtParser)\r
74     );\r
75 \r
76   Offset = ParseAcpi (\r
77              Trace,\r
78              0,\r
79              "XSDT",\r
80              Ptr,\r
81              *AcpiHdrInfo.Length,\r
82              PARSER_PARAMS (XsdtParser)\r
83              );\r
84 \r
85   TableOffset = Offset;\r
86 \r
87   if (Trace) {\r
88     EntryIndex = 0;\r
89     TablePointer = (UINT64*)(Ptr + TableOffset);\r
90     while (Offset < (*AcpiHdrInfo.Length)) {\r
91       CONST UINT32* Signature;\r
92       CONST UINT32* Length;\r
93       CONST UINT8*  Revision;\r
94 \r
95       if ((UINT64*)(UINTN)(*TablePointer) != NULL) {\r
96         UINT8*      Ptr;\r
97 \r
98         ParseAcpiHeader (\r
99           (UINT8*)(UINTN)(*TablePointer),\r
100           &Signature,\r
101           &Length,\r
102           &Revision\r
103           );\r
104 \r
105         Ptr = (UINT8*)Signature;\r
106 \r
107         UnicodeSPrint (\r
108           Buffer,\r
109           sizeof (Buffer),\r
110           L"Entry[%d] - %c%c%c%c",\r
111           EntryIndex++,\r
112           Ptr[0],\r
113           Ptr[1],\r
114           Ptr[2],\r
115           Ptr[3]\r
116           );\r
117       } else {\r
118         UnicodeSPrint (\r
119           Buffer,\r
120           sizeof (Buffer),\r
121           L"Entry[%d]",\r
122           EntryIndex++\r
123           );\r
124       }\r
125 \r
126       PrintFieldName (2, Buffer);\r
127       Print (L"0x%lx\n", *TablePointer);\r
128 \r
129       // Validate the table pointers are not NULL\r
130       if ((UINT64*)(UINTN)(*TablePointer) == NULL) {\r
131         IncrementErrorCount ();\r
132         Print (\r
133           L"ERROR: Invalid table entry at 0x%lx, table address is 0x%lx\n",\r
134           TablePointer,\r
135           *TablePointer\r
136           );\r
137       }\r
138       Offset += sizeof (UINT64);\r
139       TablePointer++;\r
140     } // while\r
141   }\r
142 \r
143   // Process the tables\r
144   Offset = TableOffset;\r
145   TablePointer = (UINT64*)(Ptr + TableOffset);\r
146   while (Offset < (*AcpiHdrInfo.Length)) {\r
147     if ((UINT64*)(UINTN)(*TablePointer) != NULL) {\r
148       ProcessAcpiTable ((UINT8*)(UINTN)(*TablePointer));\r
149     }\r
150     Offset += sizeof (UINT64);\r
151     TablePointer++;\r
152   } // while\r
153 }\r