xref: /freebsd/usr.sbin/acpi/acpidump/acpi.c (revision 861f5b95b39fd8a6b10b7bddf29e284e5ba2c49a)
1e1e9a4bfSMitsuru IWASAKI /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
31de7b4b8SPedro F. Giffuni  *
4e1e9a4bfSMitsuru IWASAKI  * Copyright (c) 1998 Doug Rabson
5e1e9a4bfSMitsuru IWASAKI  * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
6ebc22d04SAlexander Motin  * Copyright (c) 2020 Alexander Motin <mav@FreeBSD.org>
7e1e9a4bfSMitsuru IWASAKI  * All rights reserved.
8e1e9a4bfSMitsuru IWASAKI  *
9e1e9a4bfSMitsuru IWASAKI  * Redistribution and use in source and binary forms, with or without
10e1e9a4bfSMitsuru IWASAKI  * modification, are permitted provided that the following conditions
11e1e9a4bfSMitsuru IWASAKI  * are met:
12e1e9a4bfSMitsuru IWASAKI  * 1. Redistributions of source code must retain the above copyright
13e1e9a4bfSMitsuru IWASAKI  *    notice, this list of conditions and the following disclaimer.
14e1e9a4bfSMitsuru IWASAKI  * 2. Redistributions in binary form must reproduce the above copyright
15e1e9a4bfSMitsuru IWASAKI  *    notice, this list of conditions and the following disclaimer in the
16e1e9a4bfSMitsuru IWASAKI  *    documentation and/or other materials provided with the distribution.
17e1e9a4bfSMitsuru IWASAKI  *
18e1e9a4bfSMitsuru IWASAKI  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19e1e9a4bfSMitsuru IWASAKI  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20e1e9a4bfSMitsuru IWASAKI  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21e1e9a4bfSMitsuru IWASAKI  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22e1e9a4bfSMitsuru IWASAKI  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23e1e9a4bfSMitsuru IWASAKI  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24e1e9a4bfSMitsuru IWASAKI  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25e1e9a4bfSMitsuru IWASAKI  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26e1e9a4bfSMitsuru IWASAKI  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27e1e9a4bfSMitsuru IWASAKI  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28e1e9a4bfSMitsuru IWASAKI  * SUCH DAMAGE.
29e1e9a4bfSMitsuru IWASAKI  */
30e1e9a4bfSMitsuru IWASAKI 
31e1e9a4bfSMitsuru IWASAKI #include <sys/param.h>
32a74172abSNate Lawson #include <sys/endian.h>
33e1e9a4bfSMitsuru IWASAKI #include <sys/stat.h>
34945137d9SNate Lawson #include <sys/wait.h>
35e1e9a4bfSMitsuru IWASAKI #include <assert.h>
36e1e9a4bfSMitsuru IWASAKI #include <err.h>
37e1e9a4bfSMitsuru IWASAKI #include <fcntl.h>
3899065116SJung-uk Kim #include <paths.h>
39e1e9a4bfSMitsuru IWASAKI #include <stdio.h>
40a0333ad1SJohn Baldwin #include <stdint.h>
4199065116SJung-uk Kim #include <stdlib.h>
42945137d9SNate Lawson #include <string.h>
43e1e9a4bfSMitsuru IWASAKI #include <unistd.h>
44340c0022SEd Maste #include <uuid.h>
45e1e9a4bfSMitsuru IWASAKI 
46e1e9a4bfSMitsuru IWASAKI #include "acpidump.h"
47e1e9a4bfSMitsuru IWASAKI 
48c62f1cccSMitsuru IWASAKI #define BEGIN_COMMENT	"/*\n"
49c62f1cccSMitsuru IWASAKI #define END_COMMENT	" */\n"
50c62f1cccSMitsuru IWASAKI 
51945137d9SNate Lawson static void	acpi_print_string(char *s, size_t length);
52986dffafSJohn Baldwin static void	acpi_print_gas(ACPI_GENERIC_ADDRESS *gas);
53986dffafSJohn Baldwin static int	acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt);
54986dffafSJohn Baldwin static void	acpi_handle_fadt(ACPI_TABLE_HEADER *fadt);
55945137d9SNate Lawson static void	acpi_print_cpu(u_char cpu_id);
56986dffafSJohn Baldwin static void	acpi_print_cpu_uid(uint32_t uid, char *uid_string);
57986dffafSJohn Baldwin static void	acpi_print_local_apic(uint32_t apic_id, uint32_t flags);
58986dffafSJohn Baldwin static void	acpi_print_io_apic(uint32_t apic_id, uint32_t int_base,
59986dffafSJohn Baldwin 		    uint64_t apic_addr);
60986dffafSJohn Baldwin static void	acpi_print_mps_flags(uint16_t flags);
61986dffafSJohn Baldwin static void	acpi_print_intr(uint32_t intr, uint16_t mps_flags);
62986dffafSJohn Baldwin static void	acpi_print_local_nmi(u_int lint, uint16_t mps_flags);
63986dffafSJohn Baldwin static void	acpi_print_madt(ACPI_SUBTABLE_HEADER *mp);
64986dffafSJohn Baldwin static void	acpi_handle_madt(ACPI_TABLE_HEADER *sdp);
65986dffafSJohn Baldwin static void	acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp);
66986dffafSJohn Baldwin static void	acpi_handle_hpet(ACPI_TABLE_HEADER *sdp);
67986dffafSJohn Baldwin static void	acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp);
6833866658SJohn Baldwin static void	acpi_handle_slit(ACPI_TABLE_HEADER *sdp);
69ed26c389SScott Long static void	acpi_handle_wddt(ACPI_TABLE_HEADER *sdp);
705857fba5SBen Widawsky static void	acpi_handle_lpit(ACPI_TABLE_HEADER *sdp);
71a0333ad1SJohn Baldwin static void	acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain,
72a0333ad1SJohn Baldwin 		    uint32_t flags);
73986dffafSJohn Baldwin static void	acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp);
74986dffafSJohn Baldwin static void	acpi_print_srat(ACPI_SUBTABLE_HEADER *srat);
75986dffafSJohn Baldwin static void	acpi_handle_srat(ACPI_TABLE_HEADER *sdp);
76c031c93bSTakanori Watanabe static void	acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp);
77340c0022SEd Maste static void	acpi_print_nfit(ACPI_NFIT_HEADER *nfit);
78340c0022SEd Maste static void	acpi_handle_nfit(ACPI_TABLE_HEADER *sdp);
79986dffafSJohn Baldwin static void	acpi_print_sdt(ACPI_TABLE_HEADER *sdp);
80986dffafSJohn Baldwin static void	acpi_print_fadt(ACPI_TABLE_HEADER *sdp);
81986dffafSJohn Baldwin static void	acpi_print_facs(ACPI_TABLE_FACS *facs);
82986dffafSJohn Baldwin static void	acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp);
83986dffafSJohn Baldwin static ACPI_TABLE_HEADER *acpi_map_sdt(vm_offset_t pa);
84986dffafSJohn Baldwin static void	acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp);
85986dffafSJohn Baldwin static void	acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp);
86986dffafSJohn Baldwin static void	acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
87986dffafSJohn Baldwin 		    void (*action)(ACPI_SUBTABLE_HEADER *));
88340c0022SEd Maste static void	acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first,
89340c0022SEd Maste 		    void (*action)(ACPI_NFIT_HEADER *));
90c62f1cccSMitsuru IWASAKI 
91773b6454SNate Lawson /* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up. */
92a74172abSNate Lawson static int addr_size;
93a74172abSNate Lawson 
94c031c93bSTakanori Watanabe /* Strings used in the TCPA table */
95c031c93bSTakanori Watanabe static const char *tcpa_event_type_strings[] = {
96c031c93bSTakanori Watanabe 	"PREBOOT Certificate",
97c031c93bSTakanori Watanabe 	"POST Code",
98c031c93bSTakanori Watanabe 	"Unused",
99c031c93bSTakanori Watanabe 	"No Action",
100c031c93bSTakanori Watanabe 	"Separator",
101c031c93bSTakanori Watanabe 	"Action",
102c031c93bSTakanori Watanabe 	"Event Tag",
103c031c93bSTakanori Watanabe 	"S-CRTM Contents",
104c031c93bSTakanori Watanabe 	"S-CRTM Version",
105c031c93bSTakanori Watanabe 	"CPU Microcode",
106c031c93bSTakanori Watanabe 	"Platform Config Flags",
107c031c93bSTakanori Watanabe 	"Table of Devices",
108c031c93bSTakanori Watanabe 	"Compact Hash",
109c031c93bSTakanori Watanabe 	"IPL",
110c031c93bSTakanori Watanabe 	"IPL Partition Data",
111c031c93bSTakanori Watanabe 	"Non-Host Code",
112c031c93bSTakanori Watanabe 	"Non-Host Config",
113c031c93bSTakanori Watanabe 	"Non-Host Info"
114c031c93bSTakanori Watanabe };
115c031c93bSTakanori Watanabe 
116c031c93bSTakanori Watanabe static const char *TCPA_pcclient_strings[] = {
117c031c93bSTakanori Watanabe 	"<undefined>",
118c031c93bSTakanori Watanabe 	"SMBIOS",
119c031c93bSTakanori Watanabe 	"BIS Certificate",
120c031c93bSTakanori Watanabe 	"POST BIOS ROM Strings",
121c031c93bSTakanori Watanabe 	"ESCD",
122c031c93bSTakanori Watanabe 	"CMOS",
123c031c93bSTakanori Watanabe 	"NVRAM",
124c031c93bSTakanori Watanabe 	"Option ROM Execute",
125c031c93bSTakanori Watanabe 	"Option ROM Configurateion",
126c031c93bSTakanori Watanabe 	"<undefined>",
127c031c93bSTakanori Watanabe 	"Option ROM Microcode Update ",
128c031c93bSTakanori Watanabe 	"S-CRTM Version String",
129c031c93bSTakanori Watanabe 	"S-CRTM Contents",
130c031c93bSTakanori Watanabe 	"POST Contents",
131c031c93bSTakanori Watanabe 	"Table of Devices",
132c031c93bSTakanori Watanabe };
133c031c93bSTakanori Watanabe 
134ec650989SNeel Natu #define	PRINTFLAG_END()		printflag_end()
135ec650989SNeel Natu 
136ec650989SNeel Natu static char pf_sep = '{';
137ec650989SNeel Natu 
138ec650989SNeel Natu static void
139ec650989SNeel Natu printflag_end(void)
140ec650989SNeel Natu {
141ec650989SNeel Natu 
142ec650989SNeel Natu 	if (pf_sep != '{') {
143ec650989SNeel Natu 		printf("}");
144ec650989SNeel Natu 		pf_sep = '{';
145ec650989SNeel Natu 	}
146ec650989SNeel Natu 	printf("\n");
147ec650989SNeel Natu }
148ec650989SNeel Natu 
149ec650989SNeel Natu static void
150ec650989SNeel Natu printflag(uint64_t var, uint64_t mask, const char *name)
151ec650989SNeel Natu {
152ec650989SNeel Natu 
153ec650989SNeel Natu 	if (var & mask) {
154ec650989SNeel Natu 		printf("%c%s", pf_sep, name);
155ec650989SNeel Natu 		pf_sep = ',';
156ec650989SNeel Natu 	}
157ec650989SNeel Natu }
158ec650989SNeel Natu 
159e1e9a4bfSMitsuru IWASAKI static void
160e1e9a4bfSMitsuru IWASAKI acpi_print_string(char *s, size_t length)
161e1e9a4bfSMitsuru IWASAKI {
162e1e9a4bfSMitsuru IWASAKI 	int	c;
163e1e9a4bfSMitsuru IWASAKI 
164e1e9a4bfSMitsuru IWASAKI 	/* Trim trailing spaces and NULLs */
165e1e9a4bfSMitsuru IWASAKI 	while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0'))
166e1e9a4bfSMitsuru IWASAKI 		length--;
167e1e9a4bfSMitsuru IWASAKI 
168e1e9a4bfSMitsuru IWASAKI 	while (length--) {
169e1e9a4bfSMitsuru IWASAKI 		c = *s++;
170e1e9a4bfSMitsuru IWASAKI 		putchar(c);
171e1e9a4bfSMitsuru IWASAKI 	}
172e1e9a4bfSMitsuru IWASAKI }
173e1e9a4bfSMitsuru IWASAKI 
174e1e9a4bfSMitsuru IWASAKI static void
175986dffafSJohn Baldwin acpi_print_gas(ACPI_GENERIC_ADDRESS *gas)
1768e6a8737SNate Lawson {
177986dffafSJohn Baldwin 	switch(gas->SpaceId) {
1788e6a8737SNate Lawson 	case ACPI_GAS_MEMORY:
179ebc22d04SAlexander Motin 		printf("0x%016jx:%u[%u] (Memory)", (uintmax_t)gas->Address,
180ebc22d04SAlexander Motin 		    gas->BitOffset, gas->BitWidth);
1818e6a8737SNate Lawson 		break;
1828e6a8737SNate Lawson 	case ACPI_GAS_IO:
183ebc22d04SAlexander Motin 		printf("0x%02jx:%u[%u] (IO)", (uintmax_t)gas->Address,
184986dffafSJohn Baldwin 		    gas->BitOffset, gas->BitWidth);
1858e6a8737SNate Lawson 		break;
1868e6a8737SNate Lawson 	case ACPI_GAS_PCI:
187ebc22d04SAlexander Motin 		printf("%x:%x+0x%x:%u[%u] (PCI)", (uint16_t)(gas->Address >> 32),
188986dffafSJohn Baldwin 		       (uint16_t)((gas->Address >> 16) & 0xffff),
189ebc22d04SAlexander Motin 		       (uint16_t)gas->Address, gas->BitOffset, gas->BitWidth);
1908e6a8737SNate Lawson 		break;
1918e6a8737SNate Lawson 	/* XXX How to handle these below? */
1928e6a8737SNate Lawson 	case ACPI_GAS_EMBEDDED:
193986dffafSJohn Baldwin 		printf("0x%x:%u[%u] (EC)", (uint16_t)gas->Address,
194986dffafSJohn Baldwin 		       gas->BitOffset, gas->BitWidth);
1958e6a8737SNate Lawson 		break;
1968e6a8737SNate Lawson 	case ACPI_GAS_SMBUS:
197986dffafSJohn Baldwin 		printf("0x%x:%u[%u] (SMBus)", (uint16_t)gas->Address,
198986dffafSJohn Baldwin 		       gas->BitOffset, gas->BitWidth);
1998e6a8737SNate Lawson 		break;
200986dffafSJohn Baldwin 	case ACPI_GAS_CMOS:
201986dffafSJohn Baldwin 	case ACPI_GAS_PCIBAR:
202986dffafSJohn Baldwin 	case ACPI_GAS_DATATABLE:
2038e6a8737SNate Lawson 	case ACPI_GAS_FIXED:
2048e6a8737SNate Lawson 	default:
2057d369c6eSJung-uk Kim 		printf("0x%016jx (?)", (uintmax_t)gas->Address);
2068e6a8737SNate Lawson 		break;
2078e6a8737SNate Lawson 	}
2088e6a8737SNate Lawson }
2098e6a8737SNate Lawson 
210c2962974SNate Lawson /* The FADT revision indicates whether we use the DSDT or X_DSDT addresses. */
211c2962974SNate Lawson static int
212986dffafSJohn Baldwin acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt)
213e1e9a4bfSMitsuru IWASAKI {
214c2962974SNate Lawson 	int fadt_revision;
215e1e9a4bfSMitsuru IWASAKI 
216c83f0f99SNate Lawson 	/* Set the FADT revision separately from the RSDP version. */
217c83f0f99SNate Lawson 	if (addr_size == 8) {
218c83f0f99SNate Lawson 		fadt_revision = 2;
2198e6a8737SNate Lawson 
22001593a0fSAndrew Turner #if defined(__i386__)
221773b6454SNate Lawson 		/*
222c83f0f99SNate Lawson 		 * A few systems (e.g., IBM T23) have an RSDP that claims
223c83f0f99SNate Lawson 		 * revision 2 but the 64 bit addresses are invalid.  If
224c83f0f99SNate Lawson 		 * revision 2 and the 32 bit address is non-zero but the
225c83f0f99SNate Lawson 		 * 32 and 64 bit versions don't match, prefer the 32 bit
226c83f0f99SNate Lawson 		 * version for all subsequent tables.
22701593a0fSAndrew Turner 		 *
22801593a0fSAndrew Turner 		 * The only known ACPI systems this affects are early
22901593a0fSAndrew Turner 		 * implementations on 32-bit x86. Because of this limit the
23001593a0fSAndrew Turner 		 * workaround to i386.
231773b6454SNate Lawson 		 */
232986dffafSJohn Baldwin 		if (fadt->Facs != 0 &&
233986dffafSJohn Baldwin 		    (fadt->XFacs & 0xffffffff) != fadt->Facs)
234c83f0f99SNate Lawson 			fadt_revision = 1;
23501593a0fSAndrew Turner #endif
236c2962974SNate Lawson 	} else
237c83f0f99SNate Lawson 		fadt_revision = 1;
238c2962974SNate Lawson 	return (fadt_revision);
239c83f0f99SNate Lawson }
240c2962974SNate Lawson 
241c2962974SNate Lawson static void
242986dffafSJohn Baldwin acpi_handle_fadt(ACPI_TABLE_HEADER *sdp)
243c2962974SNate Lawson {
244986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *dsdp;
245986dffafSJohn Baldwin 	ACPI_TABLE_FACS	*facs;
246986dffafSJohn Baldwin 	ACPI_TABLE_FADT *fadt;
247bc711181SAndrew Turner 	vm_offset_t	addr;
248c2962974SNate Lawson 	int		fadt_revision;
249c2962974SNate Lawson 
250986dffafSJohn Baldwin 	fadt = (ACPI_TABLE_FADT *)sdp;
2512177d4e6SNate Lawson 	acpi_print_fadt(sdp);
252c83f0f99SNate Lawson 
253c2962974SNate Lawson 	fadt_revision = acpi_get_fadt_revision(fadt);
254c83f0f99SNate Lawson 	if (fadt_revision == 1)
255bc711181SAndrew Turner 		addr = fadt->Facs;
256773b6454SNate Lawson 	else
257bc711181SAndrew Turner 		addr = fadt->XFacs;
258bc711181SAndrew Turner 	if (addr != 0) {
259bc711181SAndrew Turner 		facs = (ACPI_TABLE_FACS *)acpi_map_sdt(addr);
260bc711181SAndrew Turner 
261bc711181SAndrew Turner 		if (memcmp(facs->Signature, ACPI_SIG_FACS, 4) != 0 ||
262bc711181SAndrew Turner 		    facs->Length < 64)
2638e6a8737SNate Lawson 			errx(1, "FACS is corrupt");
2648e6a8737SNate Lawson 		acpi_print_facs(facs);
265bc711181SAndrew Turner 	}
2668e6a8737SNate Lawson 
267c83f0f99SNate Lawson 	if (fadt_revision == 1)
268986dffafSJohn Baldwin 		dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt);
269773b6454SNate Lawson 	else
270986dffafSJohn Baldwin 		dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt);
271986dffafSJohn Baldwin 	if (acpi_checksum(dsdp, dsdp->Length))
272945137d9SNate Lawson 		errx(1, "DSDT is corrupt");
273945137d9SNate Lawson 	acpi_print_dsdt(dsdp);
274c62f1cccSMitsuru IWASAKI }
275c62f1cccSMitsuru IWASAKI 
276c62f1cccSMitsuru IWASAKI static void
277986dffafSJohn Baldwin acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
278986dffafSJohn Baldwin     void (*action)(ACPI_SUBTABLE_HEADER *))
279986dffafSJohn Baldwin {
280986dffafSJohn Baldwin 	ACPI_SUBTABLE_HEADER *subtable;
281986dffafSJohn Baldwin 	char *end;
282986dffafSJohn Baldwin 
283986dffafSJohn Baldwin 	subtable = first;
284986dffafSJohn Baldwin 	end = (char *)table + table->Length;
285986dffafSJohn Baldwin 	while ((char *)subtable < end) {
286986dffafSJohn Baldwin 		printf("\n");
287f5d0a8f7SEd Maste 		if (subtable->Length < sizeof(ACPI_SUBTABLE_HEADER)) {
288f5d0a8f7SEd Maste 			warnx("invalid subtable length %u", subtable->Length);
289f5d0a8f7SEd Maste 			return;
290f5d0a8f7SEd Maste 		}
291986dffafSJohn Baldwin 		action(subtable);
292986dffafSJohn Baldwin 		subtable = (ACPI_SUBTABLE_HEADER *)((char *)subtable +
293986dffafSJohn Baldwin 		    subtable->Length);
294986dffafSJohn Baldwin 	}
295986dffafSJohn Baldwin }
296986dffafSJohn Baldwin 
297986dffafSJohn Baldwin static void
298340c0022SEd Maste acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first,
299340c0022SEd Maste     void (*action)(ACPI_NFIT_HEADER *))
300340c0022SEd Maste {
301340c0022SEd Maste 	ACPI_NFIT_HEADER *subtable;
302340c0022SEd Maste 	char *end;
303340c0022SEd Maste 
304340c0022SEd Maste 	subtable = first;
305340c0022SEd Maste 	end = (char *)table + table->Length;
306340c0022SEd Maste 	while ((char *)subtable < end) {
307340c0022SEd Maste 		printf("\n");
308340c0022SEd Maste 		if (subtable->Length < sizeof(ACPI_NFIT_HEADER)) {
309340c0022SEd Maste 			warnx("invalid subtable length %u", subtable->Length);
310340c0022SEd Maste 			return;
311340c0022SEd Maste 		}
312340c0022SEd Maste 		action(subtable);
313340c0022SEd Maste 		subtable = (ACPI_NFIT_HEADER *)((char *)subtable +
314340c0022SEd Maste 		    subtable->Length);
315340c0022SEd Maste 	}
316340c0022SEd Maste }
317340c0022SEd Maste 
318340c0022SEd Maste static void
3190a473124SJohn Baldwin acpi_print_cpu(u_char cpu_id)
3200a473124SJohn Baldwin {
3210a473124SJohn Baldwin 
3220a473124SJohn Baldwin 	printf("\tACPI CPU=");
3230a473124SJohn Baldwin 	if (cpu_id == 0xff)
3240a473124SJohn Baldwin 		printf("ALL\n");
3250a473124SJohn Baldwin 	else
3260a473124SJohn Baldwin 		printf("%d\n", (u_int)cpu_id);
3270a473124SJohn Baldwin }
3280a473124SJohn Baldwin 
3290a473124SJohn Baldwin static void
330986dffafSJohn Baldwin acpi_print_cpu_uid(uint32_t uid, char *uid_string)
3310a473124SJohn Baldwin {
332986dffafSJohn Baldwin 
333986dffafSJohn Baldwin 	printf("\tUID=%d", uid);
334986dffafSJohn Baldwin 	if (uid_string != NULL)
335986dffafSJohn Baldwin 		printf(" (%s)", uid_string);
336986dffafSJohn Baldwin 	printf("\n");
337986dffafSJohn Baldwin }
338986dffafSJohn Baldwin 
339986dffafSJohn Baldwin static void
340986dffafSJohn Baldwin acpi_print_local_apic(uint32_t apic_id, uint32_t flags)
341986dffafSJohn Baldwin {
342986dffafSJohn Baldwin 
3430a473124SJohn Baldwin 	printf("\tFlags={");
344986dffafSJohn Baldwin 	if (flags & ACPI_MADT_ENABLED)
3450a473124SJohn Baldwin 		printf("ENABLED");
3460a473124SJohn Baldwin 	else
3470a473124SJohn Baldwin 		printf("DISABLED");
3480a473124SJohn Baldwin 	printf("}\n");
349986dffafSJohn Baldwin 	printf("\tAPIC ID=%d\n", apic_id);
3500a473124SJohn Baldwin }
3510a473124SJohn Baldwin 
3520a473124SJohn Baldwin static void
353986dffafSJohn Baldwin acpi_print_io_apic(uint32_t apic_id, uint32_t int_base, uint64_t apic_addr)
3540a473124SJohn Baldwin {
355986dffafSJohn Baldwin 
356986dffafSJohn Baldwin 	printf("\tAPIC ID=%d\n", apic_id);
3570a473124SJohn Baldwin 	printf("\tINT BASE=%d\n", int_base);
358986dffafSJohn Baldwin 	printf("\tADDR=0x%016jx\n", (uintmax_t)apic_addr);
3590a473124SJohn Baldwin }
3600a473124SJohn Baldwin 
3610a473124SJohn Baldwin static void
362986dffafSJohn Baldwin acpi_print_mps_flags(uint16_t flags)
3630a473124SJohn Baldwin {
3640a473124SJohn Baldwin 
3650a473124SJohn Baldwin 	printf("\tFlags={Polarity=");
366986dffafSJohn Baldwin 	switch (flags & ACPI_MADT_POLARITY_MASK) {
367986dffafSJohn Baldwin 	case ACPI_MADT_POLARITY_CONFORMS:
3680a473124SJohn Baldwin 		printf("conforming");
3690a473124SJohn Baldwin 		break;
370986dffafSJohn Baldwin 	case ACPI_MADT_POLARITY_ACTIVE_HIGH:
3710a473124SJohn Baldwin 		printf("active-hi");
3720a473124SJohn Baldwin 		break;
373986dffafSJohn Baldwin 	case ACPI_MADT_POLARITY_ACTIVE_LOW:
3740a473124SJohn Baldwin 		printf("active-lo");
3750a473124SJohn Baldwin 		break;
3760a473124SJohn Baldwin 	default:
377986dffafSJohn Baldwin 		printf("0x%x", flags & ACPI_MADT_POLARITY_MASK);
3780a473124SJohn Baldwin 		break;
3790a473124SJohn Baldwin 	}
3800a473124SJohn Baldwin 	printf(", Trigger=");
381986dffafSJohn Baldwin 	switch (flags & ACPI_MADT_TRIGGER_MASK) {
382986dffafSJohn Baldwin 	case ACPI_MADT_TRIGGER_CONFORMS:
3830a473124SJohn Baldwin 		printf("conforming");
3840a473124SJohn Baldwin 		break;
385986dffafSJohn Baldwin 	case ACPI_MADT_TRIGGER_EDGE:
3860a473124SJohn Baldwin 		printf("edge");
3870a473124SJohn Baldwin 		break;
388986dffafSJohn Baldwin 	case ACPI_MADT_TRIGGER_LEVEL:
3890a473124SJohn Baldwin 		printf("level");
3900a473124SJohn Baldwin 		break;
3910a473124SJohn Baldwin 	default:
392986dffafSJohn Baldwin 		printf("0x%x", (flags & ACPI_MADT_TRIGGER_MASK) >> 2);
3930a473124SJohn Baldwin 	}
3940a473124SJohn Baldwin 	printf("}\n");
3950a473124SJohn Baldwin }
3960a473124SJohn Baldwin 
3970a473124SJohn Baldwin static void
3982b2b1f42SAndrew Turner acpi_print_gicc_flags(uint32_t flags)
3992b2b1f42SAndrew Turner {
4002b2b1f42SAndrew Turner 
4012b2b1f42SAndrew Turner 	printf("\tFlags={Performance intr=");
4022b2b1f42SAndrew Turner 	if (flags & ACPI_MADT_PERFORMANCE_IRQ_MODE)
4032b2b1f42SAndrew Turner 		printf("edge");
4042b2b1f42SAndrew Turner 	else
4052b2b1f42SAndrew Turner 		printf("level");
4062b2b1f42SAndrew Turner 	printf(", VGIC intr=");
4072b2b1f42SAndrew Turner 	if (flags & ACPI_MADT_VGIC_IRQ_MODE)
4082b2b1f42SAndrew Turner 		printf("edge");
4092b2b1f42SAndrew Turner 	else
4102b2b1f42SAndrew Turner 		printf("level");
4112b2b1f42SAndrew Turner 	printf("}\n");
4122b2b1f42SAndrew Turner }
4132b2b1f42SAndrew Turner 
4142b2b1f42SAndrew Turner static void
415986dffafSJohn Baldwin acpi_print_intr(uint32_t intr, uint16_t mps_flags)
4160a473124SJohn Baldwin {
4170a473124SJohn Baldwin 
418986dffafSJohn Baldwin 	printf("\tINTR=%d\n", intr);
419986dffafSJohn Baldwin 	acpi_print_mps_flags(mps_flags);
420986dffafSJohn Baldwin }
421986dffafSJohn Baldwin 
422986dffafSJohn Baldwin static void
423986dffafSJohn Baldwin acpi_print_local_nmi(u_int lint, uint16_t mps_flags)
424986dffafSJohn Baldwin {
425986dffafSJohn Baldwin 
426986dffafSJohn Baldwin 	printf("\tLINT Pin=%d\n", lint);
4270a473124SJohn Baldwin 	acpi_print_mps_flags(mps_flags);
4280a473124SJohn Baldwin }
4290a473124SJohn Baldwin 
43027941afaSEd Maste static const char *apic_types[] = {
43127941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_APIC] = "Local APIC",
43227941afaSEd Maste     [ACPI_MADT_TYPE_IO_APIC] = "IO APIC",
43327941afaSEd Maste     [ACPI_MADT_TYPE_INTERRUPT_OVERRIDE] = "INT Override",
43427941afaSEd Maste     [ACPI_MADT_TYPE_NMI_SOURCE] = "NMI",
43527941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_APIC_NMI] = "Local APIC NMI",
43627941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE] = "Local APIC Override",
43727941afaSEd Maste     [ACPI_MADT_TYPE_IO_SAPIC] = "IO SAPIC",
43827941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_SAPIC] = "Local SAPIC",
43927941afaSEd Maste     [ACPI_MADT_TYPE_INTERRUPT_SOURCE] = "Platform Interrupt",
44027941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_X2APIC] = "Local X2APIC",
44127941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_X2APIC_NMI] = "Local X2APIC NMI",
44227941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_INTERRUPT] = "GIC CPU Interface Structure",
44327941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR] = "GIC Distributor Structure",
44427941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_MSI_FRAME] = "GICv2m MSI Frame",
44527941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR] = "GIC Redistributor Structure",
44627941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_TRANSLATOR] = "GIC ITS Structure"
44727941afaSEd Maste };
44827941afaSEd Maste 
449bf70beceSEd Schouten static const char *platform_int_types[] = { "0 (unknown)", "PMI", "INIT",
4500a473124SJohn Baldwin 					    "Corrected Platform Error" };
4510a473124SJohn Baldwin 
4520a473124SJohn Baldwin static void
453986dffafSJohn Baldwin acpi_print_madt(ACPI_SUBTABLE_HEADER *mp)
4540a473124SJohn Baldwin {
455986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_APIC *lapic;
456986dffafSJohn Baldwin 	ACPI_MADT_IO_APIC *ioapic;
457986dffafSJohn Baldwin 	ACPI_MADT_INTERRUPT_OVERRIDE *over;
458986dffafSJohn Baldwin 	ACPI_MADT_NMI_SOURCE *nmi;
459986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_APIC_NMI *lapic_nmi;
460986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic_over;
461986dffafSJohn Baldwin 	ACPI_MADT_IO_SAPIC *iosapic;
462986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_SAPIC *lsapic;
463986dffafSJohn Baldwin 	ACPI_MADT_INTERRUPT_SOURCE *isrc;
464986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_X2APIC *x2apic;
465986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_X2APIC_NMI *x2apic_nmi;
4662b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_INTERRUPT *gicc;
4672b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_DISTRIBUTOR *gicd;
4682b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_REDISTRIBUTOR *gicr;
4692b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_TRANSLATOR *gict;
4700a473124SJohn Baldwin 
471c86932b6SMarcelo Araujo 	if (mp->Type < nitems(apic_types))
472986dffafSJohn Baldwin 		printf("\tType=%s\n", apic_types[mp->Type]);
473a0333ad1SJohn Baldwin 	else
474986dffafSJohn Baldwin 		printf("\tType=%d (unknown)\n", mp->Type);
475986dffafSJohn Baldwin 	switch (mp->Type) {
476986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_APIC:
477986dffafSJohn Baldwin 		lapic = (ACPI_MADT_LOCAL_APIC *)mp;
478986dffafSJohn Baldwin 		acpi_print_cpu(lapic->ProcessorId);
479986dffafSJohn Baldwin 		acpi_print_local_apic(lapic->Id, lapic->LapicFlags);
4800a473124SJohn Baldwin 		break;
481986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_IO_APIC:
482986dffafSJohn Baldwin 		ioapic = (ACPI_MADT_IO_APIC *)mp;
483986dffafSJohn Baldwin 		acpi_print_io_apic(ioapic->Id, ioapic->GlobalIrqBase,
484986dffafSJohn Baldwin 		    ioapic->Address);
4850a473124SJohn Baldwin 		break;
486986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
487986dffafSJohn Baldwin 		over = (ACPI_MADT_INTERRUPT_OVERRIDE *)mp;
488986dffafSJohn Baldwin 		printf("\tBUS=%d\n", (u_int)over->Bus);
489986dffafSJohn Baldwin 		printf("\tIRQ=%d\n", (u_int)over->SourceIrq);
490986dffafSJohn Baldwin 		acpi_print_intr(over->GlobalIrq, over->IntiFlags);
4910a473124SJohn Baldwin 		break;
492986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_NMI_SOURCE:
493986dffafSJohn Baldwin 		nmi = (ACPI_MADT_NMI_SOURCE *)mp;
494986dffafSJohn Baldwin 		acpi_print_intr(nmi->GlobalIrq, nmi->IntiFlags);
4950a473124SJohn Baldwin 		break;
496986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
497986dffafSJohn Baldwin 		lapic_nmi = (ACPI_MADT_LOCAL_APIC_NMI *)mp;
498986dffafSJohn Baldwin 		acpi_print_cpu(lapic_nmi->ProcessorId);
499986dffafSJohn Baldwin 		acpi_print_local_nmi(lapic_nmi->Lint, lapic_nmi->IntiFlags);
5000a473124SJohn Baldwin 		break;
501986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
502986dffafSJohn Baldwin 		lapic_over = (ACPI_MADT_LOCAL_APIC_OVERRIDE *)mp;
503945137d9SNate Lawson 		printf("\tLocal APIC ADDR=0x%016jx\n",
504986dffafSJohn Baldwin 		    (uintmax_t)lapic_over->Address);
5050a473124SJohn Baldwin 		break;
506986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_IO_SAPIC:
507986dffafSJohn Baldwin 		iosapic = (ACPI_MADT_IO_SAPIC *)mp;
508986dffafSJohn Baldwin 		acpi_print_io_apic(iosapic->Id, iosapic->GlobalIrqBase,
509986dffafSJohn Baldwin 		    iosapic->Address);
5100a473124SJohn Baldwin 		break;
511986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_SAPIC:
512986dffafSJohn Baldwin 		lsapic = (ACPI_MADT_LOCAL_SAPIC *)mp;
513986dffafSJohn Baldwin 		acpi_print_cpu(lsapic->ProcessorId);
514986dffafSJohn Baldwin 		acpi_print_local_apic(lsapic->Id, lsapic->LapicFlags);
515986dffafSJohn Baldwin 		printf("\tAPIC EID=%d\n", (u_int)lsapic->Eid);
516986dffafSJohn Baldwin 		if (mp->Length > __offsetof(ACPI_MADT_LOCAL_SAPIC, Uid))
517986dffafSJohn Baldwin 			acpi_print_cpu_uid(lsapic->Uid, lsapic->UidString);
5180a473124SJohn Baldwin 		break;
519986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
520986dffafSJohn Baldwin 		isrc = (ACPI_MADT_INTERRUPT_SOURCE *)mp;
521c86932b6SMarcelo Araujo 		if (isrc->Type < nitems(platform_int_types))
522986dffafSJohn Baldwin 			printf("\tType=%s\n", platform_int_types[isrc->Type]);
523986dffafSJohn Baldwin 		else
524986dffafSJohn Baldwin 			printf("\tType=%d (unknown)\n", isrc->Type);
525986dffafSJohn Baldwin 		printf("\tAPIC ID=%d\n", (u_int)isrc->Id);
526986dffafSJohn Baldwin 		printf("\tAPIC EID=%d\n", (u_int)isrc->Eid);
527986dffafSJohn Baldwin 		printf("\tSAPIC Vector=%d\n", (u_int)isrc->IoSapicVector);
528986dffafSJohn Baldwin 		acpi_print_intr(isrc->GlobalIrq, isrc->IntiFlags);
529986dffafSJohn Baldwin 		break;
530986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_X2APIC:
531986dffafSJohn Baldwin 		x2apic = (ACPI_MADT_LOCAL_X2APIC *)mp;
532986dffafSJohn Baldwin 		acpi_print_cpu_uid(x2apic->Uid, NULL);
533986dffafSJohn Baldwin 		acpi_print_local_apic(x2apic->LocalApicId, x2apic->LapicFlags);
534986dffafSJohn Baldwin 		break;
535986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
536986dffafSJohn Baldwin 		x2apic_nmi = (ACPI_MADT_LOCAL_X2APIC_NMI *)mp;
537986dffafSJohn Baldwin 		acpi_print_cpu_uid(x2apic_nmi->Uid, NULL);
538986dffafSJohn Baldwin 		acpi_print_local_nmi(x2apic_nmi->Lint, x2apic_nmi->IntiFlags);
5390a473124SJohn Baldwin 		break;
5402b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
5412b2b1f42SAndrew Turner 		gicc = (ACPI_MADT_GENERIC_INTERRUPT *)mp;
5422b2b1f42SAndrew Turner 		acpi_print_cpu_uid(gicc->Uid, NULL);
5432b2b1f42SAndrew Turner 		printf("\tCPU INTERFACE=%x\n", gicc->CpuInterfaceNumber);
5442b2b1f42SAndrew Turner 		acpi_print_gicc_flags(gicc->Flags);
5452b2b1f42SAndrew Turner 		printf("\tParking Protocol Version=%x\n", gicc->ParkingVersion);
5462b2b1f42SAndrew Turner 		printf("\tPERF INTR=%d\n", gicc->PerformanceInterrupt);
5472b2b1f42SAndrew Turner 		printf("\tParked ADDR=%016jx\n",
5482b2b1f42SAndrew Turner 		    (uintmax_t)gicc->ParkedAddress);
5492b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicc->BaseAddress);
5502b2b1f42SAndrew Turner 		printf("\tGICV=%016jx\n", (uintmax_t)gicc->GicvBaseAddress);
5512b2b1f42SAndrew Turner 		printf("\tGICH=%016jx\n", (uintmax_t)gicc->GichBaseAddress);
5522b2b1f42SAndrew Turner 		printf("\tVGIC INTR=%d\n", gicc->VgicInterrupt);
5532b2b1f42SAndrew Turner 		printf("\tGICR ADDR=%016jx\n",
5542b2b1f42SAndrew Turner 		    (uintmax_t)gicc->GicrBaseAddress);
5552b2b1f42SAndrew Turner 		printf("\tMPIDR=%jx\n", (uintmax_t)gicc->ArmMpidr);
5560b4302aaSGordon Bergling 		printf("\tEfficiency Class=%d\n", (u_int)gicc->EfficiencyClass);
557c363da4aSAndrew Turner 		printf("\tSPE INTR=%d\n", gicc->SpeInterrupt);
5582b2b1f42SAndrew Turner 		break;
5592b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
5602b2b1f42SAndrew Turner 		gicd = (ACPI_MADT_GENERIC_DISTRIBUTOR *)mp;
5612b2b1f42SAndrew Turner 		printf("\tGIC ID=%d\n", (u_int)gicd->GicId);
5622b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicd->BaseAddress);
5632b2b1f42SAndrew Turner 		printf("\tVector Base=%d\n", gicd->GlobalIrqBase);
5642b2b1f42SAndrew Turner 		printf("\tGIC VERSION=%d\n", (u_int)gicd->Version);
5652b2b1f42SAndrew Turner 		break;
5662b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
5672b2b1f42SAndrew Turner 		gicr = (ACPI_MADT_GENERIC_REDISTRIBUTOR *)mp;
5682b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicr->BaseAddress);
5692b2b1f42SAndrew Turner 		printf("\tLength=%08x\n", gicr->Length);
5702b2b1f42SAndrew Turner 		break;
5712b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
5722b2b1f42SAndrew Turner 		gict = (ACPI_MADT_GENERIC_TRANSLATOR *)mp;
5732b2b1f42SAndrew Turner 		printf("\tGIC ITS ID=%d\n", gict->TranslationId);
5742b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gict->BaseAddress);
5752b2b1f42SAndrew Turner 		break;
5760a473124SJohn Baldwin 	}
5770a473124SJohn Baldwin }
5780a473124SJohn Baldwin 
5790a473124SJohn Baldwin static void
580986dffafSJohn Baldwin acpi_handle_madt(ACPI_TABLE_HEADER *sdp)
5810a473124SJohn Baldwin {
582986dffafSJohn Baldwin 	ACPI_TABLE_MADT *madt;
5830a473124SJohn Baldwin 
584773b6454SNate Lawson 	printf(BEGIN_COMMENT);
585773b6454SNate Lawson 	acpi_print_sdt(sdp);
586986dffafSJohn Baldwin 	madt = (ACPI_TABLE_MADT *)sdp;
587986dffafSJohn Baldwin 	printf("\tLocal APIC ADDR=0x%08x\n", madt->Address);
5880a473124SJohn Baldwin 	printf("\tFlags={");
589986dffafSJohn Baldwin 	if (madt->Flags & ACPI_MADT_PCAT_COMPAT)
5900a473124SJohn Baldwin 		printf("PC-AT");
5910a473124SJohn Baldwin 	printf("}\n");
592986dffafSJohn Baldwin 	acpi_walk_subtables(sdp, (madt + 1), acpi_print_madt);
5930a473124SJohn Baldwin 	printf(END_COMMENT);
5940a473124SJohn Baldwin }
5950a473124SJohn Baldwin 
5960a473124SJohn Baldwin static void
597ebc22d04SAlexander Motin acpi_handle_bert(ACPI_TABLE_HEADER *sdp)
598ebc22d04SAlexander Motin {
599ebc22d04SAlexander Motin 	ACPI_TABLE_BERT *bert;
600ebc22d04SAlexander Motin 
601ebc22d04SAlexander Motin 	printf(BEGIN_COMMENT);
602ebc22d04SAlexander Motin 	acpi_print_sdt(sdp);
603ebc22d04SAlexander Motin 	bert = (ACPI_TABLE_BERT *)sdp;
604ebc22d04SAlexander Motin 	printf("\tRegionLength=%d\n", bert->RegionLength);
605ebc22d04SAlexander Motin 	printf("\tAddress=0x%016jx\n", bert->Address);
606ebc22d04SAlexander Motin 	printf(END_COMMENT);
607ebc22d04SAlexander Motin }
608ebc22d04SAlexander Motin 
609ebc22d04SAlexander Motin static void
610ebc22d04SAlexander Motin acpi_print_whea(ACPI_WHEA_HEADER *w)
611ebc22d04SAlexander Motin {
612ebc22d04SAlexander Motin 
613ebc22d04SAlexander Motin 	printf("\n\tAction=%d\n", w->Action);
614ebc22d04SAlexander Motin 	printf("\tInstruction=%d\n", w->Instruction);
615ebc22d04SAlexander Motin 	printf("\tFlags=%02x\n", w->Flags);
616ebc22d04SAlexander Motin 	printf("\tRegisterRegion=");
617ebc22d04SAlexander Motin 	acpi_print_gas(&w->RegisterRegion);
618ebc22d04SAlexander Motin 	printf("\n\tValue=0x%016jx\n", w->Value);
619ebc22d04SAlexander Motin 	printf("\tMask=0x%016jx\n", w->Mask);
620ebc22d04SAlexander Motin }
621ebc22d04SAlexander Motin 
622ebc22d04SAlexander Motin static void
623ebc22d04SAlexander Motin acpi_handle_einj(ACPI_TABLE_HEADER *sdp)
624ebc22d04SAlexander Motin {
625ebc22d04SAlexander Motin 	ACPI_TABLE_EINJ *einj;
626ebc22d04SAlexander Motin 	ACPI_WHEA_HEADER *w;
627ebc22d04SAlexander Motin 	u_int i;
628ebc22d04SAlexander Motin 
629ebc22d04SAlexander Motin 	printf(BEGIN_COMMENT);
630ebc22d04SAlexander Motin 	acpi_print_sdt(sdp);
631ebc22d04SAlexander Motin 	einj = (ACPI_TABLE_EINJ *)sdp;
632ebc22d04SAlexander Motin 	printf("\tHeaderLength=%d\n", einj->HeaderLength);
633ebc22d04SAlexander Motin 	printf("\tFlags=0x%02x\n", einj->Flags);
634ebc22d04SAlexander Motin 	printf("\tEntries=%d\n", einj->Entries);
635ebc22d04SAlexander Motin 	w = (ACPI_WHEA_HEADER *)(einj + 1);
636ebc22d04SAlexander Motin 	for (i = 0; i < MIN(einj->Entries, (sdp->Length -
637ebc22d04SAlexander Motin 	    sizeof(ACPI_TABLE_EINJ)) / sizeof(ACPI_WHEA_HEADER)); i++)
638ebc22d04SAlexander Motin 		acpi_print_whea(w + i);
639ebc22d04SAlexander Motin 	printf(END_COMMENT);
640ebc22d04SAlexander Motin }
641ebc22d04SAlexander Motin 
642ebc22d04SAlexander Motin static void
643ebc22d04SAlexander Motin acpi_handle_erst(ACPI_TABLE_HEADER *sdp)
644ebc22d04SAlexander Motin {
645ebc22d04SAlexander Motin 	ACPI_TABLE_ERST *erst;
646ebc22d04SAlexander Motin 	ACPI_WHEA_HEADER *w;
647ebc22d04SAlexander Motin 	u_int i;
648ebc22d04SAlexander Motin 
649ebc22d04SAlexander Motin 	printf(BEGIN_COMMENT);
650ebc22d04SAlexander Motin 	acpi_print_sdt(sdp);
651ebc22d04SAlexander Motin 	erst = (ACPI_TABLE_ERST *)sdp;
652ebc22d04SAlexander Motin 	printf("\tHeaderLength=%d\n", erst->HeaderLength);
653ebc22d04SAlexander Motin 	printf("\tEntries=%d\n", erst->Entries);
654ebc22d04SAlexander Motin 	w = (ACPI_WHEA_HEADER *)(erst + 1);
655ebc22d04SAlexander Motin 	for (i = 0; i < MIN(erst->Entries, (sdp->Length -
656ebc22d04SAlexander Motin 	    sizeof(ACPI_TABLE_ERST)) / sizeof(ACPI_WHEA_HEADER)); i++)
657ebc22d04SAlexander Motin 		acpi_print_whea(w + i);
658ebc22d04SAlexander Motin 	printf(END_COMMENT);
659ebc22d04SAlexander Motin }
660ebc22d04SAlexander Motin 
661ebc22d04SAlexander Motin static void
662ebc22d04SAlexander Motin acpi_print_hest_bank(ACPI_HEST_IA_ERROR_BANK *b)
663ebc22d04SAlexander Motin {
664ebc22d04SAlexander Motin 
665ebc22d04SAlexander Motin 	printf("\tBank:\n");
666ebc22d04SAlexander Motin 	printf("\t\tBankNumber=%d\n", b->BankNumber);
667ebc22d04SAlexander Motin 	printf("\t\tClearStatusOnInit=%d\n", b->ClearStatusOnInit);
668ebc22d04SAlexander Motin 	printf("\t\tStatusFormat=%d\n", b->StatusFormat);
669ebc22d04SAlexander Motin 	printf("\t\tControlRegister=%x\n", b->ControlRegister);
670ebc22d04SAlexander Motin 	printf("\t\tControlData=%jx\n", b->ControlData);
671ebc22d04SAlexander Motin 	printf("\t\tStatusRegister=%x\n", b->StatusRegister);
672ebc22d04SAlexander Motin 	printf("\t\tAddressRegister=%x\n", b->AddressRegister);
673ebc22d04SAlexander Motin 	printf("\t\tMiscRegister=%x\n", b->MiscRegister);
674ebc22d04SAlexander Motin }
675ebc22d04SAlexander Motin 
676ebc22d04SAlexander Motin static void
677ebc22d04SAlexander Motin acpi_print_hest_notify(ACPI_HEST_NOTIFY *n)
678ebc22d04SAlexander Motin {
679ebc22d04SAlexander Motin 
680ebc22d04SAlexander Motin 	printf("\t\tType=%d\n", n->Type);
681ebc22d04SAlexander Motin 	printf("\t\tLength=%d\n", n->Length);
682ebc22d04SAlexander Motin 	printf("\t\tConfigWriteEnable=%04x\n", n->ConfigWriteEnable);
683ebc22d04SAlexander Motin 	printf("\t\tPollInterval=%d\n", n->PollInterval);
684ebc22d04SAlexander Motin 	printf("\t\tVector=%d\n", n->Vector);
685ebc22d04SAlexander Motin 	printf("\t\tPollingThresholdValue=%d\n", n->PollingThresholdValue);
686ebc22d04SAlexander Motin 	printf("\t\tPollingThresholdWindow=%d\n", n->PollingThresholdWindow);
687ebc22d04SAlexander Motin 	printf("\t\tErrorThresholdValue=%d\n", n->ErrorThresholdValue);
688ebc22d04SAlexander Motin 	printf("\t\tErrorThresholdWindow=%d\n", n->ErrorThresholdWindow);
689ebc22d04SAlexander Motin }
690ebc22d04SAlexander Motin 
691ebc22d04SAlexander Motin static void
692ebc22d04SAlexander Motin acpi_print_hest_aer(ACPI_HEST_AER_COMMON *a)
693ebc22d04SAlexander Motin {
694ebc22d04SAlexander Motin 
695ebc22d04SAlexander Motin 	printf("\tFlags=%02x\n", a->Flags);
696ebc22d04SAlexander Motin 	printf("\tEnabled=%d\n", a->Enabled);
697ebc22d04SAlexander Motin 	printf("\tRecordsToPreallocate=%d\n", a->RecordsToPreallocate);
698ebc22d04SAlexander Motin 	printf("\tMaxSectionsPerRecord=%d\n", a->MaxSectionsPerRecord);
699ebc22d04SAlexander Motin 	printf("\tBus=%d\n", a->Bus);
700ebc22d04SAlexander Motin 	printf("\tDevice=%d\n", a->Device);
701ebc22d04SAlexander Motin 	printf("\tFunction=%d\n", a->Function);
702ebc22d04SAlexander Motin 	printf("\tDeviceControl=%d\n", a->DeviceControl);
703ebc22d04SAlexander Motin 	printf("\tUncorrectableMask=%d\n", a->UncorrectableMask);
704ebc22d04SAlexander Motin 	printf("\tUncorrectableSeverity=%d\n", a->UncorrectableSeverity);
705ebc22d04SAlexander Motin 	printf("\tCorrectableMask=%d\n", a->CorrectableMask);
706ebc22d04SAlexander Motin 	printf("\tAdvancedCapabilities=%d\n", a->AdvancedCapabilities);
707ebc22d04SAlexander Motin }
708ebc22d04SAlexander Motin 
709ebc22d04SAlexander Motin static int
710ebc22d04SAlexander Motin acpi_handle_hest_structure(void *addr, int remaining)
711ebc22d04SAlexander Motin {
712ebc22d04SAlexander Motin 	ACPI_HEST_HEADER *hdr = addr;
713ebc22d04SAlexander Motin 	int i;
714ebc22d04SAlexander Motin 
715ebc22d04SAlexander Motin 	if (remaining < (int)sizeof(ACPI_HEST_HEADER))
716ebc22d04SAlexander Motin 		return (-1);
717ebc22d04SAlexander Motin 
718ebc22d04SAlexander Motin 	printf("\n\tType=%d\n", hdr->Type);
719ebc22d04SAlexander Motin 	printf("\tSourceId=%d\n", hdr->SourceId);
720ebc22d04SAlexander Motin 	switch (hdr->Type) {
721ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_IA32_CHECK: {
722ebc22d04SAlexander Motin 		ACPI_HEST_IA_MACHINE_CHECK *s = addr;
723ebc22d04SAlexander Motin 		printf("\tFlags=%02x\n", s->Flags);
724ebc22d04SAlexander Motin 		printf("\tEnabled=%d\n", s->Enabled);
725ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
726ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
727ebc22d04SAlexander Motin 		printf("\tGlobalCapabilityData=%jd\n", s->GlobalCapabilityData);
728ebc22d04SAlexander Motin 		printf("\tGlobalControlData=%jd\n", s->GlobalControlData);
729ebc22d04SAlexander Motin 		printf("\tNumHardwareBanks=%d\n", s->NumHardwareBanks);
730ebc22d04SAlexander Motin 		for (i = 0; i < s->NumHardwareBanks; i++) {
731ebc22d04SAlexander Motin 			acpi_print_hest_bank((ACPI_HEST_IA_ERROR_BANK *)
732ebc22d04SAlexander Motin 			    (s + 1) + i);
733ebc22d04SAlexander Motin 		}
734ebc22d04SAlexander Motin 		return (sizeof(*s) + s->NumHardwareBanks *
735ebc22d04SAlexander Motin 		    sizeof(ACPI_HEST_IA_ERROR_BANK));
736ebc22d04SAlexander Motin 	}
737ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: {
738ebc22d04SAlexander Motin 		ACPI_HEST_IA_CORRECTED *s = addr;
739ebc22d04SAlexander Motin 		printf("\tFlags=%02x\n", s->Flags);
740ebc22d04SAlexander Motin 		printf("\tEnabled=%d\n", s->Enabled);
741ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
742ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
743ebc22d04SAlexander Motin 		printf("\tNotify:\n");
744ebc22d04SAlexander Motin 		acpi_print_hest_notify(&s->Notify);
745ebc22d04SAlexander Motin 		printf("\tNumHardwareBanks=%d\n", s->NumHardwareBanks);
746ebc22d04SAlexander Motin 		for (i = 0; i < s->NumHardwareBanks; i++) {
747ebc22d04SAlexander Motin 			acpi_print_hest_bank((ACPI_HEST_IA_ERROR_BANK *)
748ebc22d04SAlexander Motin 			    (s + 1) + i);
749ebc22d04SAlexander Motin 		}
750ebc22d04SAlexander Motin 		return (sizeof(*s) + s->NumHardwareBanks *
751ebc22d04SAlexander Motin 		    sizeof(ACPI_HEST_IA_ERROR_BANK));
752ebc22d04SAlexander Motin 	}
753ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_IA32_NMI: {
754ebc22d04SAlexander Motin 		ACPI_HEST_IA_NMI *s = addr;
755ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
756ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
757ebc22d04SAlexander Motin 		printf("\tMaxRawDataLength=%d\n", s->MaxRawDataLength);
758ebc22d04SAlexander Motin 		return (sizeof(*s));
759ebc22d04SAlexander Motin 	}
760ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_AER_ROOT_PORT: {
761ebc22d04SAlexander Motin 		ACPI_HEST_AER_ROOT *s = addr;
762ebc22d04SAlexander Motin 		acpi_print_hest_aer(&s->Aer);
763ebc22d04SAlexander Motin 		printf("\tRootErrorCommand=%d\n", s->RootErrorCommand);
764ebc22d04SAlexander Motin 		return (sizeof(*s));
765ebc22d04SAlexander Motin 	}
766ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_AER_ENDPOINT: {
767ebc22d04SAlexander Motin 		ACPI_HEST_AER *s = addr;
768ebc22d04SAlexander Motin 		acpi_print_hest_aer(&s->Aer);
769ebc22d04SAlexander Motin 		return (sizeof(*s));
770ebc22d04SAlexander Motin 	}
771ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_AER_BRIDGE: {
772ebc22d04SAlexander Motin 		ACPI_HEST_AER_BRIDGE *s = addr;
773ebc22d04SAlexander Motin 		acpi_print_hest_aer(&s->Aer);
774ebc22d04SAlexander Motin 		printf("\tUncorrectableMask2=%d\n", s->UncorrectableMask2);
775ebc22d04SAlexander Motin 		printf("\tUncorrectableSeverity2=%d\n", s->UncorrectableSeverity2);
776ebc22d04SAlexander Motin 		printf("\tAdvancedCapabilities2=%d\n", s->AdvancedCapabilities2);
777ebc22d04SAlexander Motin 		return (sizeof(*s));
778ebc22d04SAlexander Motin 	}
779ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_GENERIC_ERROR: {
780ebc22d04SAlexander Motin 		ACPI_HEST_GENERIC *s = addr;
781ebc22d04SAlexander Motin 		printf("\tRelatedSourceId=%d\n", s->RelatedSourceId);
782ebc22d04SAlexander Motin 		printf("\tEnabled=%d\n", s->Enabled);
783ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
784ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
785ebc22d04SAlexander Motin 		printf("\tMaxRawDataLength=%d\n", s->MaxRawDataLength);
786ebc22d04SAlexander Motin 		printf("\tErrorStatusAddress=");
787ebc22d04SAlexander Motin 		acpi_print_gas(&s->ErrorStatusAddress);
788ebc22d04SAlexander Motin 		printf("\n");
789ebc22d04SAlexander Motin 		printf("\tNotify:\n");
790ebc22d04SAlexander Motin 		acpi_print_hest_notify(&s->Notify);
791ebc22d04SAlexander Motin 		printf("\tErrorBlockLength=%d\n", s->ErrorBlockLength);
792ebc22d04SAlexander Motin 		return (sizeof(*s));
793ebc22d04SAlexander Motin 	}
794ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_GENERIC_ERROR_V2: {
795ebc22d04SAlexander Motin 		ACPI_HEST_GENERIC_V2 *s = addr;
796ebc22d04SAlexander Motin 		printf("\tRelatedSourceId=%d\n", s->RelatedSourceId);
797ebc22d04SAlexander Motin 		printf("\tEnabled=%d\n", s->Enabled);
798ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
799ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
800ebc22d04SAlexander Motin 		printf("\tMaxRawDataLength=%d\n", s->MaxRawDataLength);
801ebc22d04SAlexander Motin 		printf("\tErrorStatusAddress=");
802ebc22d04SAlexander Motin 		acpi_print_gas(&s->ErrorStatusAddress);
803ebc22d04SAlexander Motin 		printf("\n");
804ebc22d04SAlexander Motin 		printf("\tNotify:\n");
805ebc22d04SAlexander Motin 		acpi_print_hest_notify(&s->Notify);
806ebc22d04SAlexander Motin 		printf("\tErrorBlockLength=%d\n", s->ErrorBlockLength);
807ebc22d04SAlexander Motin 		printf("\tReadAckRegister=");
808ebc22d04SAlexander Motin 		acpi_print_gas(&s->ReadAckRegister);
809ebc22d04SAlexander Motin 		printf("\n");
810ebc22d04SAlexander Motin 		printf("\tReadAckPreserve=%jd\n", s->ReadAckPreserve);
811ebc22d04SAlexander Motin 		printf("\tReadAckWrite=%jd\n", s->ReadAckWrite);
812ebc22d04SAlexander Motin 		return (sizeof(*s));
813ebc22d04SAlexander Motin 	}
814ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: {
815ebc22d04SAlexander Motin 		ACPI_HEST_IA_DEFERRED_CHECK *s = addr;
816ebc22d04SAlexander Motin 		printf("\tFlags=%02x\n", s->Flags);
817ebc22d04SAlexander Motin 		printf("\tEnabled=%d\n", s->Enabled);
818ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
819ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
820ebc22d04SAlexander Motin 		printf("\tNotify:\n");
821ebc22d04SAlexander Motin 		acpi_print_hest_notify(&s->Notify);
822ebc22d04SAlexander Motin 		printf("\tNumHardwareBanks=%d\n", s->NumHardwareBanks);
823ebc22d04SAlexander Motin 		for (i = 0; i < s->NumHardwareBanks; i++) {
824ebc22d04SAlexander Motin 			acpi_print_hest_bank((ACPI_HEST_IA_ERROR_BANK *)
825ebc22d04SAlexander Motin 			    (s + 1) + i);
826ebc22d04SAlexander Motin 		}
827ebc22d04SAlexander Motin 		return (sizeof(*s) + s->NumHardwareBanks *
828ebc22d04SAlexander Motin 		    sizeof(ACPI_HEST_IA_ERROR_BANK));
829ebc22d04SAlexander Motin 	}
830ebc22d04SAlexander Motin 	default:
831ebc22d04SAlexander Motin 		return (-1);
832ebc22d04SAlexander Motin 	}
833ebc22d04SAlexander Motin }
834ebc22d04SAlexander Motin 
835ebc22d04SAlexander Motin static void
836ebc22d04SAlexander Motin acpi_handle_hest(ACPI_TABLE_HEADER *sdp)
837ebc22d04SAlexander Motin {
838ebc22d04SAlexander Motin 	char *cp;
839ebc22d04SAlexander Motin 	int remaining, consumed;
840ebc22d04SAlexander Motin 	ACPI_TABLE_HEST *hest;
841ebc22d04SAlexander Motin 
842ebc22d04SAlexander Motin 	printf(BEGIN_COMMENT);
843ebc22d04SAlexander Motin 	acpi_print_sdt(sdp);
844ebc22d04SAlexander Motin 	hest = (ACPI_TABLE_HEST *)sdp;
845ebc22d04SAlexander Motin 	printf("\tErrorSourceCount=%d\n", hest->ErrorSourceCount);
846ebc22d04SAlexander Motin 
847ebc22d04SAlexander Motin 	remaining = sdp->Length - sizeof(ACPI_TABLE_HEST);
848ebc22d04SAlexander Motin 	while (remaining > 0) {
849ebc22d04SAlexander Motin 		cp = (char *)sdp + sdp->Length - remaining;
850ebc22d04SAlexander Motin 		consumed = acpi_handle_hest_structure(cp, remaining);
851ebc22d04SAlexander Motin 		if (consumed <= 0)
852ebc22d04SAlexander Motin 			break;
853ebc22d04SAlexander Motin 		else
854ebc22d04SAlexander Motin 			remaining -= consumed;
855ebc22d04SAlexander Motin 	}
856ebc22d04SAlexander Motin 	printf(END_COMMENT);
857ebc22d04SAlexander Motin }
858ebc22d04SAlexander Motin 
859ebc22d04SAlexander Motin static void
860986dffafSJohn Baldwin acpi_handle_hpet(ACPI_TABLE_HEADER *sdp)
86179d7565cSPeter Wemm {
862986dffafSJohn Baldwin 	ACPI_TABLE_HPET *hpet;
86379d7565cSPeter Wemm 
864773b6454SNate Lawson 	printf(BEGIN_COMMENT);
865773b6454SNate Lawson 	acpi_print_sdt(sdp);
866986dffafSJohn Baldwin 	hpet = (ACPI_TABLE_HPET *)sdp;
867986dffafSJohn Baldwin 	printf("\tHPET Number=%d\n", hpet->Sequence);
86887f9f09aSTakanori Watanabe 	printf("\tADDR=");
869986dffafSJohn Baldwin 	acpi_print_gas(&hpet->Address);
870ebc22d04SAlexander Motin 	printf("\n\tHW Rev=0x%x\n", hpet->Id & ACPI_HPET_ID_HARDWARE_REV_ID);
871986dffafSJohn Baldwin 	printf("\tComparators=%d\n", (hpet->Id & ACPI_HPET_ID_COMPARATORS) >>
872986dffafSJohn Baldwin 	    8);
873986dffafSJohn Baldwin 	printf("\tCounter Size=%d\n", hpet->Id & ACPI_HPET_ID_COUNT_SIZE_CAP ?
874986dffafSJohn Baldwin 	    1 : 0);
87579d7565cSPeter Wemm 	printf("\tLegacy IRQ routing capable={");
876986dffafSJohn Baldwin 	if (hpet->Id & ACPI_HPET_ID_LEGACY_CAPABLE)
87779d7565cSPeter Wemm 		printf("TRUE}\n");
87879d7565cSPeter Wemm 	else
87979d7565cSPeter Wemm 		printf("FALSE}\n");
880986dffafSJohn Baldwin 	printf("\tPCI Vendor ID=0x%04x\n", hpet->Id >> 16);
881986dffafSJohn Baldwin 	printf("\tMinimal Tick=%d\n", hpet->MinimumTick);
8829785e979SNeel Natu 	printf("\tFlags=0x%02x\n", hpet->Flags);
88379d7565cSPeter Wemm 	printf(END_COMMENT);
88479d7565cSPeter Wemm }
88579d7565cSPeter Wemm 
88679d7565cSPeter Wemm static void
887986dffafSJohn Baldwin acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp)
88855d7ff9eSNate Lawson {
889986dffafSJohn Baldwin 	ACPI_TABLE_ECDT *ecdt;
89055d7ff9eSNate Lawson 
89155d7ff9eSNate Lawson 	printf(BEGIN_COMMENT);
89255d7ff9eSNate Lawson 	acpi_print_sdt(sdp);
893986dffafSJohn Baldwin 	ecdt = (ACPI_TABLE_ECDT *)sdp;
89455d7ff9eSNate Lawson 	printf("\tEC_CONTROL=");
895986dffafSJohn Baldwin 	acpi_print_gas(&ecdt->Control);
89655d7ff9eSNate Lawson 	printf("\n\tEC_DATA=");
897986dffafSJohn Baldwin 	acpi_print_gas(&ecdt->Data);
898986dffafSJohn Baldwin 	printf("\n\tUID=%#x, ", ecdt->Uid);
899986dffafSJohn Baldwin 	printf("GPE_BIT=%#x\n", ecdt->Gpe);
900986dffafSJohn Baldwin 	printf("\tEC_ID=%s\n", ecdt->Id);
90155d7ff9eSNate Lawson 	printf(END_COMMENT);
90255d7ff9eSNate Lawson }
90355d7ff9eSNate Lawson 
90455d7ff9eSNate Lawson static void
905986dffafSJohn Baldwin acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp)
906a47e681bSScott Long {
907986dffafSJohn Baldwin 	ACPI_TABLE_MCFG *mcfg;
908986dffafSJohn Baldwin 	ACPI_MCFG_ALLOCATION *alloc;
909986dffafSJohn Baldwin 	u_int i, entries;
910a47e681bSScott Long 
911a47e681bSScott Long 	printf(BEGIN_COMMENT);
912a47e681bSScott Long 	acpi_print_sdt(sdp);
913986dffafSJohn Baldwin 	mcfg = (ACPI_TABLE_MCFG *)sdp;
914986dffafSJohn Baldwin 	entries = (sdp->Length - sizeof(ACPI_TABLE_MCFG)) /
915986dffafSJohn Baldwin 	    sizeof(ACPI_MCFG_ALLOCATION);
916986dffafSJohn Baldwin 	alloc = (ACPI_MCFG_ALLOCATION *)(mcfg + 1);
917986dffafSJohn Baldwin 	for (i = 0; i < entries; i++, alloc++) {
918a47e681bSScott Long 		printf("\n");
9190c10b85aSJung-uk Kim 		printf("\tBase Address=0x%016jx\n", (uintmax_t)alloc->Address);
920986dffafSJohn Baldwin 		printf("\tSegment Group=0x%04x\n", alloc->PciSegment);
921986dffafSJohn Baldwin 		printf("\tStart Bus=%d\n", alloc->StartBusNumber);
922986dffafSJohn Baldwin 		printf("\tEnd Bus=%d\n", alloc->EndBusNumber);
923a47e681bSScott Long 	}
924a47e681bSScott Long 	printf(END_COMMENT);
925a47e681bSScott Long }
926a47e681bSScott Long 
927a47e681bSScott Long static void
92833866658SJohn Baldwin acpi_handle_slit(ACPI_TABLE_HEADER *sdp)
92933866658SJohn Baldwin {
93033866658SJohn Baldwin 	ACPI_TABLE_SLIT *slit;
93133866658SJohn Baldwin 	UINT64 i, j;
93233866658SJohn Baldwin 
93333866658SJohn Baldwin 	printf(BEGIN_COMMENT);
93433866658SJohn Baldwin 	acpi_print_sdt(sdp);
93533866658SJohn Baldwin 	slit = (ACPI_TABLE_SLIT *)sdp;
9360c10b85aSJung-uk Kim 	printf("\tLocality Count=%ju\n", (uintmax_t)slit->LocalityCount);
93733866658SJohn Baldwin 	printf("\n\t      ");
93833866658SJohn Baldwin 	for (i = 0; i < slit->LocalityCount; i++)
9390c10b85aSJung-uk Kim 		printf(" %3ju", (uintmax_t)i);
94033866658SJohn Baldwin 	printf("\n\t     +");
94133866658SJohn Baldwin 	for (i = 0; i < slit->LocalityCount; i++)
94233866658SJohn Baldwin 		printf("----");
94333866658SJohn Baldwin 	printf("\n");
94433866658SJohn Baldwin 	for (i = 0; i < slit->LocalityCount; i++) {
9450c10b85aSJung-uk Kim 		printf("\t %3ju |", (uintmax_t)i);
94633866658SJohn Baldwin 		for (j = 0; j < slit->LocalityCount; j++)
94733866658SJohn Baldwin 			printf(" %3d",
94833866658SJohn Baldwin 			    slit->Entry[i * slit->LocalityCount + j]);
94933866658SJohn Baldwin 		printf("\n");
95033866658SJohn Baldwin 	}
95133866658SJohn Baldwin 	printf(END_COMMENT);
95233866658SJohn Baldwin }
95333866658SJohn Baldwin 
95433866658SJohn Baldwin static void
955ed26c389SScott Long acpi_handle_wddt(ACPI_TABLE_HEADER *sdp)
956ed26c389SScott Long {
957ed26c389SScott Long 	ACPI_TABLE_WDDT *wddt;
958ed26c389SScott Long 
959ed26c389SScott Long 	printf(BEGIN_COMMENT);
960ed26c389SScott Long 	acpi_print_sdt(sdp);
961ed26c389SScott Long 	wddt = (ACPI_TABLE_WDDT *)sdp;
962ed26c389SScott Long 	printf("\tSpecVersion=0x%04x, TableVersion=0x%04x\n",
963ed26c389SScott Long 	    wddt->SpecVersion, wddt->TableVersion);
964ed26c389SScott Long 	printf("\tPciVendorId=0x%04x, Address=", wddt->PciVendorId);
965ed26c389SScott Long 	acpi_print_gas(&wddt->Address);
966ed26c389SScott Long 	printf("\n\tMaxCount=%u, MinCount=%u, Period=%ums\n",
967ed26c389SScott Long 	    wddt->MaxCount, wddt->MinCount, wddt->Period);
968ed26c389SScott Long 
969ed26c389SScott Long #define	PRINTFLAG(var, flag)	printflag((var), ACPI_WDDT_## flag, #flag)
970ed26c389SScott Long 	printf("\tStatus=");
971ed26c389SScott Long 	PRINTFLAG(wddt->Status, AVAILABLE);
972ed26c389SScott Long 	PRINTFLAG(wddt->Status, ACTIVE);
973ed26c389SScott Long 	PRINTFLAG(wddt->Status, TCO_OS_OWNED);
974ed26c389SScott Long 	PRINTFLAG(wddt->Status, USER_RESET);
975ed26c389SScott Long 	PRINTFLAG(wddt->Status, WDT_RESET);
976ed26c389SScott Long 	PRINTFLAG(wddt->Status, POWER_FAIL);
977ed26c389SScott Long 	PRINTFLAG(wddt->Status, UNKNOWN_RESET);
978ed26c389SScott Long 	PRINTFLAG_END();
979ed26c389SScott Long 	printf("\tCapability=");
980ed26c389SScott Long 	PRINTFLAG(wddt->Capability, AUTO_RESET);
981ed26c389SScott Long 	PRINTFLAG(wddt->Capability, ALERT_SUPPORT);
982ed26c389SScott Long 	PRINTFLAG_END();
983ed26c389SScott Long #undef PRINTFLAG
984ed26c389SScott Long 
985ed26c389SScott Long 	printf(END_COMMENT);
986ed26c389SScott Long }
987ed26c389SScott Long 
988ed26c389SScott Long static void
9895857fba5SBen Widawsky acpi_print_native_lpit(ACPI_LPIT_NATIVE *nl)
9905857fba5SBen Widawsky {
9915857fba5SBen Widawsky 	printf("\tEntryTrigger=");
9925857fba5SBen Widawsky 	acpi_print_gas(&nl->EntryTrigger);
993ebc22d04SAlexander Motin 	printf("\n\tResidency=%u\n", nl->Residency);
9945857fba5SBen Widawsky 	printf("\tLatency=%u\n", nl->Latency);
9955857fba5SBen Widawsky 	if (nl->Header.Flags & ACPI_LPIT_NO_COUNTER)
9965857fba5SBen Widawsky 		printf("\tResidencyCounter=Not Present");
9975857fba5SBen Widawsky 	else {
9985857fba5SBen Widawsky 		printf("\tResidencyCounter=");
9995857fba5SBen Widawsky 		acpi_print_gas(&nl->ResidencyCounter);
1000ebc22d04SAlexander Motin 		printf("\n");
10015857fba5SBen Widawsky 	}
10025857fba5SBen Widawsky 	if (nl->CounterFrequency)
10035857fba5SBen Widawsky 		printf("\tCounterFrequency=%ju\n", nl->CounterFrequency);
10045857fba5SBen Widawsky 	else
10055857fba5SBen Widawsky 		printf("\tCounterFrequency=TSC\n");
10065857fba5SBen Widawsky }
10075857fba5SBen Widawsky 
10085857fba5SBen Widawsky static void
10095857fba5SBen Widawsky acpi_print_lpit(ACPI_LPIT_HEADER *lpit)
10105857fba5SBen Widawsky {
10115857fba5SBen Widawsky 	if (lpit->Type == ACPI_LPIT_TYPE_NATIVE_CSTATE)
10125857fba5SBen Widawsky 		printf("\tType=ACPI_LPIT_TYPE_NATIVE_CSTATE\n");
10135857fba5SBen Widawsky 	else
10145857fba5SBen Widawsky 		warnx("unknown LPIT type %u", lpit->Type);
10155857fba5SBen Widawsky 
10165857fba5SBen Widawsky 	printf("\tLength=%u\n", lpit->Length);
10175857fba5SBen Widawsky 	printf("\tUniqueId=0x%04x\n", lpit->UniqueId);
10185857fba5SBen Widawsky #define	PRINTFLAG(var, flag)	printflag((var), ACPI_LPIT_## flag, #flag)
10195857fba5SBen Widawsky 	printf("\tFlags=");
10205857fba5SBen Widawsky 	PRINTFLAG(lpit->Flags, STATE_DISABLED);
10215857fba5SBen Widawsky 	PRINTFLAG_END();
10225857fba5SBen Widawsky #undef PRINTFLAG
10235857fba5SBen Widawsky 
10245857fba5SBen Widawsky 	if (lpit->Type == ACPI_LPIT_TYPE_NATIVE_CSTATE)
10255857fba5SBen Widawsky 		return acpi_print_native_lpit((ACPI_LPIT_NATIVE *)lpit);
10265857fba5SBen Widawsky }
10275857fba5SBen Widawsky 
10285857fba5SBen Widawsky static void
10295857fba5SBen Widawsky acpi_walk_lpit(ACPI_TABLE_HEADER *table, void *first,
10305857fba5SBen Widawsky     void (*action)(ACPI_LPIT_HEADER *))
10315857fba5SBen Widawsky {
10325857fba5SBen Widawsky 	ACPI_LPIT_HEADER *subtable;
10335857fba5SBen Widawsky 	char *end;
10345857fba5SBen Widawsky 
10355857fba5SBen Widawsky 	subtable = first;
10365857fba5SBen Widawsky 	end = (char *)table + table->Length;
10375857fba5SBen Widawsky 	while ((char *)subtable < end) {
10385857fba5SBen Widawsky 		printf("\n");
10395857fba5SBen Widawsky 		if (subtable->Length < sizeof(ACPI_LPIT_HEADER)) {
10405857fba5SBen Widawsky 			warnx("invalid subtable length %u", subtable->Length);
10415857fba5SBen Widawsky 			return;
10425857fba5SBen Widawsky 		}
10435857fba5SBen Widawsky 		action(subtable);
10445857fba5SBen Widawsky 		subtable = (ACPI_LPIT_HEADER *)((char *)subtable +
10455857fba5SBen Widawsky 		    subtable->Length);
10465857fba5SBen Widawsky 	}
10475857fba5SBen Widawsky }
10485857fba5SBen Widawsky 
10495857fba5SBen Widawsky static void
10505857fba5SBen Widawsky acpi_handle_lpit(ACPI_TABLE_HEADER *sdp)
10515857fba5SBen Widawsky {
10525857fba5SBen Widawsky 	ACPI_TABLE_LPIT *lpit;
10535857fba5SBen Widawsky 
10545857fba5SBen Widawsky 	printf(BEGIN_COMMENT);
10555857fba5SBen Widawsky 	acpi_print_sdt(sdp);
10565857fba5SBen Widawsky 	lpit = (ACPI_TABLE_LPIT *)sdp;
10575857fba5SBen Widawsky 	acpi_walk_lpit(sdp, (lpit + 1), acpi_print_lpit);
10585857fba5SBen Widawsky 
10595857fba5SBen Widawsky 	printf(END_COMMENT);
10605857fba5SBen Widawsky }
10615857fba5SBen Widawsky 
10625857fba5SBen Widawsky static void
1063a0333ad1SJohn Baldwin acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain,
1064a0333ad1SJohn Baldwin     uint32_t flags)
1065a0333ad1SJohn Baldwin {
1066a0333ad1SJohn Baldwin 
1067a0333ad1SJohn Baldwin 	printf("\tFlags={");
1068a0333ad1SJohn Baldwin 	if (flags & ACPI_SRAT_CPU_ENABLED)
1069a0333ad1SJohn Baldwin 		printf("ENABLED");
1070a0333ad1SJohn Baldwin 	else
1071a0333ad1SJohn Baldwin 		printf("DISABLED");
1072a0333ad1SJohn Baldwin 	printf("}\n");
1073a0333ad1SJohn Baldwin 	printf("\tAPIC ID=%d\n", apic_id);
1074a0333ad1SJohn Baldwin 	printf("\tProximity Domain=%d\n", proximity_domain);
1075a0333ad1SJohn Baldwin }
1076a0333ad1SJohn Baldwin 
1077c031c93bSTakanori Watanabe static char *
1078c031c93bSTakanori Watanabe acpi_tcpa_evname(struct TCPAevent *event)
1079c031c93bSTakanori Watanabe {
1080c031c93bSTakanori Watanabe 	struct TCPApc_event *pc_event;
1081c031c93bSTakanori Watanabe 	char *eventname = NULL;
1082c031c93bSTakanori Watanabe 
1083c031c93bSTakanori Watanabe 	pc_event = (struct TCPApc_event *)(event + 1);
1084c031c93bSTakanori Watanabe 
1085c031c93bSTakanori Watanabe 	switch(event->event_type) {
1086c031c93bSTakanori Watanabe 	case PREBOOT:
1087c031c93bSTakanori Watanabe 	case POST_CODE:
1088c031c93bSTakanori Watanabe 	case UNUSED:
1089c031c93bSTakanori Watanabe 	case NO_ACTION:
1090c031c93bSTakanori Watanabe 	case SEPARATOR:
1091c031c93bSTakanori Watanabe 	case SCRTM_CONTENTS:
1092c031c93bSTakanori Watanabe 	case SCRTM_VERSION:
1093c031c93bSTakanori Watanabe 	case CPU_MICROCODE:
1094c031c93bSTakanori Watanabe 	case PLATFORM_CONFIG_FLAGS:
1095c031c93bSTakanori Watanabe 	case TABLE_OF_DEVICES:
1096c031c93bSTakanori Watanabe 	case COMPACT_HASH:
1097c031c93bSTakanori Watanabe 	case IPL:
1098c031c93bSTakanori Watanabe 	case IPL_PARTITION_DATA:
1099c031c93bSTakanori Watanabe 	case NONHOST_CODE:
1100c031c93bSTakanori Watanabe 	case NONHOST_CONFIG:
1101c031c93bSTakanori Watanabe 	case NONHOST_INFO:
1102c031c93bSTakanori Watanabe 		asprintf(&eventname, "%s",
1103c031c93bSTakanori Watanabe 		    tcpa_event_type_strings[event->event_type]);
1104c031c93bSTakanori Watanabe 		break;
1105c031c93bSTakanori Watanabe 
1106c031c93bSTakanori Watanabe 	case ACTION:
1107c031c93bSTakanori Watanabe 		eventname = calloc(event->event_size + 1, sizeof(char));
1108c031c93bSTakanori Watanabe 		memcpy(eventname, pc_event, event->event_size);
1109c031c93bSTakanori Watanabe 		break;
1110c031c93bSTakanori Watanabe 
1111c031c93bSTakanori Watanabe 	case EVENT_TAG:
1112c031c93bSTakanori Watanabe 		switch (pc_event->event_id) {
1113c031c93bSTakanori Watanabe 		case SMBIOS:
1114c031c93bSTakanori Watanabe 		case BIS_CERT:
1115c031c93bSTakanori Watanabe 		case CMOS:
1116c031c93bSTakanori Watanabe 		case NVRAM:
1117c031c93bSTakanori Watanabe 		case OPTION_ROM_EXEC:
1118c031c93bSTakanori Watanabe 		case OPTION_ROM_CONFIG:
1119c031c93bSTakanori Watanabe 		case S_CRTM_VERSION:
1120c031c93bSTakanori Watanabe 		case POST_BIOS_ROM:
1121c031c93bSTakanori Watanabe 		case ESCD:
1122c031c93bSTakanori Watanabe 		case OPTION_ROM_MICROCODE:
1123c031c93bSTakanori Watanabe 		case S_CRTM_CONTENTS:
1124c031c93bSTakanori Watanabe 		case POST_CONTENTS:
1125c031c93bSTakanori Watanabe 			asprintf(&eventname, "%s",
1126c031c93bSTakanori Watanabe 			    TCPA_pcclient_strings[pc_event->event_id]);
1127c031c93bSTakanori Watanabe 			break;
1128c031c93bSTakanori Watanabe 
1129c031c93bSTakanori Watanabe 		default:
1130c031c93bSTakanori Watanabe 			asprintf(&eventname, "<unknown tag 0x%02x>",
1131c031c93bSTakanori Watanabe 			    pc_event->event_id);
1132c031c93bSTakanori Watanabe 			break;
1133c031c93bSTakanori Watanabe 		}
1134c031c93bSTakanori Watanabe 		break;
1135c031c93bSTakanori Watanabe 
1136c031c93bSTakanori Watanabe 	default:
1137c031c93bSTakanori Watanabe 		asprintf(&eventname, "<unknown 0x%02x>", event->event_type);
1138c031c93bSTakanori Watanabe 		break;
1139c031c93bSTakanori Watanabe 	}
1140c031c93bSTakanori Watanabe 
1141c031c93bSTakanori Watanabe 	return eventname;
1142c031c93bSTakanori Watanabe }
1143c031c93bSTakanori Watanabe 
1144c031c93bSTakanori Watanabe static void
1145c031c93bSTakanori Watanabe acpi_print_tcpa(struct TCPAevent *event)
1146c031c93bSTakanori Watanabe {
1147c031c93bSTakanori Watanabe 	int i;
1148c031c93bSTakanori Watanabe 	char *eventname;
1149c031c93bSTakanori Watanabe 
1150c031c93bSTakanori Watanabe 	eventname = acpi_tcpa_evname(event);
1151c031c93bSTakanori Watanabe 
1152c031c93bSTakanori Watanabe 	printf("\t%d", event->pcr_index);
1153c031c93bSTakanori Watanabe 	printf(" 0x");
1154c031c93bSTakanori Watanabe 	for (i = 0; i < 20; i++)
1155c031c93bSTakanori Watanabe 		printf("%02x", event->pcr_value[i]);
1156c031c93bSTakanori Watanabe 	printf(" [%s]\n", eventname ? eventname : "<unknown>");
1157c031c93bSTakanori Watanabe 
1158c031c93bSTakanori Watanabe 	free(eventname);
1159c031c93bSTakanori Watanabe }
1160c031c93bSTakanori Watanabe 
1161c031c93bSTakanori Watanabe static void
1162c031c93bSTakanori Watanabe acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp)
1163c031c93bSTakanori Watanabe {
1164c031c93bSTakanori Watanabe 	struct TCPAbody *tcpa;
1165c031c93bSTakanori Watanabe 	struct TCPAevent *event;
1166977fd9daSTakanori Watanabe 	uintmax_t len, paddr;
1167c031c93bSTakanori Watanabe 	unsigned char *vaddr = NULL;
1168c031c93bSTakanori Watanabe 	unsigned char *vend = NULL;
1169c031c93bSTakanori Watanabe 
1170c031c93bSTakanori Watanabe 	printf(BEGIN_COMMENT);
1171c031c93bSTakanori Watanabe 	acpi_print_sdt(sdp);
1172c031c93bSTakanori Watanabe 	tcpa = (struct TCPAbody *) sdp;
1173c031c93bSTakanori Watanabe 
1174c031c93bSTakanori Watanabe 	switch (tcpa->platform_class) {
1175c031c93bSTakanori Watanabe 	case ACPI_TCPA_BIOS_CLIENT:
1176c031c93bSTakanori Watanabe 		len = tcpa->client.log_max_len;
1177c031c93bSTakanori Watanabe 		paddr = tcpa->client.log_start_addr;
1178c031c93bSTakanori Watanabe 		break;
1179c031c93bSTakanori Watanabe 
1180c031c93bSTakanori Watanabe 	case ACPI_TCPA_BIOS_SERVER:
1181c031c93bSTakanori Watanabe 		len = tcpa->server.log_max_len;
1182c031c93bSTakanori Watanabe 		paddr = tcpa->server.log_start_addr;
1183c031c93bSTakanori Watanabe 		break;
1184c031c93bSTakanori Watanabe 
1185c031c93bSTakanori Watanabe 	default:
1186c031c93bSTakanori Watanabe 		printf("XXX");
1187c031c93bSTakanori Watanabe 		printf(END_COMMENT);
1188c031c93bSTakanori Watanabe 		return;
1189c031c93bSTakanori Watanabe 	}
11900e1982f4STakanori Watanabe 	printf("\tClass %u Base Address 0x%jx Length %ju\n\n",
1191c031c93bSTakanori Watanabe 	    tcpa->platform_class, paddr, len);
1192c031c93bSTakanori Watanabe 
1193c031c93bSTakanori Watanabe 	if (len == 0) {
1194c031c93bSTakanori Watanabe 		printf("\tEmpty TCPA table\n");
1195c031c93bSTakanori Watanabe 		printf(END_COMMENT);
1196c031c93bSTakanori Watanabe 		return;
1197c031c93bSTakanori Watanabe 	}
11982ef23c6dSTakanori Watanabe 	if(sdp->Revision == 1){
11992ef23c6dSTakanori Watanabe 		printf("\tOLD TCPA spec log found. Dumping not supported.\n");
12002ef23c6dSTakanori Watanabe 		printf(END_COMMENT);
12012ef23c6dSTakanori Watanabe 		return;
12022ef23c6dSTakanori Watanabe 	}
1203c031c93bSTakanori Watanabe 
1204c031c93bSTakanori Watanabe 	vaddr = (unsigned char *)acpi_map_physical(paddr, len);
1205c031c93bSTakanori Watanabe 	vend = vaddr + len;
1206c031c93bSTakanori Watanabe 
1207c031c93bSTakanori Watanabe 	while (vaddr != NULL) {
12082ef23c6dSTakanori Watanabe 		if ((vaddr + sizeof(struct TCPAevent) >= vend)||
12092ef23c6dSTakanori Watanabe 		    (vaddr + sizeof(struct TCPAevent) < vaddr))
1210c031c93bSTakanori Watanabe 			break;
12110e1982f4STakanori Watanabe 		event = (struct TCPAevent *)(void *)vaddr;
1212c031c93bSTakanori Watanabe 		if (vaddr + event->event_size >= vend)
1213c031c93bSTakanori Watanabe 			break;
12142ef23c6dSTakanori Watanabe 		if (vaddr + event->event_size < vaddr)
12152ef23c6dSTakanori Watanabe 			break;
1216c031c93bSTakanori Watanabe 		if (event->event_type == 0 && event->event_size == 0)
1217c031c93bSTakanori Watanabe 			break;
1218c031c93bSTakanori Watanabe #if 0
1219c031c93bSTakanori Watanabe 		{
1220c031c93bSTakanori Watanabe 		unsigned int i, j, k;
1221c031c93bSTakanori Watanabe 
1222c031c93bSTakanori Watanabe 		printf("\n\tsize %d\n\t\t%p ", event->event_size, vaddr);
1223c031c93bSTakanori Watanabe 		for (j = 0, i = 0; i <
1224c031c93bSTakanori Watanabe 		    sizeof(struct TCPAevent) + event->event_size; i++) {
1225c031c93bSTakanori Watanabe 			printf("%02x ", vaddr[i]);
1226c031c93bSTakanori Watanabe 			if ((i+1) % 8 == 0) {
1227c031c93bSTakanori Watanabe 				for (k = 0; k < 8; k++)
1228c031c93bSTakanori Watanabe 					printf("%c", isprint(vaddr[j+k]) ?
1229c031c93bSTakanori Watanabe 					    vaddr[j+k] : '.');
1230c031c93bSTakanori Watanabe 				printf("\n\t\t%p ", &vaddr[i + 1]);
1231c031c93bSTakanori Watanabe 				j = i + 1;
1232c031c93bSTakanori Watanabe 			}
1233c031c93bSTakanori Watanabe 		}
1234c031c93bSTakanori Watanabe 		printf("\n"); }
1235c031c93bSTakanori Watanabe #endif
1236c031c93bSTakanori Watanabe 		acpi_print_tcpa(event);
1237c031c93bSTakanori Watanabe 
1238c031c93bSTakanori Watanabe 		vaddr += sizeof(struct TCPAevent) + event->event_size;
1239c031c93bSTakanori Watanabe 	}
1240c031c93bSTakanori Watanabe 
1241c031c93bSTakanori Watanabe 	printf(END_COMMENT);
1242c031c93bSTakanori Watanabe }
1243877fc2e3STakanori Watanabe static void acpi_handle_tpm2(ACPI_TABLE_HEADER *sdp)
1244877fc2e3STakanori Watanabe {
1245877fc2e3STakanori Watanabe 	ACPI_TABLE_TPM2 *tpm2;
1246877fc2e3STakanori Watanabe 
1247877fc2e3STakanori Watanabe 	printf (BEGIN_COMMENT);
1248877fc2e3STakanori Watanabe 	acpi_print_sdt(sdp);
1249877fc2e3STakanori Watanabe 	tpm2 = (ACPI_TABLE_TPM2 *) sdp;
12507aef7138SCy Schubert 	printf ("\t\tControlArea=%jx\n", tpm2->ControlAddress);
1251877fc2e3STakanori Watanabe 	printf ("\t\tStartMethod=%x\n", tpm2->StartMethod);
1252877fc2e3STakanori Watanabe 	printf (END_COMMENT);
1253877fc2e3STakanori Watanabe }
1254c031c93bSTakanori Watanabe 
1255ec650989SNeel Natu static const char *
1256ec650989SNeel Natu devscope_type2str(int type)
1257ec650989SNeel Natu {
1258ec650989SNeel Natu 	static char typebuf[16];
1259ec650989SNeel Natu 
1260ec650989SNeel Natu 	switch (type) {
1261ec650989SNeel Natu 	case 1:
1262ec650989SNeel Natu 		return ("PCI Endpoint Device");
1263ec650989SNeel Natu 	case 2:
1264ec650989SNeel Natu 		return ("PCI Sub-Hierarchy");
1265ec650989SNeel Natu 	case 3:
1266ec650989SNeel Natu 		return ("IOAPIC");
1267ec650989SNeel Natu 	case 4:
1268ec650989SNeel Natu 		return ("HPET");
1269ec650989SNeel Natu 	default:
1270ec650989SNeel Natu 		snprintf(typebuf, sizeof(typebuf), "%d", type);
1271ec650989SNeel Natu 		return (typebuf);
1272ec650989SNeel Natu 	}
1273ec650989SNeel Natu }
1274ec650989SNeel Natu 
1275ec650989SNeel Natu static int
1276ec650989SNeel Natu acpi_handle_dmar_devscope(void *addr, int remaining)
1277ec650989SNeel Natu {
1278ec650989SNeel Natu 	char sep;
1279ec650989SNeel Natu 	int pathlen;
1280ec650989SNeel Natu 	ACPI_DMAR_PCI_PATH *path, *pathend;
1281ec650989SNeel Natu 	ACPI_DMAR_DEVICE_SCOPE *devscope = addr;
1282ec650989SNeel Natu 
1283ec650989SNeel Natu 	if (remaining < (int)sizeof(ACPI_DMAR_DEVICE_SCOPE))
1284ec650989SNeel Natu 		return (-1);
1285ec650989SNeel Natu 
1286ec650989SNeel Natu 	if (remaining < devscope->Length)
1287ec650989SNeel Natu 		return (-1);
1288ec650989SNeel Natu 
1289ec650989SNeel Natu 	printf("\n");
1290ec650989SNeel Natu 	printf("\t\tType=%s\n", devscope_type2str(devscope->EntryType));
1291ec650989SNeel Natu 	printf("\t\tLength=%d\n", devscope->Length);
1292ec650989SNeel Natu 	printf("\t\tEnumerationId=%d\n", devscope->EnumerationId);
1293ec650989SNeel Natu 	printf("\t\tStartBusNumber=%d\n", devscope->Bus);
1294ec650989SNeel Natu 
1295ec650989SNeel Natu 	path = (ACPI_DMAR_PCI_PATH *)(devscope + 1);
1296ec650989SNeel Natu 	pathlen = devscope->Length - sizeof(ACPI_DMAR_DEVICE_SCOPE);
1297ec650989SNeel Natu 	pathend = path + pathlen / sizeof(ACPI_DMAR_PCI_PATH);
1298ec650989SNeel Natu 	if (path < pathend) {
1299ec650989SNeel Natu 		sep = '{';
1300ec650989SNeel Natu 		printf("\t\tPath=");
1301ec650989SNeel Natu 		do {
1302ec650989SNeel Natu 			printf("%c%d:%d", sep, path->Device, path->Function);
1303ec650989SNeel Natu 			sep=',';
1304ec650989SNeel Natu 			path++;
1305ec650989SNeel Natu 		} while (path < pathend);
1306ec650989SNeel Natu 		printf("}\n");
1307ec650989SNeel Natu 	}
1308ec650989SNeel Natu 
1309ec650989SNeel Natu 	return (devscope->Length);
1310ec650989SNeel Natu }
1311ec650989SNeel Natu 
1312ec650989SNeel Natu static void
1313ec650989SNeel Natu acpi_handle_dmar_drhd(ACPI_DMAR_HARDWARE_UNIT *drhd)
1314ec650989SNeel Natu {
1315ec650989SNeel Natu 	char *cp;
1316ec650989SNeel Natu 	int remaining, consumed;
1317ec650989SNeel Natu 
1318ec650989SNeel Natu 	printf("\n");
1319ec650989SNeel Natu 	printf("\tType=DRHD\n");
1320ec650989SNeel Natu 	printf("\tLength=%d\n", drhd->Header.Length);
1321ec650989SNeel Natu 
1322ec650989SNeel Natu #define	PRINTFLAG(var, flag)	printflag((var), ACPI_DMAR_## flag, #flag)
1323ec650989SNeel Natu 
1324ec650989SNeel Natu 	printf("\tFlags=");
1325ec650989SNeel Natu 	PRINTFLAG(drhd->Flags, INCLUDE_ALL);
1326ec650989SNeel Natu 	PRINTFLAG_END();
1327ec650989SNeel Natu 
1328ec650989SNeel Natu #undef PRINTFLAG
1329ec650989SNeel Natu 
1330ec650989SNeel Natu 	printf("\tSegment=%d\n", drhd->Segment);
13317d369c6eSJung-uk Kim 	printf("\tAddress=0x%016jx\n", (uintmax_t)drhd->Address);
1332ec650989SNeel Natu 
1333ec650989SNeel Natu 	remaining = drhd->Header.Length - sizeof(ACPI_DMAR_HARDWARE_UNIT);
1334ec650989SNeel Natu 	if (remaining > 0)
1335ec650989SNeel Natu 		printf("\tDevice Scope:");
1336ec650989SNeel Natu 	while (remaining > 0) {
1337ec650989SNeel Natu 		cp = (char *)drhd + drhd->Header.Length - remaining;
1338ec650989SNeel Natu 		consumed = acpi_handle_dmar_devscope(cp, remaining);
1339ec650989SNeel Natu 		if (consumed <= 0)
1340ec650989SNeel Natu 			break;
1341ec650989SNeel Natu 		else
1342ec650989SNeel Natu 			remaining -= consumed;
1343ec650989SNeel Natu 	}
1344ec650989SNeel Natu }
1345ec650989SNeel Natu 
1346ec650989SNeel Natu static void
1347ec650989SNeel Natu acpi_handle_dmar_rmrr(ACPI_DMAR_RESERVED_MEMORY *rmrr)
1348ec650989SNeel Natu {
1349ec650989SNeel Natu 	char *cp;
1350ec650989SNeel Natu 	int remaining, consumed;
1351ec650989SNeel Natu 
1352ec650989SNeel Natu 	printf("\n");
1353ec650989SNeel Natu 	printf("\tType=RMRR\n");
1354ec650989SNeel Natu 	printf("\tLength=%d\n", rmrr->Header.Length);
1355ec650989SNeel Natu 	printf("\tSegment=%d\n", rmrr->Segment);
13567d369c6eSJung-uk Kim 	printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rmrr->BaseAddress);
13577d369c6eSJung-uk Kim 	printf("\tLimitAddress=0x%016jx\n", (uintmax_t)rmrr->EndAddress);
1358ec650989SNeel Natu 
1359ec650989SNeel Natu 	remaining = rmrr->Header.Length - sizeof(ACPI_DMAR_RESERVED_MEMORY);
1360ec650989SNeel Natu 	if (remaining > 0)
1361ec650989SNeel Natu 		printf("\tDevice Scope:");
1362ec650989SNeel Natu 	while (remaining > 0) {
1363ec650989SNeel Natu 		cp = (char *)rmrr + rmrr->Header.Length - remaining;
1364ec650989SNeel Natu 		consumed = acpi_handle_dmar_devscope(cp, remaining);
1365ec650989SNeel Natu 		if (consumed <= 0)
1366ec650989SNeel Natu 			break;
1367ec650989SNeel Natu 		else
1368ec650989SNeel Natu 			remaining -= consumed;
1369ec650989SNeel Natu 	}
1370ec650989SNeel Natu }
1371ec650989SNeel Natu 
1372ec650989SNeel Natu static void
1373ec650989SNeel Natu acpi_handle_dmar_atsr(ACPI_DMAR_ATSR *atsr)
1374ec650989SNeel Natu {
1375ec650989SNeel Natu 	char *cp;
1376ec650989SNeel Natu 	int remaining, consumed;
1377ec650989SNeel Natu 
1378ec650989SNeel Natu 	printf("\n");
1379ec650989SNeel Natu 	printf("\tType=ATSR\n");
1380ec650989SNeel Natu 	printf("\tLength=%d\n", atsr->Header.Length);
1381ec650989SNeel Natu 
1382ec650989SNeel Natu #define	PRINTFLAG(var, flag)	printflag((var), ACPI_DMAR_## flag, #flag)
1383ec650989SNeel Natu 
1384ec650989SNeel Natu 	printf("\tFlags=");
1385ec650989SNeel Natu 	PRINTFLAG(atsr->Flags, ALL_PORTS);
1386ec650989SNeel Natu 	PRINTFLAG_END();
1387ec650989SNeel Natu 
1388ec650989SNeel Natu #undef PRINTFLAG
1389ec650989SNeel Natu 
1390ec650989SNeel Natu 	printf("\tSegment=%d\n", atsr->Segment);
1391ec650989SNeel Natu 
1392ec650989SNeel Natu 	remaining = atsr->Header.Length - sizeof(ACPI_DMAR_ATSR);
1393ec650989SNeel Natu 	if (remaining > 0)
1394ec650989SNeel Natu 		printf("\tDevice Scope:");
1395ec650989SNeel Natu 	while (remaining > 0) {
1396ec650989SNeel Natu 		cp = (char *)atsr + atsr->Header.Length - remaining;
1397ec650989SNeel Natu 		consumed = acpi_handle_dmar_devscope(cp, remaining);
1398ec650989SNeel Natu 		if (consumed <= 0)
1399ec650989SNeel Natu 			break;
1400ec650989SNeel Natu 		else
1401ec650989SNeel Natu 			remaining -= consumed;
1402ec650989SNeel Natu 	}
1403ec650989SNeel Natu }
1404ec650989SNeel Natu 
1405ec650989SNeel Natu static void
1406ec650989SNeel Natu acpi_handle_dmar_rhsa(ACPI_DMAR_RHSA *rhsa)
1407ec650989SNeel Natu {
1408ec650989SNeel Natu 
1409ec650989SNeel Natu 	printf("\n");
1410ec650989SNeel Natu 	printf("\tType=RHSA\n");
1411ec650989SNeel Natu 	printf("\tLength=%d\n", rhsa->Header.Length);
14127d369c6eSJung-uk Kim 	printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rhsa->BaseAddress);
1413ec650989SNeel Natu 	printf("\tProximityDomain=0x%08x\n", rhsa->ProximityDomain);
1414ec650989SNeel Natu }
1415ec650989SNeel Natu 
1416ec650989SNeel Natu static int
1417ec650989SNeel Natu acpi_handle_dmar_remapping_structure(void *addr, int remaining)
1418ec650989SNeel Natu {
1419ec650989SNeel Natu 	ACPI_DMAR_HEADER *hdr = addr;
1420ec650989SNeel Natu 
1421ec650989SNeel Natu 	if (remaining < (int)sizeof(ACPI_DMAR_HEADER))
1422ec650989SNeel Natu 		return (-1);
1423ec650989SNeel Natu 
1424ec650989SNeel Natu 	if (remaining < hdr->Length)
1425ec650989SNeel Natu 		return (-1);
1426ec650989SNeel Natu 
1427ec650989SNeel Natu 	switch (hdr->Type) {
1428ec650989SNeel Natu 	case ACPI_DMAR_TYPE_HARDWARE_UNIT:
1429ec650989SNeel Natu 		acpi_handle_dmar_drhd(addr);
1430ec650989SNeel Natu 		break;
1431ec650989SNeel Natu 	case ACPI_DMAR_TYPE_RESERVED_MEMORY:
1432ec650989SNeel Natu 		acpi_handle_dmar_rmrr(addr);
1433ec650989SNeel Natu 		break;
1434313a0c13SJung-uk Kim 	case ACPI_DMAR_TYPE_ROOT_ATS:
1435ec650989SNeel Natu 		acpi_handle_dmar_atsr(addr);
1436ec650989SNeel Natu 		break;
1437313a0c13SJung-uk Kim 	case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
1438ec650989SNeel Natu 		acpi_handle_dmar_rhsa(addr);
1439ec650989SNeel Natu 		break;
1440ec650989SNeel Natu 	default:
1441ec650989SNeel Natu 		printf("\n");
1442ec650989SNeel Natu 		printf("\tType=%d\n", hdr->Type);
1443ec650989SNeel Natu 		printf("\tLength=%d\n", hdr->Length);
1444ec650989SNeel Natu 		break;
1445ec650989SNeel Natu 	}
1446ec650989SNeel Natu 	return (hdr->Length);
1447ec650989SNeel Natu }
1448ec650989SNeel Natu 
1449ec650989SNeel Natu #ifndef ACPI_DMAR_X2APIC_OPT_OUT
1450ec650989SNeel Natu #define	ACPI_DMAR_X2APIC_OPT_OUT	(0x2)
1451ec650989SNeel Natu #endif
1452ec650989SNeel Natu 
1453ec650989SNeel Natu static void
1454ec650989SNeel Natu acpi_handle_dmar(ACPI_TABLE_HEADER *sdp)
1455ec650989SNeel Natu {
1456ec650989SNeel Natu 	char *cp;
1457ec650989SNeel Natu 	int remaining, consumed;
1458ec650989SNeel Natu 	ACPI_TABLE_DMAR *dmar;
1459ec650989SNeel Natu 
1460ec650989SNeel Natu 	printf(BEGIN_COMMENT);
1461ec650989SNeel Natu 	acpi_print_sdt(sdp);
1462ec650989SNeel Natu 	dmar = (ACPI_TABLE_DMAR *)sdp;
1463ec650989SNeel Natu 	printf("\tHost Address Width=%d\n", dmar->Width + 1);
1464ec650989SNeel Natu 
1465ec650989SNeel Natu #define PRINTFLAG(var, flag)	printflag((var), ACPI_DMAR_## flag, #flag)
1466ec650989SNeel Natu 
1467ec650989SNeel Natu 	printf("\tFlags=");
1468ec650989SNeel Natu 	PRINTFLAG(dmar->Flags, INTR_REMAP);
1469ec650989SNeel Natu 	PRINTFLAG(dmar->Flags, X2APIC_OPT_OUT);
1470ec650989SNeel Natu 	PRINTFLAG_END();
1471ec650989SNeel Natu 
1472ec650989SNeel Natu #undef PRINTFLAG
1473ec650989SNeel Natu 
1474ec650989SNeel Natu 	remaining = sdp->Length - sizeof(ACPI_TABLE_DMAR);
1475ec650989SNeel Natu 	while (remaining > 0) {
1476ec650989SNeel Natu 		cp = (char *)sdp + sdp->Length - remaining;
1477ec650989SNeel Natu 		consumed = acpi_handle_dmar_remapping_structure(cp, remaining);
1478ec650989SNeel Natu 		if (consumed <= 0)
1479ec650989SNeel Natu 			break;
1480ec650989SNeel Natu 		else
1481ec650989SNeel Natu 			remaining -= consumed;
1482ec650989SNeel Natu 	}
1483ec650989SNeel Natu 
1484ec650989SNeel Natu 	printf(END_COMMENT);
1485ec650989SNeel Natu }
1486ec650989SNeel Natu 
1487a0333ad1SJohn Baldwin static void
1488986dffafSJohn Baldwin acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp)
1489a0333ad1SJohn Baldwin {
1490a0333ad1SJohn Baldwin 
1491a0333ad1SJohn Baldwin 	printf("\tFlags={");
1492986dffafSJohn Baldwin 	if (mp->Flags & ACPI_SRAT_MEM_ENABLED)
1493a0333ad1SJohn Baldwin 		printf("ENABLED");
1494a0333ad1SJohn Baldwin 	else
1495a0333ad1SJohn Baldwin 		printf("DISABLED");
1496986dffafSJohn Baldwin 	if (mp->Flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)
1497a0333ad1SJohn Baldwin 		printf(",HOT_PLUGGABLE");
1498986dffafSJohn Baldwin 	if (mp->Flags & ACPI_SRAT_MEM_NON_VOLATILE)
1499a0333ad1SJohn Baldwin 		printf(",NON_VOLATILE");
1500a0333ad1SJohn Baldwin 	printf("}\n");
1501986dffafSJohn Baldwin 	printf("\tBase Address=0x%016jx\n", (uintmax_t)mp->BaseAddress);
1502986dffafSJohn Baldwin 	printf("\tLength=0x%016jx\n", (uintmax_t)mp->Length);
1503986dffafSJohn Baldwin 	printf("\tProximity Domain=%d\n", mp->ProximityDomain);
1504a0333ad1SJohn Baldwin }
1505a0333ad1SJohn Baldwin 
150627941afaSEd Maste static const char *srat_types[] = {
150727941afaSEd Maste     [ACPI_SRAT_TYPE_CPU_AFFINITY] = "CPU",
150827941afaSEd Maste     [ACPI_SRAT_TYPE_MEMORY_AFFINITY] = "Memory",
150927941afaSEd Maste     [ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY] = "X2APIC",
1510cebb7b19SEd Maste     [ACPI_SRAT_TYPE_GICC_AFFINITY] = "GICC",
1511cebb7b19SEd Maste     [ACPI_SRAT_TYPE_GIC_ITS_AFFINITY] = "GIC ITS",
151227941afaSEd Maste };
1513a0333ad1SJohn Baldwin 
1514a0333ad1SJohn Baldwin static void
1515986dffafSJohn Baldwin acpi_print_srat(ACPI_SUBTABLE_HEADER *srat)
1516a0333ad1SJohn Baldwin {
1517986dffafSJohn Baldwin 	ACPI_SRAT_CPU_AFFINITY *cpu;
1518986dffafSJohn Baldwin 	ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic;
15192b2b1f42SAndrew Turner 	ACPI_SRAT_GICC_AFFINITY *gic;
1520a0333ad1SJohn Baldwin 
1521c86932b6SMarcelo Araujo 	if (srat->Type < nitems(srat_types))
1522986dffafSJohn Baldwin 		printf("\tType=%s\n", srat_types[srat->Type]);
1523a0333ad1SJohn Baldwin 	else
1524986dffafSJohn Baldwin 		printf("\tType=%d (unknown)\n", srat->Type);
1525986dffafSJohn Baldwin 	switch (srat->Type) {
1526a0333ad1SJohn Baldwin 	case ACPI_SRAT_TYPE_CPU_AFFINITY:
1527986dffafSJohn Baldwin 		cpu = (ACPI_SRAT_CPU_AFFINITY *)srat;
1528986dffafSJohn Baldwin 		acpi_print_srat_cpu(cpu->ApicId,
1529986dffafSJohn Baldwin 		    cpu->ProximityDomainHi[2] << 24 |
1530986dffafSJohn Baldwin 		    cpu->ProximityDomainHi[1] << 16 |
1531986dffafSJohn Baldwin 		    cpu->ProximityDomainHi[0] << 0 |
1532986dffafSJohn Baldwin 		    cpu->ProximityDomainLo, cpu->Flags);
1533a0333ad1SJohn Baldwin 		break;
1534a0333ad1SJohn Baldwin 	case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
1535986dffafSJohn Baldwin 		acpi_print_srat_memory((ACPI_SRAT_MEM_AFFINITY *)srat);
1536a0333ad1SJohn Baldwin 		break;
1537a0333ad1SJohn Baldwin 	case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
1538986dffafSJohn Baldwin 		x2apic = (ACPI_SRAT_X2APIC_CPU_AFFINITY *)srat;
1539986dffafSJohn Baldwin 		acpi_print_srat_cpu(x2apic->ApicId, x2apic->ProximityDomain,
1540986dffafSJohn Baldwin 		    x2apic->Flags);
1541a0333ad1SJohn Baldwin 		break;
15422b2b1f42SAndrew Turner 	case ACPI_SRAT_TYPE_GICC_AFFINITY:
15432b2b1f42SAndrew Turner 		gic = (ACPI_SRAT_GICC_AFFINITY *)srat;
15442b2b1f42SAndrew Turner 		acpi_print_srat_cpu(gic->AcpiProcessorUid, gic->ProximityDomain,
15452b2b1f42SAndrew Turner 		    gic->Flags);
15462b2b1f42SAndrew Turner 		break;
1547a0333ad1SJohn Baldwin 	}
1548a0333ad1SJohn Baldwin }
1549a0333ad1SJohn Baldwin 
1550a0333ad1SJohn Baldwin static void
1551986dffafSJohn Baldwin acpi_handle_srat(ACPI_TABLE_HEADER *sdp)
1552a0333ad1SJohn Baldwin {
1553986dffafSJohn Baldwin 	ACPI_TABLE_SRAT *srat;
1554a0333ad1SJohn Baldwin 
1555a0333ad1SJohn Baldwin 	printf(BEGIN_COMMENT);
1556a0333ad1SJohn Baldwin 	acpi_print_sdt(sdp);
1557986dffafSJohn Baldwin 	srat = (ACPI_TABLE_SRAT *)sdp;
1558986dffafSJohn Baldwin 	printf("\tTable Revision=%d\n", srat->TableRevision);
1559986dffafSJohn Baldwin 	acpi_walk_subtables(sdp, (srat + 1), acpi_print_srat);
1560a0333ad1SJohn Baldwin 	printf(END_COMMENT);
1561a0333ad1SJohn Baldwin }
1562a0333ad1SJohn Baldwin 
1563340c0022SEd Maste static const char *nfit_types[] = {
1564340c0022SEd Maste     [ACPI_NFIT_TYPE_SYSTEM_ADDRESS] = "System Address",
1565340c0022SEd Maste     [ACPI_NFIT_TYPE_MEMORY_MAP] = "Memory Map",
1566340c0022SEd Maste     [ACPI_NFIT_TYPE_INTERLEAVE] = "Interleave",
1567340c0022SEd Maste     [ACPI_NFIT_TYPE_SMBIOS] = "SMBIOS",
1568340c0022SEd Maste     [ACPI_NFIT_TYPE_CONTROL_REGION] = "Control Region",
1569340c0022SEd Maste     [ACPI_NFIT_TYPE_DATA_REGION] = "Data Region",
15701b109c69SAlexander Motin     [ACPI_NFIT_TYPE_FLUSH_ADDRESS] = "Flush Address",
15711b109c69SAlexander Motin     [ACPI_NFIT_TYPE_CAPABILITIES] = "Platform Capabilities"
1572340c0022SEd Maste };
1573340c0022SEd Maste 
1574340c0022SEd Maste 
1575340c0022SEd Maste static void
1576340c0022SEd Maste acpi_print_nfit(ACPI_NFIT_HEADER *nfit)
1577340c0022SEd Maste {
1578340c0022SEd Maste 	char *uuidstr;
15793b7935f3SAlexander Motin 	uint32_t m, status;
1580340c0022SEd Maste 
1581340c0022SEd Maste 	ACPI_NFIT_SYSTEM_ADDRESS *sysaddr;
1582340c0022SEd Maste 	ACPI_NFIT_MEMORY_MAP *mmap;
1583340c0022SEd Maste 	ACPI_NFIT_INTERLEAVE *ileave;
1584340c0022SEd Maste 	ACPI_NFIT_CONTROL_REGION *ctlreg;
1585340c0022SEd Maste 	ACPI_NFIT_DATA_REGION *datareg;
1586340c0022SEd Maste 	ACPI_NFIT_FLUSH_ADDRESS *fladdr;
15871b109c69SAlexander Motin 	ACPI_NFIT_CAPABILITIES *caps;
1588340c0022SEd Maste 
1589340c0022SEd Maste 	if (nfit->Type < nitems(nfit_types))
1590340c0022SEd Maste 		printf("\tType=%s\n", nfit_types[nfit->Type]);
1591340c0022SEd Maste 	else
1592340c0022SEd Maste 		printf("\tType=%u (unknown)\n", nfit->Type);
1593340c0022SEd Maste 	switch (nfit->Type) {
1594340c0022SEd Maste 	case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
1595340c0022SEd Maste 		sysaddr = (ACPI_NFIT_SYSTEM_ADDRESS *)nfit;
1596340c0022SEd Maste 		printf("\tRangeIndex=%u\n", (u_int)sysaddr->RangeIndex);
1597340c0022SEd Maste 		printf("\tProximityDomain=%u\n",
1598340c0022SEd Maste 		    (u_int)sysaddr->ProximityDomain);
1599340c0022SEd Maste 		uuid_to_string((uuid_t *)(sysaddr->RangeGuid),
1600340c0022SEd Maste 		    &uuidstr, &status);
1601340c0022SEd Maste 		if (status != uuid_s_ok)
1602340c0022SEd Maste 			errx(1, "uuid_to_string: status=%u", status);
1603340c0022SEd Maste 		printf("\tRangeGuid=%s\n", uuidstr);
1604340c0022SEd Maste 		free(uuidstr);
1605340c0022SEd Maste 		printf("\tAddress=0x%016jx\n", (uintmax_t)sysaddr->Address);
1606340c0022SEd Maste 		printf("\tLength=0x%016jx\n", (uintmax_t)sysaddr->Length);
1607340c0022SEd Maste 		printf("\tMemoryMapping=0x%016jx\n",
1608340c0022SEd Maste 		    (uintmax_t)sysaddr->MemoryMapping);
1609340c0022SEd Maste 
1610340c0022SEd Maste #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_## flag, #flag)
1611340c0022SEd Maste 
1612340c0022SEd Maste 		printf("\tFlags=");
1613340c0022SEd Maste 		PRINTFLAG(sysaddr->Flags, ADD_ONLINE_ONLY);
1614340c0022SEd Maste 		PRINTFLAG(sysaddr->Flags, PROXIMITY_VALID);
1615340c0022SEd Maste 		PRINTFLAG_END();
1616340c0022SEd Maste 
1617340c0022SEd Maste #undef PRINTFLAG
1618340c0022SEd Maste 
1619340c0022SEd Maste 		break;
1620340c0022SEd Maste 	case ACPI_NFIT_TYPE_MEMORY_MAP:
1621340c0022SEd Maste 		mmap = (ACPI_NFIT_MEMORY_MAP *)nfit;
162292d0d6bbSAlexander Motin 		printf("\tDeviceHandle=0x%x\n", (u_int)mmap->DeviceHandle);
162392d0d6bbSAlexander Motin 		printf("\tPhysicalId=0x%04x\n", (u_int)mmap->PhysicalId);
1624340c0022SEd Maste 		printf("\tRegionId=%u\n", (u_int)mmap->RegionId);
1625340c0022SEd Maste 		printf("\tRangeIndex=%u\n", (u_int)mmap->RangeIndex);
1626340c0022SEd Maste 		printf("\tRegionIndex=%u\n", (u_int)mmap->RegionIndex);
1627340c0022SEd Maste 		printf("\tRegionSize=0x%016jx\n", (uintmax_t)mmap->RegionSize);
1628340c0022SEd Maste 		printf("\tRegionOffset=0x%016jx\n",
1629340c0022SEd Maste 		    (uintmax_t)mmap->RegionOffset);
1630340c0022SEd Maste 		printf("\tAddress=0x%016jx\n", (uintmax_t)mmap->Address);
1631340c0022SEd Maste 		printf("\tInterleaveIndex=%u\n", (u_int)mmap->InterleaveIndex);
1632fb1cf2a9SAlexander Motin 		printf("\tInterleaveWays=%u\n", (u_int)mmap->InterleaveWays);
1633340c0022SEd Maste 
1634340c0022SEd Maste #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_MEM_## flag, #flag)
1635340c0022SEd Maste 
1636340c0022SEd Maste 		printf("\tFlags=");
1637340c0022SEd Maste 		PRINTFLAG(mmap->Flags, SAVE_FAILED);
1638340c0022SEd Maste 		PRINTFLAG(mmap->Flags, RESTORE_FAILED);
1639340c0022SEd Maste 		PRINTFLAG(mmap->Flags, FLUSH_FAILED);
1640340c0022SEd Maste 		PRINTFLAG(mmap->Flags, NOT_ARMED);
1641340c0022SEd Maste 		PRINTFLAG(mmap->Flags, HEALTH_OBSERVED);
1642340c0022SEd Maste 		PRINTFLAG(mmap->Flags, HEALTH_ENABLED);
1643340c0022SEd Maste 		PRINTFLAG(mmap->Flags, MAP_FAILED);
1644340c0022SEd Maste 		PRINTFLAG_END();
1645340c0022SEd Maste 
1646340c0022SEd Maste #undef PRINTFLAG
1647340c0022SEd Maste 
1648340c0022SEd Maste 		break;
1649340c0022SEd Maste 	case ACPI_NFIT_TYPE_INTERLEAVE:
1650340c0022SEd Maste 		ileave = (ACPI_NFIT_INTERLEAVE *)nfit;
1651340c0022SEd Maste 		printf("\tInterleaveIndex=%u\n",
1652340c0022SEd Maste 		    (u_int)ileave->InterleaveIndex);
1653340c0022SEd Maste 		printf("\tLineCount=%u\n", (u_int)ileave->LineCount);
1654340c0022SEd Maste 		printf("\tLineSize=%u\n", (u_int)ileave->LineSize);
16553b7935f3SAlexander Motin 		for (m = 0; m < ileave->LineCount; m++) {
16563b7935f3SAlexander Motin 			printf("\tLine%uOffset=0x%08x\n", (u_int)m + 1,
16573b7935f3SAlexander Motin 			    (u_int)ileave->LineOffset[m]);
16583b7935f3SAlexander Motin 		}
1659340c0022SEd Maste 		break;
1660340c0022SEd Maste 	case ACPI_NFIT_TYPE_SMBIOS:
1661340c0022SEd Maste 		/* XXX smbios->Data[x] output is not supported */
1662340c0022SEd Maste 		break;
1663340c0022SEd Maste 	case ACPI_NFIT_TYPE_CONTROL_REGION:
1664340c0022SEd Maste 		ctlreg = (ACPI_NFIT_CONTROL_REGION *)nfit;
1665340c0022SEd Maste 		printf("\tRegionIndex=%u\n", (u_int)ctlreg->RegionIndex);
1666340c0022SEd Maste 		printf("\tVendorId=0x%04x\n", (u_int)ctlreg->VendorId);
1667340c0022SEd Maste 		printf("\tDeviceId=0x%04x\n", (u_int)ctlreg->DeviceId);
166835e39fd9SAlexander Motin 		printf("\tRevisionId=0x%02x\n", (u_int)ctlreg->RevisionId);
1669340c0022SEd Maste 		printf("\tSubsystemVendorId=0x%04x\n",
1670340c0022SEd Maste 		    (u_int)ctlreg->SubsystemVendorId);
1671340c0022SEd Maste 		printf("\tSubsystemDeviceId=0x%04x\n",
1672340c0022SEd Maste 		    (u_int)ctlreg->SubsystemDeviceId);
167335e39fd9SAlexander Motin 		printf("\tSubsystemRevisionId=0x%02x\n",
1674340c0022SEd Maste 		    (u_int)ctlreg->SubsystemRevisionId);
1675d4c2de2eSAlexander Motin 		printf("\tValidFields=0x%02x\n", (u_int)ctlreg->ValidFields);
167635e39fd9SAlexander Motin 		printf("\tManufacturingLocation=0x%02x\n",
1677340c0022SEd Maste 		    (u_int)ctlreg->ManufacturingLocation);
167835e39fd9SAlexander Motin 		printf("\tManufacturingDate=%04x\n",
167935e39fd9SAlexander Motin 		    (u_int)be16toh(ctlreg->ManufacturingDate));
168035e39fd9SAlexander Motin 		printf("\tSerialNumber=%08X\n",
168135e39fd9SAlexander Motin 		    (u_int)be32toh(ctlreg->SerialNumber));
1682fb1cf2a9SAlexander Motin 		printf("\tCode=0x%04x\n", (u_int)ctlreg->Code);
1683340c0022SEd Maste 		printf("\tWindows=%u\n", (u_int)ctlreg->Windows);
1684340c0022SEd Maste 		printf("\tWindowSize=0x%016jx\n",
1685340c0022SEd Maste 		    (uintmax_t)ctlreg->WindowSize);
1686340c0022SEd Maste 		printf("\tCommandOffset=0x%016jx\n",
1687340c0022SEd Maste 		    (uintmax_t)ctlreg->CommandOffset);
1688340c0022SEd Maste 		printf("\tCommandSize=0x%016jx\n",
1689340c0022SEd Maste 		    (uintmax_t)ctlreg->CommandSize);
1690340c0022SEd Maste 		printf("\tStatusOffset=0x%016jx\n",
1691340c0022SEd Maste 		    (uintmax_t)ctlreg->StatusOffset);
1692340c0022SEd Maste 		printf("\tStatusSize=0x%016jx\n",
1693340c0022SEd Maste 		    (uintmax_t)ctlreg->StatusSize);
1694340c0022SEd Maste 
1695340c0022SEd Maste #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_## flag, #flag)
1696340c0022SEd Maste 
1697340c0022SEd Maste 		printf("\tFlags=");
1698d4c2de2eSAlexander Motin 		PRINTFLAG(ctlreg->Flags, CONTROL_BUFFERED);
1699340c0022SEd Maste 		PRINTFLAG_END();
1700340c0022SEd Maste 
1701340c0022SEd Maste #undef PRINTFLAG
1702340c0022SEd Maste 
1703340c0022SEd Maste 		break;
1704340c0022SEd Maste 	case ACPI_NFIT_TYPE_DATA_REGION:
1705340c0022SEd Maste 		datareg = (ACPI_NFIT_DATA_REGION *)nfit;
1706340c0022SEd Maste 		printf("\tRegionIndex=%u\n", (u_int)datareg->RegionIndex);
1707340c0022SEd Maste 		printf("\tWindows=%u\n", (u_int)datareg->Windows);
1708340c0022SEd Maste 		printf("\tOffset=0x%016jx\n", (uintmax_t)datareg->Offset);
1709340c0022SEd Maste 		printf("\tSize=0x%016jx\n", (uintmax_t)datareg->Size);
1710340c0022SEd Maste 		printf("\tCapacity=0x%016jx\n", (uintmax_t)datareg->Capacity);
1711340c0022SEd Maste 		printf("\tStartAddress=0x%016jx\n",
1712340c0022SEd Maste 		    (uintmax_t)datareg->StartAddress);
1713340c0022SEd Maste 		break;
1714340c0022SEd Maste 	case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
1715340c0022SEd Maste 		fladdr = (ACPI_NFIT_FLUSH_ADDRESS *)nfit;
1716340c0022SEd Maste 		printf("\tDeviceHandle=%u\n", (u_int)fladdr->DeviceHandle);
1717340c0022SEd Maste 		printf("\tHintCount=%u\n", (u_int)fladdr->HintCount);
17183b7935f3SAlexander Motin 		for (m = 0; m < fladdr->HintCount; m++) {
17193b7935f3SAlexander Motin 			printf("\tHintAddress%u=0x%016jx\n", (u_int)m + 1,
17203b7935f3SAlexander Motin 			    (uintmax_t)fladdr->HintAddress[m]);
17213b7935f3SAlexander Motin 		}
1722340c0022SEd Maste 		break;
17231b109c69SAlexander Motin 	case ACPI_NFIT_TYPE_CAPABILITIES:
17241b109c69SAlexander Motin 		caps = (ACPI_NFIT_CAPABILITIES *)nfit;
17251b109c69SAlexander Motin 		printf("\tHighestCapability=%u\n", (u_int)caps->HighestCapability);
17261b109c69SAlexander Motin 
17271b109c69SAlexander Motin #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_CAPABILITY_## flag, #flag)
17281b109c69SAlexander Motin 
17291b109c69SAlexander Motin 		printf("\tCapabilities=");
17301b109c69SAlexander Motin 		PRINTFLAG(caps->Capabilities, CACHE_FLUSH);
17311b109c69SAlexander Motin 		PRINTFLAG(caps->Capabilities, MEM_FLUSH);
17321b109c69SAlexander Motin 		PRINTFLAG(caps->Capabilities, MEM_MIRRORING);
17331b109c69SAlexander Motin 		PRINTFLAG_END();
17341b109c69SAlexander Motin 
17351b109c69SAlexander Motin #undef PRINTFLAG
17361b109c69SAlexander Motin 		break;
1737340c0022SEd Maste 	}
1738340c0022SEd Maste }
1739340c0022SEd Maste 
1740340c0022SEd Maste static void
1741340c0022SEd Maste acpi_handle_nfit(ACPI_TABLE_HEADER *sdp)
1742340c0022SEd Maste {
1743340c0022SEd Maste 	ACPI_TABLE_NFIT *nfit;
1744340c0022SEd Maste 
1745340c0022SEd Maste 	printf(BEGIN_COMMENT);
1746340c0022SEd Maste 	acpi_print_sdt(sdp);
1747340c0022SEd Maste 	nfit = (ACPI_TABLE_NFIT *)sdp;
1748340c0022SEd Maste 	acpi_walk_nfit(sdp, (nfit + 1), acpi_print_nfit);
1749340c0022SEd Maste 	printf(END_COMMENT);
1750340c0022SEd Maste }
1751340c0022SEd Maste 
1752a0333ad1SJohn Baldwin static void
1753986dffafSJohn Baldwin acpi_print_sdt(ACPI_TABLE_HEADER *sdp)
1754c62f1cccSMitsuru IWASAKI {
1755773b6454SNate Lawson 	printf("  ");
1756278f0de6SJung-uk Kim 	acpi_print_string(sdp->Signature, ACPI_NAMESEG_SIZE);
1757c62f1cccSMitsuru IWASAKI 	printf(": Length=%d, Revision=%d, Checksum=%d,\n",
1758986dffafSJohn Baldwin 	       sdp->Length, sdp->Revision, sdp->Checksum);
1759e1e9a4bfSMitsuru IWASAKI 	printf("\tOEMID=");
1760986dffafSJohn Baldwin 	acpi_print_string(sdp->OemId, ACPI_OEM_ID_SIZE);
1761e1e9a4bfSMitsuru IWASAKI 	printf(", OEM Table ID=");
1762986dffafSJohn Baldwin 	acpi_print_string(sdp->OemTableId, ACPI_OEM_TABLE_ID_SIZE);
1763986dffafSJohn Baldwin 	printf(", OEM Revision=0x%x,\n", sdp->OemRevision);
1764e1e9a4bfSMitsuru IWASAKI 	printf("\tCreator ID=");
1765278f0de6SJung-uk Kim 	acpi_print_string(sdp->AslCompilerId, ACPI_NAMESEG_SIZE);
1766986dffafSJohn Baldwin 	printf(", Creator Revision=0x%x\n", sdp->AslCompilerRevision);
1767e1e9a4bfSMitsuru IWASAKI }
1768e1e9a4bfSMitsuru IWASAKI 
1769945137d9SNate Lawson static void
1770986dffafSJohn Baldwin acpi_print_rsdt(ACPI_TABLE_HEADER *rsdp)
1771e1e9a4bfSMitsuru IWASAKI {
1772986dffafSJohn Baldwin 	ACPI_TABLE_RSDT *rsdt;
1773986dffafSJohn Baldwin 	ACPI_TABLE_XSDT *xsdt;
1774e1e9a4bfSMitsuru IWASAKI 	int	i, entries;
1775e1e9a4bfSMitsuru IWASAKI 
1776986dffafSJohn Baldwin 	rsdt = (ACPI_TABLE_RSDT *)rsdp;
1777986dffafSJohn Baldwin 	xsdt = (ACPI_TABLE_XSDT *)rsdp;
1778773b6454SNate Lawson 	printf(BEGIN_COMMENT);
1779773b6454SNate Lawson 	acpi_print_sdt(rsdp);
1780986dffafSJohn Baldwin 	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
1781e1e9a4bfSMitsuru IWASAKI 	printf("\tEntries={ ");
1782e1e9a4bfSMitsuru IWASAKI 	for (i = 0; i < entries; i++) {
1783e1e9a4bfSMitsuru IWASAKI 		if (i > 0)
1784e1e9a4bfSMitsuru IWASAKI 			printf(", ");
1785fe1d0c2dSJung-uk Kim 		if (addr_size == 4)
17867d369c6eSJung-uk Kim 			printf("0x%08x", le32toh(rsdt->TableOffsetEntry[i]));
1787fe1d0c2dSJung-uk Kim 		else
17887d369c6eSJung-uk Kim 			printf("0x%016jx",
17897d369c6eSJung-uk Kim 			    (uintmax_t)le64toh(xsdt->TableOffsetEntry[i]));
1790e1e9a4bfSMitsuru IWASAKI 	}
1791e1e9a4bfSMitsuru IWASAKI 	printf(" }\n");
1792c62f1cccSMitsuru IWASAKI 	printf(END_COMMENT);
1793e1e9a4bfSMitsuru IWASAKI }
1794e1e9a4bfSMitsuru IWASAKI 
17958e6a8737SNate Lawson static const char *acpi_pm_profiles[] = {
17968e6a8737SNate Lawson 	"Unspecified", "Desktop", "Mobile", "Workstation",
17978e6a8737SNate Lawson 	"Enterprise Server", "SOHO Server", "Appliance PC"
17988e6a8737SNate Lawson };
17998e6a8737SNate Lawson 
1800945137d9SNate Lawson static void
1801986dffafSJohn Baldwin acpi_print_fadt(ACPI_TABLE_HEADER *sdp)
1802e1e9a4bfSMitsuru IWASAKI {
1803986dffafSJohn Baldwin 	ACPI_TABLE_FADT *fadt;
18048e6a8737SNate Lawson 	const char *pm;
1805e1e9a4bfSMitsuru IWASAKI 
1806986dffafSJohn Baldwin 	fadt = (ACPI_TABLE_FADT *)sdp;
1807c62f1cccSMitsuru IWASAKI 	printf(BEGIN_COMMENT);
18082177d4e6SNate Lawson 	acpi_print_sdt(sdp);
1809986dffafSJohn Baldwin 	printf(" \tFACS=0x%x, DSDT=0x%x\n", fadt->Facs,
1810986dffafSJohn Baldwin 	       fadt->Dsdt);
1811986dffafSJohn Baldwin 	printf("\tINT_MODEL=%s\n", fadt->Model ? "APIC" : "PIC");
1812986dffafSJohn Baldwin 	if (fadt->PreferredProfile >= sizeof(acpi_pm_profiles) / sizeof(char *))
18138e6a8737SNate Lawson 		pm = "Reserved";
18148e6a8737SNate Lawson 	else
1815986dffafSJohn Baldwin 		pm = acpi_pm_profiles[fadt->PreferredProfile];
1816986dffafSJohn Baldwin 	printf("\tPreferred_PM_Profile=%s (%d)\n", pm, fadt->PreferredProfile);
1817986dffafSJohn Baldwin 	printf("\tSCI_INT=%d\n", fadt->SciInterrupt);
1818986dffafSJohn Baldwin 	printf("\tSMI_CMD=0x%x, ", fadt->SmiCommand);
1819986dffafSJohn Baldwin 	printf("ACPI_ENABLE=0x%x, ", fadt->AcpiEnable);
1820986dffafSJohn Baldwin 	printf("ACPI_DISABLE=0x%x, ", fadt->AcpiDisable);
1821986dffafSJohn Baldwin 	printf("S4BIOS_REQ=0x%x\n", fadt->S4BiosRequest);
1822986dffafSJohn Baldwin 	printf("\tPSTATE_CNT=0x%x\n", fadt->PstateControl);
1823e1e9a4bfSMitsuru IWASAKI 	printf("\tPM1a_EVT_BLK=0x%x-0x%x\n",
1824986dffafSJohn Baldwin 	       fadt->Pm1aEventBlock,
1825986dffafSJohn Baldwin 	       fadt->Pm1aEventBlock + fadt->Pm1EventLength - 1);
1826986dffafSJohn Baldwin 	if (fadt->Pm1bEventBlock != 0)
1827e1e9a4bfSMitsuru IWASAKI 		printf("\tPM1b_EVT_BLK=0x%x-0x%x\n",
1828986dffafSJohn Baldwin 		       fadt->Pm1bEventBlock,
1829986dffafSJohn Baldwin 		       fadt->Pm1bEventBlock + fadt->Pm1EventLength - 1);
1830e1e9a4bfSMitsuru IWASAKI 	printf("\tPM1a_CNT_BLK=0x%x-0x%x\n",
1831986dffafSJohn Baldwin 	       fadt->Pm1aControlBlock,
1832986dffafSJohn Baldwin 	       fadt->Pm1aControlBlock + fadt->Pm1ControlLength - 1);
1833986dffafSJohn Baldwin 	if (fadt->Pm1bControlBlock != 0)
1834e1e9a4bfSMitsuru IWASAKI 		printf("\tPM1b_CNT_BLK=0x%x-0x%x\n",
1835986dffafSJohn Baldwin 		       fadt->Pm1bControlBlock,
1836986dffafSJohn Baldwin 		       fadt->Pm1bControlBlock + fadt->Pm1ControlLength - 1);
1837986dffafSJohn Baldwin 	if (fadt->Pm2ControlBlock != 0)
1838e1e9a4bfSMitsuru IWASAKI 		printf("\tPM2_CNT_BLK=0x%x-0x%x\n",
1839986dffafSJohn Baldwin 		       fadt->Pm2ControlBlock,
1840986dffafSJohn Baldwin 		       fadt->Pm2ControlBlock + fadt->Pm2ControlLength - 1);
1841c08c4e81SNate Lawson 	printf("\tPM_TMR_BLK=0x%x-0x%x\n",
1842986dffafSJohn Baldwin 	       fadt->PmTimerBlock,
1843986dffafSJohn Baldwin 	       fadt->PmTimerBlock + fadt->PmTimerLength - 1);
1844986dffafSJohn Baldwin 	if (fadt->Gpe0Block != 0)
18458e6a8737SNate Lawson 		printf("\tGPE0_BLK=0x%x-0x%x\n",
1846986dffafSJohn Baldwin 		       fadt->Gpe0Block,
1847986dffafSJohn Baldwin 		       fadt->Gpe0Block + fadt->Gpe0BlockLength - 1);
1848986dffafSJohn Baldwin 	if (fadt->Gpe1Block != 0)
18498e6a8737SNate Lawson 		printf("\tGPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n",
1850986dffafSJohn Baldwin 		       fadt->Gpe1Block,
1851986dffafSJohn Baldwin 		       fadt->Gpe1Block + fadt->Gpe1BlockLength - 1,
1852986dffafSJohn Baldwin 		       fadt->Gpe1Base);
1853986dffafSJohn Baldwin 	if (fadt->CstControl != 0)
1854986dffafSJohn Baldwin 		printf("\tCST_CNT=0x%x\n", fadt->CstControl);
185551c1824fSNate Lawson 	printf("\tP_LVL2_LAT=%d us, P_LVL3_LAT=%d us\n",
1856986dffafSJohn Baldwin 	       fadt->C2Latency, fadt->C3Latency);
1857e1e9a4bfSMitsuru IWASAKI 	printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n",
1858986dffafSJohn Baldwin 	       fadt->FlushSize, fadt->FlushStride);
1859e1e9a4bfSMitsuru IWASAKI 	printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n",
1860986dffafSJohn Baldwin 	       fadt->DutyOffset, fadt->DutyWidth);
1861e1e9a4bfSMitsuru IWASAKI 	printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n",
1862986dffafSJohn Baldwin 	       fadt->DayAlarm, fadt->MonthAlarm, fadt->Century);
1863e1e9a4bfSMitsuru IWASAKI 
1864ec650989SNeel Natu #define PRINTFLAG(var, flag)	printflag((var), ACPI_FADT_## flag, #flag)
1865e1e9a4bfSMitsuru IWASAKI 
18668e6a8737SNate Lawson 	printf("\tIAPC_BOOT_ARCH=");
1867986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, LEGACY_DEVICES);
1868986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, 8042);
1869986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, NO_VGA);
1870986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, NO_MSI);
1871986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, NO_ASPM);
1872f6469ce1SAndrew Turner 	PRINTFLAG(fadt->BootFlags, NO_CMOS_RTC);
1873ec650989SNeel Natu 	PRINTFLAG_END();
18748e6a8737SNate Lawson 
18758e6a8737SNate Lawson 	printf("\tFlags=");
1876986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, WBINVD);
1877986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, WBINVD_FLUSH);
1878986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, C1_SUPPORTED);
1879986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, C2_MP_SUPPORTED);
1880986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, POWER_BUTTON);
1881986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, SLEEP_BUTTON);
1882986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, FIXED_RTC);
1883986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, S4_RTC_WAKE);
1884986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, 32BIT_TIMER);
1885986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, DOCKING_SUPPORTED);
1886986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, RESET_REGISTER);
1887986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, SEALED_CASE);
1888986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, HEADLESS);
1889986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, SLEEP_TYPE);
1890986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, PCI_EXPRESS_WAKE);
1891986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, PLATFORM_CLOCK);
1892986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, S4_RTC_VALID);
1893986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, REMOTE_POWER_ON);
1894986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, APIC_CLUSTER);
1895986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, APIC_PHYSICAL);
1896f6469ce1SAndrew Turner 	PRINTFLAG(fadt->Flags, HW_REDUCED);
1897f6469ce1SAndrew Turner 	PRINTFLAG(fadt->Flags, LOW_POWER_S0);
1898ec650989SNeel Natu 	PRINTFLAG_END();
1899e1e9a4bfSMitsuru IWASAKI 
1900e1e9a4bfSMitsuru IWASAKI #undef PRINTFLAG
1901e1e9a4bfSMitsuru IWASAKI 
1902986dffafSJohn Baldwin 	if (fadt->Flags & ACPI_FADT_RESET_REGISTER) {
19038e6a8737SNate Lawson 		printf("\tRESET_REG=");
1904986dffafSJohn Baldwin 		acpi_print_gas(&fadt->ResetRegister);
1905986dffafSJohn Baldwin 		printf(", RESET_VALUE=%#x\n", fadt->ResetValue);
19068e6a8737SNate Lawson 	}
1907c2962974SNate Lawson 	if (acpi_get_fadt_revision(fadt) > 1) {
19087d369c6eSJung-uk Kim 		printf("\tX_FACS=0x%016jx, ", (uintmax_t)fadt->XFacs);
19097d369c6eSJung-uk Kim 		printf("X_DSDT=0x%016jx\n", (uintmax_t)fadt->XDsdt);
1910c08c4e81SNate Lawson 		printf("\tX_PM1a_EVT_BLK=");
1911986dffafSJohn Baldwin 		acpi_print_gas(&fadt->XPm1aEventBlock);
1912986dffafSJohn Baldwin 		if (fadt->XPm1bEventBlock.Address != 0) {
1913c08c4e81SNate Lawson 			printf("\n\tX_PM1b_EVT_BLK=");
1914986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XPm1bEventBlock);
1915c08c4e81SNate Lawson 		}
1916c08c4e81SNate Lawson 		printf("\n\tX_PM1a_CNT_BLK=");
1917986dffafSJohn Baldwin 		acpi_print_gas(&fadt->XPm1aControlBlock);
1918986dffafSJohn Baldwin 		if (fadt->XPm1bControlBlock.Address != 0) {
1919c08c4e81SNate Lawson 			printf("\n\tX_PM1b_CNT_BLK=");
1920986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XPm1bControlBlock);
1921c08c4e81SNate Lawson 		}
1922986dffafSJohn Baldwin 		if (fadt->XPm2ControlBlock.Address != 0) {
1923773b6454SNate Lawson 			printf("\n\tX_PM2_CNT_BLK=");
1924986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XPm2ControlBlock);
1925c08c4e81SNate Lawson 		}
1926773b6454SNate Lawson 		printf("\n\tX_PM_TMR_BLK=");
1927986dffafSJohn Baldwin 		acpi_print_gas(&fadt->XPmTimerBlock);
1928986dffafSJohn Baldwin 		if (fadt->XGpe0Block.Address != 0) {
1929773b6454SNate Lawson 			printf("\n\tX_GPE0_BLK=");
1930986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XGpe0Block);
1931c08c4e81SNate Lawson 		}
1932986dffafSJohn Baldwin 		if (fadt->XGpe1Block.Address != 0) {
1933773b6454SNate Lawson 			printf("\n\tX_GPE1_BLK=");
1934986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XGpe1Block);
1935c08c4e81SNate Lawson 		}
1936773b6454SNate Lawson 		printf("\n");
1937773b6454SNate Lawson 	}
19388e6a8737SNate Lawson 
19398e6a8737SNate Lawson 	printf(END_COMMENT);
19408e6a8737SNate Lawson }
19418e6a8737SNate Lawson 
19428e6a8737SNate Lawson static void
1943986dffafSJohn Baldwin acpi_print_facs(ACPI_TABLE_FACS *facs)
19448e6a8737SNate Lawson {
19458e6a8737SNate Lawson 	printf(BEGIN_COMMENT);
1946986dffafSJohn Baldwin 	printf("  FACS:\tLength=%u, ", facs->Length);
1947986dffafSJohn Baldwin 	printf("HwSig=0x%08x, ", facs->HardwareSignature);
1948986dffafSJohn Baldwin 	printf("Firm_Wake_Vec=0x%08x\n", facs->FirmwareWakingVector);
19498e6a8737SNate Lawson 
1950773b6454SNate Lawson 	printf("\tGlobal_Lock=");
1951986dffafSJohn Baldwin 	if (facs->GlobalLock != 0) {
1952986dffafSJohn Baldwin 		if (facs->GlobalLock & ACPI_GLOCK_PENDING)
19538e6a8737SNate Lawson 			printf("PENDING,");
1954986dffafSJohn Baldwin 		if (facs->GlobalLock & ACPI_GLOCK_OWNED)
19558e6a8737SNate Lawson 			printf("OWNED");
19568e6a8737SNate Lawson 	}
1957773b6454SNate Lawson 	printf("\n");
19588e6a8737SNate Lawson 
1959773b6454SNate Lawson 	printf("\tFlags=");
1960986dffafSJohn Baldwin 	if (facs->Flags & ACPI_FACS_S4_BIOS_PRESENT)
19618e6a8737SNate Lawson 		printf("S4BIOS");
1962773b6454SNate Lawson 	printf("\n");
19638e6a8737SNate Lawson 
19647d369c6eSJung-uk Kim 	if (facs->XFirmwareWakingVector != 0)
19657d369c6eSJung-uk Kim 		printf("\tX_Firm_Wake_Vec=%016jx\n",
19667d369c6eSJung-uk Kim 		    (uintmax_t)facs->XFirmwareWakingVector);
1967986dffafSJohn Baldwin 	printf("\tVersion=%u\n", facs->Version);
19688e6a8737SNate Lawson 
1969c62f1cccSMitsuru IWASAKI 	printf(END_COMMENT);
1970e1e9a4bfSMitsuru IWASAKI }
1971e1e9a4bfSMitsuru IWASAKI 
1972945137d9SNate Lawson static void
1973986dffafSJohn Baldwin acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp)
1974e1e9a4bfSMitsuru IWASAKI {
1975773b6454SNate Lawson 	printf(BEGIN_COMMENT);
1976773b6454SNate Lawson 	acpi_print_sdt(dsdp);
1977773b6454SNate Lawson 	printf(END_COMMENT);
1978e1e9a4bfSMitsuru IWASAKI }
1979e1e9a4bfSMitsuru IWASAKI 
1980e1e9a4bfSMitsuru IWASAKI int
1981e1e9a4bfSMitsuru IWASAKI acpi_checksum(void *p, size_t length)
1982e1e9a4bfSMitsuru IWASAKI {
1983986dffafSJohn Baldwin 	uint8_t *bp;
1984986dffafSJohn Baldwin 	uint8_t sum;
1985e1e9a4bfSMitsuru IWASAKI 
1986e1e9a4bfSMitsuru IWASAKI 	bp = p;
1987e1e9a4bfSMitsuru IWASAKI 	sum = 0;
1988e1e9a4bfSMitsuru IWASAKI 	while (length--)
1989e1e9a4bfSMitsuru IWASAKI 		sum += *bp++;
1990e1e9a4bfSMitsuru IWASAKI 
1991e1e9a4bfSMitsuru IWASAKI 	return (sum);
1992e1e9a4bfSMitsuru IWASAKI }
1993e1e9a4bfSMitsuru IWASAKI 
1994986dffafSJohn Baldwin static ACPI_TABLE_HEADER *
1995e1e9a4bfSMitsuru IWASAKI acpi_map_sdt(vm_offset_t pa)
1996e1e9a4bfSMitsuru IWASAKI {
1997986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *sp;
1998e1e9a4bfSMitsuru IWASAKI 
1999986dffafSJohn Baldwin 	sp = acpi_map_physical(pa, sizeof(ACPI_TABLE_HEADER));
2000986dffafSJohn Baldwin 	sp = acpi_map_physical(pa, sp->Length);
2001e1e9a4bfSMitsuru IWASAKI 	return (sp);
2002e1e9a4bfSMitsuru IWASAKI }
2003e1e9a4bfSMitsuru IWASAKI 
2004945137d9SNate Lawson static void
2005986dffafSJohn Baldwin acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp)
2006e1e9a4bfSMitsuru IWASAKI {
2007c62f1cccSMitsuru IWASAKI 	printf(BEGIN_COMMENT);
2008a74172abSNate Lawson 	printf("  RSD PTR: OEM=");
2009986dffafSJohn Baldwin 	acpi_print_string(rp->OemId, ACPI_OEM_ID_SIZE);
2010986dffafSJohn Baldwin 	printf(", ACPI_Rev=%s (%d)\n", rp->Revision < 2 ? "1.0x" : "2.0x",
2011986dffafSJohn Baldwin 	       rp->Revision);
2012986dffafSJohn Baldwin 	if (rp->Revision < 2) {
2013986dffafSJohn Baldwin 		printf("\tRSDT=0x%08x, cksum=%u\n", rp->RsdtPhysicalAddress,
2014986dffafSJohn Baldwin 		    rp->Checksum);
2015a74172abSNate Lawson 	} else {
20167d369c6eSJung-uk Kim 		printf("\tXSDT=0x%016jx, length=%u, cksum=%u\n",
20177d369c6eSJung-uk Kim 		    (uintmax_t)rp->XsdtPhysicalAddress, rp->Length,
2018986dffafSJohn Baldwin 		    rp->ExtendedChecksum);
2019a74172abSNate Lawson 	}
2020c62f1cccSMitsuru IWASAKI 	printf(END_COMMENT);
2021e1e9a4bfSMitsuru IWASAKI }
2022e1e9a4bfSMitsuru IWASAKI 
2023945137d9SNate Lawson static void
2024986dffafSJohn Baldwin acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp)
2025e1e9a4bfSMitsuru IWASAKI {
2026986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *sdp;
2027986dffafSJohn Baldwin 	ACPI_TABLE_RSDT *rsdt;
2028986dffafSJohn Baldwin 	ACPI_TABLE_XSDT *xsdt;
2029a74172abSNate Lawson 	vm_offset_t addr;
2030a74172abSNate Lawson 	int entries, i;
2031e1e9a4bfSMitsuru IWASAKI 
2032e1e9a4bfSMitsuru IWASAKI 	acpi_print_rsdt(rsdp);
2033986dffafSJohn Baldwin 	rsdt = (ACPI_TABLE_RSDT *)rsdp;
2034986dffafSJohn Baldwin 	xsdt = (ACPI_TABLE_XSDT *)rsdp;
2035986dffafSJohn Baldwin 	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
2036e1e9a4bfSMitsuru IWASAKI 	for (i = 0; i < entries; i++) {
2037fe1d0c2dSJung-uk Kim 		if (addr_size == 4)
2038986dffafSJohn Baldwin 			addr = le32toh(rsdt->TableOffsetEntry[i]);
2039fe1d0c2dSJung-uk Kim 		else
2040986dffafSJohn Baldwin 			addr = le64toh(xsdt->TableOffsetEntry[i]);
2041fe1d0c2dSJung-uk Kim 		if (addr == 0)
2042fe1d0c2dSJung-uk Kim 			continue;
2043986dffafSJohn Baldwin 		sdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
2044986dffafSJohn Baldwin 		if (acpi_checksum(sdp, sdp->Length)) {
20455cf6d493SNate Lawson 			warnx("RSDT entry %d (sig %.4s) is corrupt", i,
2046986dffafSJohn Baldwin 			    sdp->Signature);
20475cf6d493SNate Lawson 			continue;
20485cf6d493SNate Lawson 		}
2049ebc22d04SAlexander Motin 		if (!memcmp(sdp->Signature, ACPI_SIG_BERT, 4))
2050ebc22d04SAlexander Motin 			acpi_handle_bert(sdp);
2051ebc22d04SAlexander Motin 		else if (!memcmp(sdp->Signature, ACPI_SIG_EINJ, 4))
2052ebc22d04SAlexander Motin 			acpi_handle_einj(sdp);
2053ebc22d04SAlexander Motin 		else if (!memcmp(sdp->Signature, ACPI_SIG_ERST, 4))
2054ebc22d04SAlexander Motin 			acpi_handle_erst(sdp);
2055ebc22d04SAlexander Motin 		else if (!memcmp(sdp->Signature, ACPI_SIG_FADT, 4))
20562177d4e6SNate Lawson 			acpi_handle_fadt(sdp);
2057986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_MADT, 4))
2058986dffafSJohn Baldwin 			acpi_handle_madt(sdp);
2059ebc22d04SAlexander Motin 		else if (!memcmp(sdp->Signature, ACPI_SIG_HEST, 4))
2060ebc22d04SAlexander Motin 			acpi_handle_hest(sdp);
2061986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_HPET, 4))
206279d7565cSPeter Wemm 			acpi_handle_hpet(sdp);
2063986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_ECDT, 4))
206455d7ff9eSNate Lawson 			acpi_handle_ecdt(sdp);
2065986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_MCFG, 4))
2066a47e681bSScott Long 			acpi_handle_mcfg(sdp);
206733866658SJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_SLIT, 4))
206833866658SJohn Baldwin 			acpi_handle_slit(sdp);
2069986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_SRAT, 4))
2070a0333ad1SJohn Baldwin 			acpi_handle_srat(sdp);
2071c031c93bSTakanori Watanabe 		else if (!memcmp(sdp->Signature, ACPI_SIG_TCPA, 4))
2072c031c93bSTakanori Watanabe 			acpi_handle_tcpa(sdp);
2073ec650989SNeel Natu 		else if (!memcmp(sdp->Signature, ACPI_SIG_DMAR, 4))
2074ec650989SNeel Natu 			acpi_handle_dmar(sdp);
2075340c0022SEd Maste 		else if (!memcmp(sdp->Signature, ACPI_SIG_NFIT, 4))
2076340c0022SEd Maste 			acpi_handle_nfit(sdp);
2077ed26c389SScott Long 		else if (!memcmp(sdp->Signature, ACPI_SIG_WDDT, 4))
2078ed26c389SScott Long 			acpi_handle_wddt(sdp);
20795857fba5SBen Widawsky 		else if (!memcmp(sdp->Signature, ACPI_SIG_LPIT, 4))
20805857fba5SBen Widawsky 			acpi_handle_lpit(sdp);
2081877fc2e3STakanori Watanabe 		else if (!memcmp(sdp->Signature, ACPI_SIG_TPM2, 4))
2082877fc2e3STakanori Watanabe 			acpi_handle_tpm2(sdp);
2083773b6454SNate Lawson 		else {
2084773b6454SNate Lawson 			printf(BEGIN_COMMENT);
2085773b6454SNate Lawson 			acpi_print_sdt(sdp);
2086773b6454SNate Lawson 			printf(END_COMMENT);
2087773b6454SNate Lawson 		}
2088e1e9a4bfSMitsuru IWASAKI 	}
2089e1e9a4bfSMitsuru IWASAKI }
2090c62f1cccSMitsuru IWASAKI 
2091986dffafSJohn Baldwin ACPI_TABLE_HEADER *
2092476daaecSDag-Erling Smørgrav sdt_load_devmem(void)
2093945137d9SNate Lawson {
2094986dffafSJohn Baldwin 	ACPI_TABLE_RSDP *rp;
2095986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *rsdp;
2096945137d9SNate Lawson 
2097945137d9SNate Lawson 	rp = acpi_find_rsd_ptr();
2098945137d9SNate Lawson 	if (!rp)
2099945137d9SNate Lawson 		errx(1, "Can't find ACPI information");
2100945137d9SNate Lawson 
2101945137d9SNate Lawson 	if (tflag)
2102945137d9SNate Lawson 		acpi_print_rsd_ptr(rp);
2103986dffafSJohn Baldwin 	if (rp->Revision < 2) {
2104986dffafSJohn Baldwin 		rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->RsdtPhysicalAddress);
2105986dffafSJohn Baldwin 		if (memcmp(rsdp->Signature, "RSDT", 4) != 0 ||
2106986dffafSJohn Baldwin 		    acpi_checksum(rsdp, rsdp->Length) != 0)
2107945137d9SNate Lawson 			errx(1, "RSDT is corrupted");
2108a74172abSNate Lawson 		addr_size = sizeof(uint32_t);
2109a74172abSNate Lawson 	} else {
2110986dffafSJohn Baldwin 		rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->XsdtPhysicalAddress);
2111986dffafSJohn Baldwin 		if (memcmp(rsdp->Signature, "XSDT", 4) != 0 ||
2112986dffafSJohn Baldwin 		    acpi_checksum(rsdp, rsdp->Length) != 0)
2113a74172abSNate Lawson 			errx(1, "XSDT is corrupted");
2114a74172abSNate Lawson 		addr_size = sizeof(uint64_t);
2115a74172abSNate Lawson 	}
2116945137d9SNate Lawson 	return (rsdp);
2117945137d9SNate Lawson }
2118c62f1cccSMitsuru IWASAKI 
211962c7bde1SNate Lawson /* Write the DSDT to a file, concatenating any SSDTs (if present). */
2120bfa3f012SMarcel Moolenaar static int
2121986dffafSJohn Baldwin write_dsdt(int fd, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdt)
2122bfa3f012SMarcel Moolenaar {
2123986dffafSJohn Baldwin 	ACPI_TABLE_HEADER sdt;
2124986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *ssdt;
2125bfa3f012SMarcel Moolenaar 	uint8_t sum;
2126bfa3f012SMarcel Moolenaar 
212762c7bde1SNate Lawson 	/* Create a new checksum to account for the DSDT and any SSDTs. */
2128bfa3f012SMarcel Moolenaar 	sdt = *dsdt;
2129bfa3f012SMarcel Moolenaar 	if (rsdt != NULL) {
2130986dffafSJohn Baldwin 		sdt.Checksum = 0;
2131986dffafSJohn Baldwin 		sum = acpi_checksum(dsdt + 1, dsdt->Length -
2132986dffafSJohn Baldwin 		    sizeof(ACPI_TABLE_HEADER));
2133986dffafSJohn Baldwin 		ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, NULL);
2134f7675a56SNate Lawson 		while (ssdt != NULL) {
2135986dffafSJohn Baldwin 			sdt.Length += ssdt->Length - sizeof(ACPI_TABLE_HEADER);
2136986dffafSJohn Baldwin 			sum += acpi_checksum(ssdt + 1,
2137986dffafSJohn Baldwin 			    ssdt->Length - sizeof(ACPI_TABLE_HEADER));
2138986dffafSJohn Baldwin 			ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, ssdt);
2139bfa3f012SMarcel Moolenaar 		}
2140986dffafSJohn Baldwin 		sum += acpi_checksum(&sdt, sizeof(ACPI_TABLE_HEADER));
2141986dffafSJohn Baldwin 		sdt.Checksum -= sum;
2142bfa3f012SMarcel Moolenaar 	}
214362c7bde1SNate Lawson 
214462c7bde1SNate Lawson 	/* Write out the DSDT header and body. */
2145986dffafSJohn Baldwin 	write(fd, &sdt, sizeof(ACPI_TABLE_HEADER));
2146986dffafSJohn Baldwin 	write(fd, dsdt + 1, dsdt->Length - sizeof(ACPI_TABLE_HEADER));
214762c7bde1SNate Lawson 
2148b64e1b67SNate Lawson 	/* Write out any SSDTs (if present.) */
2149f7675a56SNate Lawson 	if (rsdt != NULL) {
2150bfa3f012SMarcel Moolenaar 		ssdt = sdt_from_rsdt(rsdt, "SSDT", NULL);
2151bfa3f012SMarcel Moolenaar 		while (ssdt != NULL) {
2152986dffafSJohn Baldwin 			write(fd, ssdt + 1, ssdt->Length -
2153986dffafSJohn Baldwin 			    sizeof(ACPI_TABLE_HEADER));
2154bfa3f012SMarcel Moolenaar 			ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt);
2155bfa3f012SMarcel Moolenaar 		}
2156bfa3f012SMarcel Moolenaar 	}
2157bfa3f012SMarcel Moolenaar 	return (0);
2158bfa3f012SMarcel Moolenaar }
2159bfa3f012SMarcel Moolenaar 
2160c62f1cccSMitsuru IWASAKI void
2161986dffafSJohn Baldwin dsdt_save_file(char *outfile, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
2162c62f1cccSMitsuru IWASAKI {
2163945137d9SNate Lawson 	int	fd;
2164945137d9SNate Lawson 	mode_t	mode;
2165945137d9SNate Lawson 
2166945137d9SNate Lawson 	assert(outfile != NULL);
2167945137d9SNate Lawson 	mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
2168945137d9SNate Lawson 	fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, mode);
2169945137d9SNate Lawson 	if (fd == -1) {
2170945137d9SNate Lawson 		perror("dsdt_save_file");
2171945137d9SNate Lawson 		return;
2172945137d9SNate Lawson 	}
2173bfa3f012SMarcel Moolenaar 	write_dsdt(fd, rsdt, dsdp);
2174945137d9SNate Lawson 	close(fd);
2175c62f1cccSMitsuru IWASAKI }
2176c62f1cccSMitsuru IWASAKI 
2177945137d9SNate Lawson void
2178986dffafSJohn Baldwin aml_disassemble(ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
2179c62f1cccSMitsuru IWASAKI {
21807e2cc014SDon Lewis 	char buf[PATH_MAX], tmpstr[PATH_MAX], wrkdir[PATH_MAX];
21817e2cc014SDon Lewis 	const char *iname = "/acpdump.din";
21827e2cc014SDon Lewis 	const char *oname = "/acpdump.dsl";
218399065116SJung-uk Kim 	const char *tmpdir;
2184945137d9SNate Lawson 	FILE *fp;
218599065116SJung-uk Kim 	size_t len;
21867e2cc014SDon Lewis 	int fd, status;
21877e2cc014SDon Lewis 	pid_t pid;
2188945137d9SNate Lawson 
218999065116SJung-uk Kim 	tmpdir = getenv("TMPDIR");
219099065116SJung-uk Kim 	if (tmpdir == NULL)
219199065116SJung-uk Kim 		tmpdir = _PATH_TMP;
21927e2cc014SDon Lewis 	if (realpath(tmpdir, buf) == NULL) {
2193d6a6e590SJung-uk Kim 		perror("realpath tmp dir");
219499065116SJung-uk Kim 		return;
219599065116SJung-uk Kim 	}
21967e2cc014SDon Lewis 	len = sizeof(wrkdir) - strlen(iname);
21977e2cc014SDon Lewis 	if ((size_t)snprintf(wrkdir, len, "%s/acpidump.XXXXXX", buf) > len-1 ) {
21987e2cc014SDon Lewis 		fprintf(stderr, "$TMPDIR too long\n");
21997e2cc014SDon Lewis 		return;
22007e2cc014SDon Lewis 	}
22017e2cc014SDon Lewis 	if  (mkdtemp(wrkdir) == NULL) {
22027e2cc014SDon Lewis 		perror("mkdtemp tmp working dir");
22037e2cc014SDon Lewis 		return;
22047e2cc014SDon Lewis 	}
220530bebccaSMaxim Konovalov 	len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, iname);
220630bebccaSMaxim Konovalov 	assert(len <= sizeof(tmpstr) - 1);
22077e2cc014SDon Lewis 	fd = open(tmpstr, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
2208945137d9SNate Lawson 	if (fd < 0) {
2209945137d9SNate Lawson 		perror("iasl tmp file");
2210945137d9SNate Lawson 		return;
2211c62f1cccSMitsuru IWASAKI 	}
2212bfa3f012SMarcel Moolenaar 	write_dsdt(fd, rsdt, dsdp);
2213945137d9SNate Lawson 	close(fd);
2214945137d9SNate Lawson 
2215945137d9SNate Lawson 	/* Run iasl -d on the temp file */
22167e2cc014SDon Lewis 	if ((pid = fork()) == 0) {
2217945137d9SNate Lawson 		close(STDOUT_FILENO);
2218945137d9SNate Lawson 		if (vflag == 0)
2219945137d9SNate Lawson 			close(STDERR_FILENO);
222099065116SJung-uk Kim 		execl("/usr/sbin/iasl", "iasl", "-d", tmpstr, NULL);
2221945137d9SNate Lawson 		err(1, "exec");
2222c62f1cccSMitsuru IWASAKI 	}
22237e2cc014SDon Lewis 	if (pid > 0)
22247e2cc014SDon Lewis 		wait(&status);
22257e2cc014SDon Lewis 	if (unlink(tmpstr) < 0) {
22267e2cc014SDon Lewis 		perror("unlink");
22277e2cc014SDon Lewis 		goto out;
22287e2cc014SDon Lewis 	}
22297e2cc014SDon Lewis 	if (pid < 0) {
22307e2cc014SDon Lewis 		perror("fork");
22317e2cc014SDon Lewis 		goto out;
22327e2cc014SDon Lewis 	}
22337e2cc014SDon Lewis 	if (status != 0) {
2234*861f5b95SSHENG-YI HONG 		fprintf(stderr, "iasl exit status = %d\n", status);
22357e2cc014SDon Lewis 	}
2236945137d9SNate Lawson 
2237945137d9SNate Lawson 	/* Dump iasl's output to stdout */
223830bebccaSMaxim Konovalov 	len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, oname);
223930bebccaSMaxim Konovalov 	assert(len <= sizeof(tmpstr) - 1);
224099065116SJung-uk Kim 	fp = fopen(tmpstr, "r");
22417e2cc014SDon Lewis 	if (unlink(tmpstr) < 0) {
22427e2cc014SDon Lewis 		perror("unlink");
22437e2cc014SDon Lewis 		goto out;
22447e2cc014SDon Lewis 	}
2245945137d9SNate Lawson 	if (fp == NULL) {
2246945137d9SNate Lawson 		perror("iasl tmp file (read)");
22477e2cc014SDon Lewis 		goto out;
2248945137d9SNate Lawson 	}
2249945137d9SNate Lawson 	while ((len = fread(buf, 1, sizeof(buf), fp)) > 0)
2250945137d9SNate Lawson 		fwrite(buf, 1, len, stdout);
2251945137d9SNate Lawson 	fclose(fp);
22527e2cc014SDon Lewis 
22537e2cc014SDon Lewis     out:
22547e2cc014SDon Lewis 	if (rmdir(wrkdir) < 0)
22557e2cc014SDon Lewis 		perror("rmdir");
2256c62f1cccSMitsuru IWASAKI }
2257c62f1cccSMitsuru IWASAKI 
2258945137d9SNate Lawson void
2259986dffafSJohn Baldwin sdt_print_all(ACPI_TABLE_HEADER *rsdp)
2260c62f1cccSMitsuru IWASAKI {
2261945137d9SNate Lawson 	acpi_handle_rsdt(rsdp);
2262c62f1cccSMitsuru IWASAKI }
2263c62f1cccSMitsuru IWASAKI 
2264bfa3f012SMarcel Moolenaar /* Fetch a table matching the given signature via the RSDT. */
2265986dffafSJohn Baldwin ACPI_TABLE_HEADER *
2266986dffafSJohn Baldwin sdt_from_rsdt(ACPI_TABLE_HEADER *rsdp, const char *sig, ACPI_TABLE_HEADER *last)
2267c62f1cccSMitsuru IWASAKI {
2268986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *sdt;
2269986dffafSJohn Baldwin 	ACPI_TABLE_RSDT *rsdt;
2270986dffafSJohn Baldwin 	ACPI_TABLE_XSDT *xsdt;
2271a74172abSNate Lawson 	vm_offset_t addr;
2272a74172abSNate Lawson 	int entries, i;
2273945137d9SNate Lawson 
2274986dffafSJohn Baldwin 	rsdt = (ACPI_TABLE_RSDT *)rsdp;
2275986dffafSJohn Baldwin 	xsdt = (ACPI_TABLE_XSDT *)rsdp;
2276986dffafSJohn Baldwin 	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
2277945137d9SNate Lawson 	for (i = 0; i < entries; i++) {
2278fe1d0c2dSJung-uk Kim 		if (addr_size == 4)
2279986dffafSJohn Baldwin 			addr = le32toh(rsdt->TableOffsetEntry[i]);
2280fe1d0c2dSJung-uk Kim 		else
2281986dffafSJohn Baldwin 			addr = le64toh(xsdt->TableOffsetEntry[i]);
2282fe1d0c2dSJung-uk Kim 		if (addr == 0)
2283fe1d0c2dSJung-uk Kim 			continue;
2284986dffafSJohn Baldwin 		sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
2285bfa3f012SMarcel Moolenaar 		if (last != NULL) {
2286bfa3f012SMarcel Moolenaar 			if (sdt == last)
2287bfa3f012SMarcel Moolenaar 				last = NULL;
2288bfa3f012SMarcel Moolenaar 			continue;
2289bfa3f012SMarcel Moolenaar 		}
2290986dffafSJohn Baldwin 		if (memcmp(sdt->Signature, sig, strlen(sig)))
2291a74172abSNate Lawson 			continue;
2292986dffafSJohn Baldwin 		if (acpi_checksum(sdt, sdt->Length))
2293945137d9SNate Lawson 			errx(1, "RSDT entry %d is corrupt", i);
2294945137d9SNate Lawson 		return (sdt);
2295c62f1cccSMitsuru IWASAKI 	}
2296c62f1cccSMitsuru IWASAKI 
2297945137d9SNate Lawson 	return (NULL);
2298c62f1cccSMitsuru IWASAKI }
2299c62f1cccSMitsuru IWASAKI 
2300986dffafSJohn Baldwin ACPI_TABLE_HEADER *
2301986dffafSJohn Baldwin dsdt_from_fadt(ACPI_TABLE_FADT *fadt)
2302c62f1cccSMitsuru IWASAKI {
2303986dffafSJohn Baldwin 	ACPI_TABLE_HEADER	*sdt;
2304c62f1cccSMitsuru IWASAKI 
2305986dffafSJohn Baldwin 	/* Use the DSDT address if it is version 1, otherwise use XDSDT. */
2306c2962974SNate Lawson 	if (acpi_get_fadt_revision(fadt) == 1)
2307986dffafSJohn Baldwin 		sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt);
23082e71eb12SNate Lawson 	else
2309986dffafSJohn Baldwin 		sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt);
2310986dffafSJohn Baldwin 	if (acpi_checksum(sdt, sdt->Length))
2311945137d9SNate Lawson 		errx(1, "DSDT is corrupt\n");
2312945137d9SNate Lawson 	return (sdt);
2313c62f1cccSMitsuru IWASAKI }
2314