acpi.c revision 1.15.8.3 1 1.15.8.3 martin /* $NetBSD: acpi.c,v 1.15.8.3 2019/01/03 11:26:42 martin Exp $ */
2 1.1 christos
3 1.1 christos /*-
4 1.1 christos * Copyright (c) 1998 Doug Rabson
5 1.1 christos * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki (at) FreeBSD.org>
6 1.1 christos * All rights reserved.
7 1.1 christos *
8 1.1 christos * Redistribution and use in source and binary forms, with or without
9 1.1 christos * modification, are permitted provided that the following conditions
10 1.1 christos * are met:
11 1.1 christos * 1. Redistributions of source code must retain the above copyright
12 1.1 christos * notice, this list of conditions and the following disclaimer.
13 1.1 christos * 2. Redistributions in binary form must reproduce the above copyright
14 1.1 christos * notice, this list of conditions and the following disclaimer in the
15 1.1 christos * documentation and/or other materials provided with the distribution.
16 1.1 christos *
17 1.1 christos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 1.1 christos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 1.1 christos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 1.1 christos * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 1.1 christos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 1.1 christos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 1.1 christos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 1.1 christos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 1.1 christos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 1.1 christos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 1.1 christos * SUCH DAMAGE.
28 1.1 christos *
29 1.15.8.1 martin * $FreeBSD: head/usr.sbin/acpi/acpidump/acpi.c 321299 2017-07-20 17:36:17Z emaste $
30 1.1 christos */
31 1.1 christos
32 1.5 cegger #include <sys/cdefs.h>
33 1.15.8.3 martin __RCSID("$NetBSD: acpi.c,v 1.15.8.3 2019/01/03 11:26:42 martin Exp $");
34 1.5 cegger
35 1.5 cegger #include <sys/param.h>
36 1.5 cegger #include <sys/endian.h>
37 1.5 cegger #include <sys/stat.h>
38 1.5 cegger #include <sys/wait.h>
39 1.5 cegger #include <assert.h>
40 1.5 cegger #include <err.h>
41 1.5 cegger #include <fcntl.h>
42 1.5 cegger #include <paths.h>
43 1.15.8.2 martin #include <stdbool.h>
44 1.5 cegger #include <stdio.h>
45 1.5 cegger #include <stdint.h>
46 1.5 cegger #include <stdlib.h>
47 1.5 cegger #include <string.h>
48 1.5 cegger #include <unistd.h>
49 1.5 cegger #include <stddef.h>
50 1.15.8.1 martin #include <uuid.h>
51 1.5 cegger
52 1.5 cegger #include "acpidump.h"
53 1.5 cegger
54 1.5 cegger #define BEGIN_COMMENT "/*\n"
55 1.5 cegger #define END_COMMENT " */\n"
56 1.5 cegger
57 1.15.8.2 martin /* Commonly used helper functions */
58 1.5 cegger static void acpi_print_string(char *s, size_t length);
59 1.15.8.2 martin static void acpi_print_tabs(unsigned int n);
60 1.15.8.2 martin static void acpi_dump_bytes(uint8_t *p, uint32_t len, unsigned int ntabs);
61 1.15.8.2 martin static void acpi_dump_table(ACPI_TABLE_HEADER *sdp);
62 1.5 cegger static void acpi_print_gas(ACPI_GENERIC_ADDRESS *gas);
63 1.5 cegger static void acpi_print_pci(uint16_t vendorid, uint16_t deviceid,
64 1.5 cegger uint8_t seg, uint8_t bus, uint8_t device, uint8_t func);
65 1.15.8.1 martin static void acpi_print_pci_sbdf(uint8_t seg, uint8_t bus, uint8_t device,
66 1.5 cegger uint8_t func);
67 1.5 cegger #ifdef notyet
68 1.5 cegger static void acpi_print_hest_generic_status(ACPI_HEST_GENERIC_STATUS *);
69 1.5 cegger static void acpi_print_hest_generic_data(ACPI_HEST_GENERIC_DATA *);
70 1.5 cegger #endif
71 1.5 cegger static void acpi_print_whea(ACPI_WHEA_HEADER *whea,
72 1.5 cegger void (*print_action)(ACPI_WHEA_HEADER *),
73 1.5 cegger void (*print_ins)(ACPI_WHEA_HEADER *),
74 1.5 cegger void (*print_flags)(ACPI_WHEA_HEADER *));
75 1.15.8.1 martin static uint64_t acpi_select_address(uint32_t, uint64_t);
76 1.15.8.2 martin
77 1.15.8.2 martin /* Handlers for each table */
78 1.5 cegger static void acpi_handle_fadt(ACPI_TABLE_HEADER *fadt);
79 1.5 cegger static void acpi_print_cpu(u_char cpu_id);
80 1.5 cegger static void acpi_print_cpu_uid(uint32_t uid, char *uid_string);
81 1.5 cegger static void acpi_print_local_apic(uint32_t apic_id, uint32_t flags);
82 1.5 cegger static void acpi_print_io_apic(uint32_t apic_id, uint32_t int_base,
83 1.5 cegger uint64_t apic_addr);
84 1.5 cegger static void acpi_print_mps_flags(uint16_t flags);
85 1.5 cegger static void acpi_print_intr(uint32_t intr, uint16_t mps_flags);
86 1.5 cegger static void acpi_print_local_nmi(u_int lint, uint16_t mps_flags);
87 1.5 cegger static void acpi_print_madt(ACPI_SUBTABLE_HEADER *mp);
88 1.5 cegger static void acpi_handle_bert(ACPI_TABLE_HEADER *sdp);
89 1.5 cegger static void acpi_handle_boot(ACPI_TABLE_HEADER *sdp);
90 1.5 cegger static void acpi_handle_cpep(ACPI_TABLE_HEADER *sdp);
91 1.15.8.2 martin static void acpi_handle_csrt(ACPI_TABLE_HEADER *sdp);
92 1.5 cegger static void acpi_handle_dbgp(ACPI_TABLE_HEADER *sdp);
93 1.15.8.1 martin static void acpi_handle_dbg2(ACPI_TABLE_HEADER *sdp);
94 1.5 cegger static void acpi_handle_einj(ACPI_TABLE_HEADER *sdp);
95 1.5 cegger static void acpi_handle_erst(ACPI_TABLE_HEADER *sdp);
96 1.15.8.2 martin static void acpi_handle_gtdt(ACPI_TABLE_HEADER *sdp);
97 1.5 cegger static void acpi_handle_hest(ACPI_TABLE_HEADER *sdp);
98 1.15.8.2 martin static void acpi_handle_lpit(ACPI_TABLE_HEADER *sdp);
99 1.5 cegger static void acpi_handle_madt(ACPI_TABLE_HEADER *sdp);
100 1.5 cegger static void acpi_handle_msct(ACPI_TABLE_HEADER *sdp);
101 1.5 cegger static void acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp);
102 1.5 cegger static void acpi_handle_hpet(ACPI_TABLE_HEADER *sdp);
103 1.5 cegger static void acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp);
104 1.5 cegger static void acpi_handle_sbst(ACPI_TABLE_HEADER *sdp);
105 1.5 cegger static void acpi_handle_slit(ACPI_TABLE_HEADER *sdp);
106 1.5 cegger static void acpi_handle_spcr(ACPI_TABLE_HEADER *sdp);
107 1.15.8.1 martin static void acpi_handle_spmi(ACPI_TABLE_HEADER *sdp);
108 1.5 cegger static void acpi_print_srat_cpu(uint32_t apic_id,
109 1.5 cegger uint32_t proximity_domain,
110 1.5 cegger uint32_t flags, uint32_t clockdomain);
111 1.5 cegger static void acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp);
112 1.5 cegger static void acpi_print_srat(ACPI_SUBTABLE_HEADER *srat);
113 1.5 cegger static void acpi_handle_srat(ACPI_TABLE_HEADER *sdp);
114 1.5 cegger static void acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp);
115 1.15.8.1 martin static void acpi_print_nfit(ACPI_NFIT_HEADER *nfit);
116 1.15.8.1 martin static void acpi_handle_nfit(ACPI_TABLE_HEADER *sdp);
117 1.15.8.1 martin static void acpi_handle_uefi(ACPI_TABLE_HEADER *sdp);
118 1.5 cegger static void acpi_handle_waet(ACPI_TABLE_HEADER *sdp);
119 1.5 cegger static void acpi_handle_wdat(ACPI_TABLE_HEADER *sdp);
120 1.15.8.1 martin static void acpi_handle_wddt(ACPI_TABLE_HEADER *sdp);
121 1.5 cegger static void acpi_handle_wdrt(ACPI_TABLE_HEADER *sdp);
122 1.5 cegger static void acpi_print_sdt(ACPI_TABLE_HEADER *sdp);
123 1.5 cegger static void acpi_print_fadt(ACPI_TABLE_HEADER *sdp);
124 1.5 cegger static void acpi_print_facs(ACPI_TABLE_FACS *facs);
125 1.5 cegger static void acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp);
126 1.5 cegger static ACPI_TABLE_HEADER *acpi_map_sdt(vm_offset_t pa);
127 1.5 cegger static void acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp);
128 1.5 cegger static void acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp);
129 1.5 cegger static void acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
130 1.5 cegger void (*action)(ACPI_SUBTABLE_HEADER *));
131 1.15.8.1 martin static void acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first,
132 1.15.8.1 martin void (*action)(ACPI_NFIT_HEADER *));
133 1.5 cegger
134 1.5 cegger /* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up. */
135 1.5 cegger static int addr_size;
136 1.5 cegger
137 1.15.8.1 martin /* Strings used in the TCPA table */
138 1.15.8.1 martin static const char *tcpa_event_type_strings[] = {
139 1.15.8.1 martin "PREBOOT Certificate",
140 1.15.8.1 martin "POST Code",
141 1.15.8.1 martin "Unused",
142 1.15.8.1 martin "No Action",
143 1.15.8.1 martin "Separator",
144 1.15.8.1 martin "Action",
145 1.15.8.1 martin "Event Tag",
146 1.15.8.1 martin "S-CRTM Contents",
147 1.15.8.1 martin "S-CRTM Version",
148 1.15.8.1 martin "CPU Microcode",
149 1.15.8.1 martin "Platform Config Flags",
150 1.15.8.1 martin "Table of Devices",
151 1.15.8.1 martin "Compact Hash",
152 1.15.8.1 martin "IPL",
153 1.15.8.1 martin "IPL Partition Data",
154 1.15.8.1 martin "Non-Host Code",
155 1.15.8.1 martin "Non-Host Config",
156 1.15.8.1 martin "Non-Host Info"
157 1.15.8.1 martin };
158 1.15.8.1 martin
159 1.15.8.1 martin static const char *TCPA_pcclient_strings[] = {
160 1.15.8.1 martin "<undefined>",
161 1.15.8.1 martin "SMBIOS",
162 1.15.8.1 martin "BIS Certificate",
163 1.15.8.1 martin "POST BIOS ROM Strings",
164 1.15.8.1 martin "ESCD",
165 1.15.8.1 martin "CMOS",
166 1.15.8.1 martin "NVRAM",
167 1.15.8.1 martin "Option ROM Execute",
168 1.15.8.1 martin "Option ROM Configurateion",
169 1.15.8.1 martin "<undefined>",
170 1.15.8.1 martin "Option ROM Microcode Update ",
171 1.15.8.1 martin "S-CRTM Version String",
172 1.15.8.1 martin "S-CRTM Contents",
173 1.15.8.1 martin "POST Contents",
174 1.15.8.1 martin "Table of Devices",
175 1.15.8.1 martin };
176 1.15.8.1 martin
177 1.15.8.1 martin #define PRINTFLAG_END() printflag_end()
178 1.15.8.1 martin
179 1.15.8.1 martin static char pf_sep = '{';
180 1.15.8.1 martin
181 1.15.8.1 martin static void
182 1.15.8.1 martin printflag_end(void)
183 1.15.8.1 martin {
184 1.15.8.1 martin
185 1.15.8.1 martin if (pf_sep == ',') {
186 1.15.8.1 martin printf("}");
187 1.15.8.1 martin } else if (pf_sep == '{') {
188 1.15.8.1 martin printf("{}");
189 1.15.8.1 martin }
190 1.15.8.1 martin pf_sep = '{';
191 1.15.8.1 martin printf("\n");
192 1.15.8.1 martin }
193 1.15.8.1 martin
194 1.15.8.1 martin static void
195 1.15.8.1 martin printflag(uint64_t var, uint64_t mask, const char *name)
196 1.15.8.1 martin {
197 1.15.8.1 martin
198 1.15.8.1 martin if (var & mask) {
199 1.15.8.1 martin printf("%c%s", pf_sep, name);
200 1.15.8.1 martin pf_sep = ',';
201 1.15.8.1 martin }
202 1.15.8.1 martin }
203 1.15.8.1 martin
204 1.5 cegger static void
205 1.5 cegger acpi_print_string(char *s, size_t length)
206 1.5 cegger {
207 1.5 cegger int c;
208 1.5 cegger
209 1.5 cegger /* Trim trailing spaces and NULLs */
210 1.5 cegger while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0'))
211 1.5 cegger length--;
212 1.5 cegger
213 1.5 cegger while (length--) {
214 1.5 cegger c = *s++;
215 1.15.8.3 martin if (c == '\0')
216 1.15.8.3 martin return;
217 1.5 cegger putchar(c);
218 1.5 cegger }
219 1.5 cegger }
220 1.5 cegger
221 1.5 cegger static void
222 1.5 cegger acpi_print_gas(ACPI_GENERIC_ADDRESS *gas)
223 1.5 cegger {
224 1.15.8.2 martin switch (gas->SpaceId) {
225 1.15.8.1 martin case ACPI_ADR_SPACE_SYSTEM_MEMORY:
226 1.15.8.1 martin if (gas->BitWidth <= 32)
227 1.15.8.1 martin printf("0x%08x:%u[%u] (Memory)",
228 1.15.8.1 martin (u_int)gas->Address, gas->BitOffset,
229 1.15.8.1 martin gas->BitWidth);
230 1.15.8.1 martin else
231 1.15.8.1 martin printf("0x%016jx:%u[%u] (Memory)",
232 1.15.8.1 martin (uintmax_t)gas->Address, gas->BitOffset,
233 1.15.8.1 martin gas->BitWidth);
234 1.15.8.1 martin break;
235 1.15.8.1 martin case ACPI_ADR_SPACE_SYSTEM_IO:
236 1.15.8.1 martin printf("0x%02x:%u[%u] (IO)", (u_int)gas->Address,
237 1.15.8.1 martin gas->BitOffset, gas->BitWidth);
238 1.5 cegger break;
239 1.15.8.1 martin case ACPI_ADR_SPACE_PCI_CONFIG:
240 1.5 cegger printf("%x:%x+0x%x (PCI)", (uint16_t)(gas->Address >> 32),
241 1.5 cegger (uint16_t)((gas->Address >> 16) & 0xffff),
242 1.5 cegger (uint16_t)gas->Address);
243 1.5 cegger break;
244 1.5 cegger /* XXX How to handle these below? */
245 1.15.8.1 martin case ACPI_ADR_SPACE_EC:
246 1.5 cegger printf("0x%x:%u[%u] (EC)", (uint16_t)gas->Address,
247 1.5 cegger gas->BitOffset, gas->BitWidth);
248 1.5 cegger break;
249 1.15.8.1 martin case ACPI_ADR_SPACE_SMBUS:
250 1.5 cegger printf("0x%x:%u[%u] (SMBus)", (uint16_t)gas->Address,
251 1.5 cegger gas->BitOffset, gas->BitWidth);
252 1.5 cegger break;
253 1.15.8.1 martin case ACPI_ADR_SPACE_CMOS:
254 1.15.8.1 martin case ACPI_ADR_SPACE_PCI_BAR_TARGET:
255 1.15.8.1 martin case ACPI_ADR_SPACE_IPMI:
256 1.15.8.1 martin case ACPI_ADR_SPACE_GPIO:
257 1.15.8.1 martin case ACPI_ADR_SPACE_GSBUS:
258 1.15.8.1 martin case ACPI_ADR_SPACE_PLATFORM_COMM:
259 1.15.8.1 martin case ACPI_ADR_SPACE_FIXED_HARDWARE:
260 1.5 cegger default:
261 1.15.8.1 martin printf("0x%016jx (SpaceID=%hhu)", (uintmax_t)gas->Address,
262 1.15.8.1 martin gas->SpaceId);
263 1.5 cegger break;
264 1.5 cegger }
265 1.5 cegger }
266 1.5 cegger
267 1.5 cegger static void
268 1.5 cegger acpi_print_pci(uint16_t vendorid, uint16_t deviceid,
269 1.5 cegger uint8_t seg, uint8_t bus, uint8_t device, uint8_t func)
270 1.5 cegger {
271 1.5 cegger if (vendorid == 0xffff && deviceid == 0xffff) {
272 1.5 cegger printf("\tPCI Device=NONE\n");
273 1.5 cegger return;
274 1.5 cegger }
275 1.5 cegger
276 1.5 cegger printf("\tPCI device={\n");
277 1.5 cegger printf("\t\tVendor=0x%x\n", vendorid);
278 1.5 cegger printf("\t\tDevice=0x%x\n", deviceid);
279 1.5 cegger printf("\n");
280 1.5 cegger printf("\t\tSegment Group=%d\n", seg);
281 1.5 cegger printf("\t\tBus=%d\n", bus);
282 1.5 cegger printf("\t\tDevice=%d\n", device);
283 1.5 cegger printf("\t\tFunction=%d\n", func);
284 1.5 cegger printf("\t}\n");
285 1.5 cegger }
286 1.5 cegger
287 1.5 cegger static void
288 1.15.8.1 martin acpi_print_pci_sbdf(uint8_t seg, uint8_t bus, uint8_t device, uint8_t func)
289 1.5 cegger {
290 1.5 cegger if (bus == 0xff && device == 0xff && func == 0xff) {
291 1.5 cegger printf("\tPCI Device=NONE\n");
292 1.5 cegger return;
293 1.5 cegger }
294 1.5 cegger
295 1.5 cegger printf("\tPCI device={\n");
296 1.5 cegger printf("\t\tSegment Group=%d\n", seg);
297 1.5 cegger printf("\t\tBus=%d\n", bus);
298 1.5 cegger printf("\t\tDevice=%d\n", device);
299 1.5 cegger printf("\t\tFunction=%d\n", func);
300 1.5 cegger printf("\t}\n");
301 1.5 cegger }
302 1.5 cegger
303 1.5 cegger #ifdef notyet
304 1.5 cegger static void
305 1.5 cegger acpi_print_hest_errorseverity(uint32_t error)
306 1.5 cegger {
307 1.5 cegger printf("\tError Severity={ ");
308 1.5 cegger switch (error) {
309 1.5 cegger case 0:
310 1.5 cegger printf("Recoverable");
311 1.5 cegger break;
312 1.5 cegger case 1:
313 1.5 cegger printf("Fatal");
314 1.5 cegger break;
315 1.5 cegger case 2:
316 1.5 cegger printf("Corrected");
317 1.5 cegger break;
318 1.5 cegger case 3:
319 1.5 cegger printf("None");
320 1.5 cegger break;
321 1.5 cegger default:
322 1.5 cegger printf("%d (reserved)", error);
323 1.5 cegger break;
324 1.5 cegger }
325 1.5 cegger printf("}\n");
326 1.5 cegger }
327 1.5 cegger #endif
328 1.5 cegger
329 1.5 cegger static void
330 1.5 cegger acpi_print_hest_errorbank(ACPI_HEST_IA_ERROR_BANK *bank)
331 1.5 cegger {
332 1.5 cegger printf("\n");
333 1.5 cegger printf("\tBank Number=%d\n", bank->BankNumber);
334 1.15.8.1 martin printf("\tClear Status On Init={%s}\n",
335 1.5 cegger bank->ClearStatusOnInit ? "NO" : "YES");
336 1.5 cegger printf("\tStatus Data Format={ ");
337 1.5 cegger switch (bank->StatusFormat) {
338 1.5 cegger case 0:
339 1.5 cegger printf("IA32 MCA");
340 1.5 cegger break;
341 1.5 cegger case 1:
342 1.5 cegger printf("EMT64 MCA");
343 1.5 cegger break;
344 1.5 cegger case 2:
345 1.5 cegger printf("AMD64 MCA");
346 1.5 cegger break;
347 1.5 cegger }
348 1.5 cegger printf(" }\n");
349 1.5 cegger
350 1.5 cegger if (bank->ControlRegister)
351 1.5 cegger printf("\tControl Register=0x%x\n", bank->ControlRegister);
352 1.5 cegger printf("\tControl Init Data=0x%"PRIx64"\n", bank->ControlData);
353 1.5 cegger printf("\tStatus MSR=0x%x\n", bank->StatusRegister);
354 1.5 cegger printf("\tAddress MSR=0x%x\n", bank->AddressRegister);
355 1.5 cegger printf("\tMisc MSR=0x%x\n", bank->MiscRegister);
356 1.5 cegger }
357 1.5 cegger
358 1.5 cegger static void
359 1.5 cegger acpi_print_hest_header(ACPI_HEST_HEADER *hest)
360 1.5 cegger {
361 1.15.8.1 martin printf("\tType={");
362 1.5 cegger switch (hest->Type) {
363 1.5 cegger case ACPI_HEST_TYPE_IA32_CHECK:
364 1.5 cegger printf("IA32 Machine Check Exception");
365 1.5 cegger break;
366 1.5 cegger case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
367 1.15.8.1 martin printf("IA32 Corrected Machine Check");
368 1.5 cegger break;
369 1.5 cegger case ACPI_HEST_TYPE_IA32_NMI:
370 1.15.8.1 martin printf("IA32 Non-Maskable Interrupt");
371 1.5 cegger break;
372 1.5 cegger case ACPI_HEST_TYPE_NOT_USED3:
373 1.5 cegger case ACPI_HEST_TYPE_NOT_USED4:
374 1.5 cegger case ACPI_HEST_TYPE_NOT_USED5:
375 1.15.8.1 martin printf("unused type: %d", hest->Type);
376 1.5 cegger break;
377 1.5 cegger case ACPI_HEST_TYPE_AER_ROOT_PORT:
378 1.15.8.1 martin printf("PCI Express Root Port AER");
379 1.5 cegger break;
380 1.5 cegger case ACPI_HEST_TYPE_AER_ENDPOINT:
381 1.15.8.1 martin printf("PCI Express Endpoint AER");
382 1.5 cegger break;
383 1.5 cegger case ACPI_HEST_TYPE_AER_BRIDGE:
384 1.15.8.1 martin printf("PCI Express/PCI-X Bridge AER");
385 1.5 cegger break;
386 1.5 cegger case ACPI_HEST_TYPE_GENERIC_ERROR:
387 1.15.8.1 martin printf("Generic Hardware Error Source");
388 1.15.8.1 martin break;
389 1.15.8.1 martin case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
390 1.15.8.1 martin printf("Generic Hardware Error Source version 2");
391 1.5 cegger break;
392 1.5 cegger case ACPI_HEST_TYPE_RESERVED:
393 1.5 cegger default:
394 1.15.8.1 martin printf("Reserved (%d)", hest->Type);
395 1.5 cegger break;
396 1.5 cegger }
397 1.15.8.1 martin printf("}\n");
398 1.5 cegger printf("\tSourceId=%d\n", hest->SourceId);
399 1.5 cegger }
400 1.5 cegger
401 1.5 cegger static void
402 1.5 cegger acpi_print_hest_aer_common(ACPI_HEST_AER_COMMON *data)
403 1.5 cegger {
404 1.5 cegger printf("\tFlags={ ");
405 1.5 cegger if (data->Flags & ACPI_HEST_FIRMWARE_FIRST)
406 1.5 cegger printf("FIRMWARE_FIRST");
407 1.5 cegger if (data->Flags & ACPI_HEST_GLOBAL)
408 1.5 cegger printf("GLOBAL");
409 1.5 cegger printf(" }\n");
410 1.5 cegger printf("\tEnabled={ %s ", data->Flags ? "YES" : "NO");
411 1.5 cegger if (data->Flags & ACPI_HEST_FIRMWARE_FIRST)
412 1.5 cegger printf("(ignored) ");
413 1.5 cegger printf("}\n");
414 1.5 cegger printf("\tNumber of Record to pre-allocate=%d\n",
415 1.5 cegger data->RecordsToPreallocate);
416 1.5 cegger printf("\tMax. Sections per Record=%d\n", data->MaxSectionsPerRecord);
417 1.5 cegger if (!(data->Flags & ACPI_HEST_GLOBAL))
418 1.15.8.1 martin acpi_print_pci_sbdf(0, data->Bus, data->Device, data->Function);
419 1.5 cegger printf("\tDevice Control=0x%x\n", data->DeviceControl);
420 1.5 cegger printf("\tUncorrectable Error Mask Register=0x%x\n",
421 1.5 cegger data->UncorrectableMask);
422 1.5 cegger printf("\tUncorrectable Error Severity Register=0x%x\n",
423 1.5 cegger data->UncorrectableSeverity);
424 1.5 cegger printf("\tCorrectable Error Mask Register=0x%x\n",
425 1.5 cegger data->CorrectableMask);
426 1.5 cegger printf("\tAdvanced Capabilities Register=0x%x\n",
427 1.5 cegger data->AdvancedCapabilities);
428 1.5 cegger }
429 1.5 cegger
430 1.5 cegger static void
431 1.5 cegger acpi_print_hest_notify(ACPI_HEST_NOTIFY *notify)
432 1.5 cegger {
433 1.5 cegger printf("\tHW Error Notification={\n");
434 1.15.8.1 martin printf("\t\tType={");
435 1.5 cegger switch (notify->Type) {
436 1.5 cegger case ACPI_HEST_NOTIFY_POLLED:
437 1.5 cegger printf("POLLED");
438 1.5 cegger break;
439 1.5 cegger case ACPI_HEST_NOTIFY_EXTERNAL:
440 1.5 cegger printf("EXTERN");
441 1.5 cegger break;
442 1.5 cegger case ACPI_HEST_NOTIFY_LOCAL:
443 1.5 cegger printf("LOCAL");
444 1.5 cegger break;
445 1.5 cegger case ACPI_HEST_NOTIFY_SCI:
446 1.5 cegger printf("SCI");
447 1.5 cegger break;
448 1.5 cegger case ACPI_HEST_NOTIFY_NMI:
449 1.5 cegger printf("NMI");
450 1.5 cegger break;
451 1.15.8.1 martin case ACPI_HEST_NOTIFY_CMCI:
452 1.15.8.1 martin printf("CMCI");
453 1.15.8.1 martin break;
454 1.15.8.1 martin case ACPI_HEST_NOTIFY_MCE:
455 1.15.8.1 martin printf("MCE");
456 1.15.8.1 martin break;
457 1.15.8.1 martin case ACPI_HEST_NOTIFY_GPIO:
458 1.15.8.1 martin printf("GPIO-Signal");
459 1.15.8.1 martin break;
460 1.15.8.1 martin case ACPI_HEST_NOTIFY_SEA:
461 1.15.8.1 martin printf("ARMv8 SEA");
462 1.15.8.1 martin break;
463 1.15.8.1 martin case ACPI_HEST_NOTIFY_SEI:
464 1.15.8.1 martin printf("ARMv8 SEI");
465 1.15.8.1 martin break;
466 1.15.8.1 martin case ACPI_HEST_NOTIFY_GSIV:
467 1.15.8.1 martin printf("External Interrupt - GSIV");
468 1.15.8.1 martin break;
469 1.5 cegger case ACPI_HEST_NOTIFY_RESERVED:
470 1.5 cegger printf("RESERVED");
471 1.5 cegger break;
472 1.5 cegger default:
473 1.15.8.1 martin printf("%d (reserved)", notify->Type);
474 1.5 cegger break;
475 1.5 cegger }
476 1.15.8.1 martin printf("}\n");
477 1.5 cegger
478 1.5 cegger printf("\t\tLength=%d\n", notify->Length);
479 1.15.8.1 martin
480 1.15.8.1 martin #define PRINTFLAG(var, flag) printflag((var), ACPI_HEST_## flag, #flag)
481 1.15.8.1 martin
482 1.15.8.1 martin printf("\t\tConfig Write Enable=");
483 1.15.8.1 martin PRINTFLAG(notify->ConfigWriteEnable, TYPE);
484 1.15.8.1 martin PRINTFLAG(notify->ConfigWriteEnable, POLL_INTERVAL);
485 1.15.8.1 martin PRINTFLAG(notify->ConfigWriteEnable, POLL_THRESHOLD_VALUE);
486 1.15.8.1 martin PRINTFLAG(notify->ConfigWriteEnable, POLL_THRESHOLD_WINDOW);
487 1.15.8.1 martin PRINTFLAG(notify->ConfigWriteEnable, ERR_THRESHOLD_VALUE);
488 1.15.8.1 martin PRINTFLAG(notify->ConfigWriteEnable, ERR_THRESHOLD_WINDOW);
489 1.15.8.1 martin PRINTFLAG_END();
490 1.15.8.1 martin
491 1.15.8.1 martin #undef PRINTFLAG
492 1.5 cegger
493 1.5 cegger printf("\t\tPoll Interval=%d msec\n", notify->PollInterval);
494 1.5 cegger printf("\t\tInterrupt Vector=%d\n", notify->Vector);
495 1.5 cegger printf("\t\tSwitch To Polling Threshold Value=%d\n",
496 1.5 cegger notify->PollingThresholdValue);
497 1.5 cegger printf("\t\tSwitch To Polling Threshold Window=%d msec\n",
498 1.5 cegger notify->PollingThresholdWindow);
499 1.5 cegger printf("\t\tError Threshold Value=%d\n",
500 1.5 cegger notify->ErrorThresholdValue);
501 1.5 cegger printf("\t\tError Threshold Window=%d msec\n",
502 1.5 cegger notify->ErrorThresholdWindow);
503 1.5 cegger printf("\t}\n");
504 1.5 cegger }
505 1.5 cegger
506 1.5 cegger #ifdef notyet
507 1.5 cegger static void
508 1.5 cegger acpi_print_hest_generic_status(ACPI_HEST_GENERIC_STATUS *data)
509 1.5 cegger {
510 1.5 cegger uint32_t i, pos, entries;
511 1.5 cegger ACPI_HEST_GENERIC_DATA *gen;
512 1.5 cegger
513 1.5 cegger entries = data->BlockStatus & ACPI_HEST_ERROR_ENTRY_COUNT;
514 1.5 cegger
515 1.5 cegger printf("\tGeneric Error Status={\n");
516 1.5 cegger printf("\t\tBlock Status={ ");
517 1.5 cegger if (data->BlockStatus & ACPI_HEST_UNCORRECTABLE)
518 1.5 cegger printf("UNCORRECTABLE");
519 1.5 cegger if (data->BlockStatus & ACPI_HEST_CORRECTABLE)
520 1.5 cegger printf("CORRECTABLE");
521 1.5 cegger if (data->BlockStatus & ACPI_HEST_MULTIPLE_UNCORRECTABLE)
522 1.5 cegger printf("MULTIPLE UNCORRECTABLE");
523 1.5 cegger if (data->BlockStatus & ACPI_HEST_MULTIPLE_CORRECTABLE)
524 1.5 cegger printf("MULTIPLE CORRECTABLE");
525 1.5 cegger printf(" }\n");
526 1.5 cegger printf("\t\tEntry Count=%d\n", entries);
527 1.5 cegger printf("\t\tRaw Data Offset=%d\n", data->RawDataOffset);
528 1.5 cegger printf("\t\tRaw Data Length=%d\n", data->RawDataLength);
529 1.5 cegger printf("\t\tData Length=%d\n", data->DataLength);
530 1.5 cegger printf("\t");
531 1.5 cegger acpi_print_hest_errorseverity(data->ErrorSeverity);
532 1.5 cegger printf("\t}\n");
533 1.5 cegger
534 1.5 cegger pos = sizeof(ACPI_HEST_GENERIC_STATUS);
535 1.5 cegger for (i = 0; i < entries; i++) {
536 1.5 cegger gen = (ACPI_HEST_GENERIC_DATA *)((char *)data + pos);
537 1.5 cegger acpi_print_hest_generic_data(gen);
538 1.5 cegger pos += sizeof(ACPI_HEST_GENERIC_DATA);
539 1.5 cegger }
540 1.5 cegger }
541 1.5 cegger #endif
542 1.5 cegger
543 1.5 cegger #ifdef notyet
544 1.5 cegger static void
545 1.5 cegger acpi_print_hest_generic_data(ACPI_HEST_GENERIC_DATA *data)
546 1.5 cegger {
547 1.5 cegger printf("\tGeneric Error Data={\n");
548 1.5 cegger printf("\t\tSectionType=");
549 1.5 cegger acpi_print_string((char *)data->SectionType, sizeof(data->SectionType));
550 1.5 cegger printf("\n\t");
551 1.5 cegger acpi_print_hest_errorseverity(data->ErrorSeverity);
552 1.5 cegger printf("\t\tRevision=0x%x\n", data->Revision);
553 1.5 cegger printf("\t\tValidation Bits=0x%x\n", data->ValidationBits);
554 1.5 cegger printf("\t\tFlags=0x%x\n", data->Flags);
555 1.5 cegger printf("\t\tData Length=%d\n", data->ErrorDataLength);
556 1.5 cegger printf("\t\tField Replication Unit Id=");
557 1.5 cegger acpi_print_string((char *)data->FruId, sizeof(data->FruId));
558 1.5 cegger printf("\n");
559 1.5 cegger printf("\t\tField Replication Unit=");
560 1.5 cegger acpi_print_string((char *)data->FruText, sizeof(data->FruText));
561 1.5 cegger printf("\n");
562 1.5 cegger printf("\t}\n");
563 1.5 cegger }
564 1.5 cegger #endif
565 1.5 cegger
566 1.5 cegger static void
567 1.5 cegger acpi_print_whea(ACPI_WHEA_HEADER *whea,
568 1.5 cegger void (*print_action)(ACPI_WHEA_HEADER *),
569 1.5 cegger void (*print_ins)(ACPI_WHEA_HEADER *),
570 1.5 cegger void (*print_flags)(ACPI_WHEA_HEADER *))
571 1.5 cegger {
572 1.5 cegger printf("\n");
573 1.5 cegger
574 1.5 cegger print_action(whea);
575 1.5 cegger print_ins(whea);
576 1.5 cegger if (print_flags)
577 1.5 cegger print_flags(whea);
578 1.5 cegger printf("\tRegisterRegion=");
579 1.5 cegger acpi_print_gas(&whea->RegisterRegion);
580 1.5 cegger printf("\n");
581 1.5 cegger printf("\tMASK=0x%08"PRIx64"\n", whea->Mask);
582 1.5 cegger }
583 1.5 cegger
584 1.5 cegger static void
585 1.5 cegger acpi_print_hest_ia32_check(ACPI_HEST_IA_MACHINE_CHECK *data)
586 1.5 cegger {
587 1.5 cegger uint32_t i, pos;
588 1.5 cegger ACPI_HEST_IA_ERROR_BANK *bank;
589 1.5 cegger
590 1.5 cegger acpi_print_hest_header(&data->Header);
591 1.5 cegger printf("\tFlags={ ");
592 1.5 cegger if (data->Flags & ACPI_HEST_FIRMWARE_FIRST)
593 1.5 cegger printf("FIRMWARE_FIRST");
594 1.5 cegger printf(" }\n");
595 1.5 cegger printf("\tEnabled={ %s }\n", data->Enabled ? "YES" : "NO");
596 1.5 cegger printf("\tNumber of Record to pre-allocate=%d\n",
597 1.5 cegger data->RecordsToPreallocate);
598 1.5 cegger printf("\tMax Sections per Record=%d\n",
599 1.5 cegger data->MaxSectionsPerRecord);
600 1.5 cegger printf("\tGlobal Capability Init Data=0x%"PRIx64"\n",
601 1.5 cegger data->GlobalCapabilityData);
602 1.5 cegger printf("\tGlobal Control Init Data=0x%"PRIx64"\n",
603 1.5 cegger data->GlobalControlData);
604 1.5 cegger printf("\tNumber of Hardware Error Reporting Banks=%d\n",
605 1.5 cegger data->NumHardwareBanks);
606 1.5 cegger
607 1.5 cegger pos = sizeof(ACPI_HEST_IA_MACHINE_CHECK);
608 1.5 cegger for (i = 0; i < data->NumHardwareBanks; i++) {
609 1.5 cegger bank = (ACPI_HEST_IA_ERROR_BANK *)((char *)data + pos);
610 1.5 cegger acpi_print_hest_errorbank(bank);
611 1.5 cegger pos += sizeof(ACPI_HEST_IA_ERROR_BANK);
612 1.5 cegger }
613 1.5 cegger }
614 1.5 cegger
615 1.5 cegger static void
616 1.5 cegger acpi_print_hest_ia32_correctedcheck(ACPI_HEST_IA_CORRECTED *data)
617 1.5 cegger {
618 1.5 cegger uint32_t i, pos;
619 1.5 cegger ACPI_HEST_IA_ERROR_BANK *bank;
620 1.5 cegger
621 1.5 cegger acpi_print_hest_header(&data->Header);
622 1.5 cegger printf("\tFlags={ ");
623 1.5 cegger if (data->Flags & ACPI_HEST_FIRMWARE_FIRST)
624 1.5 cegger printf("FIRMWARE_FIRST");
625 1.5 cegger printf(" }\n");
626 1.5 cegger printf("\tEnabled={ %s }\n", data->Enabled ? "YES" : "NO");
627 1.5 cegger printf("\tNumber of Record to pre-allocate=%d\n",
628 1.5 cegger data->RecordsToPreallocate);
629 1.5 cegger printf("\tMax Sections per Record=%d\n",
630 1.5 cegger data->MaxSectionsPerRecord);
631 1.5 cegger acpi_print_hest_notify(&data->Notify);
632 1.5 cegger
633 1.5 cegger printf("\tNumber of Hardware Error Reporting Banks=%d\n",
634 1.5 cegger data->NumHardwareBanks);
635 1.5 cegger
636 1.5 cegger pos = sizeof(ACPI_HEST_IA_MACHINE_CHECK);
637 1.5 cegger for (i = 0; i < data->NumHardwareBanks; i++) {
638 1.5 cegger bank = (ACPI_HEST_IA_ERROR_BANK *)((char *)data + pos);
639 1.5 cegger acpi_print_hest_errorbank(bank);
640 1.5 cegger pos += sizeof(ACPI_HEST_IA_ERROR_BANK);
641 1.5 cegger }
642 1.5 cegger }
643 1.5 cegger
644 1.5 cegger static void
645 1.5 cegger acpi_print_hest_ia32_nmi(ACPI_HEST_IA_NMI *data)
646 1.5 cegger {
647 1.5 cegger acpi_print_hest_header(&data->Header);
648 1.5 cegger printf("\tNumber of Record to pre-allocate=%d\n",
649 1.5 cegger data->RecordsToPreallocate);
650 1.5 cegger printf("\tMax Sections per Record=%d\n",
651 1.5 cegger data->MaxSectionsPerRecord);
652 1.5 cegger printf("\tMax Raw Data Length=%d\n",
653 1.5 cegger data->MaxRawDataLength);
654 1.5 cegger }
655 1.5 cegger
656 1.5 cegger static void
657 1.5 cegger acpi_print_hest_aer_root(ACPI_HEST_AER_ROOT *data)
658 1.5 cegger {
659 1.5 cegger acpi_print_hest_header(&data->Header);
660 1.5 cegger acpi_print_hest_aer_common(&data->Aer);
661 1.5 cegger printf("Root Error Command Register=0x%x\n", data->RootErrorCommand);
662 1.5 cegger }
663 1.5 cegger
664 1.5 cegger static void
665 1.5 cegger acpi_print_hest_aer_endpoint(ACPI_HEST_AER *data)
666 1.5 cegger {
667 1.5 cegger acpi_print_hest_header(&data->Header);
668 1.5 cegger acpi_print_hest_aer_common(&data->Aer);
669 1.5 cegger }
670 1.5 cegger
671 1.5 cegger static void
672 1.5 cegger acpi_print_hest_aer_bridge(ACPI_HEST_AER_BRIDGE *data)
673 1.5 cegger {
674 1.5 cegger acpi_print_hest_header(&data->Header);
675 1.5 cegger acpi_print_hest_aer_common(&data->Aer);
676 1.5 cegger
677 1.5 cegger printf("\tSecondary Uncorrectable Error Mask Register=0x%x\n",
678 1.5 cegger data->UncorrectableMask2);
679 1.5 cegger printf("\tSecondary Uncorrectable Error Severity Register=0x%x\n",
680 1.5 cegger data->UncorrectableSeverity2);
681 1.5 cegger printf("\tSecondory Advanced Capabilities Register=0x%x\n",
682 1.5 cegger data->AdvancedCapabilities2);
683 1.5 cegger }
684 1.5 cegger
685 1.5 cegger static void
686 1.5 cegger acpi_print_hest_generic(ACPI_HEST_GENERIC *data)
687 1.5 cegger {
688 1.5 cegger acpi_print_hest_header(&data->Header);
689 1.5 cegger if (data->RelatedSourceId != 0xffff)
690 1.5 cegger printf("\tReleated SourceId=%d\n", data->RelatedSourceId);
691 1.15.8.1 martin printf("\tEnabled={%s}\n", data->Enabled ? "YES" : "NO");
692 1.15.8.1 martin printf("\tNumber of Records to pre-allocate=%u\n",
693 1.5 cegger data->RecordsToPreallocate);
694 1.15.8.1 martin printf("\tMax Sections per Record=%u\n", data->MaxSectionsPerRecord);
695 1.15.8.1 martin printf("\tMax Raw Data Length=%u\n", data->MaxRawDataLength);
696 1.5 cegger printf("\tError Status Address=");
697 1.5 cegger acpi_print_gas(&data->ErrorStatusAddress);
698 1.15.8.1 martin printf("\n");
699 1.5 cegger acpi_print_hest_notify(&data->Notify);
700 1.15.8.1 martin printf("\tError Block Length=%u\n", data->ErrorBlockLength);
701 1.15.8.1 martin }
702 1.15.8.1 martin
703 1.15.8.1 martin static void
704 1.15.8.1 martin acpi_print_hest_generic_v2(ACPI_HEST_GENERIC_V2 *data)
705 1.15.8.1 martin {
706 1.15.8.1 martin
707 1.15.8.1 martin /* The first 64 bytes are the same as ACPI_HEST_GENERIC */
708 1.15.8.1 martin acpi_print_hest_generic((ACPI_HEST_GENERIC *)data);
709 1.15.8.1 martin
710 1.15.8.1 martin printf("\tError Status Address");
711 1.15.8.1 martin acpi_print_gas(&data->ReadAckRegister);
712 1.15.8.1 martin printf("\tRead Ack Preserve=0x%016jx\n",
713 1.15.8.1 martin (uintmax_t)data->ReadAckPreserve);
714 1.15.8.1 martin printf("\tRead Ack Write=0x%016jx\n",
715 1.15.8.1 martin (uintmax_t)data->ReadAckWrite);
716 1.5 cegger }
717 1.5 cegger
718 1.5 cegger static void
719 1.5 cegger acpi_handle_hest(ACPI_TABLE_HEADER *sdp)
720 1.5 cegger {
721 1.5 cegger ACPI_TABLE_HEST *hest;
722 1.5 cegger ACPI_HEST_HEADER *subhest;
723 1.5 cegger uint32_t i, pos;
724 1.5 cegger
725 1.5 cegger printf(BEGIN_COMMENT);
726 1.5 cegger acpi_print_sdt(sdp);
727 1.5 cegger hest = (ACPI_TABLE_HEST *)sdp;
728 1.5 cegger
729 1.5 cegger printf("\tError Source Count=%d\n", hest->ErrorSourceCount);
730 1.5 cegger pos = sizeof(ACPI_TABLE_HEST);
731 1.5 cegger for (i = 0; i < hest->ErrorSourceCount; i++) {
732 1.5 cegger subhest = (ACPI_HEST_HEADER *)((char *)hest + pos);
733 1.5 cegger printf("\n");
734 1.5 cegger
735 1.5 cegger switch (subhest->Type) {
736 1.5 cegger case ACPI_HEST_TYPE_IA32_CHECK:
737 1.15.8.1 martin acpi_print_hest_ia32_check(
738 1.15.8.1 martin (ACPI_HEST_IA_MACHINE_CHECK *)subhest);
739 1.5 cegger pos += sizeof(ACPI_HEST_IA_MACHINE_CHECK);
740 1.5 cegger break;
741 1.5 cegger
742 1.5 cegger case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
743 1.15.8.1 martin acpi_print_hest_ia32_correctedcheck(
744 1.15.8.1 martin (ACPI_HEST_IA_CORRECTED *)subhest);
745 1.5 cegger pos += sizeof(ACPI_HEST_IA_CORRECTED);
746 1.5 cegger break;
747 1.5 cegger
748 1.5 cegger case ACPI_HEST_TYPE_IA32_NMI:
749 1.15.8.1 martin acpi_print_hest_ia32_nmi(
750 1.15.8.1 martin (ACPI_HEST_IA_NMI *)subhest);
751 1.5 cegger pos += sizeof(ACPI_HEST_IA_NMI);
752 1.5 cegger break;
753 1.5 cegger
754 1.5 cegger case ACPI_HEST_TYPE_NOT_USED3:
755 1.5 cegger case ACPI_HEST_TYPE_NOT_USED4:
756 1.5 cegger case ACPI_HEST_TYPE_NOT_USED5:
757 1.5 cegger pos += sizeof(ACPI_HEST_HEADER);
758 1.5 cegger break;
759 1.5 cegger
760 1.5 cegger case ACPI_HEST_TYPE_AER_ROOT_PORT:
761 1.15.8.1 martin acpi_print_hest_aer_root((ACPI_HEST_AER_ROOT *)subhest);
762 1.5 cegger pos += sizeof(ACPI_HEST_AER_ROOT);
763 1.5 cegger break;
764 1.5 cegger
765 1.5 cegger case ACPI_HEST_TYPE_AER_ENDPOINT:
766 1.15.8.1 martin acpi_print_hest_aer_endpoint((ACPI_HEST_AER *)subhest);
767 1.15.8.1 martin pos += sizeof(ACPI_HEST_AER);
768 1.5 cegger break;
769 1.5 cegger
770 1.5 cegger case ACPI_HEST_TYPE_AER_BRIDGE:
771 1.15.8.1 martin acpi_print_hest_aer_bridge((ACPI_HEST_AER_BRIDGE *)subhest);
772 1.5 cegger pos += sizeof(ACPI_HEST_AER_BRIDGE);
773 1.5 cegger break;
774 1.5 cegger
775 1.5 cegger case ACPI_HEST_TYPE_GENERIC_ERROR:
776 1.15.8.1 martin acpi_print_hest_generic((ACPI_HEST_GENERIC *)subhest);
777 1.5 cegger pos += sizeof(ACPI_HEST_GENERIC);
778 1.5 cegger break;
779 1.5 cegger
780 1.15.8.1 martin case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
781 1.15.8.1 martin acpi_print_hest_generic_v2(
782 1.15.8.1 martin (ACPI_HEST_GENERIC_V2 *)subhest);
783 1.15.8.1 martin pos += sizeof(ACPI_HEST_GENERIC_V2);
784 1.15.8.1 martin break;
785 1.15.8.1 martin
786 1.5 cegger case ACPI_HEST_TYPE_RESERVED:
787 1.5 cegger default:
788 1.5 cegger pos += sizeof(ACPI_HEST_HEADER);
789 1.5 cegger break;
790 1.5 cegger }
791 1.5 cegger }
792 1.5 cegger
793 1.5 cegger printf(END_COMMENT);
794 1.5 cegger }
795 1.5 cegger
796 1.15.8.1 martin static uint64_t
797 1.15.8.1 martin acpi_select_address(uint32_t addr32, uint64_t addr64)
798 1.5 cegger {
799 1.5 cegger
800 1.15.8.1 martin if (addr64 == 0)
801 1.15.8.1 martin return addr32;
802 1.5 cegger
803 1.15.8.1 martin if ((addr32 != 0) && ((addr64 & 0xfffffff) != addr32)) {
804 1.5 cegger /*
805 1.5 cegger * A few systems (e.g., IBM T23) have an RSDP that claims
806 1.5 cegger * revision 2 but the 64 bit addresses are invalid. If
807 1.5 cegger * revision 2 and the 32 bit address is non-zero but the
808 1.5 cegger * 32 and 64 bit versions don't match, prefer the 32 bit
809 1.5 cegger * version for all subsequent tables.
810 1.5 cegger */
811 1.15.8.1 martin return addr32;
812 1.15.8.1 martin }
813 1.15.8.1 martin
814 1.15.8.1 martin return addr64;
815 1.5 cegger }
816 1.5 cegger
817 1.5 cegger static void
818 1.5 cegger acpi_handle_fadt(ACPI_TABLE_HEADER *sdp)
819 1.5 cegger {
820 1.5 cegger ACPI_TABLE_HEADER *dsdp;
821 1.5 cegger ACPI_TABLE_FACS *facs;
822 1.5 cegger ACPI_TABLE_FADT *fadt;
823 1.5 cegger
824 1.5 cegger fadt = (ACPI_TABLE_FADT *)sdp;
825 1.5 cegger acpi_print_fadt(sdp);
826 1.5 cegger
827 1.15.8.2 martin if (acpi_select_address(fadt->Facs, fadt->XFacs) == 0) {
828 1.15.8.2 martin if ((fadt->Flags & ACPI_FADT_HW_REDUCED) == 0)
829 1.15.8.2 martin errx(EXIT_FAILURE, "Missing FACS and HW_REDUCED_ACPI flag not set in FADT");
830 1.15.8.2 martin } else {
831 1.15.8.2 martin facs = (ACPI_TABLE_FACS *)acpi_map_sdt(
832 1.15.8.2 martin acpi_select_address(fadt->Facs, fadt->XFacs));
833 1.15.8.2 martin if (memcmp(facs->Signature, ACPI_SIG_FACS, 4) != 0 || facs->Length < 64)
834 1.15.8.2 martin errx(EXIT_FAILURE, "FACS is corrupt");
835 1.15.8.2 martin acpi_print_facs(facs);
836 1.15.8.2 martin }
837 1.5 cegger
838 1.15.8.1 martin dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(
839 1.15.8.1 martin acpi_select_address(fadt->Dsdt, fadt->XDsdt));
840 1.15.8.1 martin if (memcmp(dsdp->Signature, ACPI_SIG_DSDT, 4) != 0)
841 1.15.8.1 martin errx(EXIT_FAILURE, "DSDT signature mismatch");
842 1.5 cegger if (acpi_checksum(dsdp, dsdp->Length))
843 1.5 cegger errx(EXIT_FAILURE, "DSDT is corrupt");
844 1.5 cegger acpi_print_dsdt(dsdp);
845 1.5 cegger }
846 1.5 cegger
847 1.5 cegger static void
848 1.5 cegger acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
849 1.5 cegger void (*action)(ACPI_SUBTABLE_HEADER *))
850 1.5 cegger {
851 1.5 cegger ACPI_SUBTABLE_HEADER *subtable;
852 1.5 cegger char *end;
853 1.5 cegger
854 1.5 cegger subtable = first;
855 1.5 cegger end = (char *)table + table->Length;
856 1.5 cegger while ((char *)subtable < end) {
857 1.5 cegger printf("\n");
858 1.15.8.1 martin if (subtable->Length < sizeof(ACPI_SUBTABLE_HEADER)) {
859 1.15.8.1 martin warnx("invalid subtable length %u", subtable->Length);
860 1.15.8.1 martin return;
861 1.15.8.1 martin }
862 1.5 cegger action(subtable);
863 1.5 cegger subtable = (ACPI_SUBTABLE_HEADER *)((char *)subtable +
864 1.5 cegger subtable->Length);
865 1.5 cegger }
866 1.5 cegger }
867 1.5 cegger
868 1.5 cegger static void
869 1.15.8.1 martin acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first,
870 1.15.8.1 martin void (*action)(ACPI_NFIT_HEADER *))
871 1.15.8.1 martin {
872 1.15.8.1 martin ACPI_NFIT_HEADER *subtable;
873 1.15.8.1 martin char *end;
874 1.15.8.1 martin
875 1.15.8.1 martin subtable = first;
876 1.15.8.1 martin end = (char *)table + table->Length;
877 1.15.8.1 martin while ((char *)subtable < end) {
878 1.15.8.1 martin printf("\n");
879 1.15.8.1 martin if (subtable->Length < sizeof(ACPI_NFIT_HEADER)) {
880 1.15.8.1 martin warnx("invalid subtable length %u", subtable->Length);
881 1.15.8.1 martin return;
882 1.15.8.1 martin }
883 1.15.8.1 martin action(subtable);
884 1.15.8.1 martin subtable = (ACPI_NFIT_HEADER *)((char *)subtable +
885 1.15.8.1 martin subtable->Length);
886 1.15.8.1 martin }
887 1.15.8.1 martin }
888 1.15.8.1 martin
889 1.15.8.1 martin static void
890 1.5 cegger acpi_print_cpu(u_char cpu_id)
891 1.5 cegger {
892 1.5 cegger
893 1.5 cegger printf("\tACPI CPU=");
894 1.5 cegger if (cpu_id == 0xff)
895 1.5 cegger printf("ALL\n");
896 1.5 cegger else
897 1.5 cegger printf("%d\n", (u_int)cpu_id);
898 1.5 cegger }
899 1.5 cegger
900 1.5 cegger static void
901 1.5 cegger acpi_print_cpu_uid(uint32_t uid, char *uid_string)
902 1.5 cegger {
903 1.5 cegger
904 1.5 cegger printf("\tUID=%d", uid);
905 1.5 cegger if (uid_string != NULL)
906 1.5 cegger printf(" (%s)", uid_string);
907 1.5 cegger printf("\n");
908 1.5 cegger }
909 1.5 cegger
910 1.5 cegger static void
911 1.5 cegger acpi_print_local_apic(uint32_t apic_id, uint32_t flags)
912 1.5 cegger {
913 1.5 cegger
914 1.5 cegger printf("\tFlags={");
915 1.5 cegger if (flags & ACPI_MADT_ENABLED)
916 1.5 cegger printf("ENABLED");
917 1.5 cegger else
918 1.5 cegger printf("DISABLED");
919 1.5 cegger printf("}\n");
920 1.5 cegger printf("\tAPIC ID=%d\n", apic_id);
921 1.5 cegger }
922 1.5 cegger
923 1.5 cegger static void
924 1.5 cegger acpi_print_io_apic(uint32_t apic_id, uint32_t int_base, uint64_t apic_addr)
925 1.5 cegger {
926 1.5 cegger
927 1.5 cegger printf("\tAPIC ID=%d\n", apic_id);
928 1.5 cegger printf("\tINT BASE=%d\n", int_base);
929 1.5 cegger printf("\tADDR=0x%016jx\n", (uintmax_t)apic_addr);
930 1.5 cegger }
931 1.5 cegger
932 1.5 cegger static void
933 1.5 cegger acpi_print_mps_flags(uint16_t flags)
934 1.5 cegger {
935 1.5 cegger
936 1.5 cegger printf("\tFlags={Polarity=");
937 1.5 cegger switch (flags & ACPI_MADT_POLARITY_MASK) {
938 1.5 cegger case ACPI_MADT_POLARITY_CONFORMS:
939 1.5 cegger printf("conforming");
940 1.5 cegger break;
941 1.5 cegger case ACPI_MADT_POLARITY_ACTIVE_HIGH:
942 1.5 cegger printf("active-hi");
943 1.5 cegger break;
944 1.5 cegger case ACPI_MADT_POLARITY_ACTIVE_LOW:
945 1.5 cegger printf("active-lo");
946 1.5 cegger break;
947 1.5 cegger default:
948 1.5 cegger printf("0x%x", flags & ACPI_MADT_POLARITY_MASK);
949 1.5 cegger break;
950 1.5 cegger }
951 1.5 cegger printf(", Trigger=");
952 1.5 cegger switch (flags & ACPI_MADT_TRIGGER_MASK) {
953 1.5 cegger case ACPI_MADT_TRIGGER_CONFORMS:
954 1.5 cegger printf("conforming");
955 1.5 cegger break;
956 1.5 cegger case ACPI_MADT_TRIGGER_EDGE:
957 1.5 cegger printf("edge");
958 1.5 cegger break;
959 1.5 cegger case ACPI_MADT_TRIGGER_LEVEL:
960 1.5 cegger printf("level");
961 1.5 cegger break;
962 1.5 cegger default:
963 1.5 cegger printf("0x%x", (flags & ACPI_MADT_TRIGGER_MASK) >> 2);
964 1.5 cegger }
965 1.5 cegger printf("}\n");
966 1.5 cegger }
967 1.5 cegger
968 1.5 cegger static void
969 1.15.8.1 martin acpi_print_gicc_flags(uint32_t flags)
970 1.15.8.1 martin {
971 1.15.8.1 martin
972 1.15.8.1 martin printf("\tFlags={Performance intr=");
973 1.15.8.1 martin if (flags & ACPI_MADT_PERFORMANCE_IRQ_MODE)
974 1.15.8.1 martin printf("edge");
975 1.15.8.1 martin else
976 1.15.8.1 martin printf("level");
977 1.15.8.1 martin printf(", VGIC intr=");
978 1.15.8.1 martin if (flags & ACPI_MADT_VGIC_IRQ_MODE)
979 1.15.8.1 martin printf("edge");
980 1.15.8.1 martin else
981 1.15.8.1 martin printf("level");
982 1.15.8.1 martin printf("}\n");
983 1.15.8.1 martin }
984 1.15.8.1 martin
985 1.15.8.1 martin static void
986 1.5 cegger acpi_print_intr(uint32_t intr, uint16_t mps_flags)
987 1.5 cegger {
988 1.5 cegger
989 1.5 cegger printf("\tINTR=%d\n", intr);
990 1.5 cegger acpi_print_mps_flags(mps_flags);
991 1.5 cegger }
992 1.5 cegger
993 1.5 cegger static void
994 1.5 cegger acpi_print_local_nmi(u_int lint, uint16_t mps_flags)
995 1.5 cegger {
996 1.5 cegger
997 1.5 cegger printf("\tLINT Pin=%d\n", lint);
998 1.5 cegger acpi_print_mps_flags(mps_flags);
999 1.5 cegger }
1000 1.5 cegger
1001 1.15.8.1 martin static const char *apic_types[] = {
1002 1.15.8.1 martin [ACPI_MADT_TYPE_LOCAL_APIC] = "Local APIC",
1003 1.15.8.1 martin [ACPI_MADT_TYPE_IO_APIC] = "IO APIC",
1004 1.15.8.1 martin [ACPI_MADT_TYPE_INTERRUPT_OVERRIDE] = "INT Override",
1005 1.15.8.1 martin [ACPI_MADT_TYPE_NMI_SOURCE] = "NMI",
1006 1.15.8.1 martin [ACPI_MADT_TYPE_LOCAL_APIC_NMI] = "Local APIC NMI",
1007 1.15.8.1 martin [ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE] = "Local APIC Override",
1008 1.15.8.1 martin [ACPI_MADT_TYPE_IO_SAPIC] = "IO SAPIC",
1009 1.15.8.1 martin [ACPI_MADT_TYPE_LOCAL_SAPIC] = "Local SAPIC",
1010 1.15.8.1 martin [ACPI_MADT_TYPE_INTERRUPT_SOURCE] = "Platform Interrupt",
1011 1.15.8.1 martin [ACPI_MADT_TYPE_LOCAL_X2APIC] = "Local X2APIC",
1012 1.15.8.1 martin [ACPI_MADT_TYPE_LOCAL_X2APIC_NMI] = "Local X2APIC NMI",
1013 1.15.8.1 martin [ACPI_MADT_TYPE_GENERIC_INTERRUPT] = "GIC CPU Interface Structure",
1014 1.15.8.1 martin [ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR] = "GIC Distributor Structure",
1015 1.15.8.1 martin [ACPI_MADT_TYPE_GENERIC_MSI_FRAME] = "GICv2m MSI Frame",
1016 1.15.8.1 martin [ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR] = "GIC Redistributor Structure",
1017 1.15.8.1 martin [ACPI_MADT_TYPE_GENERIC_TRANSLATOR] = "GIC ITS Structure"
1018 1.15.8.1 martin };
1019 1.15.8.1 martin
1020 1.15.8.1 martin static const char *platform_int_types[] = { "0 (unknown)", "PMI", "INIT",
1021 1.15.8.1 martin "Corrected Platform Error" };
1022 1.15.8.1 martin
1023 1.15.8.1 martin static void
1024 1.15.8.1 martin acpi_print_gicm_flags(ACPI_MADT_GENERIC_MSI_FRAME *gicm)
1025 1.15.8.1 martin {
1026 1.15.8.1 martin uint32_t flags = gicm->Flags;
1027 1.15.8.1 martin
1028 1.15.8.1 martin printf("\tFLAGS={");
1029 1.15.8.1 martin if (flags & ACPI_MADT_OVERRIDE_SPI_VALUES)
1030 1.15.8.1 martin printf("SPI Count/Base Select");
1031 1.15.8.1 martin printf("}\n");
1032 1.15.8.1 martin }
1033 1.5 cegger
1034 1.5 cegger static void
1035 1.5 cegger acpi_print_madt(ACPI_SUBTABLE_HEADER *mp)
1036 1.5 cegger {
1037 1.5 cegger ACPI_MADT_LOCAL_APIC *lapic;
1038 1.5 cegger ACPI_MADT_IO_APIC *ioapic;
1039 1.5 cegger ACPI_MADT_INTERRUPT_OVERRIDE *over;
1040 1.5 cegger ACPI_MADT_NMI_SOURCE *nmi;
1041 1.5 cegger ACPI_MADT_LOCAL_APIC_NMI *lapic_nmi;
1042 1.5 cegger ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic_over;
1043 1.5 cegger ACPI_MADT_IO_SAPIC *iosapic;
1044 1.5 cegger ACPI_MADT_LOCAL_SAPIC *lsapic;
1045 1.5 cegger ACPI_MADT_INTERRUPT_SOURCE *isrc;
1046 1.5 cegger ACPI_MADT_LOCAL_X2APIC *x2apic;
1047 1.5 cegger ACPI_MADT_LOCAL_X2APIC_NMI *x2apic_nmi;
1048 1.15.8.1 martin ACPI_MADT_GENERIC_INTERRUPT *gicc;
1049 1.15.8.1 martin ACPI_MADT_GENERIC_DISTRIBUTOR *gicd;
1050 1.15.8.1 martin ACPI_MADT_GENERIC_MSI_FRAME *gicm;
1051 1.15.8.1 martin ACPI_MADT_GENERIC_REDISTRIBUTOR *gicr;
1052 1.15.8.1 martin ACPI_MADT_GENERIC_TRANSLATOR *gict;
1053 1.5 cegger
1054 1.15.8.1 martin if (mp->Type < __arraycount(apic_types))
1055 1.5 cegger printf("\tType=%s\n", apic_types[mp->Type]);
1056 1.5 cegger else
1057 1.5 cegger printf("\tType=%d (unknown)\n", mp->Type);
1058 1.5 cegger switch (mp->Type) {
1059 1.5 cegger case ACPI_MADT_TYPE_LOCAL_APIC:
1060 1.5 cegger lapic = (ACPI_MADT_LOCAL_APIC *)mp;
1061 1.5 cegger acpi_print_cpu(lapic->ProcessorId);
1062 1.5 cegger acpi_print_local_apic(lapic->Id, lapic->LapicFlags);
1063 1.5 cegger break;
1064 1.5 cegger case ACPI_MADT_TYPE_IO_APIC:
1065 1.5 cegger ioapic = (ACPI_MADT_IO_APIC *)mp;
1066 1.5 cegger acpi_print_io_apic(ioapic->Id, ioapic->GlobalIrqBase,
1067 1.5 cegger ioapic->Address);
1068 1.5 cegger break;
1069 1.5 cegger case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
1070 1.5 cegger over = (ACPI_MADT_INTERRUPT_OVERRIDE *)mp;
1071 1.5 cegger printf("\tBUS=%d\n", (u_int)over->Bus);
1072 1.5 cegger printf("\tIRQ=%d\n", (u_int)over->SourceIrq);
1073 1.5 cegger acpi_print_intr(over->GlobalIrq, over->IntiFlags);
1074 1.5 cegger break;
1075 1.5 cegger case ACPI_MADT_TYPE_NMI_SOURCE:
1076 1.5 cegger nmi = (ACPI_MADT_NMI_SOURCE *)mp;
1077 1.5 cegger acpi_print_intr(nmi->GlobalIrq, nmi->IntiFlags);
1078 1.5 cegger break;
1079 1.5 cegger case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
1080 1.5 cegger lapic_nmi = (ACPI_MADT_LOCAL_APIC_NMI *)mp;
1081 1.5 cegger acpi_print_cpu(lapic_nmi->ProcessorId);
1082 1.5 cegger acpi_print_local_nmi(lapic_nmi->Lint, lapic_nmi->IntiFlags);
1083 1.5 cegger break;
1084 1.5 cegger case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
1085 1.5 cegger lapic_over = (ACPI_MADT_LOCAL_APIC_OVERRIDE *)mp;
1086 1.5 cegger printf("\tLocal APIC ADDR=0x%016jx\n",
1087 1.5 cegger (uintmax_t)lapic_over->Address);
1088 1.5 cegger break;
1089 1.5 cegger case ACPI_MADT_TYPE_IO_SAPIC:
1090 1.5 cegger iosapic = (ACPI_MADT_IO_SAPIC *)mp;
1091 1.5 cegger acpi_print_io_apic(iosapic->Id, iosapic->GlobalIrqBase,
1092 1.5 cegger iosapic->Address);
1093 1.5 cegger break;
1094 1.5 cegger case ACPI_MADT_TYPE_LOCAL_SAPIC:
1095 1.5 cegger lsapic = (ACPI_MADT_LOCAL_SAPIC *)mp;
1096 1.5 cegger acpi_print_cpu(lsapic->ProcessorId);
1097 1.5 cegger acpi_print_local_apic(lsapic->Id, lsapic->LapicFlags);
1098 1.5 cegger printf("\tAPIC EID=%d\n", (u_int)lsapic->Eid);
1099 1.5 cegger if (mp->Length > offsetof(ACPI_MADT_LOCAL_SAPIC, Uid))
1100 1.5 cegger acpi_print_cpu_uid(lsapic->Uid, lsapic->UidString);
1101 1.5 cegger break;
1102 1.5 cegger case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
1103 1.5 cegger isrc = (ACPI_MADT_INTERRUPT_SOURCE *)mp;
1104 1.15.8.1 martin if (isrc->Type < __arraycount(platform_int_types))
1105 1.5 cegger printf("\tType=%s\n", platform_int_types[isrc->Type]);
1106 1.5 cegger else
1107 1.5 cegger printf("\tType=%d (unknown)\n", isrc->Type);
1108 1.5 cegger printf("\tAPIC ID=%d\n", (u_int)isrc->Id);
1109 1.5 cegger printf("\tAPIC EID=%d\n", (u_int)isrc->Eid);
1110 1.5 cegger printf("\tSAPIC Vector=%d\n", (u_int)isrc->IoSapicVector);
1111 1.5 cegger acpi_print_intr(isrc->GlobalIrq, isrc->IntiFlags);
1112 1.5 cegger break;
1113 1.5 cegger case ACPI_MADT_TYPE_LOCAL_X2APIC:
1114 1.5 cegger x2apic = (ACPI_MADT_LOCAL_X2APIC *)mp;
1115 1.5 cegger acpi_print_cpu_uid(x2apic->Uid, NULL);
1116 1.5 cegger acpi_print_local_apic(x2apic->LocalApicId, x2apic->LapicFlags);
1117 1.5 cegger break;
1118 1.5 cegger case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
1119 1.5 cegger x2apic_nmi = (ACPI_MADT_LOCAL_X2APIC_NMI *)mp;
1120 1.5 cegger acpi_print_cpu_uid(x2apic_nmi->Uid, NULL);
1121 1.5 cegger acpi_print_local_nmi(x2apic_nmi->Lint, x2apic_nmi->IntiFlags);
1122 1.5 cegger break;
1123 1.15.8.1 martin case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
1124 1.15.8.1 martin gicc = (ACPI_MADT_GENERIC_INTERRUPT *)mp;
1125 1.15.8.1 martin acpi_print_cpu_uid(gicc->Uid, NULL);
1126 1.15.8.1 martin printf("\tCPU INTERFACE=%x\n", gicc->CpuInterfaceNumber);
1127 1.15.8.1 martin acpi_print_gicc_flags(gicc->Flags);
1128 1.15.8.1 martin printf("\tParking Protocol Version=%x\n", gicc->ParkingVersion);
1129 1.15.8.1 martin printf("\tPERF INTR=%d\n", gicc->PerformanceInterrupt);
1130 1.15.8.1 martin printf("\tParked ADDR=%016jx\n",
1131 1.15.8.1 martin (uintmax_t)gicc->ParkedAddress);
1132 1.15.8.1 martin printf("\tBase ADDR=%016jx\n", (uintmax_t)gicc->BaseAddress);
1133 1.15.8.1 martin printf("\tGICV=%016jx\n", (uintmax_t)gicc->GicvBaseAddress);
1134 1.15.8.1 martin printf("\tGICH=%016jx\n", (uintmax_t)gicc->GichBaseAddress);
1135 1.15.8.1 martin printf("\tVGIC INTR=%d\n", gicc->VgicInterrupt);
1136 1.15.8.1 martin printf("\tGICR ADDR=%016jx\n",
1137 1.15.8.1 martin (uintmax_t)gicc->GicrBaseAddress);
1138 1.15.8.1 martin printf("\tMPIDR=%jx\n", (uintmax_t)gicc->ArmMpidr);
1139 1.15.8.1 martin printf("\tEfficency Class=%d\n", (u_int)gicc->EfficiencyClass);
1140 1.15.8.1 martin break;
1141 1.15.8.1 martin case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
1142 1.15.8.1 martin gicd = (ACPI_MADT_GENERIC_DISTRIBUTOR *)mp;
1143 1.15.8.1 martin printf("\tGIC ID=%d\n", (u_int)gicd->GicId);
1144 1.15.8.1 martin printf("\tBase ADDR=%016jx\n", (uintmax_t)gicd->BaseAddress);
1145 1.15.8.1 martin printf("\tVector Base=%d\n", gicd->GlobalIrqBase);
1146 1.15.8.1 martin printf("\tGIC VERSION=%d\n", (u_int)gicd->Version);
1147 1.15.8.1 martin break;
1148 1.15.8.1 martin case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
1149 1.15.8.1 martin gicm = (ACPI_MADT_GENERIC_MSI_FRAME*)mp;
1150 1.15.8.1 martin printf("\tBase ADDR=%016jx\n", (uintmax_t)gicm->BaseAddress);
1151 1.15.8.1 martin acpi_print_gicm_flags(gicm);
1152 1.15.8.1 martin printf("\tSPI Count=%u\n", gicm->SpiCount);
1153 1.15.8.1 martin printf("\tSPI Base=%u\n", gicm->SpiBase);
1154 1.15.8.1 martin break;
1155 1.15.8.1 martin case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
1156 1.15.8.1 martin gicr = (ACPI_MADT_GENERIC_REDISTRIBUTOR *)mp;
1157 1.15.8.1 martin printf("\tBase ADDR=%016jx\n", (uintmax_t)gicr->BaseAddress);
1158 1.15.8.1 martin printf("\tLength=%08x\n", gicr->Length);
1159 1.15.8.1 martin break;
1160 1.15.8.1 martin case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
1161 1.15.8.1 martin gict = (ACPI_MADT_GENERIC_TRANSLATOR *)mp;
1162 1.15.8.1 martin printf("\tGIC ITS ID=%d\n", gict->TranslationId);
1163 1.15.8.1 martin printf("\tBase ADDR=%016jx\n", (uintmax_t)gict->BaseAddress);
1164 1.15.8.1 martin break;
1165 1.5 cegger }
1166 1.5 cegger }
1167 1.5 cegger
1168 1.5 cegger #ifdef notyet
1169 1.5 cegger static void
1170 1.5 cegger acpi_print_bert_region(ACPI_BERT_REGION *region)
1171 1.5 cegger {
1172 1.5 cegger uint32_t i, pos, entries;
1173 1.5 cegger ACPI_HEST_GENERIC_DATA *data;
1174 1.5 cegger
1175 1.5 cegger printf("\n");
1176 1.5 cegger printf("\tBlockStatus={ ");
1177 1.5 cegger
1178 1.5 cegger if (region->BlockStatus & ACPI_BERT_UNCORRECTABLE)
1179 1.5 cegger printf("Uncorrectable");
1180 1.5 cegger if (region->BlockStatus & ACPI_BERT_CORRECTABLE)
1181 1.5 cegger printf("Correctable");
1182 1.5 cegger if (region->BlockStatus & ACPI_BERT_MULTIPLE_UNCORRECTABLE)
1183 1.5 cegger printf("Multiple Uncorrectable");
1184 1.5 cegger if (region->BlockStatus & ACPI_BERT_MULTIPLE_CORRECTABLE)
1185 1.5 cegger printf("Multiple Correctable");
1186 1.5 cegger entries = region->BlockStatus & ACPI_BERT_ERROR_ENTRY_COUNT;
1187 1.5 cegger printf(", Error Entry Count=%d", entries);
1188 1.5 cegger printf("}\n");
1189 1.5 cegger
1190 1.5 cegger printf("\tRaw Data Offset=0x%x\n", region->RawDataOffset);
1191 1.5 cegger printf("\tRaw Data Length=0x%x\n", region->RawDataLength);
1192 1.5 cegger printf("\tData Length=0x%x\n", region->DataLength);
1193 1.5 cegger
1194 1.5 cegger acpi_print_hest_errorseverity(region->ErrorSeverity);
1195 1.5 cegger
1196 1.5 cegger pos = sizeof(ACPI_BERT_REGION);
1197 1.5 cegger for (i = 0; i < entries; i++) {
1198 1.5 cegger data = (ACPI_HEST_GENERIC_DATA *)((char *)region + pos);
1199 1.5 cegger acpi_print_hest_generic_data(data);
1200 1.5 cegger pos += sizeof(ACPI_HEST_GENERIC_DATA);
1201 1.5 cegger }
1202 1.5 cegger }
1203 1.5 cegger #endif
1204 1.5 cegger
1205 1.5 cegger static void
1206 1.5 cegger acpi_handle_bert(ACPI_TABLE_HEADER *sdp)
1207 1.5 cegger {
1208 1.5 cegger ACPI_TABLE_BERT *bert;
1209 1.5 cegger
1210 1.5 cegger printf(BEGIN_COMMENT);
1211 1.5 cegger acpi_print_sdt(sdp);
1212 1.5 cegger bert = (ACPI_TABLE_BERT *)sdp;
1213 1.5 cegger
1214 1.5 cegger printf("\tLength of Boot Error Region=%d bytes\n", bert->RegionLength);
1215 1.5 cegger printf("\tPhysical Address of Region=0x%"PRIx64"\n", bert->Address);
1216 1.5 cegger
1217 1.5 cegger printf(END_COMMENT);
1218 1.5 cegger }
1219 1.5 cegger
1220 1.5 cegger static void
1221 1.5 cegger acpi_handle_boot(ACPI_TABLE_HEADER *sdp)
1222 1.5 cegger {
1223 1.5 cegger ACPI_TABLE_BOOT *boot;
1224 1.5 cegger
1225 1.5 cegger printf(BEGIN_COMMENT);
1226 1.5 cegger acpi_print_sdt(sdp);
1227 1.5 cegger boot = (ACPI_TABLE_BOOT *)sdp;
1228 1.5 cegger printf("\tCMOS Index=0x%02x\n", boot->CmosIndex);
1229 1.5 cegger printf(END_COMMENT);
1230 1.5 cegger }
1231 1.5 cegger
1232 1.5 cegger static void
1233 1.5 cegger acpi_handle_cpep(ACPI_TABLE_HEADER *sdp)
1234 1.5 cegger {
1235 1.5 cegger ACPI_TABLE_CPEP *cpep;
1236 1.5 cegger ACPI_CPEP_POLLING *poll;
1237 1.5 cegger uint32_t cpep_pos;
1238 1.5 cegger
1239 1.5 cegger printf(BEGIN_COMMENT);
1240 1.5 cegger acpi_print_sdt(sdp);
1241 1.5 cegger cpep = (ACPI_TABLE_CPEP *)sdp;
1242 1.5 cegger
1243 1.5 cegger cpep_pos = sizeof(ACPI_TABLE_CPEP);
1244 1.5 cegger while (cpep_pos < sdp->Length) {
1245 1.5 cegger poll = (ACPI_CPEP_POLLING *)((char *)cpep + cpep_pos);
1246 1.5 cegger acpi_print_cpu(poll->Id);
1247 1.5 cegger printf("\tACPI CPU EId=%d\n", poll->Eid);
1248 1.5 cegger printf("\tPoll Interval=%d msec\n", poll->Interval);
1249 1.5 cegger cpep_pos += sizeof(ACPI_CPEP_POLLING);
1250 1.5 cegger }
1251 1.5 cegger printf(END_COMMENT);
1252 1.5 cegger }
1253 1.5 cegger
1254 1.5 cegger static void
1255 1.15.8.2 martin acpi_print_csrt_resource_group(ACPI_CSRT_GROUP *grp)
1256 1.15.8.2 martin {
1257 1.15.8.2 martin ACPI_CSRT_DESCRIPTOR *desc;
1258 1.15.8.2 martin
1259 1.15.8.2 martin printf("\tLength=%u\n", grp->Length);
1260 1.15.8.2 martin printf("\tVendorId=");
1261 1.15.8.2 martin acpi_print_string((char *)&grp->VendorId, 4);
1262 1.15.8.2 martin printf("\n");
1263 1.15.8.2 martin if (grp->SubvendorId != 0) {
1264 1.15.8.2 martin printf("\tSubvendorId=");
1265 1.15.8.2 martin acpi_print_string((char *)&grp->SubvendorId, 4);
1266 1.15.8.2 martin printf("\n");
1267 1.15.8.2 martin }
1268 1.15.8.2 martin printf("\tDeviceId=0x%08x\n", grp->DeviceId);
1269 1.15.8.2 martin if (grp->SubdeviceId != 0)
1270 1.15.8.2 martin printf("\tSubdeviceId=0x%08x\n", grp->SubdeviceId);
1271 1.15.8.2 martin printf("\tRevision=%hu\n", grp->Revision);
1272 1.15.8.2 martin printf("\tSharedInfoLength=%u\n", grp->SharedInfoLength);
1273 1.15.8.2 martin
1274 1.15.8.2 martin /* Next is Shared Info */
1275 1.15.8.2 martin if (grp->SharedInfoLength != 0) {
1276 1.15.8.2 martin printf("\tShared Info ");
1277 1.15.8.2 martin acpi_dump_bytes((uint8_t *)(grp + 1),
1278 1.15.8.2 martin grp->SharedInfoLength, 1);
1279 1.15.8.2 martin }
1280 1.15.8.2 martin
1281 1.15.8.2 martin /* And then, Resource Descriptors */
1282 1.15.8.2 martin desc = (ACPI_CSRT_DESCRIPTOR *)
1283 1.15.8.2 martin ((vaddr_t)(grp + 1) + grp->SharedInfoLength);
1284 1.15.8.2 martin while (desc < (ACPI_CSRT_DESCRIPTOR *)((vaddr_t)grp + grp->Length)) {
1285 1.15.8.2 martin bool unknownsubytpe = false;
1286 1.15.8.2 martin printf("\n\tLength=%u\n", desc->Length);
1287 1.15.8.2 martin printf("\tResource Type=");
1288 1.15.8.2 martin switch (desc->Type) {
1289 1.15.8.2 martin case ACPI_CSRT_TYPE_INTERRUPT:
1290 1.15.8.2 martin printf("Interrupt");
1291 1.15.8.2 martin switch (desc->Subtype) {
1292 1.15.8.2 martin case ACPI_CSRT_XRUPT_LINE:
1293 1.15.8.2 martin printf("(Interrupt line)\n");
1294 1.15.8.2 martin break;
1295 1.15.8.2 martin case ACPI_CSRT_XRUPT_CONTROLLER:
1296 1.15.8.2 martin printf("(Interrupt controller)\n");
1297 1.15.8.2 martin break;
1298 1.15.8.2 martin default:
1299 1.15.8.2 martin unknownsubytpe = true;
1300 1.15.8.2 martin break;
1301 1.15.8.2 martin }
1302 1.15.8.2 martin break;
1303 1.15.8.2 martin case ACPI_CSRT_TYPE_TIMER:
1304 1.15.8.2 martin printf("Timer");
1305 1.15.8.2 martin switch (desc->Subtype) {
1306 1.15.8.2 martin case ACPI_CSRT_TIMER:
1307 1.15.8.2 martin printf("\n");
1308 1.15.8.2 martin break;
1309 1.15.8.2 martin default:
1310 1.15.8.2 martin unknownsubytpe = true;
1311 1.15.8.2 martin break;
1312 1.15.8.2 martin }
1313 1.15.8.2 martin break;
1314 1.15.8.2 martin case ACPI_CSRT_TYPE_DMA:
1315 1.15.8.2 martin printf("DMA");
1316 1.15.8.2 martin switch (desc->Subtype) {
1317 1.15.8.2 martin case ACPI_CSRT_DMA_CHANNEL:
1318 1.15.8.2 martin printf("(DMA channel)\n");
1319 1.15.8.2 martin break;
1320 1.15.8.2 martin case ACPI_CSRT_DMA_CONTROLLER:
1321 1.15.8.2 martin printf("(DMA controller)\n");
1322 1.15.8.2 martin break;
1323 1.15.8.2 martin default:
1324 1.15.8.2 martin unknownsubytpe = true;
1325 1.15.8.2 martin break;
1326 1.15.8.2 martin }
1327 1.15.8.2 martin break;
1328 1.15.8.2 martin case 0x0004: /* XXX Platform Security */
1329 1.15.8.2 martin printf("Platform Security");
1330 1.15.8.2 martin switch (desc->Subtype) {
1331 1.15.8.2 martin case 0x0001:
1332 1.15.8.2 martin printf("\n");
1333 1.15.8.2 martin /* Platform Security */
1334 1.15.8.2 martin break;
1335 1.15.8.2 martin default:
1336 1.15.8.2 martin unknownsubytpe = true;
1337 1.15.8.2 martin break;
1338 1.15.8.2 martin }
1339 1.15.8.2 martin break;
1340 1.15.8.2 martin default:
1341 1.15.8.2 martin printf("Unknown (%hx)\n", desc->Type);
1342 1.15.8.2 martin break;
1343 1.15.8.2 martin }
1344 1.15.8.2 martin if (unknownsubytpe)
1345 1.15.8.2 martin printf("(unknown subtype(%hx))\n", desc->Subtype);
1346 1.15.8.2 martin
1347 1.15.8.2 martin printf("\tUID=0x%08x\n", desc->Uid);
1348 1.15.8.2 martin printf("\tVendor defined info ");
1349 1.15.8.2 martin acpi_dump_bytes((uint8_t *)(desc + 1),
1350 1.15.8.2 martin desc->Length - sizeof(ACPI_CSRT_DESCRIPTOR), 1);
1351 1.15.8.2 martin
1352 1.15.8.2 martin /* Next */
1353 1.15.8.2 martin desc = (ACPI_CSRT_DESCRIPTOR *)((vaddr_t)desc + desc->Length);
1354 1.15.8.2 martin }
1355 1.15.8.2 martin }
1356 1.15.8.2 martin
1357 1.15.8.2 martin static void
1358 1.15.8.2 martin acpi_handle_csrt(ACPI_TABLE_HEADER *sdp)
1359 1.15.8.2 martin {
1360 1.15.8.2 martin ACPI_CSRT_GROUP *grp;
1361 1.15.8.2 martin uint totallen = sdp->Length;
1362 1.15.8.2 martin
1363 1.15.8.2 martin printf(BEGIN_COMMENT);
1364 1.15.8.2 martin acpi_print_sdt(sdp);
1365 1.15.8.2 martin grp = (ACPI_CSRT_GROUP *)(sdp + 1);
1366 1.15.8.2 martin
1367 1.15.8.2 martin while (grp < (ACPI_CSRT_GROUP *)((vaddr_t)sdp + totallen)) {
1368 1.15.8.2 martin printf("\n");
1369 1.15.8.2 martin acpi_print_csrt_resource_group(grp);
1370 1.15.8.2 martin
1371 1.15.8.2 martin /* Next */
1372 1.15.8.2 martin grp = (ACPI_CSRT_GROUP *)((vaddr_t)grp + grp->Length);
1373 1.15.8.2 martin }
1374 1.15.8.2 martin
1375 1.15.8.2 martin printf(END_COMMENT);
1376 1.15.8.2 martin }
1377 1.15.8.2 martin
1378 1.15.8.2 martin static void
1379 1.5 cegger acpi_handle_dbgp(ACPI_TABLE_HEADER *sdp)
1380 1.5 cegger {
1381 1.5 cegger ACPI_TABLE_DBGP *dbgp;
1382 1.5 cegger
1383 1.5 cegger printf(BEGIN_COMMENT);
1384 1.5 cegger acpi_print_sdt(sdp);
1385 1.5 cegger dbgp = (ACPI_TABLE_DBGP *)sdp;
1386 1.5 cegger printf("\tType={");
1387 1.5 cegger switch (dbgp->Type) {
1388 1.5 cegger case 0:
1389 1.5 cegger printf("full 16550");
1390 1.5 cegger break;
1391 1.5 cegger case 1:
1392 1.5 cegger printf("subset of 16550");
1393 1.5 cegger break;
1394 1.5 cegger }
1395 1.5 cegger printf("}\n");
1396 1.15.8.1 martin printf("\tDebugPort=");
1397 1.5 cegger acpi_print_gas(&dbgp->DebugPort);
1398 1.15.8.1 martin printf("\n");
1399 1.15.8.1 martin printf(END_COMMENT);
1400 1.15.8.1 martin }
1401 1.15.8.1 martin
1402 1.15.8.2 martin /* This function is used by DBG2 and SPCR. */
1403 1.15.8.2 martin static void
1404 1.15.8.2 martin acpi_print_dbg2_serial_subtype(uint16_t subtype)
1405 1.15.8.2 martin {
1406 1.15.8.2 martin
1407 1.15.8.2 martin switch (subtype) {
1408 1.15.8.2 martin case ACPI_DBG2_16550_COMPATIBLE:
1409 1.15.8.2 martin printf("Fully 16550 compatible\n");
1410 1.15.8.2 martin break;
1411 1.15.8.2 martin case ACPI_DBG2_16550_SUBSET:
1412 1.15.8.2 martin printf("16550 subset with DBGP Rev. 1\n");
1413 1.15.8.2 martin break;
1414 1.15.8.2 martin case ACPI_DBG2_ARM_PL011:
1415 1.15.8.2 martin printf("ARM PL011\n");
1416 1.15.8.2 martin break;
1417 1.15.8.2 martin case ACPI_DBG2_ARM_SBSA_32BIT:
1418 1.15.8.2 martin printf("ARM SBSA 32bit only\n");
1419 1.15.8.2 martin break;
1420 1.15.8.2 martin case ACPI_DBG2_ARM_SBSA_GENERIC:
1421 1.15.8.2 martin printf("ARM SBSA Generic\n");
1422 1.15.8.2 martin break;
1423 1.15.8.2 martin case ACPI_DBG2_ARM_DCC:
1424 1.15.8.2 martin printf("ARM DCC\n");
1425 1.15.8.2 martin break;
1426 1.15.8.2 martin case ACPI_DBG2_BCM2835:
1427 1.15.8.2 martin printf("BCM2835\n");
1428 1.15.8.2 martin break;
1429 1.15.8.2 martin default:
1430 1.15.8.2 martin printf("reserved (%04hx)\n", subtype);
1431 1.15.8.2 martin break;
1432 1.15.8.2 martin }
1433 1.15.8.2 martin }
1434 1.15.8.2 martin
1435 1.15.8.1 martin static void
1436 1.15.8.1 martin acpi_print_dbg2_device(ACPI_DBG2_DEVICE *dev)
1437 1.15.8.1 martin {
1438 1.15.8.1 martin
1439 1.15.8.1 martin printf("\t\tRevision=%u\n", dev->Revision);
1440 1.15.8.1 martin printf("\t\tLength=%u\n", dev->Length);
1441 1.15.8.1 martin printf("\t\tRegisterCount=%u\n", dev->RegisterCount);
1442 1.15.8.1 martin
1443 1.15.8.1 martin printf("\t\tNamepath=");
1444 1.15.8.1 martin acpi_print_string((char *)((vaddr_t)dev + dev->NamepathOffset),
1445 1.15.8.1 martin dev->NamepathLength);
1446 1.15.8.1 martin printf("\n");
1447 1.15.8.1 martin
1448 1.15.8.1 martin if (dev->OemDataLength) {
1449 1.15.8.1 martin printf("\t\tOemDataLength=%u\n", dev->OemDataLength);
1450 1.15.8.1 martin printf("\t\tOemDataOffset=%u\n", dev->OemDataOffset);
1451 1.15.8.1 martin /* XXX need dump */
1452 1.15.8.1 martin }
1453 1.15.8.1 martin
1454 1.15.8.1 martin printf("\t\tPortType=");
1455 1.15.8.1 martin switch (dev->PortType) {
1456 1.15.8.1 martin case ACPI_DBG2_SERIAL_PORT:
1457 1.15.8.1 martin printf("Serial\n" "\t\tPortSubtype=");
1458 1.15.8.2 martin acpi_print_dbg2_serial_subtype(dev->PortSubtype);
1459 1.15.8.1 martin break;
1460 1.15.8.1 martin case ACPI_DBG2_1394_PORT:
1461 1.15.8.1 martin printf("IEEE1394\n" "\t\tPortSubtype=");
1462 1.15.8.1 martin if (dev->PortSubtype == ACPI_DBG2_1394_STANDARD)
1463 1.15.8.1 martin printf("Standard\n");
1464 1.15.8.1 martin else
1465 1.15.8.1 martin printf("reserved (%04hx)\n", dev->PortSubtype);
1466 1.15.8.1 martin break;
1467 1.15.8.1 martin case ACPI_DBG2_USB_PORT:
1468 1.15.8.1 martin printf("USB\n" "\t\tPortSubtype=");
1469 1.15.8.1 martin switch (dev->PortSubtype) {
1470 1.15.8.1 martin case ACPI_DBG2_USB_XHCI:
1471 1.15.8.1 martin printf("XHCIn");
1472 1.15.8.1 martin break;
1473 1.15.8.1 martin case ACPI_DBG2_USB_EHCI:
1474 1.15.8.1 martin printf("EHCI\n");
1475 1.15.8.1 martin break;
1476 1.15.8.1 martin default:
1477 1.15.8.1 martin printf("reserved (%04hx)\n", dev->PortSubtype);
1478 1.15.8.1 martin break;
1479 1.15.8.1 martin }
1480 1.15.8.1 martin break;
1481 1.15.8.1 martin case ACPI_DBG2_NET_PORT:
1482 1.15.8.1 martin printf("Net\n" "\t\tPciVendorID=%04x\n", dev->PortSubtype);
1483 1.15.8.1 martin break;
1484 1.15.8.1 martin default:
1485 1.15.8.1 martin printf("reserved (%04hx)\n", dev->PortType);
1486 1.15.8.1 martin printf("\t\tPortSubtype=reserved (%04hx)\n", dev->PortSubtype);
1487 1.15.8.1 martin break;
1488 1.15.8.1 martin }
1489 1.15.8.1 martin
1490 1.15.8.1 martin printf("\t\tBaseAddressOffset=0x%04x\n", dev->BaseAddressOffset);
1491 1.15.8.1 martin printf("\t\tAddressSizeOffset=0x%04x\n", dev->AddressSizeOffset);
1492 1.15.8.1 martin }
1493 1.15.8.1 martin
1494 1.15.8.1 martin static void
1495 1.15.8.1 martin acpi_handle_dbg2(ACPI_TABLE_HEADER *sdp)
1496 1.15.8.1 martin {
1497 1.15.8.1 martin ACPI_TABLE_DBG2 *dbg2;
1498 1.15.8.1 martin ACPI_DBG2_DEVICE *device;
1499 1.15.8.1 martin unsigned int i;
1500 1.15.8.1 martin
1501 1.15.8.1 martin printf(BEGIN_COMMENT);
1502 1.15.8.1 martin acpi_print_sdt(sdp);
1503 1.15.8.1 martin dbg2 = (ACPI_TABLE_DBG2 *)sdp;
1504 1.15.8.1 martin
1505 1.15.8.1 martin printf("\tCount=%u\n", dbg2->InfoCount);
1506 1.15.8.1 martin device = (ACPI_DBG2_DEVICE *)((vaddr_t)sdp + dbg2->InfoOffset);
1507 1.15.8.1 martin for (i = 0; i < dbg2->InfoCount; i++) {
1508 1.15.8.1 martin printf("\tDevice %u={\n", i);
1509 1.15.8.1 martin acpi_print_dbg2_device(device);
1510 1.15.8.1 martin printf("\t}\n");
1511 1.15.8.1 martin device++;
1512 1.15.8.1 martin }
1513 1.15.8.1 martin
1514 1.5 cegger printf(END_COMMENT);
1515 1.5 cegger }
1516 1.5 cegger
1517 1.5 cegger static void
1518 1.5 cegger acpi_print_einj_action(ACPI_WHEA_HEADER *whea)
1519 1.5 cegger {
1520 1.5 cegger printf("\tACTION={");
1521 1.5 cegger switch (whea->Action) {
1522 1.5 cegger case ACPI_EINJ_BEGIN_OPERATION:
1523 1.5 cegger printf("Begin Operation");
1524 1.5 cegger break;
1525 1.5 cegger case ACPI_EINJ_GET_TRIGGER_TABLE:
1526 1.5 cegger printf("Get Trigger Table");
1527 1.5 cegger break;
1528 1.5 cegger case ACPI_EINJ_SET_ERROR_TYPE:
1529 1.5 cegger printf("Set Error Type");
1530 1.5 cegger break;
1531 1.5 cegger case ACPI_EINJ_GET_ERROR_TYPE:
1532 1.5 cegger printf("Get Error Type");
1533 1.5 cegger break;
1534 1.5 cegger case ACPI_EINJ_END_OPERATION:
1535 1.5 cegger printf("End Operation");
1536 1.5 cegger break;
1537 1.5 cegger case ACPI_EINJ_EXECUTE_OPERATION:
1538 1.5 cegger printf("Execute Operation");
1539 1.5 cegger break;
1540 1.5 cegger case ACPI_EINJ_CHECK_BUSY_STATUS:
1541 1.5 cegger printf("Check Busy Status");
1542 1.5 cegger break;
1543 1.5 cegger case ACPI_EINJ_GET_COMMAND_STATUS:
1544 1.5 cegger printf("Get Command Status");
1545 1.5 cegger break;
1546 1.15.8.1 martin case ACPI_EINJ_SET_ERROR_TYPE_WITH_ADDRESS:
1547 1.15.8.1 martin printf("Set Error Type With Address");
1548 1.15.8.1 martin break;
1549 1.15.8.1 martin case ACPI_EINJ_GET_EXECUTE_TIMINGS:
1550 1.15.8.1 martin printf("Get Execute Operation Timings");
1551 1.15.8.1 martin break;
1552 1.5 cegger case ACPI_EINJ_ACTION_RESERVED:
1553 1.5 cegger printf("Preserved");
1554 1.5 cegger break;
1555 1.5 cegger case ACPI_EINJ_TRIGGER_ERROR:
1556 1.5 cegger printf("Trigger Error");
1557 1.5 cegger break;
1558 1.5 cegger default:
1559 1.5 cegger printf("%d", whea->Action);
1560 1.5 cegger break;
1561 1.5 cegger }
1562 1.5 cegger printf("}\n");
1563 1.5 cegger }
1564 1.5 cegger
1565 1.5 cegger static void
1566 1.5 cegger acpi_print_einj_instruction(ACPI_WHEA_HEADER *whea)
1567 1.5 cegger {
1568 1.5 cegger uint32_t ins = whea->Instruction;
1569 1.5 cegger
1570 1.5 cegger printf("\tINSTRUCTION={");
1571 1.5 cegger switch (ins) {
1572 1.5 cegger case ACPI_EINJ_READ_REGISTER:
1573 1.5 cegger printf("Read Register");
1574 1.5 cegger break;
1575 1.5 cegger case ACPI_EINJ_READ_REGISTER_VALUE:
1576 1.5 cegger printf("Read Register Value");
1577 1.5 cegger break;
1578 1.5 cegger case ACPI_EINJ_WRITE_REGISTER:
1579 1.5 cegger printf("Write Register");
1580 1.5 cegger break;
1581 1.5 cegger case ACPI_EINJ_WRITE_REGISTER_VALUE:
1582 1.5 cegger printf("Write Register Value");
1583 1.5 cegger break;
1584 1.5 cegger case ACPI_EINJ_NOOP:
1585 1.5 cegger printf("Noop");
1586 1.5 cegger break;
1587 1.5 cegger case ACPI_EINJ_INSTRUCTION_RESERVED:
1588 1.5 cegger printf("Reserved");
1589 1.5 cegger break;
1590 1.5 cegger default:
1591 1.5 cegger printf("%d", ins);
1592 1.5 cegger break;
1593 1.5 cegger }
1594 1.5 cegger printf("}\n");
1595 1.5 cegger }
1596 1.5 cegger
1597 1.5 cegger static void
1598 1.5 cegger acpi_print_einj_flags(ACPI_WHEA_HEADER *whea)
1599 1.5 cegger {
1600 1.5 cegger uint32_t flags = whea->Flags;
1601 1.5 cegger
1602 1.15.8.1 martin printf("\tFLAGS={");
1603 1.5 cegger if (flags & ACPI_EINJ_PRESERVE)
1604 1.5 cegger printf("PRESERVED");
1605 1.5 cegger printf("}\n");
1606 1.5 cegger }
1607 1.5 cegger
1608 1.5 cegger static void
1609 1.5 cegger acpi_handle_einj(ACPI_TABLE_HEADER *sdp)
1610 1.5 cegger {
1611 1.5 cegger ACPI_TABLE_EINJ *einj;
1612 1.5 cegger ACPI_EINJ_ENTRY *einj_entry;
1613 1.5 cegger uint32_t einj_pos;
1614 1.5 cegger u_int i;
1615 1.5 cegger
1616 1.5 cegger printf(BEGIN_COMMENT);
1617 1.5 cegger acpi_print_sdt(sdp);
1618 1.5 cegger einj = (ACPI_TABLE_EINJ *)sdp;
1619 1.5 cegger
1620 1.5 cegger printf("\tHeader Length=%d\n", einj->HeaderLength);
1621 1.5 cegger printf("\tFlags=0x%x\n", einj->Flags);
1622 1.5 cegger printf("\tEntries=%d\n", einj->Entries);
1623 1.5 cegger
1624 1.5 cegger einj_pos = sizeof(ACPI_TABLE_EINJ);
1625 1.5 cegger for (i = 0; i < einj->Entries; i++) {
1626 1.5 cegger einj_entry = (ACPI_EINJ_ENTRY *)((char *)einj + einj_pos);
1627 1.5 cegger acpi_print_whea(&einj_entry->WheaHeader,
1628 1.5 cegger acpi_print_einj_action, acpi_print_einj_instruction,
1629 1.5 cegger acpi_print_einj_flags);
1630 1.5 cegger einj_pos += sizeof(ACPI_EINJ_ENTRY);
1631 1.5 cegger }
1632 1.5 cegger printf(END_COMMENT);
1633 1.5 cegger }
1634 1.5 cegger
1635 1.5 cegger static void
1636 1.5 cegger acpi_print_erst_action(ACPI_WHEA_HEADER *whea)
1637 1.5 cegger {
1638 1.5 cegger printf("\tACTION={");
1639 1.5 cegger switch (whea->Action) {
1640 1.5 cegger case ACPI_ERST_BEGIN_WRITE:
1641 1.5 cegger printf("Begin Write");
1642 1.5 cegger break;
1643 1.5 cegger case ACPI_ERST_BEGIN_READ:
1644 1.5 cegger printf("Begin Read");
1645 1.5 cegger break;
1646 1.5 cegger case ACPI_ERST_BEGIN_CLEAR:
1647 1.5 cegger printf("Begin Clear");
1648 1.5 cegger break;
1649 1.5 cegger case ACPI_ERST_END:
1650 1.5 cegger printf("End");
1651 1.5 cegger break;
1652 1.5 cegger case ACPI_ERST_SET_RECORD_OFFSET:
1653 1.5 cegger printf("Set Record Offset");
1654 1.5 cegger break;
1655 1.5 cegger case ACPI_ERST_EXECUTE_OPERATION:
1656 1.5 cegger printf("Execute Operation");
1657 1.5 cegger break;
1658 1.5 cegger case ACPI_ERST_CHECK_BUSY_STATUS:
1659 1.5 cegger printf("Check Busy Status");
1660 1.5 cegger break;
1661 1.5 cegger case ACPI_ERST_GET_COMMAND_STATUS:
1662 1.5 cegger printf("Get Command Status");
1663 1.5 cegger break;
1664 1.5 cegger case ACPI_ERST_GET_RECORD_ID:
1665 1.5 cegger printf("Get Record ID");
1666 1.5 cegger break;
1667 1.5 cegger case ACPI_ERST_SET_RECORD_ID:
1668 1.5 cegger printf("Set Record ID");
1669 1.5 cegger break;
1670 1.5 cegger case ACPI_ERST_GET_RECORD_COUNT:
1671 1.5 cegger printf("Get Record Count");
1672 1.5 cegger break;
1673 1.5 cegger case ACPI_ERST_BEGIN_DUMMY_WRIITE:
1674 1.5 cegger printf("Begin Dummy Write");
1675 1.5 cegger break;
1676 1.5 cegger case ACPI_ERST_NOT_USED:
1677 1.5 cegger printf("Unused");
1678 1.5 cegger break;
1679 1.5 cegger case ACPI_ERST_GET_ERROR_RANGE:
1680 1.5 cegger printf("Get Error Range");
1681 1.5 cegger break;
1682 1.5 cegger case ACPI_ERST_GET_ERROR_LENGTH:
1683 1.5 cegger printf("Get Error Length");
1684 1.5 cegger break;
1685 1.5 cegger case ACPI_ERST_GET_ERROR_ATTRIBUTES:
1686 1.5 cegger printf("Get Error Attributes");
1687 1.5 cegger break;
1688 1.15.8.1 martin case ACPI_ERST_EXECUTE_TIMINGS:
1689 1.15.8.1 martin printf("Execute Operation Timings");
1690 1.15.8.1 martin break;
1691 1.5 cegger case ACPI_ERST_ACTION_RESERVED:
1692 1.5 cegger printf("Reserved");
1693 1.5 cegger break;
1694 1.5 cegger default:
1695 1.5 cegger printf("%d", whea->Action);
1696 1.5 cegger break;
1697 1.5 cegger }
1698 1.5 cegger printf("}\n");
1699 1.5 cegger }
1700 1.5 cegger
1701 1.5 cegger static void
1702 1.5 cegger acpi_print_erst_instruction(ACPI_WHEA_HEADER *whea)
1703 1.5 cegger {
1704 1.5 cegger printf("\tINSTRUCTION={");
1705 1.5 cegger switch (whea->Instruction) {
1706 1.5 cegger case ACPI_ERST_READ_REGISTER:
1707 1.5 cegger printf("Read Register");
1708 1.5 cegger break;
1709 1.5 cegger case ACPI_ERST_READ_REGISTER_VALUE:
1710 1.5 cegger printf("Read Register Value");
1711 1.5 cegger break;
1712 1.5 cegger case ACPI_ERST_WRITE_REGISTER:
1713 1.5 cegger printf("Write Register");
1714 1.5 cegger break;
1715 1.5 cegger case ACPI_ERST_WRITE_REGISTER_VALUE:
1716 1.5 cegger printf("Write Register Value");
1717 1.5 cegger break;
1718 1.5 cegger case ACPI_ERST_NOOP:
1719 1.5 cegger printf("Noop");
1720 1.5 cegger break;
1721 1.5 cegger case ACPI_ERST_LOAD_VAR1:
1722 1.5 cegger printf("Load Var1");
1723 1.5 cegger break;
1724 1.5 cegger case ACPI_ERST_LOAD_VAR2:
1725 1.5 cegger printf("Load Var2");
1726 1.5 cegger break;
1727 1.5 cegger case ACPI_ERST_STORE_VAR1:
1728 1.5 cegger printf("Store Var1");
1729 1.5 cegger break;
1730 1.5 cegger case ACPI_ERST_ADD:
1731 1.5 cegger printf("Add");
1732 1.5 cegger break;
1733 1.5 cegger case ACPI_ERST_SUBTRACT:
1734 1.5 cegger printf("Subtract");
1735 1.5 cegger break;
1736 1.5 cegger case ACPI_ERST_ADD_VALUE:
1737 1.5 cegger printf("Add Value");
1738 1.5 cegger break;
1739 1.5 cegger case ACPI_ERST_SUBTRACT_VALUE:
1740 1.5 cegger printf("Subtract Value");
1741 1.5 cegger break;
1742 1.5 cegger case ACPI_ERST_STALL:
1743 1.5 cegger printf("Stall");
1744 1.5 cegger break;
1745 1.5 cegger case ACPI_ERST_STALL_WHILE_TRUE:
1746 1.5 cegger printf("Stall While True");
1747 1.5 cegger break;
1748 1.5 cegger case ACPI_ERST_SKIP_NEXT_IF_TRUE:
1749 1.5 cegger printf("Skip Next If True");
1750 1.5 cegger break;
1751 1.5 cegger case ACPI_ERST_GOTO:
1752 1.5 cegger printf("Goto");
1753 1.5 cegger break;
1754 1.5 cegger case ACPI_ERST_SET_SRC_ADDRESS_BASE:
1755 1.5 cegger printf("Set Src Address Base");
1756 1.5 cegger break;
1757 1.5 cegger case ACPI_ERST_SET_DST_ADDRESS_BASE:
1758 1.5 cegger printf("Set Dst Address Base");
1759 1.5 cegger break;
1760 1.5 cegger case ACPI_ERST_MOVE_DATA:
1761 1.5 cegger printf("Move Data");
1762 1.5 cegger break;
1763 1.5 cegger case ACPI_ERST_INSTRUCTION_RESERVED:
1764 1.5 cegger printf("Reserved");
1765 1.5 cegger break;
1766 1.5 cegger default:
1767 1.5 cegger printf("%d (reserved)", whea->Instruction);
1768 1.5 cegger break;
1769 1.5 cegger }
1770 1.5 cegger printf("}\n");
1771 1.5 cegger }
1772 1.5 cegger
1773 1.5 cegger static void
1774 1.5 cegger acpi_print_erst_flags(ACPI_WHEA_HEADER *whea)
1775 1.5 cegger {
1776 1.5 cegger uint32_t flags = whea->Flags;
1777 1.5 cegger
1778 1.15.8.1 martin printf("\tFLAGS={");
1779 1.5 cegger if (flags & ACPI_ERST_PRESERVE)
1780 1.5 cegger printf("PRESERVED");
1781 1.5 cegger printf("}\n");
1782 1.5 cegger }
1783 1.5 cegger
1784 1.5 cegger static void
1785 1.5 cegger acpi_handle_erst(ACPI_TABLE_HEADER *sdp)
1786 1.5 cegger {
1787 1.5 cegger ACPI_TABLE_ERST *erst;
1788 1.5 cegger ACPI_ERST_ENTRY *erst_entry;
1789 1.5 cegger uint32_t erst_pos;
1790 1.5 cegger u_int i;
1791 1.5 cegger
1792 1.5 cegger printf(BEGIN_COMMENT);
1793 1.5 cegger acpi_print_sdt(sdp);
1794 1.5 cegger erst = (ACPI_TABLE_ERST *)sdp;
1795 1.5 cegger
1796 1.5 cegger printf("\tHeader Length=%d\n", erst->HeaderLength);
1797 1.5 cegger printf("\tEntries=%d\n", erst->Entries);
1798 1.5 cegger
1799 1.5 cegger erst_pos = sizeof(ACPI_TABLE_ERST);
1800 1.5 cegger for (i = 0; i < erst->Entries; i++) {
1801 1.5 cegger erst_entry = (ACPI_ERST_ENTRY *)((char *)erst + erst_pos);
1802 1.5 cegger acpi_print_whea(&erst_entry->WheaHeader,
1803 1.5 cegger acpi_print_erst_action, acpi_print_erst_instruction,
1804 1.5 cegger acpi_print_erst_flags);
1805 1.5 cegger erst_pos += sizeof(ACPI_ERST_ENTRY);
1806 1.5 cegger }
1807 1.5 cegger printf(END_COMMENT);
1808 1.5 cegger }
1809 1.5 cegger
1810 1.5 cegger static void
1811 1.15.8.2 martin acpi_print_gtd_timer(const char *name, uint32_t interrupt, uint32_t flags)
1812 1.15.8.2 martin {
1813 1.15.8.2 martin
1814 1.15.8.2 martin printf("\t%s Timer GSIV=%d\n", name, interrupt);
1815 1.15.8.2 martin printf("\t%s Flags={Mode=", name);
1816 1.15.8.2 martin if (flags & ACPI_GTDT_INTERRUPT_MODE)
1817 1.15.8.2 martin printf("edge");
1818 1.15.8.2 martin else
1819 1.15.8.2 martin printf("level");
1820 1.15.8.2 martin printf(", Polarity=");
1821 1.15.8.2 martin if (flags & ACPI_GTDT_INTERRUPT_POLARITY)
1822 1.15.8.2 martin printf("active-lo");
1823 1.15.8.2 martin else
1824 1.15.8.2 martin printf("active-hi");
1825 1.15.8.2 martin if (flags & ACPI_GTDT_ALWAYS_ON)
1826 1.15.8.2 martin printf(", always-on");
1827 1.15.8.2 martin printf("}\n");
1828 1.15.8.2 martin }
1829 1.15.8.2 martin
1830 1.15.8.2 martin static void
1831 1.15.8.2 martin acpi_print_gtd_block_timer_flags(const char *name, uint32_t interrupt,
1832 1.15.8.2 martin uint32_t flags)
1833 1.15.8.2 martin {
1834 1.15.8.2 martin
1835 1.15.8.2 martin printf("\t\t%s Timer GSIV=%d\n", name, interrupt);
1836 1.15.8.2 martin printf("\t\t%s Timer Flags={Mode=", name);
1837 1.15.8.2 martin if (flags & ACPI_GTDT_GT_IRQ_MODE)
1838 1.15.8.2 martin printf("Secure");
1839 1.15.8.2 martin else
1840 1.15.8.2 martin printf("Non-Secure");
1841 1.15.8.2 martin printf(", Polarity=");
1842 1.15.8.2 martin if (flags & ACPI_GTDT_GT_IRQ_POLARITY)
1843 1.15.8.2 martin printf("active-lo");
1844 1.15.8.2 martin else
1845 1.15.8.2 martin printf("active-hi");
1846 1.15.8.2 martin printf("}\n");
1847 1.15.8.2 martin }
1848 1.15.8.2 martin
1849 1.15.8.2 martin static void
1850 1.15.8.2 martin acpi_print_gtblock(ACPI_GTDT_TIMER_BLOCK *gtblock)
1851 1.15.8.2 martin {
1852 1.15.8.2 martin ACPI_GTDT_TIMER_ENTRY *entry;
1853 1.15.8.2 martin unsigned int i;
1854 1.15.8.2 martin
1855 1.15.8.2 martin printf("\tType=GT Block\n");
1856 1.15.8.2 martin printf("\tLength=%d\n", gtblock->Header.Length);
1857 1.15.8.2 martin /* XXX might not 8byte aligned */
1858 1.15.8.2 martin printf("\tBlockAddress=%016jx\n",
1859 1.15.8.2 martin (uintmax_t)gtblock->BlockAddress);
1860 1.15.8.2 martin
1861 1.15.8.2 martin printf("\tGT Block Timer Count=%d\n", gtblock->TimerCount);
1862 1.15.8.2 martin entry = (ACPI_GTDT_TIMER_ENTRY *)((vaddr_t)gtblock
1863 1.15.8.2 martin + gtblock->TimerOffset);
1864 1.15.8.2 martin for (i = 0; i < gtblock->TimerCount; i++) {
1865 1.15.8.2 martin printf("\n");
1866 1.15.8.2 martin if (entry >= (ACPI_GTDT_TIMER_ENTRY *)((vaddr_t)gtblock
1867 1.15.8.2 martin + gtblock->Header.Length)) {
1868 1.15.8.2 martin printf("\\ttWrong Timer entry\n");
1869 1.15.8.2 martin break;
1870 1.15.8.2 martin }
1871 1.15.8.2 martin printf("\t\tFrame Number=%d\n", entry->FrameNumber);
1872 1.15.8.2 martin /* XXX might not 8byte aligned */
1873 1.15.8.2 martin printf("\t\tBaseAddress=%016jx\n",
1874 1.15.8.2 martin (uintmax_t)entry->BaseAddress);
1875 1.15.8.2 martin /* XXX might not 8byte aligned */
1876 1.15.8.2 martin printf("\t\tEl0BaseAddress=%016jx\n",
1877 1.15.8.2 martin (uintmax_t)entry->El0BaseAddress);
1878 1.15.8.2 martin
1879 1.15.8.2 martin acpi_print_gtd_block_timer_flags("Physical",
1880 1.15.8.2 martin entry->TimerInterrupt, entry->TimerFlags);
1881 1.15.8.2 martin acpi_print_gtd_block_timer_flags("Virtual",
1882 1.15.8.2 martin entry->VirtualTimerInterrupt, entry->VirtualTimerFlags);
1883 1.15.8.2 martin
1884 1.15.8.2 martin printf("\t\tCommon Flags={Mode=");
1885 1.15.8.2 martin if (entry->CommonFlags & ACPI_GTDT_GT_IS_SECURE_TIMER)
1886 1.15.8.2 martin printf("Secure");
1887 1.15.8.2 martin else
1888 1.15.8.2 martin printf("Non-Secure");
1889 1.15.8.2 martin if (entry->CommonFlags & ACPI_GTDT_GT_ALWAYS_ON)
1890 1.15.8.2 martin printf(", always-on");
1891 1.15.8.2 martin printf("}\n");
1892 1.15.8.2 martin
1893 1.15.8.2 martin entry++;
1894 1.15.8.2 martin }
1895 1.15.8.2 martin }
1896 1.15.8.2 martin
1897 1.15.8.2 martin static void
1898 1.15.8.2 martin acpi_print_sbsa_watchdog(ACPI_GTDT_WATCHDOG *wdog)
1899 1.15.8.2 martin {
1900 1.15.8.2 martin
1901 1.15.8.2 martin printf("\tType=Watchdog GT\n");
1902 1.15.8.2 martin printf("\tLength=%d\n", wdog->Header.Length);
1903 1.15.8.2 martin /* XXX might not 8byte aligned */
1904 1.15.8.2 martin printf("\tRefreshFrameAddress=%016jx\n",
1905 1.15.8.2 martin (uintmax_t)wdog->RefreshFrameAddress);
1906 1.15.8.2 martin /* XXX might not 8byte aligned */
1907 1.15.8.2 martin printf("\tControlFrameAddress=%016jx\n",
1908 1.15.8.2 martin (uintmax_t)wdog->ControlFrameAddress);
1909 1.15.8.2 martin printf("\tGSIV=%d\n", wdog->TimerInterrupt);
1910 1.15.8.2 martin
1911 1.15.8.2 martin printf("\tFlags={Mode=");
1912 1.15.8.2 martin if (wdog->TimerFlags & ACPI_GTDT_WATCHDOG_IRQ_MODE)
1913 1.15.8.2 martin printf("edge");
1914 1.15.8.2 martin else
1915 1.15.8.2 martin printf("level");
1916 1.15.8.2 martin printf(", Polarity=");
1917 1.15.8.2 martin if (wdog->TimerFlags & ACPI_GTDT_WATCHDOG_IRQ_POLARITY)
1918 1.15.8.2 martin printf("active-lo");
1919 1.15.8.2 martin else
1920 1.15.8.2 martin printf("active-hi");
1921 1.15.8.2 martin if (wdog->TimerFlags & ACPI_GTDT_WATCHDOG_SECURE)
1922 1.15.8.2 martin printf(", Secure");
1923 1.15.8.2 martin else
1924 1.15.8.2 martin printf(", Non-Secure");
1925 1.15.8.2 martin printf("}\n");
1926 1.15.8.2 martin }
1927 1.15.8.2 martin
1928 1.15.8.2 martin static void
1929 1.15.8.2 martin acpi_handle_gtdt(ACPI_TABLE_HEADER *sdp)
1930 1.15.8.2 martin {
1931 1.15.8.2 martin ACPI_TABLE_GTDT *gtdt;
1932 1.15.8.2 martin ACPI_GTDT_HEADER *hdr;
1933 1.15.8.2 martin u_int i;
1934 1.15.8.2 martin
1935 1.15.8.2 martin printf(BEGIN_COMMENT);
1936 1.15.8.2 martin acpi_print_sdt(sdp);
1937 1.15.8.2 martin gtdt = (ACPI_TABLE_GTDT *)sdp;
1938 1.15.8.2 martin
1939 1.15.8.2 martin printf("\tCounterBlockAddresss=%016jx\n",
1940 1.15.8.2 martin (uintmax_t)gtdt->CounterBlockAddresss); /* XXX not 8byte aligned */
1941 1.15.8.2 martin printf("\tCounterReadBlockAddress=%016jx\n",
1942 1.15.8.2 martin (uintmax_t)gtdt->CounterReadBlockAddress);
1943 1.15.8.2 martin
1944 1.15.8.2 martin #define PRINTTIMER(gtdt, name) acpi_print_gtd_timer( \
1945 1.15.8.2 martin #name, (gtdt)-> name## Interrupt, \
1946 1.15.8.2 martin (gtdt)-> name ## Flags)
1947 1.15.8.2 martin
1948 1.15.8.2 martin PRINTTIMER(gtdt, SecureEl1);
1949 1.15.8.2 martin PRINTTIMER(gtdt, NonSecureEl1);
1950 1.15.8.2 martin PRINTTIMER(gtdt, VirtualTimer);
1951 1.15.8.2 martin PRINTTIMER(gtdt, NonSecureEl2);
1952 1.15.8.2 martin
1953 1.15.8.2 martin #undef PRINTTIMER
1954 1.15.8.2 martin
1955 1.15.8.2 martin printf("\tPlatform Timer Count=%d\n", gtdt->PlatformTimerCount);
1956 1.15.8.2 martin
1957 1.15.8.2 martin hdr = (ACPI_GTDT_HEADER *)((vaddr_t)sdp + gtdt->PlatformTimerOffset);
1958 1.15.8.2 martin for (i = 0; i < gtdt->PlatformTimerCount; i++) {
1959 1.15.8.2 martin printf("\n");
1960 1.15.8.2 martin if (hdr >= (ACPI_GTDT_HEADER *)((vaddr_t)sdp + sdp->Length)) {
1961 1.15.8.2 martin printf("\tWrong GTDT header"
1962 1.15.8.2 martin "(type = %hhu, length = %hu)\n",
1963 1.15.8.2 martin hdr->Type, hdr->Length);
1964 1.15.8.2 martin break;
1965 1.15.8.2 martin }
1966 1.15.8.2 martin
1967 1.15.8.2 martin switch (hdr->Type) {
1968 1.15.8.2 martin case ACPI_GTDT_TYPE_TIMER_BLOCK:
1969 1.15.8.2 martin acpi_print_gtblock((ACPI_GTDT_TIMER_BLOCK *)hdr);
1970 1.15.8.2 martin break;
1971 1.15.8.2 martin case ACPI_GTDT_TYPE_WATCHDOG:
1972 1.15.8.2 martin acpi_print_sbsa_watchdog((ACPI_GTDT_WATCHDOG *)hdr);
1973 1.15.8.2 martin break;
1974 1.15.8.2 martin default:
1975 1.15.8.2 martin printf("\tUnknown Platform Timer Type"
1976 1.15.8.2 martin "(type = %hhu, length = %hu)\n",
1977 1.15.8.2 martin hdr->Type, hdr->Length);
1978 1.15.8.2 martin break;
1979 1.15.8.2 martin }
1980 1.15.8.2 martin /* Next */
1981 1.15.8.2 martin hdr = (ACPI_GTDT_HEADER *)((vaddr_t)hdr + hdr->Length);
1982 1.15.8.2 martin }
1983 1.15.8.2 martin printf(END_COMMENT);
1984 1.15.8.2 martin }
1985 1.15.8.2 martin
1986 1.15.8.2 martin static void
1987 1.5 cegger acpi_handle_madt(ACPI_TABLE_HEADER *sdp)
1988 1.5 cegger {
1989 1.5 cegger ACPI_TABLE_MADT *madt;
1990 1.5 cegger
1991 1.5 cegger printf(BEGIN_COMMENT);
1992 1.5 cegger acpi_print_sdt(sdp);
1993 1.5 cegger madt = (ACPI_TABLE_MADT *)sdp;
1994 1.5 cegger printf("\tLocal APIC ADDR=0x%08x\n", madt->Address);
1995 1.5 cegger printf("\tFlags={");
1996 1.5 cegger if (madt->Flags & ACPI_MADT_PCAT_COMPAT)
1997 1.5 cegger printf("PC-AT");
1998 1.5 cegger printf("}\n");
1999 1.5 cegger acpi_walk_subtables(sdp, (madt + 1), acpi_print_madt);
2000 1.5 cegger printf(END_COMMENT);
2001 1.5 cegger }
2002 1.5 cegger
2003 1.5 cegger static void
2004 1.5 cegger acpi_handle_hpet(ACPI_TABLE_HEADER *sdp)
2005 1.5 cegger {
2006 1.5 cegger ACPI_TABLE_HPET *hpet;
2007 1.5 cegger
2008 1.5 cegger printf(BEGIN_COMMENT);
2009 1.5 cegger acpi_print_sdt(sdp);
2010 1.5 cegger hpet = (ACPI_TABLE_HPET *)sdp;
2011 1.5 cegger printf("\tHPET Number=%d\n", hpet->Sequence);
2012 1.5 cegger printf("\tADDR=");
2013 1.5 cegger acpi_print_gas(&hpet->Address);
2014 1.5 cegger printf("\tHW Rev=0x%x\n", hpet->Id & ACPI_HPET_ID_HARDWARE_REV_ID);
2015 1.5 cegger printf("\tComparators=%d\n", (hpet->Id & ACPI_HPET_ID_COMPARATORS) >>
2016 1.5 cegger 8);
2017 1.5 cegger printf("\tCounter Size=%d\n", hpet->Id & ACPI_HPET_ID_COUNT_SIZE_CAP ?
2018 1.5 cegger 1 : 0);
2019 1.5 cegger printf("\tLegacy IRQ routing capable={");
2020 1.5 cegger if (hpet->Id & ACPI_HPET_ID_LEGACY_CAPABLE)
2021 1.5 cegger printf("TRUE}\n");
2022 1.5 cegger else
2023 1.5 cegger printf("FALSE}\n");
2024 1.5 cegger printf("\tPCI Vendor ID=0x%04x\n", hpet->Id >> 16);
2025 1.5 cegger printf("\tMinimal Tick=%d\n", hpet->MinimumTick);
2026 1.15.8.1 martin printf("\tFlags=0x%02x\n", hpet->Flags);
2027 1.5 cegger printf(END_COMMENT);
2028 1.5 cegger }
2029 1.5 cegger
2030 1.5 cegger static void
2031 1.15.8.2 martin acpi_print_native_lpit(ACPI_LPIT_NATIVE *nl)
2032 1.15.8.2 martin {
2033 1.15.8.2 martin printf("\tEntryTrigger=");
2034 1.15.8.2 martin acpi_print_gas(&nl->EntryTrigger);
2035 1.15.8.2 martin printf("\tResidency=%u\n", nl->Residency);
2036 1.15.8.2 martin printf("\tLatency=%u\n", nl->Latency);
2037 1.15.8.2 martin if (nl->Header.Flags & ACPI_LPIT_NO_COUNTER)
2038 1.15.8.2 martin printf("\tResidencyCounter=Not Present");
2039 1.15.8.2 martin else {
2040 1.15.8.2 martin printf("\tResidencyCounter=");
2041 1.15.8.2 martin acpi_print_gas(&nl->ResidencyCounter);
2042 1.15.8.2 martin }
2043 1.15.8.2 martin if (nl->CounterFrequency)
2044 1.15.8.2 martin printf("\tCounterFrequency=%ju\n", nl->CounterFrequency);
2045 1.15.8.2 martin else
2046 1.15.8.2 martin printf("\tCounterFrequency=TSC\n");
2047 1.15.8.2 martin }
2048 1.15.8.2 martin
2049 1.15.8.2 martin static void
2050 1.15.8.2 martin acpi_print_lpit(ACPI_LPIT_HEADER *lpit)
2051 1.15.8.2 martin {
2052 1.15.8.2 martin if (lpit->Type == ACPI_LPIT_TYPE_NATIVE_CSTATE)
2053 1.15.8.2 martin printf("\tType=ACPI_LPIT_TYPE_NATIVE_CSTATE\n");
2054 1.15.8.2 martin else
2055 1.15.8.2 martin warnx("unknown LPIT type %u", lpit->Type);
2056 1.15.8.2 martin
2057 1.15.8.2 martin printf("\tLength=%u\n", lpit->Length);
2058 1.15.8.2 martin printf("\tUniqueId=0x%04x\n", lpit->UniqueId);
2059 1.15.8.2 martin #define PRINTFLAG(var, flag) printflag((var), ACPI_LPIT_## flag, #flag)
2060 1.15.8.2 martin printf("\tFlags=");
2061 1.15.8.2 martin PRINTFLAG(lpit->Flags, STATE_DISABLED);
2062 1.15.8.2 martin PRINTFLAG_END();
2063 1.15.8.2 martin #undef PRINTFLAG
2064 1.15.8.2 martin
2065 1.15.8.2 martin if (lpit->Type == ACPI_LPIT_TYPE_NATIVE_CSTATE)
2066 1.15.8.2 martin return acpi_print_native_lpit((ACPI_LPIT_NATIVE *)lpit);
2067 1.15.8.2 martin }
2068 1.15.8.2 martin
2069 1.15.8.2 martin static void
2070 1.15.8.2 martin acpi_walk_lpit(ACPI_TABLE_HEADER *table, void *first,
2071 1.15.8.2 martin void (*action)(ACPI_LPIT_HEADER *))
2072 1.15.8.2 martin {
2073 1.15.8.2 martin ACPI_LPIT_HEADER *subtable;
2074 1.15.8.2 martin char *end;
2075 1.15.8.2 martin
2076 1.15.8.2 martin subtable = first;
2077 1.15.8.2 martin end = (char *)table + table->Length;
2078 1.15.8.2 martin while ((char *)subtable < end) {
2079 1.15.8.2 martin printf("\n");
2080 1.15.8.2 martin if (subtable->Length < sizeof(ACPI_LPIT_HEADER)) {
2081 1.15.8.2 martin warnx("invalid subtable length %u", subtable->Length);
2082 1.15.8.2 martin return;
2083 1.15.8.2 martin }
2084 1.15.8.2 martin action(subtable);
2085 1.15.8.2 martin subtable = (ACPI_LPIT_HEADER *)((char *)subtable +
2086 1.15.8.2 martin subtable->Length);
2087 1.15.8.2 martin }
2088 1.15.8.2 martin }
2089 1.15.8.2 martin
2090 1.15.8.2 martin static void
2091 1.15.8.2 martin acpi_handle_lpit(ACPI_TABLE_HEADER *sdp)
2092 1.15.8.2 martin {
2093 1.15.8.2 martin ACPI_TABLE_LPIT *lpit;
2094 1.15.8.2 martin
2095 1.15.8.2 martin printf(BEGIN_COMMENT);
2096 1.15.8.2 martin acpi_print_sdt(sdp);
2097 1.15.8.2 martin lpit = (ACPI_TABLE_LPIT *)sdp;
2098 1.15.8.2 martin acpi_walk_lpit(sdp, (lpit + 1), acpi_print_lpit);
2099 1.15.8.2 martin
2100 1.15.8.2 martin printf(END_COMMENT);
2101 1.15.8.2 martin }
2102 1.15.8.2 martin
2103 1.15.8.2 martin static void
2104 1.5 cegger acpi_handle_msct(ACPI_TABLE_HEADER *sdp)
2105 1.5 cegger {
2106 1.5 cegger ACPI_TABLE_MSCT *msct;
2107 1.5 cegger ACPI_MSCT_PROXIMITY *msctentry;
2108 1.5 cegger uint32_t pos;
2109 1.5 cegger
2110 1.5 cegger printf(BEGIN_COMMENT);
2111 1.5 cegger acpi_print_sdt(sdp);
2112 1.5 cegger msct = (ACPI_TABLE_MSCT *)sdp;
2113 1.5 cegger
2114 1.5 cegger printf("\tProximity Offset=0x%x\n", msct->ProximityOffset);
2115 1.5 cegger printf("\tMax Proximity Domains=%d\n", msct->MaxProximityDomains);
2116 1.5 cegger printf("\tMax Clock Domains=%d\n", msct->MaxClockDomains);
2117 1.5 cegger printf("\tMax Physical Address=0x%"PRIx64"\n", msct->MaxAddress);
2118 1.5 cegger
2119 1.5 cegger pos = msct->ProximityOffset;
2120 1.5 cegger while (pos < msct->Header.Length) {
2121 1.5 cegger msctentry = (ACPI_MSCT_PROXIMITY *)((char *)msct + pos);
2122 1.5 cegger pos += msctentry->Length;
2123 1.5 cegger
2124 1.5 cegger printf("\n");
2125 1.5 cegger printf("\tRevision=%d\n", msctentry->Revision);
2126 1.5 cegger printf("\tLength=%d\n", msctentry->Length);
2127 1.5 cegger printf("\tRange Start=%d\n", msctentry->RangeStart);
2128 1.5 cegger printf("\tRange End=%d\n", msctentry->RangeEnd);
2129 1.5 cegger printf("\tProcessor Capacity=%d\n",
2130 1.5 cegger msctentry->ProcessorCapacity);
2131 1.5 cegger printf("\tMemory Capacity=0x%"PRIx64" byte\n",
2132 1.5 cegger msctentry->MemoryCapacity);
2133 1.5 cegger }
2134 1.1 christos
2135 1.5 cegger printf(END_COMMENT);
2136 1.5 cegger }
2137 1.1 christos
2138 1.5 cegger static void
2139 1.5 cegger acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp)
2140 1.5 cegger {
2141 1.5 cegger ACPI_TABLE_ECDT *ecdt;
2142 1.1 christos
2143 1.5 cegger printf(BEGIN_COMMENT);
2144 1.5 cegger acpi_print_sdt(sdp);
2145 1.5 cegger ecdt = (ACPI_TABLE_ECDT *)sdp;
2146 1.5 cegger printf("\tEC_CONTROL=");
2147 1.5 cegger acpi_print_gas(&ecdt->Control);
2148 1.5 cegger printf("\n\tEC_DATA=");
2149 1.5 cegger acpi_print_gas(&ecdt->Data);
2150 1.5 cegger printf("\n\tUID=%#x, ", ecdt->Uid);
2151 1.5 cegger printf("GPE_BIT=%#x\n", ecdt->Gpe);
2152 1.5 cegger printf("\tEC_ID=%s\n", ecdt->Id);
2153 1.5 cegger printf(END_COMMENT);
2154 1.5 cegger }
2155 1.1 christos
2156 1.5 cegger static void
2157 1.5 cegger acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp)
2158 1.5 cegger {
2159 1.5 cegger ACPI_TABLE_MCFG *mcfg;
2160 1.5 cegger ACPI_MCFG_ALLOCATION *alloc;
2161 1.5 cegger u_int i, entries;
2162 1.1 christos
2163 1.5 cegger printf(BEGIN_COMMENT);
2164 1.5 cegger acpi_print_sdt(sdp);
2165 1.5 cegger mcfg = (ACPI_TABLE_MCFG *)sdp;
2166 1.5 cegger entries = (sdp->Length - sizeof(ACPI_TABLE_MCFG)) /
2167 1.5 cegger sizeof(ACPI_MCFG_ALLOCATION);
2168 1.5 cegger alloc = (ACPI_MCFG_ALLOCATION *)(mcfg + 1);
2169 1.5 cegger for (i = 0; i < entries; i++, alloc++) {
2170 1.5 cegger printf("\n");
2171 1.15.8.1 martin printf("\tBase Address=0x%016jx\n", (uintmax_t)alloc->Address);
2172 1.5 cegger printf("\tSegment Group=0x%04x\n", alloc->PciSegment);
2173 1.5 cegger printf("\tStart Bus=%d\n", alloc->StartBusNumber);
2174 1.5 cegger printf("\tEnd Bus=%d\n", alloc->EndBusNumber);
2175 1.5 cegger }
2176 1.5 cegger printf(END_COMMENT);
2177 1.5 cegger }
2178 1.1 christos
2179 1.1 christos static void
2180 1.5 cegger acpi_handle_sbst(ACPI_TABLE_HEADER *sdp)
2181 1.1 christos {
2182 1.5 cegger ACPI_TABLE_SBST *sbst;
2183 1.5 cegger
2184 1.5 cegger printf(BEGIN_COMMENT);
2185 1.5 cegger acpi_print_sdt(sdp);
2186 1.5 cegger sbst = (ACPI_TABLE_SBST *)sdp;
2187 1.5 cegger
2188 1.5 cegger printf("\tWarning Level=%d mWh\n", sbst->WarningLevel);
2189 1.5 cegger printf("\tLow Level=%d mWh\n", sbst->LowLevel);
2190 1.5 cegger printf("\tCritical Level=%d mWh\n", sbst->CriticalLevel);
2191 1.1 christos
2192 1.5 cegger printf(END_COMMENT);
2193 1.1 christos }
2194 1.1 christos
2195 1.1 christos static void
2196 1.5 cegger acpi_handle_slit(ACPI_TABLE_HEADER *sdp)
2197 1.1 christos {
2198 1.5 cegger ACPI_TABLE_SLIT *slit;
2199 1.5 cegger u_int idx;
2200 1.5 cegger uint64_t cnt;
2201 1.5 cegger
2202 1.5 cegger printf(BEGIN_COMMENT);
2203 1.5 cegger acpi_print_sdt(sdp);
2204 1.5 cegger slit = (ACPI_TABLE_SLIT *)sdp;
2205 1.1 christos
2206 1.5 cegger cnt = slit->LocalityCount * slit->LocalityCount;
2207 1.15.8.1 martin printf("\tLocalityCount=%ju\n", (uintmax_t)slit->LocalityCount);
2208 1.5 cegger printf("\tEntry=\n\t");
2209 1.5 cegger for (idx = 0; idx < cnt; idx++) {
2210 1.5 cegger printf("%u ", slit->Entry[idx]);
2211 1.5 cegger if ((idx % slit->LocalityCount) == (slit->LocalityCount - 1)) {
2212 1.5 cegger printf("\n");
2213 1.5 cegger if (idx < cnt - 1)
2214 1.5 cegger printf("\t");
2215 1.5 cegger }
2216 1.5 cegger }
2217 1.1 christos
2218 1.5 cegger printf(END_COMMENT);
2219 1.1 christos }
2220 1.1 christos
2221 1.1 christos static void
2222 1.5 cegger acpi_handle_spcr(ACPI_TABLE_HEADER *sdp)
2223 1.1 christos {
2224 1.5 cegger ACPI_TABLE_SPCR *spcr;
2225 1.5 cegger
2226 1.5 cegger printf(BEGIN_COMMENT);
2227 1.5 cegger acpi_print_sdt(sdp);
2228 1.5 cegger spcr = (ACPI_TABLE_SPCR *)sdp;
2229 1.5 cegger
2230 1.15.8.2 martin printf("\n\tInterface Type=");
2231 1.15.8.2 martin switch (sdp->Revision) {
2232 1.15.8.2 martin case 1:
2233 1.15.8.2 martin printf("full 16550%s\n",
2234 1.15.8.2 martin (spcr->InterfaceType == 1) ?
2235 1.15.8.2 martin "(must also accept writing FCR register)" : "");
2236 1.15.8.2 martin break;
2237 1.15.8.2 martin case 2:
2238 1.15.8.2 martin acpi_print_dbg2_serial_subtype(spcr->InterfaceType);
2239 1.15.8.2 martin break;
2240 1.15.8.2 martin default:
2241 1.15.8.2 martin printf("unknown Revision\n");
2242 1.15.8.2 martin break;
2243 1.15.8.2 martin }
2244 1.15.8.2 martin
2245 1.5 cegger printf("\tSerial Port=");
2246 1.5 cegger acpi_print_gas(&spcr->SerialPort);
2247 1.5 cegger printf("\n\tInterrupt Type={");
2248 1.5 cegger if (spcr->InterruptType & 0x1) {
2249 1.5 cegger printf("\n\t\tdual-8259 IRQ=");
2250 1.5 cegger switch (spcr->PcInterrupt) {
2251 1.5 cegger case 2 ... 7:
2252 1.5 cegger case 9 ... 12:
2253 1.5 cegger case 14 ... 15:
2254 1.5 cegger printf("%d", spcr->PcInterrupt);
2255 1.5 cegger break;
2256 1.5 cegger default:
2257 1.5 cegger printf("%d (invalid entry)", spcr->PcInterrupt);
2258 1.5 cegger break;
2259 1.5 cegger }
2260 1.5 cegger }
2261 1.5 cegger if (spcr->InterruptType & 0x2) {
2262 1.5 cegger printf("\n\t\tIO APIC={ GSI=%d }", spcr->Interrupt);
2263 1.5 cegger }
2264 1.5 cegger if (spcr->InterruptType & 0x4) {
2265 1.5 cegger printf("\n\t\tIO SAPIC={ GSI=%d }", spcr->Interrupt);
2266 1.5 cegger }
2267 1.15.8.2 martin if (spcr->InterruptType & 0x8) {
2268 1.15.8.2 martin printf("\n\t\tARMH GIC={ GSI=%d }", spcr->Interrupt);
2269 1.15.8.2 martin }
2270 1.5 cegger printf("\n\t}\n");
2271 1.5 cegger
2272 1.5 cegger printf("\tBaud Rate=");
2273 1.5 cegger switch (spcr->BaudRate) {
2274 1.5 cegger case 3:
2275 1.5 cegger printf("9600");
2276 1.5 cegger break;
2277 1.5 cegger case 4:
2278 1.5 cegger printf("19200");
2279 1.5 cegger break;
2280 1.5 cegger case 6:
2281 1.5 cegger printf("57600");
2282 1.5 cegger break;
2283 1.5 cegger case 7:
2284 1.5 cegger printf("115200");
2285 1.5 cegger break;
2286 1.5 cegger default:
2287 1.5 cegger printf("unknown speed index %d", spcr->BaudRate);
2288 1.5 cegger break;
2289 1.5 cegger }
2290 1.5 cegger printf("\n\tParity={");
2291 1.5 cegger switch (spcr->Parity) {
2292 1.5 cegger case 0:
2293 1.5 cegger printf("OFF");
2294 1.5 cegger break;
2295 1.5 cegger default:
2296 1.5 cegger printf("ON");
2297 1.5 cegger break;
2298 1.5 cegger }
2299 1.5 cegger printf("}\n");
2300 1.5 cegger
2301 1.5 cegger printf("\tStop Bits={");
2302 1.5 cegger switch (spcr->StopBits) {
2303 1.5 cegger case 1:
2304 1.5 cegger printf("ON");
2305 1.5 cegger break;
2306 1.5 cegger default:
2307 1.5 cegger printf("OFF");
2308 1.5 cegger break;
2309 1.5 cegger }
2310 1.5 cegger printf("}\n");
2311 1.1 christos
2312 1.5 cegger printf("\tFlow Control={");
2313 1.5 cegger if (spcr->FlowControl & 0x1)
2314 1.5 cegger printf("DCD, ");
2315 1.5 cegger if (spcr->FlowControl & 0x2)
2316 1.5 cegger printf("RTS/CTS hardware, ");
2317 1.5 cegger if (spcr->FlowControl & 0x4)
2318 1.5 cegger printf("XON/XOFF software");
2319 1.5 cegger printf("}\n");
2320 1.1 christos
2321 1.5 cegger printf("\tTerminal=");
2322 1.5 cegger switch (spcr->TerminalType) {
2323 1.5 cegger case 0:
2324 1.5 cegger printf("VT100");
2325 1.5 cegger break;
2326 1.5 cegger case 1:
2327 1.5 cegger printf("VT100+");
2328 1.5 cegger break;
2329 1.5 cegger case 2:
2330 1.5 cegger printf("VT-UTF8");
2331 1.5 cegger break;
2332 1.5 cegger case 3:
2333 1.5 cegger printf("ANSI");
2334 1.5 cegger break;
2335 1.5 cegger default:
2336 1.5 cegger printf("unknown type %d", spcr->TerminalType);
2337 1.5 cegger break;
2338 1.1 christos }
2339 1.5 cegger printf("\n");
2340 1.5 cegger
2341 1.5 cegger acpi_print_pci(spcr->PciVendorId, spcr->PciDeviceId,
2342 1.5 cegger spcr->PciSegment, spcr->PciBus, spcr->PciDevice, spcr->PciFunction);
2343 1.5 cegger
2344 1.5 cegger printf("\tPCI Flags={");
2345 1.5 cegger if (spcr->PciFlags & ACPI_SPCR_DO_NOT_DISABLE)
2346 1.5 cegger printf("DONOT_DISABLE");
2347 1.5 cegger printf("}\n");
2348 1.5 cegger
2349 1.5 cegger printf(END_COMMENT);
2350 1.5 cegger }
2351 1.5 cegger
2352 1.5 cegger static void
2353 1.15.8.1 martin acpi_handle_spmi(ACPI_TABLE_HEADER *sdp)
2354 1.15.8.1 martin {
2355 1.15.8.1 martin ACPI_TABLE_SPMI *spmi;
2356 1.15.8.1 martin
2357 1.15.8.1 martin printf(BEGIN_COMMENT);
2358 1.15.8.1 martin acpi_print_sdt(sdp);
2359 1.15.8.1 martin spmi = (ACPI_TABLE_SPMI *)sdp;
2360 1.15.8.1 martin
2361 1.15.8.1 martin printf("\tInterface Type=");
2362 1.15.8.1 martin switch (spmi->InterfaceType) {
2363 1.15.8.1 martin case ACPI_SPMI_KEYBOARD:
2364 1.15.8.1 martin printf("Keyboard Controller Stype (KCS)");
2365 1.15.8.1 martin break;
2366 1.15.8.1 martin case ACPI_SPMI_SMI:
2367 1.15.8.1 martin printf("Server Management Interface Chip (SMIC)");
2368 1.15.8.1 martin break;
2369 1.15.8.1 martin case ACPI_SPMI_BLOCK_TRANSFER:
2370 1.15.8.1 martin printf("Block Transfer (BT)");
2371 1.15.8.1 martin break;
2372 1.15.8.1 martin case ACPI_SPMI_SMBUS:
2373 1.15.8.1 martin printf("SMBus System Interface (SSIF)");
2374 1.15.8.1 martin break;
2375 1.15.8.1 martin default:
2376 1.15.8.1 martin printf("Reserved(%d)", spmi->InterfaceType);
2377 1.15.8.1 martin break;
2378 1.15.8.1 martin }
2379 1.15.8.2 martin printf("\n\tSpecRevision=%d.%d", spmi->SpecRevision >> 8,
2380 1.15.8.1 martin spmi->SpecRevision & 0xff);
2381 1.15.8.1 martin
2382 1.15.8.1 martin printf("\n\tInterrupt Type={");
2383 1.15.8.1 martin if (spmi->InterruptType & 0x1) {
2384 1.15.8.1 martin printf("\n\t\tSCI triggered GPE=%d", spmi->GpeNumber);
2385 1.15.8.1 martin }
2386 1.15.8.1 martin if (spmi->InterruptType & 0x2) {
2387 1.15.8.1 martin printf("\n\t\tIO APIC/SAPIC={ GSI=%d }", spmi->Interrupt);
2388 1.15.8.1 martin }
2389 1.15.8.1 martin printf("\n\t}\n");
2390 1.15.8.1 martin
2391 1.15.8.1 martin printf("\tBase Address=");
2392 1.15.8.1 martin acpi_print_gas(&spmi->IpmiRegister);
2393 1.15.8.1 martin printf("\n");
2394 1.15.8.1 martin
2395 1.15.8.1 martin if ((spmi->PciDeviceFlag & 0x01) != 0)
2396 1.15.8.1 martin acpi_print_pci_sbdf(spmi->PciSegment, spmi->PciBus,
2397 1.15.8.1 martin spmi->PciDevice, spmi->PciFunction);
2398 1.15.8.1 martin
2399 1.15.8.1 martin printf(END_COMMENT);
2400 1.15.8.1 martin }
2401 1.15.8.1 martin
2402 1.15.8.1 martin static void
2403 1.5 cegger acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain,
2404 1.5 cegger uint32_t flags, uint32_t clockdomain)
2405 1.5 cegger {
2406 1.5 cegger
2407 1.5 cegger printf("\tFlags={");
2408 1.5 cegger if (flags & ACPI_SRAT_CPU_ENABLED)
2409 1.5 cegger printf("ENABLED");
2410 1.5 cegger else
2411 1.5 cegger printf("DISABLED");
2412 1.5 cegger printf("}\n");
2413 1.5 cegger printf("\tAPIC ID=%d\n", apic_id);
2414 1.5 cegger printf("\tProximity Domain=%d\n", proximity_domain);
2415 1.5 cegger printf("\tClock Domain=%d\n", clockdomain);
2416 1.5 cegger }
2417 1.5 cegger
2418 1.5 cegger static void
2419 1.5 cegger acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp)
2420 1.5 cegger {
2421 1.5 cegger
2422 1.5 cegger printf("\tFlags={");
2423 1.5 cegger if (mp->Flags & ACPI_SRAT_MEM_ENABLED)
2424 1.5 cegger printf("ENABLED");
2425 1.5 cegger else
2426 1.5 cegger printf("DISABLED");
2427 1.5 cegger if (mp->Flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)
2428 1.5 cegger printf(",HOT_PLUGGABLE");
2429 1.5 cegger if (mp->Flags & ACPI_SRAT_MEM_NON_VOLATILE)
2430 1.5 cegger printf(",NON_VOLATILE");
2431 1.5 cegger printf("}\n");
2432 1.5 cegger printf("\tBase Address=0x%016jx\n", (uintmax_t)mp->BaseAddress);
2433 1.5 cegger printf("\tLength=0x%016jx\n", (uintmax_t)mp->Length);
2434 1.5 cegger printf("\tProximity Domain=%d\n", mp->ProximityDomain);
2435 1.1 christos }
2436 1.1 christos
2437 1.15.8.1 martin static const char *srat_types[] = {
2438 1.15.8.1 martin [ACPI_SRAT_TYPE_CPU_AFFINITY] = "CPU",
2439 1.15.8.1 martin [ACPI_SRAT_TYPE_MEMORY_AFFINITY] = "Memory",
2440 1.15.8.1 martin [ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY] = "X2APIC",
2441 1.15.8.1 martin [ACPI_SRAT_TYPE_GICC_AFFINITY] = "GICC",
2442 1.15.8.1 martin };
2443 1.5 cegger
2444 1.1 christos static void
2445 1.5 cegger acpi_print_srat(ACPI_SUBTABLE_HEADER *srat)
2446 1.1 christos {
2447 1.5 cegger ACPI_SRAT_CPU_AFFINITY *cpu;
2448 1.5 cegger ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic;
2449 1.15.8.1 martin ACPI_SRAT_GICC_AFFINITY *gic;
2450 1.5 cegger
2451 1.15.8.1 martin if (srat->Type < __arraycount(srat_types))
2452 1.5 cegger printf("\tType=%s\n", srat_types[srat->Type]);
2453 1.5 cegger else
2454 1.5 cegger printf("\tType=%d (unknown)\n", srat->Type);
2455 1.5 cegger switch (srat->Type) {
2456 1.5 cegger case ACPI_SRAT_TYPE_CPU_AFFINITY:
2457 1.5 cegger cpu = (ACPI_SRAT_CPU_AFFINITY *)srat;
2458 1.5 cegger acpi_print_srat_cpu(cpu->ApicId,
2459 1.5 cegger cpu->ProximityDomainHi[2] << 24 |
2460 1.5 cegger cpu->ProximityDomainHi[1] << 16 |
2461 1.5 cegger cpu->ProximityDomainHi[0] << 0 |
2462 1.5 cegger cpu->ProximityDomainLo,
2463 1.5 cegger cpu->Flags, cpu->ClockDomain);
2464 1.5 cegger break;
2465 1.5 cegger case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
2466 1.5 cegger acpi_print_srat_memory((ACPI_SRAT_MEM_AFFINITY *)srat);
2467 1.5 cegger break;
2468 1.5 cegger case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
2469 1.5 cegger x2apic = (ACPI_SRAT_X2APIC_CPU_AFFINITY *)srat;
2470 1.5 cegger acpi_print_srat_cpu(x2apic->ApicId, x2apic->ProximityDomain,
2471 1.5 cegger x2apic->Flags, x2apic->ClockDomain);
2472 1.5 cegger break;
2473 1.15.8.1 martin case ACPI_SRAT_TYPE_GICC_AFFINITY:
2474 1.15.8.1 martin gic = (ACPI_SRAT_GICC_AFFINITY *)srat;
2475 1.15.8.1 martin acpi_print_srat_cpu(gic->AcpiProcessorUid, gic->ProximityDomain,
2476 1.15.8.1 martin gic->Flags, gic->ClockDomain);
2477 1.15.8.1 martin break;
2478 1.5 cegger }
2479 1.5 cegger }
2480 1.1 christos
2481 1.5 cegger static void
2482 1.5 cegger acpi_handle_srat(ACPI_TABLE_HEADER *sdp)
2483 1.5 cegger {
2484 1.5 cegger ACPI_TABLE_SRAT *srat;
2485 1.1 christos
2486 1.5 cegger printf(BEGIN_COMMENT);
2487 1.5 cegger acpi_print_sdt(sdp);
2488 1.5 cegger srat = (ACPI_TABLE_SRAT *)sdp;
2489 1.5 cegger printf("\tTable Revision=%d\n", srat->TableRevision);
2490 1.5 cegger acpi_walk_subtables(sdp, (srat + 1), acpi_print_srat);
2491 1.5 cegger printf(END_COMMENT);
2492 1.1 christos }
2493 1.1 christos
2494 1.15.8.1 martin static const char *nfit_types[] = {
2495 1.15.8.1 martin [ACPI_NFIT_TYPE_SYSTEM_ADDRESS] = "System Address",
2496 1.15.8.1 martin [ACPI_NFIT_TYPE_MEMORY_MAP] = "Memory Map",
2497 1.15.8.1 martin [ACPI_NFIT_TYPE_INTERLEAVE] = "Interleave",
2498 1.15.8.1 martin [ACPI_NFIT_TYPE_SMBIOS] = "SMBIOS",
2499 1.15.8.1 martin [ACPI_NFIT_TYPE_CONTROL_REGION] = "Control Region",
2500 1.15.8.1 martin [ACPI_NFIT_TYPE_DATA_REGION] = "Data Region",
2501 1.15.8.1 martin [ACPI_NFIT_TYPE_FLUSH_ADDRESS] = "Flush Address"
2502 1.15.8.1 martin };
2503 1.15.8.1 martin
2504 1.15.8.1 martin
2505 1.15.8.1 martin static void
2506 1.15.8.1 martin acpi_print_nfit(ACPI_NFIT_HEADER *nfit)
2507 1.15.8.1 martin {
2508 1.15.8.1 martin char *uuidstr;
2509 1.15.8.1 martin uint32_t status;
2510 1.15.8.1 martin
2511 1.15.8.1 martin ACPI_NFIT_SYSTEM_ADDRESS *sysaddr;
2512 1.15.8.1 martin ACPI_NFIT_MEMORY_MAP *mmap;
2513 1.15.8.1 martin ACPI_NFIT_INTERLEAVE *ileave;
2514 1.15.8.1 martin ACPI_NFIT_SMBIOS *smbios __unused;
2515 1.15.8.1 martin ACPI_NFIT_CONTROL_REGION *ctlreg;
2516 1.15.8.1 martin ACPI_NFIT_DATA_REGION *datareg;
2517 1.15.8.1 martin ACPI_NFIT_FLUSH_ADDRESS *fladdr;
2518 1.15.8.1 martin
2519 1.15.8.1 martin if (nfit->Type < __arraycount(nfit_types))
2520 1.15.8.1 martin printf("\tType=%s\n", nfit_types[nfit->Type]);
2521 1.15.8.1 martin else
2522 1.15.8.1 martin printf("\tType=%u (unknown)\n", nfit->Type);
2523 1.15.8.1 martin switch (nfit->Type) {
2524 1.15.8.1 martin case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
2525 1.15.8.1 martin sysaddr = (ACPI_NFIT_SYSTEM_ADDRESS *)nfit;
2526 1.15.8.1 martin printf("\tRangeIndex=%u\n", (u_int)sysaddr->RangeIndex);
2527 1.15.8.1 martin printf("\tProximityDomain=%u\n",
2528 1.15.8.1 martin (u_int)sysaddr->ProximityDomain);
2529 1.15.8.1 martin uuid_to_string((uuid_t *)(sysaddr->RangeGuid),
2530 1.15.8.1 martin &uuidstr, &status);
2531 1.15.8.1 martin if (status != uuid_s_ok)
2532 1.15.8.1 martin errx(1, "uuid_to_string: status=%u", status);
2533 1.15.8.1 martin printf("\tRangeGuid=%s\n", uuidstr);
2534 1.15.8.1 martin free(uuidstr);
2535 1.15.8.1 martin printf("\tAddress=0x%016jx\n", (uintmax_t)sysaddr->Address);
2536 1.15.8.1 martin printf("\tLength=0x%016jx\n", (uintmax_t)sysaddr->Length);
2537 1.15.8.1 martin printf("\tMemoryMapping=0x%016jx\n",
2538 1.15.8.1 martin (uintmax_t)sysaddr->MemoryMapping);
2539 1.15.8.1 martin
2540 1.15.8.1 martin #define PRINTFLAG(var, flag) printflag((var), ACPI_NFIT_## flag, #flag)
2541 1.15.8.1 martin
2542 1.15.8.1 martin printf("\tFlags=");
2543 1.15.8.1 martin PRINTFLAG(sysaddr->Flags, ADD_ONLINE_ONLY);
2544 1.15.8.1 martin PRINTFLAG(sysaddr->Flags, PROXIMITY_VALID);
2545 1.15.8.1 martin PRINTFLAG_END();
2546 1.15.8.1 martin
2547 1.15.8.1 martin #undef PRINTFLAG
2548 1.15.8.1 martin
2549 1.15.8.1 martin break;
2550 1.15.8.1 martin case ACPI_NFIT_TYPE_MEMORY_MAP:
2551 1.15.8.1 martin mmap = (ACPI_NFIT_MEMORY_MAP *)nfit;
2552 1.15.8.1 martin printf("\tDeviceHandle=%u\n", (u_int)mmap->DeviceHandle);
2553 1.15.8.1 martin printf("\tPhysicalId=%u\n", (u_int)mmap->PhysicalId);
2554 1.15.8.1 martin printf("\tRegionId=%u\n", (u_int)mmap->RegionId);
2555 1.15.8.1 martin printf("\tRangeIndex=%u\n", (u_int)mmap->RangeIndex);
2556 1.15.8.1 martin printf("\tRegionIndex=%u\n", (u_int)mmap->RegionIndex);
2557 1.15.8.1 martin printf("\tRegionSize=0x%016jx\n", (uintmax_t)mmap->RegionSize);
2558 1.15.8.1 martin printf("\tRegionOffset=0x%016jx\n",
2559 1.15.8.1 martin (uintmax_t)mmap->RegionOffset);
2560 1.15.8.1 martin printf("\tAddress=0x%016jx\n", (uintmax_t)mmap->Address);
2561 1.15.8.1 martin printf("\tInterleaveIndex=%u\n", (u_int)mmap->InterleaveIndex);
2562 1.15.8.1 martin printf("\tInterleaveWays=%u\n", (u_int)mmap->InterleaveWays);
2563 1.15.8.1 martin
2564 1.15.8.1 martin #define PRINTFLAG(var, flag) printflag((var), ACPI_NFIT_MEM_## flag, #flag)
2565 1.15.8.1 martin
2566 1.15.8.1 martin printf("\tFlags=");
2567 1.15.8.1 martin PRINTFLAG(mmap->Flags, SAVE_FAILED);
2568 1.15.8.1 martin PRINTFLAG(mmap->Flags, RESTORE_FAILED);
2569 1.15.8.1 martin PRINTFLAG(mmap->Flags, FLUSH_FAILED);
2570 1.15.8.1 martin PRINTFLAG(mmap->Flags, NOT_ARMED);
2571 1.15.8.1 martin PRINTFLAG(mmap->Flags, HEALTH_OBSERVED);
2572 1.15.8.1 martin PRINTFLAG(mmap->Flags, HEALTH_ENABLED);
2573 1.15.8.1 martin PRINTFLAG(mmap->Flags, MAP_FAILED);
2574 1.15.8.1 martin PRINTFLAG_END();
2575 1.15.8.1 martin
2576 1.15.8.1 martin #undef PRINTFLAG
2577 1.15.8.1 martin
2578 1.15.8.1 martin break;
2579 1.15.8.1 martin case ACPI_NFIT_TYPE_INTERLEAVE:
2580 1.15.8.1 martin ileave = (ACPI_NFIT_INTERLEAVE *)nfit;
2581 1.15.8.1 martin printf("\tInterleaveIndex=%u\n",
2582 1.15.8.1 martin (u_int)ileave->InterleaveIndex);
2583 1.15.8.1 martin printf("\tLineCount=%u\n", (u_int)ileave->LineCount);
2584 1.15.8.1 martin printf("\tLineSize=%u\n", (u_int)ileave->LineSize);
2585 1.15.8.1 martin /* XXX ileave->LineOffset[i] output is not supported */
2586 1.15.8.1 martin break;
2587 1.15.8.1 martin case ACPI_NFIT_TYPE_SMBIOS:
2588 1.15.8.1 martin smbios = (ACPI_NFIT_SMBIOS *)nfit;
2589 1.15.8.1 martin /* XXX smbios->Data[x] output is not supported */
2590 1.15.8.1 martin break;
2591 1.15.8.1 martin case ACPI_NFIT_TYPE_CONTROL_REGION:
2592 1.15.8.1 martin ctlreg = (ACPI_NFIT_CONTROL_REGION *)nfit;
2593 1.15.8.1 martin printf("\tRegionIndex=%u\n", (u_int)ctlreg->RegionIndex);
2594 1.15.8.1 martin printf("\tVendorId=0x%04x\n", (u_int)ctlreg->VendorId);
2595 1.15.8.1 martin printf("\tDeviceId=0x%04x\n", (u_int)ctlreg->DeviceId);
2596 1.15.8.1 martin printf("\tRevisionId=%u\n", (u_int)ctlreg->RevisionId);
2597 1.15.8.1 martin printf("\tSubsystemVendorId=0x%04x\n",
2598 1.15.8.1 martin (u_int)ctlreg->SubsystemVendorId);
2599 1.15.8.1 martin printf("\tSubsystemDeviceId=0x%04x\n",
2600 1.15.8.1 martin (u_int)ctlreg->SubsystemDeviceId);
2601 1.15.8.1 martin printf("\tSubsystemRevisionId=%u\n",
2602 1.15.8.1 martin (u_int)ctlreg->SubsystemRevisionId);
2603 1.15.8.1 martin printf("\tValidFields=%02x\n", (u_int)ctlreg->ValidFields);
2604 1.15.8.1 martin printf("\tManufacturingLocation=%u\n",
2605 1.15.8.1 martin (u_int)ctlreg->ManufacturingLocation);
2606 1.15.8.1 martin printf("\tManufacturingDate=%u\n",
2607 1.15.8.1 martin (u_int)ctlreg->ManufacturingDate);
2608 1.15.8.1 martin printf("\tSerialNumber=%u\n",
2609 1.15.8.1 martin (u_int)ctlreg->SerialNumber);
2610 1.15.8.1 martin printf("\tCode=0x%04x\n", (u_int)ctlreg->Code);
2611 1.15.8.1 martin printf("\tWindows=%u\n", (u_int)ctlreg->Windows);
2612 1.15.8.1 martin printf("\tWindowSize=0x%016jx\n",
2613 1.15.8.1 martin (uintmax_t)ctlreg->WindowSize);
2614 1.15.8.1 martin printf("\tCommandOffset=0x%016jx\n",
2615 1.15.8.1 martin (uintmax_t)ctlreg->CommandOffset);
2616 1.15.8.1 martin printf("\tCommandSize=0x%016jx\n",
2617 1.15.8.1 martin (uintmax_t)ctlreg->CommandSize);
2618 1.15.8.1 martin printf("\tStatusOffset=0x%016jx\n",
2619 1.15.8.1 martin (uintmax_t)ctlreg->StatusOffset);
2620 1.15.8.1 martin printf("\tStatusSize=0x%016jx\n",
2621 1.15.8.1 martin (uintmax_t)ctlreg->StatusSize);
2622 1.15.8.1 martin
2623 1.15.8.1 martin #define PRINTFLAG(var, flag) printflag((var), ACPI_NFIT_## flag, #flag)
2624 1.15.8.1 martin
2625 1.15.8.1 martin printf("\tFlags=");
2626 1.15.8.1 martin PRINTFLAG(ctlreg->Flags, CONTROL_BUFFERED);
2627 1.15.8.1 martin PRINTFLAG_END();
2628 1.15.8.1 martin
2629 1.15.8.1 martin #undef PRINTFLAG
2630 1.15.8.1 martin
2631 1.15.8.1 martin break;
2632 1.15.8.1 martin case ACPI_NFIT_TYPE_DATA_REGION:
2633 1.15.8.1 martin datareg = (ACPI_NFIT_DATA_REGION *)nfit;
2634 1.15.8.1 martin printf("\tRegionIndex=%u\n", (u_int)datareg->RegionIndex);
2635 1.15.8.1 martin printf("\tWindows=%u\n", (u_int)datareg->Windows);
2636 1.15.8.1 martin printf("\tOffset=0x%016jx\n", (uintmax_t)datareg->Offset);
2637 1.15.8.1 martin printf("\tSize=0x%016jx\n", (uintmax_t)datareg->Size);
2638 1.15.8.1 martin printf("\tCapacity=0x%016jx\n", (uintmax_t)datareg->Capacity);
2639 1.15.8.1 martin printf("\tStartAddress=0x%016jx\n",
2640 1.15.8.1 martin (uintmax_t)datareg->StartAddress);
2641 1.15.8.1 martin break;
2642 1.15.8.1 martin case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
2643 1.15.8.1 martin fladdr = (ACPI_NFIT_FLUSH_ADDRESS *)nfit;
2644 1.15.8.1 martin printf("\tDeviceHandle=%u\n", (u_int)fladdr->DeviceHandle);
2645 1.15.8.1 martin printf("\tHintCount=%u\n", (u_int)fladdr->HintCount);
2646 1.15.8.1 martin /* XXX fladdr->HintAddress[i] output is not supported */
2647 1.15.8.1 martin break;
2648 1.15.8.1 martin }
2649 1.15.8.1 martin }
2650 1.15.8.1 martin
2651 1.15.8.1 martin static void
2652 1.15.8.1 martin acpi_handle_nfit(ACPI_TABLE_HEADER *sdp)
2653 1.15.8.1 martin {
2654 1.15.8.1 martin ACPI_TABLE_NFIT *nfit;
2655 1.15.8.1 martin
2656 1.15.8.1 martin printf(BEGIN_COMMENT);
2657 1.15.8.1 martin acpi_print_sdt(sdp);
2658 1.15.8.1 martin nfit = (ACPI_TABLE_NFIT *)sdp;
2659 1.15.8.1 martin acpi_walk_nfit(sdp, (nfit + 1), acpi_print_nfit);
2660 1.15.8.1 martin printf(END_COMMENT);
2661 1.15.8.1 martin }
2662 1.15.8.1 martin
2663 1.15.8.1 martin static char *
2664 1.15.8.1 martin acpi_tcpa_evname(struct TCPAevent *event)
2665 1.15.8.1 martin {
2666 1.15.8.1 martin struct TCPApc_event *pc_event;
2667 1.15.8.1 martin char *eventname = NULL;
2668 1.15.8.1 martin
2669 1.15.8.1 martin pc_event = (struct TCPApc_event *)(event + 1);
2670 1.15.8.1 martin
2671 1.15.8.2 martin switch (event->event_type) {
2672 1.15.8.1 martin case PREBOOT:
2673 1.15.8.1 martin case POST_CODE:
2674 1.15.8.1 martin case UNUSED:
2675 1.15.8.1 martin case NO_ACTION:
2676 1.15.8.1 martin case SEPARATOR:
2677 1.15.8.1 martin case SCRTM_CONTENTS:
2678 1.15.8.1 martin case SCRTM_VERSION:
2679 1.15.8.1 martin case CPU_MICROCODE:
2680 1.15.8.1 martin case PLATFORM_CONFIG_FLAGS:
2681 1.15.8.1 martin case TABLE_OF_DEVICES:
2682 1.15.8.1 martin case COMPACT_HASH:
2683 1.15.8.1 martin case IPL:
2684 1.15.8.1 martin case IPL_PARTITION_DATA:
2685 1.15.8.1 martin case NONHOST_CODE:
2686 1.15.8.1 martin case NONHOST_CONFIG:
2687 1.15.8.1 martin case NONHOST_INFO:
2688 1.15.8.1 martin asprintf(&eventname, "%s",
2689 1.15.8.1 martin tcpa_event_type_strings[event->event_type]);
2690 1.15.8.1 martin break;
2691 1.15.8.1 martin
2692 1.15.8.1 martin case ACTION:
2693 1.15.8.1 martin eventname = calloc(event->event_size + 1, sizeof(char));
2694 1.15.8.1 martin memcpy(eventname, pc_event, event->event_size);
2695 1.15.8.1 martin break;
2696 1.15.8.1 martin
2697 1.15.8.1 martin case EVENT_TAG:
2698 1.15.8.1 martin switch (pc_event->event_id) {
2699 1.15.8.1 martin case SMBIOS:
2700 1.15.8.1 martin case BIS_CERT:
2701 1.15.8.1 martin case CMOS:
2702 1.15.8.1 martin case NVRAM:
2703 1.15.8.1 martin case OPTION_ROM_EXEC:
2704 1.15.8.1 martin case OPTION_ROM_CONFIG:
2705 1.15.8.1 martin case S_CRTM_VERSION:
2706 1.15.8.1 martin case POST_BIOS_ROM:
2707 1.15.8.1 martin case ESCD:
2708 1.15.8.1 martin case OPTION_ROM_MICROCODE:
2709 1.15.8.1 martin case S_CRTM_CONTENTS:
2710 1.15.8.1 martin case POST_CONTENTS:
2711 1.15.8.1 martin asprintf(&eventname, "%s",
2712 1.15.8.1 martin TCPA_pcclient_strings[pc_event->event_id]);
2713 1.15.8.1 martin break;
2714 1.15.8.1 martin
2715 1.15.8.1 martin default:
2716 1.15.8.1 martin asprintf(&eventname, "<unknown tag 0x%02x>",
2717 1.15.8.1 martin pc_event->event_id);
2718 1.15.8.1 martin break;
2719 1.15.8.1 martin }
2720 1.15.8.1 martin break;
2721 1.15.8.1 martin
2722 1.15.8.1 martin default:
2723 1.15.8.1 martin asprintf(&eventname, "<unknown 0x%02x>", event->event_type);
2724 1.15.8.1 martin break;
2725 1.15.8.1 martin }
2726 1.15.8.1 martin
2727 1.15.8.1 martin return eventname;
2728 1.15.8.1 martin }
2729 1.15.8.1 martin
2730 1.15.8.1 martin static void
2731 1.15.8.1 martin acpi_print_tcpa(struct TCPAevent *event)
2732 1.15.8.1 martin {
2733 1.15.8.1 martin int i;
2734 1.15.8.1 martin char *eventname;
2735 1.15.8.1 martin
2736 1.15.8.1 martin eventname = acpi_tcpa_evname(event);
2737 1.15.8.1 martin
2738 1.15.8.1 martin printf("\t%d", event->pcr_index);
2739 1.15.8.1 martin printf(" 0x");
2740 1.15.8.1 martin for (i = 0; i < 20; i++)
2741 1.15.8.1 martin printf("%02x", event->pcr_value[i]);
2742 1.15.8.1 martin printf(" [%s]\n", eventname ? eventname : "<unknown>");
2743 1.15.8.1 martin
2744 1.15.8.1 martin free(eventname);
2745 1.15.8.1 martin }
2746 1.15.8.1 martin
2747 1.1 christos static void
2748 1.5 cegger acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp)
2749 1.1 christos {
2750 1.15.8.1 martin struct TCPAbody *tcpa;
2751 1.15.8.1 martin struct TCPAevent *event;
2752 1.15.8.1 martin uintmax_t len, paddr;
2753 1.15.8.1 martin unsigned char *vaddr = NULL;
2754 1.15.8.1 martin unsigned char *vend = NULL;
2755 1.5 cegger
2756 1.5 cegger printf(BEGIN_COMMENT);
2757 1.5 cegger acpi_print_sdt(sdp);
2758 1.15.8.1 martin tcpa = (struct TCPAbody *) sdp;
2759 1.15.8.1 martin
2760 1.15.8.1 martin switch (tcpa->platform_class) {
2761 1.15.8.1 martin case ACPI_TCPA_BIOS_CLIENT:
2762 1.15.8.1 martin len = tcpa->client.log_max_len;
2763 1.15.8.1 martin paddr = tcpa->client.log_start_addr;
2764 1.13 christos break;
2765 1.13 christos
2766 1.15.8.1 martin case ACPI_TCPA_BIOS_SERVER:
2767 1.15.8.1 martin len = tcpa->server.log_max_len;
2768 1.15.8.1 martin paddr = tcpa->server.log_start_addr;
2769 1.13 christos break;
2770 1.13 christos
2771 1.13 christos default:
2772 1.15.8.1 martin printf("XXX");
2773 1.15.8.1 martin printf(END_COMMENT);
2774 1.15.8.1 martin return;
2775 1.15.8.1 martin }
2776 1.15.8.1 martin printf("\tClass %u Base Address 0x%jx Length %ju\n\n",
2777 1.15.8.1 martin tcpa->platform_class, paddr, len);
2778 1.15.8.1 martin
2779 1.15.8.1 martin if (len == 0) {
2780 1.15.8.1 martin printf("\tEmpty TCPA table\n");
2781 1.15.8.1 martin printf(END_COMMENT);
2782 1.15.8.1 martin return;
2783 1.15.8.1 martin }
2784 1.15.8.2 martin if (sdp->Revision == 1) {
2785 1.15.8.1 martin printf("\tOLD TCPA spec log found. Dumping not supported.\n");
2786 1.15.8.1 martin printf(END_COMMENT);
2787 1.15.8.1 martin return;
2788 1.15.8.1 martin }
2789 1.15.8.1 martin
2790 1.15.8.1 martin vaddr = (unsigned char *)acpi_map_physical(paddr, len);
2791 1.15.8.1 martin vend = vaddr + len;
2792 1.15.8.1 martin
2793 1.15.8.1 martin while (vaddr != NULL) {
2794 1.15.8.1 martin if ((vaddr + sizeof(struct TCPAevent) >= vend)||
2795 1.15.8.1 martin (vaddr + sizeof(struct TCPAevent) < vaddr))
2796 1.15.8.1 martin break;
2797 1.15.8.1 martin event = (struct TCPAevent *)(void *)vaddr;
2798 1.15.8.1 martin if (vaddr + event->event_size >= vend)
2799 1.15.8.1 martin break;
2800 1.15.8.1 martin if (vaddr + event->event_size < vaddr)
2801 1.15.8.1 martin break;
2802 1.15.8.1 martin if (event->event_type == 0 && event->event_size == 0)
2803 1.15.8.1 martin break;
2804 1.15.8.1 martin #if 0
2805 1.15.8.1 martin {
2806 1.15.8.1 martin unsigned int i, j, k;
2807 1.15.8.1 martin
2808 1.15.8.1 martin printf("\n\tsize %d\n\t\t%p ", event->event_size, vaddr);
2809 1.15.8.1 martin for (j = 0, i = 0; i <
2810 1.15.8.1 martin sizeof(struct TCPAevent) + event->event_size; i++) {
2811 1.15.8.1 martin printf("%02x ", vaddr[i]);
2812 1.15.8.1 martin if ((i+1) % 8 == 0) {
2813 1.15.8.1 martin for (k = 0; k < 8; k++)
2814 1.15.8.1 martin printf("%c", isprint(vaddr[j+k]) ?
2815 1.15.8.1 martin vaddr[j+k] : '.');
2816 1.15.8.1 martin printf("\n\t\t%p ", &vaddr[i + 1]);
2817 1.15.8.1 martin j = i + 1;
2818 1.15.8.1 martin }
2819 1.15.8.1 martin }
2820 1.15.8.1 martin printf("\n"); }
2821 1.15.8.1 martin #endif
2822 1.15.8.1 martin acpi_print_tcpa(event);
2823 1.15.8.1 martin
2824 1.15.8.1 martin vaddr += sizeof(struct TCPAevent) + event->event_size;
2825 1.15.8.1 martin }
2826 1.15.8.1 martin
2827 1.15.8.1 martin printf(END_COMMENT);
2828 1.15.8.1 martin }
2829 1.15.8.1 martin
2830 1.15.8.1 martin static const char *
2831 1.15.8.1 martin devscope_type2str(int type)
2832 1.15.8.1 martin {
2833 1.15.8.1 martin static char typebuf[16];
2834 1.15.8.1 martin
2835 1.15.8.1 martin switch (type) {
2836 1.15.8.1 martin case 1:
2837 1.15.8.1 martin return ("PCI Endpoint Device");
2838 1.15.8.1 martin case 2:
2839 1.15.8.1 martin return ("PCI Sub-Hierarchy");
2840 1.15.8.1 martin case 3:
2841 1.15.8.1 martin return ("IOAPIC");
2842 1.15.8.1 martin case 4:
2843 1.15.8.1 martin return ("HPET");
2844 1.15.8.2 martin case 5:
2845 1.15.8.2 martin return ("ACPI Name space");
2846 1.15.8.1 martin default:
2847 1.15.8.1 martin snprintf(typebuf, sizeof(typebuf), "%d", type);
2848 1.15.8.1 martin return (typebuf);
2849 1.15.8.1 martin }
2850 1.15.8.1 martin }
2851 1.15.8.1 martin
2852 1.15.8.1 martin static int
2853 1.15.8.1 martin acpi_handle_dmar_devscope(void *addr, int remaining)
2854 1.15.8.1 martin {
2855 1.15.8.1 martin char sep;
2856 1.15.8.1 martin int pathlen;
2857 1.15.8.1 martin ACPI_DMAR_PCI_PATH *path, *pathend;
2858 1.15.8.1 martin ACPI_DMAR_DEVICE_SCOPE *devscope = addr;
2859 1.15.8.1 martin
2860 1.15.8.1 martin if (remaining < (int)sizeof(ACPI_DMAR_DEVICE_SCOPE))
2861 1.15.8.1 martin return (-1);
2862 1.15.8.1 martin
2863 1.15.8.1 martin if (remaining < devscope->Length)
2864 1.15.8.1 martin return (-1);
2865 1.15.8.1 martin
2866 1.15.8.1 martin printf("\n");
2867 1.15.8.1 martin printf("\t\tType=%s\n", devscope_type2str(devscope->EntryType));
2868 1.15.8.1 martin printf("\t\tLength=%d\n", devscope->Length);
2869 1.15.8.1 martin printf("\t\tEnumerationId=%d\n", devscope->EnumerationId);
2870 1.15.8.1 martin printf("\t\tStartBusNumber=%d\n", devscope->Bus);
2871 1.15.8.1 martin
2872 1.15.8.1 martin path = (ACPI_DMAR_PCI_PATH *)(devscope + 1);
2873 1.15.8.1 martin pathlen = devscope->Length - sizeof(ACPI_DMAR_DEVICE_SCOPE);
2874 1.15.8.1 martin pathend = path + pathlen / sizeof(ACPI_DMAR_PCI_PATH);
2875 1.15.8.1 martin if (path < pathend) {
2876 1.15.8.1 martin sep = '{';
2877 1.15.8.1 martin printf("\t\tPath=");
2878 1.15.8.1 martin do {
2879 1.15.8.1 martin printf("%c%d:%d", sep, path->Device, path->Function);
2880 1.15.8.1 martin sep=',';
2881 1.15.8.1 martin path++;
2882 1.15.8.1 martin } while (path < pathend);
2883 1.15.8.1 martin printf("}\n");
2884 1.15.8.1 martin }
2885 1.15.8.1 martin
2886 1.15.8.1 martin return (devscope->Length);
2887 1.15.8.1 martin }
2888 1.15.8.1 martin
2889 1.15.8.1 martin static void
2890 1.15.8.1 martin acpi_handle_dmar_drhd(ACPI_DMAR_HARDWARE_UNIT *drhd)
2891 1.15.8.1 martin {
2892 1.15.8.1 martin char *cp;
2893 1.15.8.1 martin int remaining, consumed;
2894 1.15.8.1 martin
2895 1.15.8.1 martin printf("\n");
2896 1.15.8.1 martin printf("\tType=DRHD\n");
2897 1.15.8.1 martin printf("\tLength=%d\n", drhd->Header.Length);
2898 1.15.8.1 martin
2899 1.15.8.1 martin #define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag)
2900 1.15.8.1 martin
2901 1.15.8.1 martin printf("\tFlags=");
2902 1.15.8.1 martin PRINTFLAG(drhd->Flags, INCLUDE_ALL);
2903 1.15.8.1 martin PRINTFLAG_END();
2904 1.15.8.1 martin
2905 1.15.8.1 martin #undef PRINTFLAG
2906 1.15.8.1 martin
2907 1.15.8.1 martin printf("\tSegment=%d\n", drhd->Segment);
2908 1.15.8.1 martin printf("\tAddress=0x%016jx\n", (uintmax_t)drhd->Address);
2909 1.15.8.1 martin
2910 1.15.8.1 martin remaining = drhd->Header.Length - sizeof(ACPI_DMAR_HARDWARE_UNIT);
2911 1.15.8.1 martin if (remaining > 0)
2912 1.15.8.1 martin printf("\tDevice Scope:");
2913 1.15.8.1 martin while (remaining > 0) {
2914 1.15.8.1 martin cp = (char *)drhd + drhd->Header.Length - remaining;
2915 1.15.8.1 martin consumed = acpi_handle_dmar_devscope(cp, remaining);
2916 1.15.8.1 martin if (consumed <= 0)
2917 1.15.8.1 martin break;
2918 1.15.8.1 martin else
2919 1.15.8.1 martin remaining -= consumed;
2920 1.15.8.1 martin }
2921 1.15.8.1 martin }
2922 1.15.8.1 martin
2923 1.15.8.1 martin static void
2924 1.15.8.1 martin acpi_handle_dmar_rmrr(ACPI_DMAR_RESERVED_MEMORY *rmrr)
2925 1.15.8.1 martin {
2926 1.15.8.1 martin char *cp;
2927 1.15.8.1 martin int remaining, consumed;
2928 1.15.8.1 martin
2929 1.15.8.1 martin printf("\n");
2930 1.15.8.1 martin printf("\tType=RMRR\n");
2931 1.15.8.1 martin printf("\tLength=%d\n", rmrr->Header.Length);
2932 1.15.8.1 martin printf("\tSegment=%d\n", rmrr->Segment);
2933 1.15.8.1 martin printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rmrr->BaseAddress);
2934 1.15.8.1 martin printf("\tLimitAddress=0x%016jx\n", (uintmax_t)rmrr->EndAddress);
2935 1.15.8.1 martin
2936 1.15.8.1 martin remaining = rmrr->Header.Length - sizeof(ACPI_DMAR_RESERVED_MEMORY);
2937 1.15.8.1 martin if (remaining > 0)
2938 1.15.8.1 martin printf("\tDevice Scope:");
2939 1.15.8.1 martin while (remaining > 0) {
2940 1.15.8.1 martin cp = (char *)rmrr + rmrr->Header.Length - remaining;
2941 1.15.8.1 martin consumed = acpi_handle_dmar_devscope(cp, remaining);
2942 1.15.8.1 martin if (consumed <= 0)
2943 1.15.8.1 martin break;
2944 1.15.8.1 martin else
2945 1.15.8.1 martin remaining -= consumed;
2946 1.15.8.1 martin }
2947 1.15.8.1 martin }
2948 1.15.8.1 martin
2949 1.15.8.1 martin static void
2950 1.15.8.1 martin acpi_handle_dmar_atsr(ACPI_DMAR_ATSR *atsr)
2951 1.15.8.1 martin {
2952 1.15.8.1 martin char *cp;
2953 1.15.8.1 martin int remaining, consumed;
2954 1.15.8.1 martin
2955 1.15.8.1 martin printf("\n");
2956 1.15.8.1 martin printf("\tType=ATSR\n");
2957 1.15.8.1 martin printf("\tLength=%d\n", atsr->Header.Length);
2958 1.15.8.1 martin
2959 1.15.8.1 martin #define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag)
2960 1.15.8.1 martin
2961 1.15.8.1 martin printf("\tFlags=");
2962 1.15.8.1 martin PRINTFLAG(atsr->Flags, ALL_PORTS);
2963 1.15.8.1 martin PRINTFLAG_END();
2964 1.15.8.1 martin
2965 1.15.8.1 martin #undef PRINTFLAG
2966 1.15.8.1 martin
2967 1.15.8.1 martin printf("\tSegment=%d\n", atsr->Segment);
2968 1.15.8.1 martin
2969 1.15.8.1 martin remaining = atsr->Header.Length - sizeof(ACPI_DMAR_ATSR);
2970 1.15.8.1 martin if (remaining > 0)
2971 1.15.8.1 martin printf("\tDevice Scope:");
2972 1.15.8.1 martin while (remaining > 0) {
2973 1.15.8.1 martin cp = (char *)atsr + atsr->Header.Length - remaining;
2974 1.15.8.1 martin consumed = acpi_handle_dmar_devscope(cp, remaining);
2975 1.15.8.1 martin if (consumed <= 0)
2976 1.15.8.1 martin break;
2977 1.15.8.1 martin else
2978 1.15.8.1 martin remaining -= consumed;
2979 1.15.8.1 martin }
2980 1.15.8.1 martin }
2981 1.15.8.1 martin
2982 1.15.8.1 martin static void
2983 1.15.8.1 martin acpi_handle_dmar_rhsa(ACPI_DMAR_RHSA *rhsa)
2984 1.15.8.1 martin {
2985 1.15.8.1 martin
2986 1.15.8.1 martin printf("\n");
2987 1.15.8.1 martin printf("\tType=RHSA\n");
2988 1.15.8.1 martin printf("\tLength=%d\n", rhsa->Header.Length);
2989 1.15.8.1 martin printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rhsa->BaseAddress);
2990 1.15.8.1 martin printf("\tProximityDomain=0x%08x\n", rhsa->ProximityDomain);
2991 1.15.8.1 martin }
2992 1.15.8.1 martin
2993 1.15.8.2 martin static void
2994 1.15.8.2 martin acpi_handle_dmar_andd(ACPI_DMAR_ANDD *andd)
2995 1.15.8.2 martin {
2996 1.15.8.2 martin
2997 1.15.8.2 martin printf("\n");
2998 1.15.8.2 martin printf("\tType=ANDD\n");
2999 1.15.8.2 martin printf("\tLength=%d\n", andd->Header.Length);
3000 1.15.8.2 martin printf("\tDeviceNumber=%d\n", andd->DeviceNumber);
3001 1.15.8.2 martin printf("\tDeviceName=0x%s\n", andd->DeviceName);
3002 1.15.8.2 martin }
3003 1.15.8.2 martin
3004 1.15.8.1 martin static int
3005 1.15.8.1 martin acpi_handle_dmar_remapping_structure(void *addr, int remaining)
3006 1.15.8.1 martin {
3007 1.15.8.1 martin ACPI_DMAR_HEADER *hdr = addr;
3008 1.15.8.1 martin
3009 1.15.8.1 martin if (remaining < (int)sizeof(ACPI_DMAR_HEADER))
3010 1.15.8.1 martin return (-1);
3011 1.15.8.1 martin
3012 1.15.8.1 martin if (remaining < hdr->Length)
3013 1.15.8.1 martin return (-1);
3014 1.15.8.1 martin
3015 1.15.8.1 martin switch (hdr->Type) {
3016 1.15.8.1 martin case ACPI_DMAR_TYPE_HARDWARE_UNIT:
3017 1.15.8.1 martin acpi_handle_dmar_drhd(addr);
3018 1.15.8.1 martin break;
3019 1.15.8.1 martin case ACPI_DMAR_TYPE_RESERVED_MEMORY:
3020 1.15.8.1 martin acpi_handle_dmar_rmrr(addr);
3021 1.15.8.1 martin break;
3022 1.15.8.1 martin case ACPI_DMAR_TYPE_ROOT_ATS:
3023 1.15.8.1 martin acpi_handle_dmar_atsr(addr);
3024 1.15.8.1 martin break;
3025 1.15.8.1 martin case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
3026 1.15.8.1 martin acpi_handle_dmar_rhsa(addr);
3027 1.13 christos break;
3028 1.15.8.2 martin case ACPI_DMAR_TYPE_NAMESPACE:
3029 1.15.8.2 martin acpi_handle_dmar_andd(addr);
3030 1.15.8.2 martin break;
3031 1.15.8.1 martin default:
3032 1.15.8.1 martin printf("\n");
3033 1.15.8.1 martin printf("\tType=%d\n", hdr->Type);
3034 1.15.8.1 martin printf("\tLength=%d\n", hdr->Length);
3035 1.15.8.1 martin break;
3036 1.15.8.1 martin }
3037 1.15.8.1 martin return (hdr->Length);
3038 1.15.8.1 martin }
3039 1.15.8.1 martin
3040 1.15.8.1 martin #ifndef ACPI_DMAR_X2APIC_OPT_OUT
3041 1.15.8.1 martin #define ACPI_DMAR_X2APIC_OPT_OUT (0x2)
3042 1.15.8.1 martin #endif
3043 1.15.8.1 martin
3044 1.15.8.1 martin static void
3045 1.15.8.1 martin acpi_handle_dmar(ACPI_TABLE_HEADER *sdp)
3046 1.15.8.1 martin {
3047 1.15.8.1 martin char *cp;
3048 1.15.8.1 martin int remaining, consumed;
3049 1.15.8.1 martin ACPI_TABLE_DMAR *dmar;
3050 1.15.8.1 martin
3051 1.15.8.1 martin printf(BEGIN_COMMENT);
3052 1.15.8.1 martin acpi_print_sdt(sdp);
3053 1.15.8.1 martin dmar = (ACPI_TABLE_DMAR *)sdp;
3054 1.15.8.1 martin printf("\tHost Address Width=%d\n", dmar->Width + 1);
3055 1.15.8.1 martin
3056 1.15.8.1 martin #define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag)
3057 1.15.8.1 martin
3058 1.15.8.1 martin printf("\tFlags=");
3059 1.15.8.1 martin PRINTFLAG(dmar->Flags, INTR_REMAP);
3060 1.15.8.1 martin PRINTFLAG(dmar->Flags, X2APIC_OPT_OUT);
3061 1.15.8.2 martin PRINTFLAG(dmar->Flags, X2APIC_MODE);
3062 1.15.8.1 martin PRINTFLAG_END();
3063 1.15.8.1 martin
3064 1.15.8.1 martin #undef PRINTFLAG
3065 1.15.8.1 martin
3066 1.15.8.1 martin remaining = sdp->Length - sizeof(ACPI_TABLE_DMAR);
3067 1.15.8.1 martin while (remaining > 0) {
3068 1.15.8.1 martin cp = (char *)sdp + sdp->Length - remaining;
3069 1.15.8.1 martin consumed = acpi_handle_dmar_remapping_structure(cp, remaining);
3070 1.15.8.1 martin if (consumed <= 0)
3071 1.15.8.1 martin break;
3072 1.15.8.1 martin else
3073 1.15.8.1 martin remaining -= consumed;
3074 1.13 christos }
3075 1.1 christos
3076 1.12 christos printf(END_COMMENT);
3077 1.1 christos }
3078 1.1 christos
3079 1.1 christos static void
3080 1.15.8.1 martin acpi_handle_uefi(ACPI_TABLE_HEADER *sdp)
3081 1.15.8.1 martin {
3082 1.15.8.1 martin ACPI_TABLE_UEFI *uefi;
3083 1.15.8.1 martin char *uuidstr;
3084 1.15.8.1 martin uint32_t status;
3085 1.15.8.1 martin
3086 1.15.8.1 martin printf(BEGIN_COMMENT);
3087 1.15.8.1 martin acpi_print_sdt(sdp);
3088 1.15.8.1 martin uefi = (ACPI_TABLE_UEFI *)sdp;
3089 1.15.8.1 martin
3090 1.15.8.1 martin uuid_to_string((uuid_t *)(uefi->Identifier),
3091 1.15.8.1 martin &uuidstr, &status);
3092 1.15.8.1 martin if (status != uuid_s_ok)
3093 1.15.8.1 martin errx(1, "uuid_to_string: status=%u", status);
3094 1.15.8.1 martin printf("\tUUID=%s\n", uuidstr);
3095 1.15.8.1 martin free(uuidstr);
3096 1.15.8.1 martin
3097 1.15.8.1 martin printf("\tDataOffset=%04hx\n", uefi->DataOffset);
3098 1.15.8.1 martin /* XXX need write */
3099 1.15.8.1 martin
3100 1.15.8.1 martin printf(END_COMMENT);
3101 1.15.8.1 martin }
3102 1.15.8.1 martin
3103 1.15.8.1 martin static void
3104 1.5 cegger acpi_handle_waet(ACPI_TABLE_HEADER *sdp)
3105 1.1 christos {
3106 1.5 cegger ACPI_TABLE_WAET *waet;
3107 1.5 cegger
3108 1.5 cegger printf(BEGIN_COMMENT);
3109 1.5 cegger acpi_print_sdt(sdp);
3110 1.5 cegger waet = (ACPI_TABLE_WAET *)sdp;
3111 1.1 christos
3112 1.5 cegger printf("\tRTC Timer={");
3113 1.5 cegger if (waet->Flags & ACPI_WAET_RTC_NO_ACK)
3114 1.5 cegger printf("No ACK required");
3115 1.5 cegger else
3116 1.5 cegger printf("default behaviour");
3117 1.5 cegger printf("}\n");
3118 1.5 cegger printf("\t ACPI PM Timer={");
3119 1.5 cegger if (waet->Flags & ACPI_WAET_TIMER_ONE_READ)
3120 1.5 cegger printf("One Read sufficient");
3121 1.5 cegger else
3122 1.5 cegger printf("default behaviour");
3123 1.5 cegger printf("}\n");
3124 1.3 joerg
3125 1.5 cegger printf(END_COMMENT);
3126 1.1 christos }
3127 1.1 christos
3128 1.5 cegger static void
3129 1.5 cegger acpi_print_wdat_action(ACPI_WHEA_HEADER *whea)
3130 1.5 cegger {
3131 1.5 cegger printf("\tACTION={");
3132 1.5 cegger switch (whea->Action) {
3133 1.5 cegger case ACPI_WDAT_RESET:
3134 1.5 cegger printf("RESET");
3135 1.5 cegger break;
3136 1.5 cegger case ACPI_WDAT_GET_CURRENT_COUNTDOWN:
3137 1.5 cegger printf("GET_CURRENT_COUNTDOWN");
3138 1.5 cegger break;
3139 1.5 cegger case ACPI_WDAT_GET_COUNTDOWN:
3140 1.5 cegger printf("GET_COUNTDOWN");
3141 1.5 cegger break;
3142 1.5 cegger case ACPI_WDAT_SET_COUNTDOWN:
3143 1.5 cegger printf("SET_COUNTDOWN");
3144 1.5 cegger break;
3145 1.5 cegger case ACPI_WDAT_GET_RUNNING_STATE:
3146 1.5 cegger printf("GET_RUNNING_STATE");
3147 1.5 cegger break;
3148 1.5 cegger case ACPI_WDAT_SET_RUNNING_STATE:
3149 1.5 cegger printf("SET_RUNNING_STATE");
3150 1.5 cegger break;
3151 1.5 cegger case ACPI_WDAT_GET_STOPPED_STATE:
3152 1.5 cegger printf("GET_STOPPED_STATE");
3153 1.5 cegger break;
3154 1.5 cegger case ACPI_WDAT_SET_STOPPED_STATE:
3155 1.5 cegger printf("SET_STOPPED_STATE");
3156 1.5 cegger break;
3157 1.5 cegger case ACPI_WDAT_GET_REBOOT:
3158 1.5 cegger printf("GET_REBOOT");
3159 1.5 cegger break;
3160 1.5 cegger case ACPI_WDAT_SET_REBOOT:
3161 1.5 cegger printf("SET_REBOOT");
3162 1.5 cegger break;
3163 1.5 cegger case ACPI_WDAT_GET_SHUTDOWN:
3164 1.5 cegger printf("GET_SHUTDOWN");
3165 1.5 cegger break;
3166 1.5 cegger case ACPI_WDAT_SET_SHUTDOWN:
3167 1.5 cegger printf("SET_SHUTDOWN");
3168 1.5 cegger break;
3169 1.5 cegger case ACPI_WDAT_GET_STATUS:
3170 1.5 cegger printf("GET_STATUS");
3171 1.5 cegger break;
3172 1.5 cegger case ACPI_WDAT_SET_STATUS:
3173 1.5 cegger printf("SET_STATUS");
3174 1.5 cegger break;
3175 1.5 cegger case ACPI_WDAT_ACTION_RESERVED:
3176 1.5 cegger printf("ACTION_RESERVED");
3177 1.5 cegger break;
3178 1.5 cegger default:
3179 1.5 cegger printf("%d", whea->Action);
3180 1.5 cegger break;
3181 1.5 cegger }
3182 1.5 cegger printf("}\n");
3183 1.5 cegger }
3184 1.1 christos
3185 1.5 cegger static void
3186 1.5 cegger acpi_print_wdat_instruction(ACPI_WHEA_HEADER *whea)
3187 1.1 christos {
3188 1.5 cegger uint32_t ins;
3189 1.5 cegger
3190 1.5 cegger ins = whea->Instruction & ~ACPI_WDAT_PRESERVE_REGISTER;
3191 1.5 cegger
3192 1.5 cegger printf("\tINSTRUCTION={");
3193 1.5 cegger switch (ins) {
3194 1.5 cegger case ACPI_WDAT_READ_VALUE:
3195 1.5 cegger printf("READ_VALUE");
3196 1.5 cegger break;
3197 1.5 cegger case ACPI_WDAT_READ_COUNTDOWN:
3198 1.5 cegger printf("READ_COUNTDOWN");
3199 1.5 cegger break;
3200 1.5 cegger case ACPI_WDAT_WRITE_VALUE:
3201 1.5 cegger printf("WRITE_VALUE");
3202 1.5 cegger break;
3203 1.5 cegger case ACPI_WDAT_WRITE_COUNTDOWN:
3204 1.5 cegger printf("WRITE_COUNTDOWN");
3205 1.5 cegger break;
3206 1.5 cegger case ACPI_WDAT_INSTRUCTION_RESERVED:
3207 1.5 cegger printf("INSTRUCTION_RESERVED");
3208 1.5 cegger break;
3209 1.5 cegger default:
3210 1.5 cegger printf("%d", ins);
3211 1.5 cegger break;
3212 1.5 cegger }
3213 1.5 cegger
3214 1.5 cegger if (whea->Instruction & ACPI_WDAT_PRESERVE_REGISTER)
3215 1.15.8.1 martin printf(", Preserve Register");
3216 1.5 cegger
3217 1.5 cegger printf("}\n");
3218 1.5 cegger }
3219 1.1 christos
3220 1.5 cegger static void
3221 1.5 cegger acpi_handle_wdat(ACPI_TABLE_HEADER *sdp)
3222 1.5 cegger {
3223 1.5 cegger ACPI_TABLE_WDAT *wdat;
3224 1.5 cegger ACPI_WHEA_HEADER *whea;
3225 1.15.8.1 martin ACPI_WDAT_ENTRY *wdat_pos;
3226 1.5 cegger u_int i;
3227 1.1 christos
3228 1.5 cegger printf(BEGIN_COMMENT);
3229 1.5 cegger acpi_print_sdt(sdp);
3230 1.5 cegger wdat = (ACPI_TABLE_WDAT *)sdp;
3231 1.1 christos
3232 1.5 cegger printf("\tHeader Length=%d\n", wdat->HeaderLength);
3233 1.1 christos
3234 1.15.8.1 martin acpi_print_pci_sbdf(wdat->PciSegment, wdat->PciBus, wdat->PciDevice,
3235 1.5 cegger wdat->PciFunction);
3236 1.5 cegger printf("\n\tTimer Counter Period=%d msec\n", wdat->TimerPeriod);
3237 1.5 cegger printf("\tTimer Maximum Counter Value=%d\n", wdat->MaxCount);
3238 1.5 cegger printf("\tTimer Minimum Counter Value=%d\n", wdat->MinCount);
3239 1.5 cegger
3240 1.5 cegger printf("\tFlags={");
3241 1.5 cegger if (wdat->Flags & ACPI_WDAT_ENABLED)
3242 1.5 cegger printf("ENABLED");
3243 1.5 cegger if (wdat->Flags & ACPI_WDAT_STOPPED)
3244 1.5 cegger printf(", STOPPED");
3245 1.5 cegger printf("}\n");
3246 1.1 christos
3247 1.15.8.1 martin wdat_pos = (ACPI_WDAT_ENTRY *)((char *)wdat + sizeof(ACPI_TABLE_WDAT));
3248 1.1 christos
3249 1.5 cegger for (i = 0; i < wdat->Entries; i++) {
3250 1.5 cegger whea = (ACPI_WHEA_HEADER *)wdat_pos;
3251 1.5 cegger acpi_print_whea(whea,
3252 1.5 cegger acpi_print_wdat_action, acpi_print_wdat_instruction,
3253 1.5 cegger NULL);
3254 1.15.8.1 martin wdat_pos++;
3255 1.5 cegger }
3256 1.5 cegger printf(END_COMMENT);
3257 1.1 christos }
3258 1.5 cegger
3259 1.5 cegger static void
3260 1.15.8.1 martin acpi_handle_wddt(ACPI_TABLE_HEADER *sdp)
3261 1.15.8.1 martin {
3262 1.15.8.1 martin ACPI_TABLE_WDDT *wddt;
3263 1.15.8.1 martin
3264 1.15.8.1 martin printf(BEGIN_COMMENT);
3265 1.15.8.1 martin acpi_print_sdt(sdp);
3266 1.15.8.1 martin wddt = (ACPI_TABLE_WDDT *)sdp;
3267 1.15.8.1 martin
3268 1.15.8.1 martin printf("\tSpecVersion=%04hx\n", wddt->SpecVersion);
3269 1.15.8.1 martin printf("\tTableVersion=%04hx\n", wddt->TableVersion);
3270 1.15.8.1 martin printf("\tPciVendorID=%04hx\n", wddt->PciVendorId);
3271 1.15.8.1 martin printf("\tAddress=");
3272 1.15.8.1 martin acpi_print_gas(&wddt->Address);
3273 1.15.8.1 martin printf("\n\tTimer Maximum Counter Value=%d\n", wddt->MaxCount);
3274 1.15.8.1 martin printf("\tTimer Minimum Counter Value=%d\n", wddt->MinCount);
3275 1.15.8.1 martin printf("\tTimer Counter Period=%d\n", wddt->Period);
3276 1.15.8.1 martin
3277 1.15.8.1 martin #define PRINTFLAG(var, flag) printflag((var), ACPI_WDDT_## flag, #flag)
3278 1.15.8.1 martin
3279 1.15.8.1 martin printf("\tStatus=");
3280 1.15.8.1 martin PRINTFLAG(wddt->Status, AVAILABLE);
3281 1.15.8.1 martin PRINTFLAG(wddt->Status, ACTIVE);
3282 1.15.8.1 martin PRINTFLAG(wddt->Status, TCO_OS_OWNED);
3283 1.15.8.1 martin PRINTFLAG(wddt->Status, USER_RESET);
3284 1.15.8.1 martin PRINTFLAG(wddt->Status, WDT_RESET);
3285 1.15.8.1 martin PRINTFLAG(wddt->Status, POWER_FAIL);
3286 1.15.8.1 martin PRINTFLAG(wddt->Status, UNKNOWN_RESET);
3287 1.15.8.1 martin PRINTFLAG_END();
3288 1.15.8.1 martin
3289 1.15.8.1 martin printf("\tCapability=");
3290 1.15.8.1 martin PRINTFLAG(wddt->Capability, AUTO_RESET);
3291 1.15.8.1 martin PRINTFLAG(wddt->Capability, ALERT_SUPPORT);
3292 1.15.8.1 martin PRINTFLAG_END();
3293 1.15.8.1 martin
3294 1.15.8.1 martin #undef PRINTFLAG
3295 1.15.8.1 martin
3296 1.15.8.1 martin printf(END_COMMENT);
3297 1.15.8.1 martin }
3298 1.15.8.1 martin
3299 1.15.8.1 martin static void
3300 1.5 cegger acpi_handle_wdrt(ACPI_TABLE_HEADER *sdp)
3301 1.1 christos {
3302 1.5 cegger ACPI_TABLE_WDRT *wdrt;
3303 1.1 christos
3304 1.1 christos printf(BEGIN_COMMENT);
3305 1.5 cegger acpi_print_sdt(sdp);
3306 1.5 cegger wdrt = (ACPI_TABLE_WDRT *)sdp;
3307 1.5 cegger
3308 1.5 cegger printf("\tControl Register=");
3309 1.5 cegger acpi_print_gas(&wdrt->ControlRegister);
3310 1.5 cegger printf("\tCount Register=");
3311 1.5 cegger acpi_print_gas(&wdrt->CountRegister);
3312 1.5 cegger acpi_print_pci(wdrt->PciVendorId, wdrt->PciDeviceId,
3313 1.5 cegger wdrt->PciSegment, wdrt->PciBus, wdrt->PciDevice, wdrt->PciFunction);
3314 1.5 cegger
3315 1.5 cegger /* Value must be >= 511 and < 65535 */
3316 1.5 cegger printf("\tMaxCount=%d", wdrt->MaxCount);
3317 1.5 cegger if (wdrt->MaxCount < 511)
3318 1.5 cegger printf(" (Out of Range. Valid range: 511 <= maxcount < 65535)");
3319 1.5 cegger printf("\n");
3320 1.5 cegger
3321 1.5 cegger printf("\tUnit={");
3322 1.5 cegger switch (wdrt->Units) {
3323 1.5 cegger case 0:
3324 1.5 cegger printf("1 seconds/count");
3325 1.5 cegger break;
3326 1.5 cegger case 1:
3327 1.5 cegger printf("100 milliseconds/count");
3328 1.5 cegger break;
3329 1.5 cegger case 2:
3330 1.5 cegger printf("10 milliseconds/count");
3331 1.5 cegger break;
3332 1.5 cegger default:
3333 1.5 cegger printf("%d", wdrt->Units);
3334 1.5 cegger break;
3335 1.5 cegger }
3336 1.5 cegger printf("}\n");
3337 1.5 cegger
3338 1.5 cegger printf(END_COMMENT);
3339 1.5 cegger }
3340 1.5 cegger
3341 1.5 cegger static void
3342 1.5 cegger acpi_print_sdt(ACPI_TABLE_HEADER *sdp)
3343 1.5 cegger {
3344 1.5 cegger printf(" ");
3345 1.5 cegger acpi_print_string(sdp->Signature, ACPI_NAME_SIZE);
3346 1.8 jmcneill printf(": Length=%d, Revision=%d, Checksum=%d",
3347 1.5 cegger sdp->Length, sdp->Revision, sdp->Checksum);
3348 1.8 jmcneill if (acpi_checksum(sdp, sdp->Length))
3349 1.8 jmcneill printf(" (Incorrect)");
3350 1.8 jmcneill printf(",\n\tOEMID=");
3351 1.5 cegger acpi_print_string(sdp->OemId, ACPI_OEM_ID_SIZE);
3352 1.1 christos printf(", OEM Table ID=");
3353 1.5 cegger acpi_print_string(sdp->OemTableId, ACPI_OEM_TABLE_ID_SIZE);
3354 1.5 cegger printf(", OEM Revision=0x%x,\n", sdp->OemRevision);
3355 1.1 christos printf("\tCreator ID=");
3356 1.5 cegger acpi_print_string(sdp->AslCompilerId, ACPI_NAME_SIZE);
3357 1.5 cegger printf(", Creator Revision=0x%x\n", sdp->AslCompilerRevision);
3358 1.1 christos }
3359 1.1 christos
3360 1.15.8.2 martin void
3361 1.15.8.2 martin acpi_print_tabs(unsigned int n)
3362 1.15.8.2 martin {
3363 1.15.8.2 martin
3364 1.15.8.2 martin while (n-- > 0)
3365 1.15.8.2 martin printf("\t");
3366 1.15.8.2 martin }
3367 1.15.8.2 martin
3368 1.5 cegger static void
3369 1.15.8.2 martin acpi_dump_bytes(uint8_t *p, uint32_t len, unsigned int ntabs)
3370 1.7 jmcneill {
3371 1.7 jmcneill unsigned int i;
3372 1.7 jmcneill
3373 1.15.8.2 martin acpi_print_tabs(ntabs);
3374 1.15.8.2 martin printf("Data={");
3375 1.15.8.2 martin for (i = 0; i < len; i++) {
3376 1.7 jmcneill if (cflag) {
3377 1.15.8.2 martin if (i % 64 == 0) {
3378 1.15.8.2 martin printf("\n");
3379 1.15.8.2 martin acpi_print_tabs(ntabs);
3380 1.15.8.2 martin printf(" ");
3381 1.15.8.2 martin }else if (i % 16 == 0)
3382 1.7 jmcneill printf(" ");
3383 1.7 jmcneill printf("%c", (p[i] >= ' ' && p[i] <= '~') ? p[i] : '.');
3384 1.7 jmcneill } else {
3385 1.15.8.2 martin if (i % 16 == 0) {
3386 1.15.8.2 martin printf("\n");
3387 1.15.8.2 martin acpi_print_tabs(ntabs + 1);
3388 1.15.8.2 martin } else if (i % 8 == 0)
3389 1.7 jmcneill printf(" ");
3390 1.7 jmcneill printf(" %02x", p[i]);
3391 1.7 jmcneill }
3392 1.7 jmcneill }
3393 1.15.8.2 martin printf("\n");
3394 1.15.8.2 martin acpi_print_tabs(ntabs);
3395 1.15.8.2 martin printf("}\n");
3396 1.15.8.2 martin }
3397 1.15.8.2 martin
3398 1.15.8.2 martin /* Dump data which has ACPI_TABLE_HEADER */
3399 1.15.8.2 martin static void
3400 1.15.8.2 martin acpi_dump_table(ACPI_TABLE_HEADER *sdp)
3401 1.15.8.2 martin {
3402 1.15.8.2 martin
3403 1.15.8.2 martin acpi_dump_bytes((uint8_t *)sdp, sdp->Length, 1);
3404 1.7 jmcneill }
3405 1.7 jmcneill
3406 1.7 jmcneill static void
3407 1.5 cegger acpi_print_rsdt(ACPI_TABLE_HEADER *rsdp)
3408 1.1 christos {
3409 1.5 cegger ACPI_TABLE_RSDT *rsdt;
3410 1.5 cegger ACPI_TABLE_XSDT *xsdt;
3411 1.1 christos int i, entries;
3412 1.1 christos
3413 1.5 cegger rsdt = (ACPI_TABLE_RSDT *)rsdp;
3414 1.5 cegger xsdt = (ACPI_TABLE_XSDT *)rsdp;
3415 1.5 cegger printf(BEGIN_COMMENT);
3416 1.1 christos acpi_print_sdt(rsdp);
3417 1.5 cegger entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
3418 1.1 christos printf("\tEntries={ ");
3419 1.1 christos for (i = 0; i < entries; i++) {
3420 1.1 christos if (i > 0)
3421 1.1 christos printf(", ");
3422 1.15.8.1 martin if (addr_size == 4)
3423 1.15.8.1 martin printf("0x%08x", le32toh(rsdt->TableOffsetEntry[i]));
3424 1.15.8.1 martin else
3425 1.15.8.1 martin printf("0x%016jx",
3426 1.15.8.1 martin (uintmax_t)le64toh(xsdt->TableOffsetEntry[i]));
3427 1.1 christos }
3428 1.1 christos printf(" }\n");
3429 1.1 christos printf(END_COMMENT);
3430 1.1 christos }
3431 1.1 christos
3432 1.5 cegger static const char *acpi_pm_profiles[] = {
3433 1.5 cegger "Unspecified", "Desktop", "Mobile", "Workstation",
3434 1.15.8.1 martin "Enterprise Server", "SOHO Server", "Appliance PC",
3435 1.15.8.1 martin "Performance Server", "Tablet"
3436 1.5 cegger };
3437 1.5 cegger
3438 1.5 cegger static void
3439 1.5 cegger acpi_print_fadt(ACPI_TABLE_HEADER *sdp)
3440 1.1 christos {
3441 1.5 cegger ACPI_TABLE_FADT *fadt;
3442 1.5 cegger const char *pm;
3443 1.1 christos
3444 1.5 cegger fadt = (ACPI_TABLE_FADT *)sdp;
3445 1.1 christos printf(BEGIN_COMMENT);
3446 1.5 cegger acpi_print_sdt(sdp);
3447 1.5 cegger printf(" \tFACS=0x%x, DSDT=0x%x\n", fadt->Facs,
3448 1.5 cegger fadt->Dsdt);
3449 1.15.8.1 martin /* XXX ACPI 2.0 eliminated this */
3450 1.5 cegger printf("\tINT_MODEL=%s\n", fadt->Model ? "APIC" : "PIC");
3451 1.5 cegger if (fadt->PreferredProfile >= sizeof(acpi_pm_profiles) / sizeof(char *))
3452 1.5 cegger pm = "Reserved";
3453 1.5 cegger else
3454 1.5 cegger pm = acpi_pm_profiles[fadt->PreferredProfile];
3455 1.5 cegger printf("\tPreferred_PM_Profile=%s (%d)\n", pm, fadt->PreferredProfile);
3456 1.5 cegger printf("\tSCI_INT=%d\n", fadt->SciInterrupt);
3457 1.5 cegger printf("\tSMI_CMD=0x%x, ", fadt->SmiCommand);
3458 1.5 cegger printf("ACPI_ENABLE=0x%x, ", fadt->AcpiEnable);
3459 1.5 cegger printf("ACPI_DISABLE=0x%x, ", fadt->AcpiDisable);
3460 1.5 cegger printf("S4BIOS_REQ=0x%x\n", fadt->S4BiosRequest);
3461 1.5 cegger printf("\tPSTATE_CNT=0x%x\n", fadt->PstateControl);
3462 1.5 cegger printf("\tPM1a_EVT_BLK=0x%x-0x%x\n",
3463 1.5 cegger fadt->Pm1aEventBlock,
3464 1.5 cegger fadt->Pm1aEventBlock + fadt->Pm1EventLength - 1);
3465 1.5 cegger if (fadt->Pm1bEventBlock != 0)
3466 1.1 christos printf("\tPM1b_EVT_BLK=0x%x-0x%x\n",
3467 1.5 cegger fadt->Pm1bEventBlock,
3468 1.5 cegger fadt->Pm1bEventBlock + fadt->Pm1EventLength - 1);
3469 1.5 cegger printf("\tPM1a_CNT_BLK=0x%x-0x%x\n",
3470 1.5 cegger fadt->Pm1aControlBlock,
3471 1.5 cegger fadt->Pm1aControlBlock + fadt->Pm1ControlLength - 1);
3472 1.5 cegger if (fadt->Pm1bControlBlock != 0)
3473 1.1 christos printf("\tPM1b_CNT_BLK=0x%x-0x%x\n",
3474 1.5 cegger fadt->Pm1bControlBlock,
3475 1.5 cegger fadt->Pm1bControlBlock + fadt->Pm1ControlLength - 1);
3476 1.5 cegger if (fadt->Pm2ControlBlock != 0)
3477 1.1 christos printf("\tPM2_CNT_BLK=0x%x-0x%x\n",
3478 1.5 cegger fadt->Pm2ControlBlock,
3479 1.5 cegger fadt->Pm2ControlBlock + fadt->Pm2ControlLength - 1);
3480 1.15.8.2 martin if (fadt->PmTimerBlock != 0)
3481 1.15.8.2 martin printf("\tPM_TMR_BLK=0x%x-0x%x\n",
3482 1.15.8.2 martin fadt->PmTimerBlock,
3483 1.15.8.2 martin fadt->PmTimerBlock + fadt->PmTimerLength - 1);
3484 1.5 cegger if (fadt->Gpe0Block != 0)
3485 1.5 cegger printf("\tGPE0_BLK=0x%x-0x%x\n",
3486 1.5 cegger fadt->Gpe0Block,
3487 1.5 cegger fadt->Gpe0Block + fadt->Gpe0BlockLength - 1);
3488 1.5 cegger if (fadt->Gpe1Block != 0)
3489 1.5 cegger printf("\tGPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n",
3490 1.5 cegger fadt->Gpe1Block,
3491 1.5 cegger fadt->Gpe1Block + fadt->Gpe1BlockLength - 1,
3492 1.5 cegger fadt->Gpe1Base);
3493 1.5 cegger if (fadt->CstControl != 0)
3494 1.5 cegger printf("\tCST_CNT=0x%x\n", fadt->CstControl);
3495 1.5 cegger printf("\tP_LVL2_LAT=%d us, P_LVL3_LAT=%d us\n",
3496 1.5 cegger fadt->C2Latency, fadt->C3Latency);
3497 1.1 christos printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n",
3498 1.5 cegger fadt->FlushSize, fadt->FlushStride);
3499 1.1 christos printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n",
3500 1.5 cegger fadt->DutyOffset, fadt->DutyWidth);
3501 1.1 christos printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n",
3502 1.5 cegger fadt->DayAlarm, fadt->MonthAlarm, fadt->Century);
3503 1.1 christos
3504 1.15.8.1 martin #define PRINTFLAG(var, flag) printflag((var), ACPI_FADT_## flag, #flag)
3505 1.1 christos
3506 1.5 cegger printf("\tIAPC_BOOT_ARCH=");
3507 1.5 cegger PRINTFLAG(fadt->BootFlags, LEGACY_DEVICES);
3508 1.5 cegger PRINTFLAG(fadt->BootFlags, 8042);
3509 1.5 cegger PRINTFLAG(fadt->BootFlags, NO_VGA);
3510 1.5 cegger PRINTFLAG(fadt->BootFlags, NO_MSI);
3511 1.5 cegger PRINTFLAG(fadt->BootFlags, NO_ASPM);
3512 1.15.8.1 martin PRINTFLAG(fadt->BootFlags, NO_CMOS_RTC);
3513 1.15.8.1 martin PRINTFLAG_END();
3514 1.5 cegger
3515 1.5 cegger printf("\tFlags=");
3516 1.5 cegger PRINTFLAG(fadt->Flags, WBINVD);
3517 1.5 cegger PRINTFLAG(fadt->Flags, WBINVD_FLUSH);
3518 1.5 cegger PRINTFLAG(fadt->Flags, C1_SUPPORTED);
3519 1.5 cegger PRINTFLAG(fadt->Flags, C2_MP_SUPPORTED);
3520 1.5 cegger PRINTFLAG(fadt->Flags, POWER_BUTTON);
3521 1.5 cegger PRINTFLAG(fadt->Flags, SLEEP_BUTTON);
3522 1.5 cegger PRINTFLAG(fadt->Flags, FIXED_RTC);
3523 1.5 cegger PRINTFLAG(fadt->Flags, S4_RTC_WAKE);
3524 1.5 cegger PRINTFLAG(fadt->Flags, 32BIT_TIMER);
3525 1.5 cegger PRINTFLAG(fadt->Flags, DOCKING_SUPPORTED);
3526 1.5 cegger PRINTFLAG(fadt->Flags, RESET_REGISTER);
3527 1.5 cegger PRINTFLAG(fadt->Flags, SEALED_CASE);
3528 1.5 cegger PRINTFLAG(fadt->Flags, HEADLESS);
3529 1.5 cegger PRINTFLAG(fadt->Flags, SLEEP_TYPE);
3530 1.5 cegger PRINTFLAG(fadt->Flags, PCI_EXPRESS_WAKE);
3531 1.5 cegger PRINTFLAG(fadt->Flags, PLATFORM_CLOCK);
3532 1.5 cegger PRINTFLAG(fadt->Flags, S4_RTC_VALID);
3533 1.5 cegger PRINTFLAG(fadt->Flags, REMOTE_POWER_ON);
3534 1.5 cegger PRINTFLAG(fadt->Flags, APIC_CLUSTER);
3535 1.5 cegger PRINTFLAG(fadt->Flags, APIC_PHYSICAL);
3536 1.15.8.1 martin PRINTFLAG(fadt->Flags, HW_REDUCED);
3537 1.15.8.1 martin PRINTFLAG(fadt->Flags, LOW_POWER_S0);
3538 1.15.8.1 martin PRINTFLAG_END();
3539 1.1 christos
3540 1.15.8.1 martin if (sdp->Length < ACPI_FADT_V2_SIZE)
3541 1.15.8.1 martin goto out;
3542 1.1 christos
3543 1.5 cegger if (fadt->Flags & ACPI_FADT_RESET_REGISTER) {
3544 1.5 cegger printf("\tRESET_REG=");
3545 1.5 cegger acpi_print_gas(&fadt->ResetRegister);
3546 1.5 cegger printf(", RESET_VALUE=%#x\n", fadt->ResetValue);
3547 1.5 cegger }
3548 1.15.8.1 martin
3549 1.15.8.1 martin printf("\tArmBootFlags=");
3550 1.15.8.1 martin PRINTFLAG(fadt->ArmBootFlags, PSCI_COMPLIANT);
3551 1.15.8.1 martin PRINTFLAG(fadt->ArmBootFlags, PSCI_USE_HVC);
3552 1.15.8.1 martin PRINTFLAG_END();
3553 1.15.8.1 martin
3554 1.15.8.1 martin #undef PRINTFLAG
3555 1.15.8.1 martin
3556 1.15.8.1 martin printf("\tMinorRevision=%u\n", fadt->MinorRevision);
3557 1.15.8.1 martin
3558 1.15.8.1 martin if (sdp->Length < ACPI_FADT_V3_SIZE)
3559 1.15.8.1 martin goto out;
3560 1.15.8.1 martin
3561 1.15.8.1 martin printf("\tX_FACS=0x%016jx, ", (uintmax_t)fadt->XFacs);
3562 1.15.8.1 martin printf("X_DSDT=0x%016jx\n", (uintmax_t)fadt->XDsdt);
3563 1.15.8.1 martin printf("\tX_PM1a_EVT_BLK=");
3564 1.15.8.1 martin acpi_print_gas(&fadt->XPm1aEventBlock);
3565 1.15.8.1 martin if (fadt->XPm1bEventBlock.Address != 0) {
3566 1.15.8.1 martin printf("\n\tX_PM1b_EVT_BLK=");
3567 1.15.8.1 martin acpi_print_gas(&fadt->XPm1bEventBlock);
3568 1.15.8.1 martin }
3569 1.15.8.1 martin printf("\n\tX_PM1a_CNT_BLK=");
3570 1.15.8.1 martin acpi_print_gas(&fadt->XPm1aControlBlock);
3571 1.15.8.1 martin if (fadt->XPm1bControlBlock.Address != 0) {
3572 1.15.8.1 martin printf("\n\tX_PM1b_CNT_BLK=");
3573 1.15.8.1 martin acpi_print_gas(&fadt->XPm1bControlBlock);
3574 1.15.8.1 martin }
3575 1.15.8.1 martin if (fadt->XPm2ControlBlock.Address != 0) {
3576 1.15.8.1 martin printf("\n\tX_PM2_CNT_BLK=");
3577 1.15.8.1 martin acpi_print_gas(&fadt->XPm2ControlBlock);
3578 1.15.8.1 martin }
3579 1.15.8.2 martin if (fadt->XPmTimerBlock.Address != 0) {
3580 1.15.8.2 martin printf("\n\tX_PM_TMR_BLK=");
3581 1.15.8.2 martin acpi_print_gas(&fadt->XPmTimerBlock);
3582 1.15.8.2 martin }
3583 1.15.8.1 martin if (fadt->XGpe0Block.Address != 0) {
3584 1.15.8.1 martin printf("\n\tX_GPE0_BLK=");
3585 1.15.8.1 martin acpi_print_gas(&fadt->XGpe0Block);
3586 1.15.8.1 martin }
3587 1.15.8.1 martin if (fadt->XGpe1Block.Address != 0) {
3588 1.15.8.1 martin printf("\n\tX_GPE1_BLK=");
3589 1.15.8.1 martin acpi_print_gas(&fadt->XGpe1Block);
3590 1.15.8.1 martin }
3591 1.15.8.1 martin printf("\n");
3592 1.15.8.1 martin
3593 1.15.8.1 martin if (sdp->Length < ACPI_FADT_V5_SIZE)
3594 1.15.8.1 martin goto out;
3595 1.15.8.1 martin
3596 1.15.8.1 martin if (fadt->SleepControl.Address != 0) {
3597 1.15.8.1 martin printf("\tSleepControl=");
3598 1.15.8.1 martin acpi_print_gas(&fadt->SleepControl);
3599 1.5 cegger printf("\n");
3600 1.5 cegger }
3601 1.15.8.1 martin if (fadt->SleepStatus.Address != 0) {
3602 1.15.8.1 martin printf("\n\tSleepStatus=");
3603 1.15.8.1 martin acpi_print_gas(&fadt->SleepStatus);
3604 1.15.8.1 martin printf("\n");
3605 1.15.8.1 martin }
3606 1.15.8.1 martin
3607 1.15.8.1 martin if (sdp->Length < ACPI_FADT_V6_SIZE)
3608 1.15.8.1 martin goto out;
3609 1.5 cegger
3610 1.15.8.1 martin printf("\tHypervisorId=0x%016"PRIx64"\n", fadt->HypervisorId);
3611 1.15.8.1 martin
3612 1.15.8.1 martin out:
3613 1.1 christos printf(END_COMMENT);
3614 1.1 christos }
3615 1.1 christos
3616 1.5 cegger static void
3617 1.5 cegger acpi_print_facs(ACPI_TABLE_FACS *facs)
3618 1.1 christos {
3619 1.5 cegger printf(BEGIN_COMMENT);
3620 1.5 cegger printf(" FACS:\tLength=%u, ", facs->Length);
3621 1.5 cegger printf("HwSig=0x%08x, ", facs->HardwareSignature);
3622 1.5 cegger printf("Firm_Wake_Vec=0x%08x\n", facs->FirmwareWakingVector);
3623 1.5 cegger
3624 1.15.8.1 martin #define PRINTFLAG(var, flag) printflag((var), ACPI_GLOCK_## flag, #flag)
3625 1.15.8.1 martin
3626 1.5 cegger printf("\tGlobal_Lock=");
3627 1.15.8.1 martin PRINTFLAG(facs->GlobalLock, PENDING);
3628 1.15.8.1 martin PRINTFLAG(facs->GlobalLock, OWNED);
3629 1.15.8.1 martin PRINTFLAG_END();
3630 1.15.8.1 martin
3631 1.15.8.1 martin #undef PRINTFLAG
3632 1.15.8.1 martin
3633 1.15.8.1 martin #define PRINTFLAG(var, flag) printflag((var), ACPI_FACS_## flag, #flag)
3634 1.5 cegger
3635 1.5 cegger printf("\tFlags=");
3636 1.15.8.1 martin PRINTFLAG(facs->Flags, S4_BIOS_PRESENT);
3637 1.15.8.1 martin PRINTFLAG(facs->Flags, 64BIT_WAKE);
3638 1.15.8.1 martin PRINTFLAG_END();
3639 1.5 cegger
3640 1.15.8.1 martin #undef PRINTFLAG
3641 1.15.8.1 martin
3642 1.15.8.1 martin if (facs->XFirmwareWakingVector != 0)
3643 1.15.8.1 martin printf("\tX_Firm_Wake_Vec=%016jx\n",
3644 1.15.8.1 martin (uintmax_t)facs->XFirmwareWakingVector);
3645 1.5 cegger printf("\tVersion=%u\n", facs->Version);
3646 1.5 cegger
3647 1.15.8.1 martin printf("\tOspmFlags={");
3648 1.15.8.1 martin if (facs->OspmFlags & ACPI_FACS_64BIT_ENVIRONMENT)
3649 1.15.8.1 martin printf("64BIT_WAKE");
3650 1.15.8.1 martin printf("}\n");
3651 1.15.8.1 martin
3652 1.5 cegger printf(END_COMMENT);
3653 1.5 cegger }
3654 1.1 christos
3655 1.5 cegger static void
3656 1.5 cegger acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp)
3657 1.5 cegger {
3658 1.5 cegger printf(BEGIN_COMMENT);
3659 1.1 christos acpi_print_sdt(dsdp);
3660 1.5 cegger printf(END_COMMENT);
3661 1.1 christos }
3662 1.1 christos
3663 1.1 christos int
3664 1.1 christos acpi_checksum(void *p, size_t length)
3665 1.1 christos {
3666 1.5 cegger uint8_t *bp;
3667 1.5 cegger uint8_t sum;
3668 1.1 christos
3669 1.1 christos bp = p;
3670 1.1 christos sum = 0;
3671 1.1 christos while (length--)
3672 1.1 christos sum += *bp++;
3673 1.1 christos
3674 1.1 christos return (sum);
3675 1.1 christos }
3676 1.1 christos
3677 1.5 cegger static ACPI_TABLE_HEADER *
3678 1.1 christos acpi_map_sdt(vm_offset_t pa)
3679 1.1 christos {
3680 1.5 cegger ACPI_TABLE_HEADER *sp;
3681 1.1 christos
3682 1.5 cegger sp = acpi_map_physical(pa, sizeof(ACPI_TABLE_HEADER));
3683 1.5 cegger sp = acpi_map_physical(pa, sp->Length);
3684 1.1 christos return (sp);
3685 1.1 christos }
3686 1.1 christos
3687 1.5 cegger static void
3688 1.5 cegger acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp)
3689 1.1 christos {
3690 1.1 christos printf(BEGIN_COMMENT);
3691 1.5 cegger printf(" RSD PTR: OEM=");
3692 1.5 cegger acpi_print_string(rp->OemId, ACPI_OEM_ID_SIZE);
3693 1.5 cegger printf(", ACPI_Rev=%s (%d)\n", rp->Revision < 2 ? "1.0x" : "2.0x",
3694 1.5 cegger rp->Revision);
3695 1.5 cegger if (rp->Revision < 2) {
3696 1.5 cegger printf("\tRSDT=0x%08x, cksum=%u\n", rp->RsdtPhysicalAddress,
3697 1.5 cegger rp->Checksum);
3698 1.5 cegger } else {
3699 1.15.8.1 martin printf("\tXSDT=0x%016jx, length=%u, cksum=%u\n",
3700 1.15.8.1 martin (uintmax_t)rp->XsdtPhysicalAddress, rp->Length,
3701 1.5 cegger rp->ExtendedChecksum);
3702 1.5 cegger }
3703 1.1 christos printf(END_COMMENT);
3704 1.1 christos }
3705 1.1 christos
3706 1.5 cegger static void
3707 1.5 cegger acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp)
3708 1.1 christos {
3709 1.5 cegger ACPI_TABLE_HEADER *sdp;
3710 1.5 cegger ACPI_TABLE_RSDT *rsdt;
3711 1.5 cegger ACPI_TABLE_XSDT *xsdt;
3712 1.15 christos vm_offset_t addr = 0;
3713 1.5 cegger int entries, i;
3714 1.1 christos
3715 1.1 christos acpi_print_rsdt(rsdp);
3716 1.5 cegger rsdt = (ACPI_TABLE_RSDT *)rsdp;
3717 1.5 cegger xsdt = (ACPI_TABLE_XSDT *)rsdp;
3718 1.5 cegger entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
3719 1.1 christos for (i = 0; i < entries; i++) {
3720 1.15.8.1 martin if (addr_size == 4)
3721 1.5 cegger addr = le32toh(rsdt->TableOffsetEntry[i]);
3722 1.15.8.1 martin else
3723 1.5 cegger addr = le64toh(xsdt->TableOffsetEntry[i]);
3724 1.15.8.1 martin if (addr == 0)
3725 1.15.8.1 martin continue;
3726 1.5 cegger sdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
3727 1.5 cegger if (acpi_checksum(sdp, sdp->Length)) {
3728 1.5 cegger warnx("RSDT entry %d (sig %.4s) is corrupt", i,
3729 1.5 cegger sdp->Signature);
3730 1.8 jmcneill if (sflag)
3731 1.8 jmcneill continue;
3732 1.4 drochner }
3733 1.5 cegger if (!memcmp(sdp->Signature, ACPI_SIG_FADT, 4))
3734 1.5 cegger acpi_handle_fadt(sdp);
3735 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_BERT, 4))
3736 1.5 cegger acpi_handle_bert(sdp);
3737 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_BOOT, 4))
3738 1.5 cegger acpi_handle_boot(sdp);
3739 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_CPEP, 4))
3740 1.5 cegger acpi_handle_cpep(sdp);
3741 1.15.8.2 martin else if (!memcmp(sdp->Signature, ACPI_SIG_CSRT, 4))
3742 1.15.8.2 martin acpi_handle_csrt(sdp);
3743 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_DBGP, 4))
3744 1.5 cegger acpi_handle_dbgp(sdp);
3745 1.15.8.1 martin else if (!memcmp(sdp->Signature, ACPI_SIG_DBG2, 4))
3746 1.15.8.1 martin acpi_handle_dbg2(sdp);
3747 1.15.8.1 martin else if (!memcmp(sdp->Signature, ACPI_SIG_DMAR, 4))
3748 1.15.8.1 martin acpi_handle_dmar(sdp);
3749 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_EINJ, 4))
3750 1.5 cegger acpi_handle_einj(sdp);
3751 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_ERST, 4))
3752 1.5 cegger acpi_handle_erst(sdp);
3753 1.15.8.2 martin else if (!memcmp(sdp->Signature, ACPI_SIG_GTDT, 4))
3754 1.15.8.2 martin acpi_handle_gtdt(sdp);
3755 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_MADT, 4))
3756 1.5 cegger acpi_handle_madt(sdp);
3757 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_MSCT, 4))
3758 1.5 cegger acpi_handle_msct(sdp);
3759 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_HEST, 4))
3760 1.5 cegger acpi_handle_hest(sdp);
3761 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_HPET, 4))
3762 1.5 cegger acpi_handle_hpet(sdp);
3763 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_ECDT, 4))
3764 1.5 cegger acpi_handle_ecdt(sdp);
3765 1.15.8.2 martin else if (!memcmp(sdp->Signature, ACPI_SIG_LPIT, 4))
3766 1.15.8.2 martin acpi_handle_lpit(sdp);
3767 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_MCFG, 4))
3768 1.5 cegger acpi_handle_mcfg(sdp);
3769 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_SBST, 4))
3770 1.5 cegger acpi_handle_sbst(sdp);
3771 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_SLIT, 4))
3772 1.5 cegger acpi_handle_slit(sdp);
3773 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_SPCR, 4))
3774 1.5 cegger acpi_handle_spcr(sdp);
3775 1.15.8.1 martin else if (!memcmp(sdp->Signature, ACPI_SIG_SPMI, 4))
3776 1.15.8.1 martin acpi_handle_spmi(sdp);
3777 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_SRAT, 4))
3778 1.5 cegger acpi_handle_srat(sdp);
3779 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_TCPA, 4))
3780 1.5 cegger acpi_handle_tcpa(sdp);
3781 1.15.8.1 martin else if (!memcmp(sdp->Signature, ACPI_SIG_NFIT, 4))
3782 1.15.8.1 martin acpi_handle_nfit(sdp);
3783 1.15.8.1 martin else if (!memcmp(sdp->Signature, ACPI_SIG_UEFI, 4))
3784 1.15.8.1 martin acpi_handle_uefi(sdp);
3785 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_WAET, 4))
3786 1.5 cegger acpi_handle_waet(sdp);
3787 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_WDAT, 4))
3788 1.5 cegger acpi_handle_wdat(sdp);
3789 1.15.8.1 martin else if (!memcmp(sdp->Signature, ACPI_SIG_WDDT, 4))
3790 1.15.8.1 martin acpi_handle_wddt(sdp);
3791 1.5 cegger else if (!memcmp(sdp->Signature, ACPI_SIG_WDRT, 4))
3792 1.5 cegger acpi_handle_wdrt(sdp);
3793 1.5 cegger else {
3794 1.5 cegger printf(BEGIN_COMMENT);
3795 1.1 christos acpi_print_sdt(sdp);
3796 1.15.8.2 martin printf("\n");
3797 1.15.8.2 martin acpi_dump_table(sdp);
3798 1.5 cegger printf(END_COMMENT);
3799 1.1 christos }
3800 1.1 christos }
3801 1.1 christos }
3802 1.1 christos
3803 1.5 cegger ACPI_TABLE_HEADER *
3804 1.5 cegger sdt_load_devmem(void)
3805 1.5 cegger {
3806 1.5 cegger ACPI_TABLE_RSDP *rp;
3807 1.5 cegger ACPI_TABLE_HEADER *rsdp;
3808 1.1 christos
3809 1.5 cegger rp = acpi_find_rsd_ptr();
3810 1.5 cegger if (!rp)
3811 1.5 cegger errx(EXIT_FAILURE, "Can't find ACPI information");
3812 1.5 cegger
3813 1.5 cegger if (tflag)
3814 1.5 cegger acpi_print_rsd_ptr(rp);
3815 1.5 cegger if (rp->Revision < 2) {
3816 1.5 cegger rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->RsdtPhysicalAddress);
3817 1.5 cegger if (memcmp(rsdp->Signature, "RSDT", 4) != 0 ||
3818 1.5 cegger acpi_checksum(rsdp, rsdp->Length) != 0)
3819 1.5 cegger errx(EXIT_FAILURE, "RSDT is corrupted");
3820 1.5 cegger addr_size = sizeof(uint32_t);
3821 1.5 cegger } else {
3822 1.5 cegger rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->XsdtPhysicalAddress);
3823 1.5 cegger if (memcmp(rsdp->Signature, "XSDT", 4) != 0 ||
3824 1.5 cegger acpi_checksum(rsdp, rsdp->Length) != 0)
3825 1.5 cegger errx(EXIT_FAILURE, "XSDT is corrupted");
3826 1.5 cegger addr_size = sizeof(uint64_t);
3827 1.5 cegger }
3828 1.5 cegger return (rsdp);
3829 1.1 christos }
3830 1.1 christos
3831 1.5 cegger /* Write the DSDT to a file, concatenating any SSDTs (if present). */
3832 1.5 cegger static int
3833 1.5 cegger write_dsdt(int fd, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdt)
3834 1.5 cegger {
3835 1.5 cegger ACPI_TABLE_HEADER sdt;
3836 1.5 cegger ACPI_TABLE_HEADER *ssdt;
3837 1.5 cegger uint8_t sum;
3838 1.5 cegger
3839 1.5 cegger /* Create a new checksum to account for the DSDT and any SSDTs. */
3840 1.5 cegger sdt = *dsdt;
3841 1.5 cegger if (rsdt != NULL) {
3842 1.5 cegger sdt.Checksum = 0;
3843 1.5 cegger sum = acpi_checksum(dsdt + 1, dsdt->Length -
3844 1.5 cegger sizeof(ACPI_TABLE_HEADER));
3845 1.5 cegger ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, NULL);
3846 1.5 cegger while (ssdt != NULL) {
3847 1.5 cegger sdt.Length += ssdt->Length - sizeof(ACPI_TABLE_HEADER);
3848 1.5 cegger sum += acpi_checksum(ssdt + 1,
3849 1.5 cegger ssdt->Length - sizeof(ACPI_TABLE_HEADER));
3850 1.5 cegger ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, ssdt);
3851 1.5 cegger }
3852 1.5 cegger sum += acpi_checksum(&sdt, sizeof(ACPI_TABLE_HEADER));
3853 1.5 cegger sdt.Checksum -= sum;
3854 1.5 cegger }
3855 1.5 cegger
3856 1.5 cegger /* Write out the DSDT header and body. */
3857 1.5 cegger write(fd, &sdt, sizeof(ACPI_TABLE_HEADER));
3858 1.5 cegger write(fd, dsdt + 1, dsdt->Length - sizeof(ACPI_TABLE_HEADER));
3859 1.5 cegger
3860 1.5 cegger /* Write out any SSDTs (if present.) */
3861 1.5 cegger if (rsdt != NULL) {
3862 1.5 cegger ssdt = sdt_from_rsdt(rsdt, "SSDT", NULL);
3863 1.5 cegger while (ssdt != NULL) {
3864 1.5 cegger write(fd, ssdt + 1, ssdt->Length -
3865 1.5 cegger sizeof(ACPI_TABLE_HEADER));
3866 1.5 cegger ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt);
3867 1.5 cegger }
3868 1.5 cegger }
3869 1.1 christos return (0);
3870 1.1 christos }
3871 1.1 christos
3872 1.5 cegger void
3873 1.5 cegger dsdt_save_file(char *outfile, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
3874 1.1 christos {
3875 1.5 cegger int fd;
3876 1.5 cegger mode_t mode;
3877 1.5 cegger
3878 1.5 cegger assert(outfile != NULL);
3879 1.5 cegger mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
3880 1.5 cegger fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, mode);
3881 1.5 cegger if (fd == -1) {
3882 1.5 cegger perror("dsdt_save_file");
3883 1.5 cegger return;
3884 1.5 cegger }
3885 1.5 cegger write_dsdt(fd, rsdt, dsdp);
3886 1.5 cegger close(fd);
3887 1.1 christos }
3888 1.1 christos
3889 1.5 cegger void
3890 1.5 cegger aml_disassemble(ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
3891 1.1 christos {
3892 1.15.8.1 martin char buf[MAXPATHLEN], tmpstr[MAXPATHLEN], wrkdir[MAXPATHLEN];
3893 1.15.8.1 martin const char *iname = "/acpdump.din";
3894 1.15.8.1 martin const char *oname = "/acpdump.dsl";
3895 1.5 cegger const char *tmpdir;
3896 1.5 cegger FILE *fp;
3897 1.5 cegger size_t len;
3898 1.15.8.1 martin int fd, status;
3899 1.15.8.1 martin pid_t pid;
3900 1.5 cegger
3901 1.5 cegger if (rsdt == NULL)
3902 1.5 cegger errx(EXIT_FAILURE, "aml_disassemble: invalid rsdt");
3903 1.5 cegger if (dsdp == NULL)
3904 1.5 cegger errx(EXIT_FAILURE, "aml_disassemble: invalid dsdp");
3905 1.5 cegger
3906 1.5 cegger tmpdir = getenv("TMPDIR");
3907 1.5 cegger if (tmpdir == NULL)
3908 1.5 cegger tmpdir = _PATH_TMP;
3909 1.15.8.1 martin if (realpath(tmpdir, buf) == NULL) {
3910 1.15.8.1 martin perror("realpath tmp dir");
3911 1.15.8.1 martin return;
3912 1.15.8.1 martin }
3913 1.15.8.1 martin len = sizeof(wrkdir) - strlen(iname);
3914 1.15.8.1 martin if ((size_t)snprintf(wrkdir, len, "%s/acpidump.XXXXXX", buf) > len-1 ) {
3915 1.15.8.1 martin fprintf(stderr, "$TMPDIR too long\n");
3916 1.15.8.1 martin return;
3917 1.15.8.1 martin }
3918 1.15.8.1 martin if (mkdtemp(wrkdir) == NULL) {
3919 1.15.8.1 martin perror("mkdtemp tmp working dir");
3920 1.5 cegger return;
3921 1.5 cegger }
3922 1.15.8.1 martin len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, iname);
3923 1.15.8.1 martin assert(len <= sizeof(tmpstr) - 1);
3924 1.15.8.1 martin fd = open(tmpstr, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
3925 1.5 cegger if (fd < 0) {
3926 1.5 cegger perror("iasl tmp file");
3927 1.5 cegger return;
3928 1.5 cegger }
3929 1.5 cegger write_dsdt(fd, rsdt, dsdp);
3930 1.5 cegger close(fd);
3931 1.5 cegger
3932 1.5 cegger /* Run iasl -d on the temp file */
3933 1.15.8.1 martin if ((pid = fork()) == 0) {
3934 1.5 cegger close(STDOUT_FILENO);
3935 1.5 cegger if (vflag == 0)
3936 1.5 cegger close(STDERR_FILENO);
3937 1.5 cegger execl("/usr/bin/iasl", "iasl", "-d", tmpstr, NULL);
3938 1.5 cegger err(EXIT_FAILURE, "exec");
3939 1.5 cegger }
3940 1.15.8.1 martin if (pid > 0)
3941 1.15.8.1 martin wait(&status);
3942 1.15.8.1 martin if (unlink(tmpstr) < 0) {
3943 1.15.8.1 martin perror("unlink");
3944 1.15.8.1 martin goto out;
3945 1.15.8.1 martin }
3946 1.15.8.1 martin if (pid < 0) {
3947 1.15.8.1 martin perror("fork");
3948 1.15.8.1 martin goto out;
3949 1.15.8.1 martin }
3950 1.15.8.1 martin if (status != 0) {
3951 1.15.8.1 martin fprintf(stderr, "iast exit status = %d\n", status);
3952 1.15.8.1 martin }
3953 1.1 christos
3954 1.5 cegger /* Dump iasl's output to stdout */
3955 1.15.8.1 martin len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, oname);
3956 1.15.8.1 martin assert(len <= sizeof(tmpstr) - 1);
3957 1.5 cegger fp = fopen(tmpstr, "r");
3958 1.15.8.1 martin if (unlink(tmpstr) < 0) {
3959 1.15.8.1 martin perror("unlink");
3960 1.15.8.1 martin goto out;
3961 1.15.8.1 martin }
3962 1.5 cegger if (fp == NULL) {
3963 1.5 cegger perror("iasl tmp file (read)");
3964 1.15.8.1 martin goto out;
3965 1.5 cegger }
3966 1.5 cegger while ((len = fread(buf, 1, sizeof(buf), fp)) > 0)
3967 1.5 cegger fwrite(buf, 1, len, stdout);
3968 1.5 cegger fclose(fp);
3969 1.15.8.1 martin
3970 1.15.8.1 martin out:
3971 1.15.8.1 martin if (rmdir(wrkdir) < 0)
3972 1.15.8.1 martin perror("rmdir");
3973 1.1 christos }
3974 1.1 christos
3975 1.5 cegger void
3976 1.5 cegger sdt_print_all(ACPI_TABLE_HEADER *rsdp)
3977 1.1 christos {
3978 1.5 cegger acpi_handle_rsdt(rsdp);
3979 1.1 christos }
3980 1.1 christos
3981 1.5 cegger /* Fetch a table matching the given signature via the RSDT. */
3982 1.5 cegger ACPI_TABLE_HEADER *
3983 1.5 cegger sdt_from_rsdt(ACPI_TABLE_HEADER *rsdp, const char *sig, ACPI_TABLE_HEADER *last)
3984 1.1 christos {
3985 1.5 cegger ACPI_TABLE_HEADER *sdt;
3986 1.5 cegger ACPI_TABLE_RSDT *rsdt;
3987 1.5 cegger ACPI_TABLE_XSDT *xsdt;
3988 1.15 christos vm_offset_t addr = 0;
3989 1.5 cegger int entries, i;
3990 1.1 christos
3991 1.5 cegger rsdt = (ACPI_TABLE_RSDT *)rsdp;
3992 1.5 cegger xsdt = (ACPI_TABLE_XSDT *)rsdp;
3993 1.5 cegger entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
3994 1.5 cegger for (i = 0; i < entries; i++) {
3995 1.15.8.1 martin if (addr_size == 4)
3996 1.5 cegger addr = le32toh(rsdt->TableOffsetEntry[i]);
3997 1.15.8.1 martin else
3998 1.5 cegger addr = le64toh(xsdt->TableOffsetEntry[i]);
3999 1.15.8.1 martin if (addr == 0)
4000 1.15.8.1 martin continue;
4001 1.5 cegger sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
4002 1.5 cegger if (last != NULL) {
4003 1.5 cegger if (sdt == last)
4004 1.5 cegger last = NULL;
4005 1.5 cegger continue;
4006 1.5 cegger }
4007 1.5 cegger if (memcmp(sdt->Signature, sig, strlen(sig)))
4008 1.5 cegger continue;
4009 1.5 cegger if (acpi_checksum(sdt, sdt->Length))
4010 1.5 cegger errx(EXIT_FAILURE, "RSDT entry %d is corrupt", i);
4011 1.5 cegger return (sdt);
4012 1.5 cegger }
4013 1.1 christos
4014 1.5 cegger return (NULL);
4015 1.1 christos }
4016 1.1 christos
4017 1.5 cegger ACPI_TABLE_HEADER *
4018 1.5 cegger dsdt_from_fadt(ACPI_TABLE_FADT *fadt)
4019 1.1 christos {
4020 1.5 cegger ACPI_TABLE_HEADER *sdt;
4021 1.1 christos
4022 1.5 cegger /* Use the DSDT address if it is version 1, otherwise use XDSDT. */
4023 1.15.8.1 martin sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(
4024 1.15.8.1 martin acpi_select_address(fadt->Dsdt, fadt->XDsdt));
4025 1.5 cegger if (acpi_checksum(sdt, sdt->Length))
4026 1.10 christos errx(EXIT_FAILURE, "DSDT is corrupt");
4027 1.5 cegger return (sdt);
4028 1.1 christos }
4029