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