ShellPkg: Add acpiview tool to dump ACPI tables
[mirror_edk2.git] / ShellPkg / Library / UefiShellAcpiViewCommandLib / Parsers / Rsdp / RsdpParser.c
1 /**\r
2   RSDP 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 <Library/UefiLib.h>\r
18 #include "AcpiParser.h"\r
19 #include "AcpiTableParser.h"\r
20 \r
21 // Local Variables\r
22 STATIC CONST UINT64* XsdtAddress;\r
23 \r
24 /** This function validates the RSDT Address.\r
25 \r
26   @param [in] Ptr     Pointer to the start of the field data.\r
27   @param [in] Context Pointer to context specific information e.g. this\r
28                       could be a pointer to the ACPI table header.\r
29 */\r
30 STATIC\r
31 VOID\r
32 EFIAPI\r
33 ValidateRsdtAddress (\r
34   IN UINT8* Ptr,\r
35   IN VOID*  Context\r
36   );\r
37 \r
38 /** This function validates the XSDT Address.\r
39 \r
40   @param [in] Ptr     Pointer to the start of the field data.\r
41   @param [in] Context Pointer to context specific information e.g. this\r
42                       could be a pointer to the ACPI table header.\r
43 */\r
44 STATIC\r
45 VOID\r
46 EFIAPI\r
47 ValidateXsdtAddress (\r
48   IN UINT8* Ptr,\r
49   IN VOID*  Context\r
50   );\r
51 \r
52 /** An array describing the ACPI RSDP Table.\r
53 */\r
54 STATIC CONST ACPI_PARSER RsdpParser[] = {\r
55   {L"Signature", 8, 0, NULL, Dump8Chars, NULL, NULL, NULL},\r
56   {L"Checksum", 1, 8, L"0x%x", NULL, NULL, NULL, NULL},\r
57   {L"Oem ID", 6, 9, NULL, Dump6Chars, NULL, NULL, NULL},\r
58   {L"Revision", 1, 15, L"%d", NULL, NULL, NULL, NULL},\r
59   {L"RSDT Address", 4, 16, L"0x%x", NULL, NULL, ValidateRsdtAddress, NULL},\r
60   {L"Length", 4, 20, L"%d", NULL, NULL, NULL, NULL},\r
61   {L"XSDT Address", 8, 24, L"0x%lx", NULL, (VOID**)&XsdtAddress,\r
62    ValidateXsdtAddress, NULL},\r
63   {L"Extended Checksum", 1, 32, L"0x%x", NULL, NULL, NULL, NULL},\r
64   {L"Reserved", 3, 33, L"%x %x %x", Dump3Chars, NULL, NULL, NULL}\r
65 };\r
66 \r
67 /** This function validates the RSDT Address.\r
68 \r
69   @param [in] Ptr     Pointer to the start of the field data.\r
70   @param [in] Context Pointer to context specific information e.g. this\r
71                       could be a pointer to the ACPI table header.\r
72 */\r
73 STATIC\r
74 VOID\r
75 EFIAPI\r
76 ValidateRsdtAddress (\r
77   IN UINT8* Ptr,\r
78   IN VOID*  Context\r
79   )\r
80 {\r
81 #if defined(MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)\r
82   // Reference: Server Base Boot Requirements System Software on ARM Platforms\r
83   // Section: 4.2.1.1 RSDP\r
84   // Root System Description Pointer (RSDP), ACPI ? 5.2.5.\r
85   //   - Within the RSDP, the RsdtAddress field must be null (zero) and the\r
86   //     XsdtAddresss MUST be a valid, non-null, 64-bit value.\r
87   UINT32 RsdtAddr = *(UINT32*)Ptr;\r
88   if (RsdtAddr != 0) {\r
89     IncrementErrorCount ();\r
90     Print (\r
91       L"\nERROR: Rsdt Address = 0x%p. This must be NULL on ARM Platforms.",\r
92       RsdtAddr\r
93       );\r
94   }\r
95 #endif\r
96 }\r
97 \r
98 /** This function validates the XSDT Address.\r
99 \r
100   @param [in] Ptr     Pointer to the start of the field data.\r
101   @param [in] Context Pointer to context specific information e.g. this\r
102                       could be a pointer to the ACPI table header.\r
103 */\r
104 STATIC\r
105 VOID\r
106 EFIAPI\r
107 ValidateXsdtAddress (\r
108   IN UINT8* Ptr,\r
109   IN VOID*  Context\r
110   )\r
111 {\r
112 #if defined(MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)\r
113   // Reference: Server Base Boot Requirements System Software on ARM Platforms\r
114   // Section: 4.2.1.1 RSDP\r
115   // Root System Description Pointer (RSDP), ACPI ? 5.2.5.\r
116   //   - Within the RSDP, the RsdtAddress field must be null (zero) and the\r
117   //     XsdtAddresss MUST be a valid, non-null, 64-bit value.\r
118   UINT64 XsdtAddr = *(UINT64*)Ptr;\r
119   if (XsdtAddr == 0) {\r
120     IncrementErrorCount ();\r
121     Print (\r
122       L"\nERROR: Xsdt Address = 0x%p. This must not be NULL on ARM Platforms.",\r
123       XsdtAddr\r
124       );\r
125   }\r
126 #endif\r
127 }\r
128 \r
129 /** This function parses the ACPI RSDP table.\r
130 \r
131   This function invokes the parser for the XSDT table.\r
132   * Note - This function does not support parsing of RSDT table.\r
133 \r
134   This function also performs a RAW dump of the ACPI table and\r
135   validates the checksum.\r
136 \r
137   @param [in] Trace              If TRUE, trace the ACPI fields.\r
138   @param [in] Ptr                Pointer to the start of the buffer.\r
139   @param [in] AcpiTableLength    Length of the ACPI table.\r
140   @param [in] AcpiTableRevision  Revision of the ACPI table.\r
141 */\r
142 VOID\r
143 EFIAPI\r
144 ParseAcpiRsdp (\r
145   IN BOOLEAN Trace,\r
146   IN UINT8*  Ptr,\r
147   IN UINT32  AcpiTableLength,\r
148   IN UINT8   AcpiTableRevision\r
149   )\r
150 {\r
151   if (Trace) {\r
152     DumpRaw (Ptr, AcpiTableLength);\r
153     VerifyChecksum (TRUE, Ptr, AcpiTableLength);\r
154   }\r
155 \r
156   ParseAcpi (Trace, 0, "RSDP", Ptr, AcpiTableLength, PARSER_PARAMS (RsdpParser));\r
157 \r
158   // This code currently supports parsing of XSDT table only\r
159   // and does not parse the RSDT table. Platforms provide the\r
160   // RSDT to enable compatibility with ACPI 1.0 operating systems.\r
161   // Therefore the RSDT should not be used on ARM platforms.\r
162   if ((*XsdtAddress) == 0) {\r
163     IncrementErrorCount ();\r
164     Print (L"ERROR: XSDT Pointer is not set.\n");\r
165     return;\r
166   }\r
167 \r
168   ProcessAcpiTable ((UINT8*)(UINTN)(*XsdtAddress));\r
169 }\r