]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Fadt/FadtParser.c
ShellPkg/UefiShellAcpiViewCommandLib: Fix ECC issues
[mirror_edk2.git] / ShellPkg / Library / UefiShellAcpiViewCommandLib / Parsers / Fadt / FadtParser.c
CommitLineData
a6eaba4d 1/** @file\r
ee4dc24f
RN
2 FADT 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 "AcpiParser.h"\r
20#include "AcpiTableParser.h"\r
21\r
22// Local variables\r
23STATIC CONST UINT32* DsdtAddress;\r
24STATIC CONST UINT64* X_DsdtAddress;\r
25STATIC CONST UINT8* FadtMinorRevision;\r
26STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo;\r
27\r
a6eaba4d
DB
28/**\r
29 A macro defining the Hardware reduced ACPI flag\r
30**/\r
ee4dc24f
RN
31#define HW_REDUCED_ACPI BIT20\r
32\r
a6eaba4d
DB
33/**\r
34 Get the ACPI XSDT header info.\r
35**/\r
ee4dc24f
RN
36CONST ACPI_DESCRIPTION_HEADER_INFO* CONST\r
37EFIAPI\r
38GetAcpiXsdtHeaderInfo (\r
39 VOID\r
a6eaba4d 40 );\r
ee4dc24f 41\r
a6eaba4d
DB
42/**\r
43 This function validates the Firmware Control Field.\r
44\r
45 @param [in] Ptr Pointer to the start of the field data.\r
46 @param [in] Context Pointer to context specific information e.g. this\r
47 could be a pointer to the ACPI table header.\r
48**/\r
ee4dc24f
RN
49STATIC\r
50VOID\r
51EFIAPI\r
52ValidateFirmwareCtrl (\r
53 IN UINT8* Ptr,\r
54 IN VOID* Context\r
a6eaba4d
DB
55 );\r
56\r
57/**\r
58 This function validates the X_Firmware Control Field.\r
ee4dc24f 59\r
a6eaba4d
DB
60 @param [in] Ptr Pointer to the start of the field data.\r
61 @param [in] Context Pointer to context specific information e.g. this\r
62 could be a pointer to the ACPI table header.\r
63**/\r
ee4dc24f
RN
64STATIC\r
65VOID\r
66EFIAPI\r
67ValidateXFirmwareCtrl (\r
68 IN UINT8* Ptr,\r
69 IN VOID* Context\r
a6eaba4d 70 );\r
ee4dc24f 71\r
a6eaba4d
DB
72/**\r
73 This function validates the flags.\r
74\r
75 @param [in] Ptr Pointer to the start of the field data.\r
76 @param [in] Context Pointer to context specific information e.g. this\r
77 could be a pointer to the ACPI table header.\r
78**/\r
ee4dc24f
RN
79STATIC\r
80VOID\r
81EFIAPI\r
82ValidateFlags (\r
83 IN UINT8* Ptr,\r
84 IN VOID* Context\r
a6eaba4d 85 );\r
ee4dc24f 86\r
a6eaba4d
DB
87/**\r
88 An ACPI_PARSER array describing the ACPI FADT Table.\r
89**/\r
ee4dc24f
RN
90STATIC CONST ACPI_PARSER FadtParser[] = {\r
91 PARSE_ACPI_HEADER (&AcpiHdrInfo),\r
92 {L"FIRMWARE_CTRL", 4, 36, L"0x%x", NULL, NULL, ValidateFirmwareCtrl, NULL},\r
93 {L"DSDT", 4, 40, L"0x%x", NULL, (VOID**)&DsdtAddress, NULL, NULL},\r
94 {L"Reserved", 1, 44, L"%x", NULL, NULL, NULL, NULL},\r
95 {L"Preferred_PM_Profile", 1, 45, L"0x%x", NULL, NULL, NULL, NULL},\r
96 {L"SCI_INT", 2, 46, L"0x%x", NULL, NULL, NULL, NULL},\r
97 {L"SMI_CMD", 4, 48, L"0x%x", NULL, NULL, NULL, NULL},\r
98 {L"ACPI_ENABLE", 1, 52, L"0x%x", NULL, NULL, NULL, NULL},\r
99 {L"ACPI_DISABLE", 1, 53, L"0x%x", NULL, NULL, NULL, NULL},\r
100 {L"S4BIOS_REQ", 1, 54, L"0x%x", NULL, NULL, NULL, NULL},\r
101 {L"PSTATE_CNT", 1, 55, L"0x%x", NULL, NULL, NULL, NULL},\r
102 {L"PM1a_EVT_BLK", 4, 56, L"0x%x", NULL, NULL, NULL, NULL},\r
103 {L"PM1b_EVT_BLK", 4, 60, L"0x%x", NULL, NULL, NULL, NULL},\r
104 {L"PM1a_CNT_BLK", 4, 64, L"0x%x", NULL, NULL, NULL, NULL},\r
105 {L"PM1b_CNT_BLK", 4, 68, L"0x%x", NULL, NULL, NULL, NULL},\r
106 {L"PM2_CNT_BLK", 4, 72, L"0x%x", NULL, NULL, NULL, NULL},\r
107 {L"PM_TMR_BLK", 4, 76, L"0x%x", NULL, NULL, NULL, NULL},\r
108 {L"GPE0_BLK", 4, 80, L"0x%x", NULL, NULL, NULL, NULL},\r
109 {L"GPE1_BLK", 4, 84, L"0x%x", NULL, NULL, NULL, NULL},\r
110 {L"PM1_EVT_LEN", 1, 88, L"0x%x", NULL, NULL, NULL, NULL},\r
111 {L"PM1_CNT_LEN", 1, 89, L"0x%x", NULL, NULL, NULL, NULL},\r
112 {L"PM2_CNT_LEN", 1, 90, L"0x%x", NULL, NULL, NULL, NULL},\r
113 {L"PM_TMR_LEN", 1, 91, L"0x%x", NULL, NULL, NULL, NULL},\r
114 {L"GPE0_BLK_LEN", 1, 92, L"0x%x", NULL, NULL, NULL, NULL},\r
115 {L"GPE1_BLK_LEN", 1, 93, L"0x%x", NULL, NULL, NULL, NULL},\r
116 {L"GPE1_BASE", 1, 94, L"0x%x", NULL, NULL, NULL, NULL},\r
117 {L"CST_CNT", 1, 95, L"0x%x", NULL, NULL, NULL, NULL},\r
118 {L"P_LVL2_LAT", 2, 96, L"0x%x", NULL, NULL, NULL, NULL},\r
119 {L"P_LVL3_LAT", 2, 98, L"0x%x", NULL, NULL, NULL, NULL},\r
120 {L"FLUSH_SIZE", 2, 100, L"0x%x", NULL, NULL, NULL, NULL},\r
121 {L"FLUSH_STRIDE", 2, 102, L"0x%x", NULL, NULL, NULL, NULL},\r
122 {L"DUTY_OFFSET", 1, 104, L"0x%x", NULL, NULL, NULL, NULL},\r
123 {L"DUTY_WIDTH", 1, 105, L"0x%x", NULL, NULL, NULL, NULL},\r
124 {L"DAY_ALRM", 1, 106, L"0x%x", NULL, NULL, NULL, NULL},\r
125 {L"MON_ALRM", 1, 107, L"0x%x", NULL, NULL, NULL, NULL},\r
126 {L"CENTURY", 1, 108, L"0x%x", NULL, NULL, NULL, NULL},\r
127 {L"IAPC_BOOT_ARCH", 2, 109, L"0x%x", NULL, NULL, NULL, NULL},\r
128 {L"Reserved", 1, 111, L"0x%x", NULL, NULL, NULL, NULL},\r
129 {L"Flags", 4, 112, L"0x%x", NULL, NULL, ValidateFlags, NULL},\r
130 {L"RESET_REG", 12, 116, NULL, DumpGas, NULL, NULL, NULL},\r
131 {L"RESET_VALUE", 1, 128, L"0x%x", NULL, NULL, NULL, NULL},\r
132 {L"ARM_BOOT_ARCH", 2, 129, L"0x%x", NULL, NULL, NULL, NULL},\r
133 {L"FADT Minor Version", 1, 131, L"0x%x", NULL, (VOID**)&FadtMinorRevision,\r
134 NULL, NULL},\r
135 {L"X_FIRMWARE_CTRL", 8, 132, L"0x%lx", NULL, NULL,\r
136 ValidateXFirmwareCtrl, NULL},\r
137 {L"X_DSDT", 8, 140, L"0x%lx", NULL, (VOID**)&X_DsdtAddress, NULL, NULL},\r
138 {L"X_PM1a_EVT_BLK", 12, 148, NULL, DumpGas, NULL, NULL, NULL},\r
139 {L"X_PM1b_EVT_BLK", 12, 160, NULL, DumpGas, NULL, NULL, NULL},\r
140 {L"X_PM1a_CNT_BLK", 12, 172, NULL, DumpGas, NULL, NULL, NULL},\r
141 {L"X_PM1b_CNT_BLK", 12, 184, NULL, DumpGas, NULL, NULL, NULL},\r
142 {L"X_PM2_CNT_BLK", 12, 196, NULL, DumpGas, NULL, NULL, NULL},\r
143 {L"X_PM_TMR_BLK", 12, 208, NULL, DumpGas, NULL, NULL, NULL},\r
144 {L"X_GPE0_BLK", 12, 220, NULL, DumpGas, NULL, NULL, NULL},\r
145 {L"X_GPE1_BLK", 12, 232, NULL, DumpGas, NULL, NULL, NULL},\r
146 {L"SLEEP_CONTROL_REG", 12, 244, NULL, DumpGas, NULL, NULL, NULL},\r
147 {L"SLEEP_STATUS_REG", 12, 256, NULL, DumpGas, NULL, NULL, NULL},\r
148 {L"Hypervisor VendorIdentity", 8, 268, L"%lx", NULL, NULL, NULL, NULL}\r
149};\r
150\r
a6eaba4d
DB
151/**\r
152 This function validates the Firmware Control Field.\r
ee4dc24f
RN
153\r
154 @param [in] Ptr Pointer to the start of the field data.\r
155 @param [in] Context Pointer to context specific information e.g. this\r
156 could be a pointer to the ACPI table header.\r
a6eaba4d 157**/\r
ee4dc24f
RN
158STATIC\r
159VOID\r
160EFIAPI\r
161ValidateFirmwareCtrl (\r
162 IN UINT8* Ptr,\r
163 IN VOID* Context\r
164)\r
165{\r
166#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)\r
167 if (*(UINT32*)Ptr != 0) {\r
168 IncrementErrorCount ();\r
169 Print (\r
170 L"\nERROR: Firmware Control must be zero for ARM platforms."\r
171 );\r
172 }\r
173#endif\r
174}\r
175\r
a6eaba4d
DB
176/**\r
177 This function validates the X_Firmware Control Field.\r
ee4dc24f
RN
178\r
179 @param [in] Ptr Pointer to the start of the field data.\r
180 @param [in] Context Pointer to context specific information e.g. this\r
181 could be a pointer to the ACPI table header.\r
a6eaba4d 182**/\r
ee4dc24f
RN
183STATIC\r
184VOID\r
185EFIAPI\r
186ValidateXFirmwareCtrl (\r
187 IN UINT8* Ptr,\r
188 IN VOID* Context\r
189)\r
190{\r
191#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)\r
192 if (*(UINT64*)Ptr != 0) {\r
193 IncrementErrorCount ();\r
194 Print (\r
195 L"\nERROR: X Firmware Control must be zero for ARM platforms."\r
196 );\r
197 }\r
198#endif\r
199}\r
200\r
a6eaba4d
DB
201/**\r
202 This function validates the flags.\r
ee4dc24f
RN
203\r
204 @param [in] Ptr Pointer to the start of the field data.\r
205 @param [in] Context Pointer to context specific information e.g. this\r
206 could be a pointer to the ACPI table header.\r
a6eaba4d 207**/\r
ee4dc24f
RN
208STATIC\r
209VOID\r
210EFIAPI\r
211ValidateFlags (\r
212 IN UINT8* Ptr,\r
213 IN VOID* Context\r
214)\r
215{\r
216#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)\r
217 if (((*(UINT32*)Ptr) & HW_REDUCED_ACPI) == 0) {\r
218 IncrementErrorCount ();\r
219 Print (\r
220 L"\nERROR: HW_REDUCED_ACPI flag must be set for ARM platforms."\r
221 );\r
222 }\r
223#endif\r
224}\r
225\r
a6eaba4d
DB
226/**\r
227 This function parses the ACPI FADT table.\r
228 This function parses the FADT table and optionally traces the ACPI table fields.\r
ee4dc24f
RN
229\r
230 This function also performs validation of the ACPI table fields.\r
231\r
232 @param [in] Trace If TRUE, trace the ACPI fields.\r
233 @param [in] Ptr Pointer to the start of the buffer.\r
234 @param [in] AcpiTableLength Length of the ACPI table.\r
235 @param [in] AcpiTableRevision Revision of the ACPI table.\r
a6eaba4d 236**/\r
ee4dc24f
RN
237VOID\r
238EFIAPI\r
239ParseAcpiFadt (\r
240 IN BOOLEAN Trace,\r
241 IN UINT8* Ptr,\r
242 IN UINT32 AcpiTableLength,\r
243 IN UINT8 AcpiTableRevision\r
244 )\r
245{\r
246 UINT8* DsdtPtr;\r
247\r
248 ParseAcpi (\r
249 Trace,\r
250 0,\r
251 "FADT",\r
252 Ptr,\r
253 AcpiTableLength,\r
254 PARSER_PARAMS (FadtParser)\r
255 );\r
256\r
257 if (Trace) {\r
258 Print (L"\nSummary:\n");\r
259 PrintFieldName (2, L"FADT Version");\r
260 Print (L"%d.%d\n", *AcpiHdrInfo.Revision, *FadtMinorRevision);\r
261\r
262 if (*GetAcpiXsdtHeaderInfo ()->OemTableId != *AcpiHdrInfo.OemTableId) {\r
263 IncrementErrorCount ();\r
264 Print (L"ERROR: OEM Table Id does not match with RSDT/XSDT.\n");\r
265 }\r
266 }\r
267\r
268 // If X_DSDT is not zero then use X_DSDT and ignore DSDT,\r
269 // else use DSDT.\r
270 if (*X_DsdtAddress != 0) {\r
271 DsdtPtr = (UINT8*)(UINTN)(*X_DsdtAddress);\r
272 } else if (*DsdtAddress != 0) {\r
273 DsdtPtr = (UINT8*)(UINTN)(*DsdtAddress);\r
274 } else {\r
275 // Both DSDT and X_DSDT cannot be zero.\r
276#if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)\r
277 if (Trace) {\r
278 // The DSDT Table is mandatory for ARM systems\r
279 // as the CPU information MUST be presented in\r
280 // the DSDT.\r
281 IncrementErrorCount ();\r
282 Print (L"ERROR: Both X_DSDT and DSDT are NULL.\n");\r
283 }\r
284#endif\r
285 return;\r
286 }\r
287\r
288 ProcessAcpiTable (DsdtPtr);\r
289}\r