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