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