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