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
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.
14 - ACPI 6.2 Specification - Errata A, September 2017
17 #include <IndustryStandard/Acpi.h>
18 #include <Library/UefiLib.h>
19 #include "AcpiParser.h"
20 #include "AcpiTableParser.h"
23 STATIC CONST UINT32
* DsdtAddress
;
24 STATIC CONST UINT64
* X_DsdtAddress
;
25 STATIC CONST UINT8
* FadtMinorRevision
;
26 STATIC ACPI_DESCRIPTION_HEADER_INFO AcpiHdrInfo
;
29 A macro defining the Hardware reduced ACPI flag
31 #define HW_REDUCED_ACPI BIT20
34 Get the ACPI XSDT header info.
36 CONST ACPI_DESCRIPTION_HEADER_INFO
* CONST
38 GetAcpiXsdtHeaderInfo (
43 This function validates the Firmware Control Field.
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.
52 ValidateFirmwareCtrl (
58 This function validates the X_Firmware Control Field.
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.
67 ValidateXFirmwareCtrl (
73 This function validates the flags.
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.
88 An ACPI_PARSER array describing the ACPI FADT Table.
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
,
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
}
152 This function validates the Firmware Control Field.
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.
161 ValidateFirmwareCtrl (
166 #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
167 if (*(UINT32
*)Ptr
!= 0) {
168 IncrementErrorCount ();
170 L
"\nERROR: Firmware Control must be zero for ARM platforms."
177 This function validates the X_Firmware Control Field.
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.
186 ValidateXFirmwareCtrl (
191 #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
192 if (*(UINT64
*)Ptr
!= 0) {
193 IncrementErrorCount ();
195 L
"\nERROR: X Firmware Control must be zero for ARM platforms."
202 This function validates the flags.
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.
216 #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
217 if (((*(UINT32
*)Ptr
) & HW_REDUCED_ACPI
) == 0) {
218 IncrementErrorCount ();
220 L
"\nERROR: HW_REDUCED_ACPI flag must be set for ARM platforms."
227 This function parses the ACPI FADT table.
228 This function parses the FADT table and optionally traces the ACPI table fields.
230 This function also performs validation of the ACPI table fields.
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.
242 IN UINT32 AcpiTableLength
,
243 IN UINT8 AcpiTableRevision
254 PARSER_PARAMS (FadtParser
)
258 Print (L
"\nSummary:\n");
259 PrintFieldName (2, L
"FADT Version");
260 Print (L
"%d.%d\n", *AcpiHdrInfo
.Revision
, *FadtMinorRevision
);
262 if (*GetAcpiXsdtHeaderInfo ()->OemTableId
!= *AcpiHdrInfo
.OemTableId
) {
263 IncrementErrorCount ();
264 Print (L
"ERROR: OEM Table Id does not match with RSDT/XSDT.\n");
268 // If X_DSDT is not zero then use X_DSDT and ignore DSDT,
270 if (*X_DsdtAddress
!= 0) {
271 DsdtPtr
= (UINT8
*)(UINTN
)(*X_DsdtAddress
);
272 } else if (*DsdtAddress
!= 0) {
273 DsdtPtr
= (UINT8
*)(UINTN
)(*DsdtAddress
);
275 // Both DSDT and X_DSDT cannot be zero.
276 #if defined (MDE_CPU_ARM) || defined (MDE_CPU_AARCH64)
278 // The DSDT Table is mandatory for ARM systems
279 // as the CPU information MUST be presented in
281 IncrementErrorCount ();
282 Print (L
"ERROR: Both X_DSDT and DSDT are NULL.\n");
288 ProcessAcpiTable (DsdtPtr
);