4 Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
5 SPDX-License-Identifier: BSD-2-Clause-Patent
8 - ACPI 6.2 Specification - Errata A, September 2017
11 #include <IndustryStandard/Acpi.h>
12 #include <Library/UefiLib.h>
13 #include "AcpiParser.h"
14 #include "AcpiTableParser.h"
17 STATIC CONST UINT32
* DsdtAddress
;
18 STATIC CONST UINT64
* X_DsdtAddress
;
19 STATIC CONST UINT8
* FadtMinorRevision
;
20 STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo
;
23 A macro defining the Hardware reduced ACPI flag
25 #define HW_REDUCED_ACPI BIT20
28 Get the ACPI XSDT header info.
30 CONST ACPI_DESCRIPTION_HEADER_INFO
*
32 GetAcpiXsdtHeaderInfo (
37 This function validates the Firmware Control Field.
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.
46 ValidateFirmwareCtrl (
52 This function validates the X_Firmware Control Field.
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.
61 ValidateXFirmwareCtrl (
67 This function validates the flags.
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.
82 An ACPI_PARSER array describing the ACPI FADT Table.
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
,
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
}
146 This function validates the Firmware Control Field.
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.
155 ValidateFirmwareCtrl (
160 #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
161 if (*(UINT32
*)Ptr
!= 0) {
162 IncrementErrorCount ();
164 L
"\nERROR: Firmware Control must be zero for ARM platforms."
171 This function validates the X_Firmware Control Field.
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.
180 ValidateXFirmwareCtrl (
185 #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
186 if (*(UINT64
*)Ptr
!= 0) {
187 IncrementErrorCount ();
189 L
"\nERROR: X Firmware Control must be zero for ARM platforms."
196 This function validates the flags.
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.
210 #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
211 if (((*(UINT32
*)Ptr
) & HW_REDUCED_ACPI
) == 0) {
212 IncrementErrorCount ();
214 L
"\nERROR: HW_REDUCED_ACPI flag must be set for ARM platforms."
221 This function parses the ACPI FADT table.
222 This function parses the FADT table and optionally traces the ACPI table fields.
224 This function also performs validation of the ACPI table fields.
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.
236 IN UINT32 AcpiTableLength
,
237 IN UINT8 AcpiTableRevision
248 PARSER_PARAMS (FadtParser
)
252 Print (L
"\nSummary:\n");
253 PrintFieldName (2, L
"FADT Version");
254 Print (L
"%d.%d\n", *AcpiHdrInfo
.Revision
, *FadtMinorRevision
);
256 if (*GetAcpiXsdtHeaderInfo ()->OemTableId
!= *AcpiHdrInfo
.OemTableId
) {
257 IncrementErrorCount ();
258 Print (L
"ERROR: OEM Table Id does not match with RSDT/XSDT.\n");
262 // If X_DSDT is not zero then use X_DSDT and ignore DSDT,
264 if (*X_DsdtAddress
!= 0) {
265 DsdtPtr
= (UINT8
*)(UINTN
)(*X_DsdtAddress
);
266 } else if (*DsdtAddress
!= 0) {
267 DsdtPtr
= (UINT8
*)(UINTN
)(*DsdtAddress
);
269 // Both DSDT and X_DSDT cannot be zero.
270 #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
272 // The DSDT Table is mandatory for ARM systems
273 // as the CPU information MUST be presented in
275 IncrementErrorCount ();
276 Print (L
"ERROR: Both X_DSDT and DSDT are NULL.\n");
282 ProcessAcpiTable (DsdtPtr
);