xref: /freebsd/usr.sbin/acpi/acpidump/acpi.c (revision d4c2de2e0bad44d204797c5adfc300bb1b26f6db)
1e1e9a4bfSMitsuru IWASAKI /*-
2e1e9a4bfSMitsuru IWASAKI  * Copyright (c) 1998 Doug Rabson
3e1e9a4bfSMitsuru IWASAKI  * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
4e1e9a4bfSMitsuru IWASAKI  * All rights reserved.
5e1e9a4bfSMitsuru IWASAKI  *
6e1e9a4bfSMitsuru IWASAKI  * Redistribution and use in source and binary forms, with or without
7e1e9a4bfSMitsuru IWASAKI  * modification, are permitted provided that the following conditions
8e1e9a4bfSMitsuru IWASAKI  * are met:
9e1e9a4bfSMitsuru IWASAKI  * 1. Redistributions of source code must retain the above copyright
10e1e9a4bfSMitsuru IWASAKI  *    notice, this list of conditions and the following disclaimer.
11e1e9a4bfSMitsuru IWASAKI  * 2. Redistributions in binary form must reproduce the above copyright
12e1e9a4bfSMitsuru IWASAKI  *    notice, this list of conditions and the following disclaimer in the
13e1e9a4bfSMitsuru IWASAKI  *    documentation and/or other materials provided with the distribution.
14e1e9a4bfSMitsuru IWASAKI  *
15e1e9a4bfSMitsuru IWASAKI  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16e1e9a4bfSMitsuru IWASAKI  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17e1e9a4bfSMitsuru IWASAKI  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18e1e9a4bfSMitsuru IWASAKI  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19e1e9a4bfSMitsuru IWASAKI  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20e1e9a4bfSMitsuru IWASAKI  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21e1e9a4bfSMitsuru IWASAKI  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22e1e9a4bfSMitsuru IWASAKI  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23e1e9a4bfSMitsuru IWASAKI  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24e1e9a4bfSMitsuru IWASAKI  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25e1e9a4bfSMitsuru IWASAKI  * SUCH DAMAGE.
26e1e9a4bfSMitsuru IWASAKI  *
27e1e9a4bfSMitsuru IWASAKI  *	$FreeBSD$
28e1e9a4bfSMitsuru IWASAKI  */
29e1e9a4bfSMitsuru IWASAKI 
30e1e9a4bfSMitsuru IWASAKI #include <sys/param.h>
31a74172abSNate Lawson #include <sys/endian.h>
32e1e9a4bfSMitsuru IWASAKI #include <sys/stat.h>
33945137d9SNate Lawson #include <sys/wait.h>
34e1e9a4bfSMitsuru IWASAKI #include <assert.h>
35e1e9a4bfSMitsuru IWASAKI #include <err.h>
36e1e9a4bfSMitsuru IWASAKI #include <fcntl.h>
3799065116SJung-uk Kim #include <paths.h>
38e1e9a4bfSMitsuru IWASAKI #include <stdio.h>
39a0333ad1SJohn Baldwin #include <stdint.h>
4099065116SJung-uk Kim #include <stdlib.h>
41945137d9SNate Lawson #include <string.h>
42e1e9a4bfSMitsuru IWASAKI #include <unistd.h>
43340c0022SEd Maste #include <uuid.h>
44e1e9a4bfSMitsuru IWASAKI 
45e1e9a4bfSMitsuru IWASAKI #include "acpidump.h"
46e1e9a4bfSMitsuru IWASAKI 
47c62f1cccSMitsuru IWASAKI #define BEGIN_COMMENT	"/*\n"
48c62f1cccSMitsuru IWASAKI #define END_COMMENT	" */\n"
49c62f1cccSMitsuru IWASAKI 
50945137d9SNate Lawson static void	acpi_print_string(char *s, size_t length);
51986dffafSJohn Baldwin static void	acpi_print_gas(ACPI_GENERIC_ADDRESS *gas);
52986dffafSJohn Baldwin static int	acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt);
53986dffafSJohn Baldwin static void	acpi_handle_fadt(ACPI_TABLE_HEADER *fadt);
54945137d9SNate Lawson static void	acpi_print_cpu(u_char cpu_id);
55986dffafSJohn Baldwin static void	acpi_print_cpu_uid(uint32_t uid, char *uid_string);
56986dffafSJohn Baldwin static void	acpi_print_local_apic(uint32_t apic_id, uint32_t flags);
57986dffafSJohn Baldwin static void	acpi_print_io_apic(uint32_t apic_id, uint32_t int_base,
58986dffafSJohn Baldwin 		    uint64_t apic_addr);
59986dffafSJohn Baldwin static void	acpi_print_mps_flags(uint16_t flags);
60986dffafSJohn Baldwin static void	acpi_print_intr(uint32_t intr, uint16_t mps_flags);
61986dffafSJohn Baldwin static void	acpi_print_local_nmi(u_int lint, uint16_t mps_flags);
62986dffafSJohn Baldwin static void	acpi_print_madt(ACPI_SUBTABLE_HEADER *mp);
63986dffafSJohn Baldwin static void	acpi_handle_madt(ACPI_TABLE_HEADER *sdp);
64986dffafSJohn Baldwin static void	acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp);
65986dffafSJohn Baldwin static void	acpi_handle_hpet(ACPI_TABLE_HEADER *sdp);
66986dffafSJohn Baldwin static void	acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp);
6733866658SJohn Baldwin static void	acpi_handle_slit(ACPI_TABLE_HEADER *sdp);
68a0333ad1SJohn Baldwin static void	acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain,
69a0333ad1SJohn Baldwin 		    uint32_t flags);
70986dffafSJohn Baldwin static void	acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp);
71986dffafSJohn Baldwin static void	acpi_print_srat(ACPI_SUBTABLE_HEADER *srat);
72986dffafSJohn Baldwin static void	acpi_handle_srat(ACPI_TABLE_HEADER *sdp);
73c031c93bSTakanori Watanabe static void	acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp);
74340c0022SEd Maste static void	acpi_print_nfit(ACPI_NFIT_HEADER *nfit);
75340c0022SEd Maste static void	acpi_handle_nfit(ACPI_TABLE_HEADER *sdp);
76986dffafSJohn Baldwin static void	acpi_print_sdt(ACPI_TABLE_HEADER *sdp);
77986dffafSJohn Baldwin static void	acpi_print_fadt(ACPI_TABLE_HEADER *sdp);
78986dffafSJohn Baldwin static void	acpi_print_facs(ACPI_TABLE_FACS *facs);
79986dffafSJohn Baldwin static void	acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp);
80986dffafSJohn Baldwin static ACPI_TABLE_HEADER *acpi_map_sdt(vm_offset_t pa);
81986dffafSJohn Baldwin static void	acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp);
82986dffafSJohn Baldwin static void	acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp);
83986dffafSJohn Baldwin static void	acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
84986dffafSJohn Baldwin 		    void (*action)(ACPI_SUBTABLE_HEADER *));
85340c0022SEd Maste static void	acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first,
86340c0022SEd Maste 		    void (*action)(ACPI_NFIT_HEADER *));
87c62f1cccSMitsuru IWASAKI 
88773b6454SNate Lawson /* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up. */
89a74172abSNate Lawson static int addr_size;
90a74172abSNate Lawson 
91c031c93bSTakanori Watanabe /* Strings used in the TCPA table */
92c031c93bSTakanori Watanabe static const char *tcpa_event_type_strings[] = {
93c031c93bSTakanori Watanabe 	"PREBOOT Certificate",
94c031c93bSTakanori Watanabe 	"POST Code",
95c031c93bSTakanori Watanabe 	"Unused",
96c031c93bSTakanori Watanabe 	"No Action",
97c031c93bSTakanori Watanabe 	"Separator",
98c031c93bSTakanori Watanabe 	"Action",
99c031c93bSTakanori Watanabe 	"Event Tag",
100c031c93bSTakanori Watanabe 	"S-CRTM Contents",
101c031c93bSTakanori Watanabe 	"S-CRTM Version",
102c031c93bSTakanori Watanabe 	"CPU Microcode",
103c031c93bSTakanori Watanabe 	"Platform Config Flags",
104c031c93bSTakanori Watanabe 	"Table of Devices",
105c031c93bSTakanori Watanabe 	"Compact Hash",
106c031c93bSTakanori Watanabe 	"IPL",
107c031c93bSTakanori Watanabe 	"IPL Partition Data",
108c031c93bSTakanori Watanabe 	"Non-Host Code",
109c031c93bSTakanori Watanabe 	"Non-Host Config",
110c031c93bSTakanori Watanabe 	"Non-Host Info"
111c031c93bSTakanori Watanabe };
112c031c93bSTakanori Watanabe 
113c031c93bSTakanori Watanabe static const char *TCPA_pcclient_strings[] = {
114c031c93bSTakanori Watanabe 	"<undefined>",
115c031c93bSTakanori Watanabe 	"SMBIOS",
116c031c93bSTakanori Watanabe 	"BIS Certificate",
117c031c93bSTakanori Watanabe 	"POST BIOS ROM Strings",
118c031c93bSTakanori Watanabe 	"ESCD",
119c031c93bSTakanori Watanabe 	"CMOS",
120c031c93bSTakanori Watanabe 	"NVRAM",
121c031c93bSTakanori Watanabe 	"Option ROM Execute",
122c031c93bSTakanori Watanabe 	"Option ROM Configurateion",
123c031c93bSTakanori Watanabe 	"<undefined>",
124c031c93bSTakanori Watanabe 	"Option ROM Microcode Update ",
125c031c93bSTakanori Watanabe 	"S-CRTM Version String",
126c031c93bSTakanori Watanabe 	"S-CRTM Contents",
127c031c93bSTakanori Watanabe 	"POST Contents",
128c031c93bSTakanori Watanabe 	"Table of Devices",
129c031c93bSTakanori Watanabe };
130c031c93bSTakanori Watanabe 
131ec650989SNeel Natu #define	PRINTFLAG_END()		printflag_end()
132ec650989SNeel Natu 
133ec650989SNeel Natu static char pf_sep = '{';
134ec650989SNeel Natu 
135ec650989SNeel Natu static void
136ec650989SNeel Natu printflag_end(void)
137ec650989SNeel Natu {
138ec650989SNeel Natu 
139ec650989SNeel Natu 	if (pf_sep != '{') {
140ec650989SNeel Natu 		printf("}");
141ec650989SNeel Natu 		pf_sep = '{';
142ec650989SNeel Natu 	}
143ec650989SNeel Natu 	printf("\n");
144ec650989SNeel Natu }
145ec650989SNeel Natu 
146ec650989SNeel Natu static void
147ec650989SNeel Natu printflag(uint64_t var, uint64_t mask, const char *name)
148ec650989SNeel Natu {
149ec650989SNeel Natu 
150ec650989SNeel Natu 	if (var & mask) {
151ec650989SNeel Natu 		printf("%c%s", pf_sep, name);
152ec650989SNeel Natu 		pf_sep = ',';
153ec650989SNeel Natu 	}
154ec650989SNeel Natu }
155ec650989SNeel Natu 
156e1e9a4bfSMitsuru IWASAKI static void
157e1e9a4bfSMitsuru IWASAKI acpi_print_string(char *s, size_t length)
158e1e9a4bfSMitsuru IWASAKI {
159e1e9a4bfSMitsuru IWASAKI 	int	c;
160e1e9a4bfSMitsuru IWASAKI 
161e1e9a4bfSMitsuru IWASAKI 	/* Trim trailing spaces and NULLs */
162e1e9a4bfSMitsuru IWASAKI 	while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0'))
163e1e9a4bfSMitsuru IWASAKI 		length--;
164e1e9a4bfSMitsuru IWASAKI 
165e1e9a4bfSMitsuru IWASAKI 	while (length--) {
166e1e9a4bfSMitsuru IWASAKI 		c = *s++;
167e1e9a4bfSMitsuru IWASAKI 		putchar(c);
168e1e9a4bfSMitsuru IWASAKI 	}
169e1e9a4bfSMitsuru IWASAKI }
170e1e9a4bfSMitsuru IWASAKI 
171e1e9a4bfSMitsuru IWASAKI static void
172986dffafSJohn Baldwin acpi_print_gas(ACPI_GENERIC_ADDRESS *gas)
1738e6a8737SNate Lawson {
174986dffafSJohn Baldwin 	switch(gas->SpaceId) {
1758e6a8737SNate Lawson 	case ACPI_GAS_MEMORY:
1767d369c6eSJung-uk Kim 		if (gas->BitWidth <= 32)
1777d369c6eSJung-uk Kim 			printf("0x%08x:%u[%u] (Memory)",
1787d369c6eSJung-uk Kim 			    (u_int)gas->Address, gas->BitOffset,
1797d369c6eSJung-uk Kim 			    gas->BitWidth);
1807d369c6eSJung-uk Kim 		else
1817d369c6eSJung-uk Kim 			printf("0x%016jx:%u[%u] (Memory)",
1827d369c6eSJung-uk Kim 			    (uintmax_t)gas->Address, gas->BitOffset,
1837d369c6eSJung-uk Kim 			    gas->BitWidth);
1848e6a8737SNate Lawson 		break;
1858e6a8737SNate Lawson 	case ACPI_GAS_IO:
1867d369c6eSJung-uk Kim 		printf("0x%02x:%u[%u] (IO)", (u_int)gas->Address,
187986dffafSJohn Baldwin 		    gas->BitOffset, gas->BitWidth);
1888e6a8737SNate Lawson 		break;
1898e6a8737SNate Lawson 	case ACPI_GAS_PCI:
190986dffafSJohn Baldwin 		printf("%x:%x+0x%x (PCI)", (uint16_t)(gas->Address >> 32),
191986dffafSJohn Baldwin 		       (uint16_t)((gas->Address >> 16) & 0xffff),
192986dffafSJohn Baldwin 		       (uint16_t)gas->Address);
1938e6a8737SNate Lawson 		break;
1948e6a8737SNate Lawson 	/* XXX How to handle these below? */
1958e6a8737SNate Lawson 	case ACPI_GAS_EMBEDDED:
196986dffafSJohn Baldwin 		printf("0x%x:%u[%u] (EC)", (uint16_t)gas->Address,
197986dffafSJohn Baldwin 		       gas->BitOffset, gas->BitWidth);
1988e6a8737SNate Lawson 		break;
1998e6a8737SNate Lawson 	case ACPI_GAS_SMBUS:
200986dffafSJohn Baldwin 		printf("0x%x:%u[%u] (SMBus)", (uint16_t)gas->Address,
201986dffafSJohn Baldwin 		       gas->BitOffset, gas->BitWidth);
2028e6a8737SNate Lawson 		break;
203986dffafSJohn Baldwin 	case ACPI_GAS_CMOS:
204986dffafSJohn Baldwin 	case ACPI_GAS_PCIBAR:
205986dffafSJohn Baldwin 	case ACPI_GAS_DATATABLE:
2068e6a8737SNate Lawson 	case ACPI_GAS_FIXED:
2078e6a8737SNate Lawson 	default:
2087d369c6eSJung-uk Kim 		printf("0x%016jx (?)", (uintmax_t)gas->Address);
2098e6a8737SNate Lawson 		break;
2108e6a8737SNate Lawson 	}
2118e6a8737SNate Lawson }
2128e6a8737SNate Lawson 
213c2962974SNate Lawson /* The FADT revision indicates whether we use the DSDT or X_DSDT addresses. */
214c2962974SNate Lawson static int
215986dffafSJohn Baldwin acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt)
216e1e9a4bfSMitsuru IWASAKI {
217c2962974SNate Lawson 	int fadt_revision;
218e1e9a4bfSMitsuru IWASAKI 
219c83f0f99SNate Lawson 	/* Set the FADT revision separately from the RSDP version. */
220c83f0f99SNate Lawson 	if (addr_size == 8) {
221c83f0f99SNate Lawson 		fadt_revision = 2;
2228e6a8737SNate Lawson 
223773b6454SNate Lawson 		/*
224c83f0f99SNate Lawson 		 * A few systems (e.g., IBM T23) have an RSDP that claims
225c83f0f99SNate Lawson 		 * revision 2 but the 64 bit addresses are invalid.  If
226c83f0f99SNate Lawson 		 * revision 2 and the 32 bit address is non-zero but the
227c83f0f99SNate Lawson 		 * 32 and 64 bit versions don't match, prefer the 32 bit
228c83f0f99SNate Lawson 		 * version for all subsequent tables.
229773b6454SNate Lawson 		 */
230986dffafSJohn Baldwin 		if (fadt->Facs != 0 &&
231986dffafSJohn Baldwin 		    (fadt->XFacs & 0xffffffff) != fadt->Facs)
232c83f0f99SNate Lawson 			fadt_revision = 1;
233c2962974SNate Lawson 	} else
234c83f0f99SNate Lawson 		fadt_revision = 1;
235c2962974SNate Lawson 	return (fadt_revision);
236c83f0f99SNate Lawson }
237c2962974SNate Lawson 
238c2962974SNate Lawson static void
239986dffafSJohn Baldwin acpi_handle_fadt(ACPI_TABLE_HEADER *sdp)
240c2962974SNate Lawson {
241986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *dsdp;
242986dffafSJohn Baldwin 	ACPI_TABLE_FACS	*facs;
243986dffafSJohn Baldwin 	ACPI_TABLE_FADT *fadt;
244c2962974SNate Lawson 	int		fadt_revision;
245c2962974SNate Lawson 
246986dffafSJohn Baldwin 	fadt = (ACPI_TABLE_FADT *)sdp;
2472177d4e6SNate Lawson 	acpi_print_fadt(sdp);
248c83f0f99SNate Lawson 
249c2962974SNate Lawson 	fadt_revision = acpi_get_fadt_revision(fadt);
250c83f0f99SNate Lawson 	if (fadt_revision == 1)
251986dffafSJohn Baldwin 		facs = (ACPI_TABLE_FACS *)acpi_map_sdt(fadt->Facs);
252773b6454SNate Lawson 	else
253986dffafSJohn Baldwin 		facs = (ACPI_TABLE_FACS *)acpi_map_sdt(fadt->XFacs);
254986dffafSJohn Baldwin 	if (memcmp(facs->Signature, ACPI_SIG_FACS, 4) != 0 || facs->Length < 64)
2558e6a8737SNate Lawson 		errx(1, "FACS is corrupt");
2568e6a8737SNate Lawson 	acpi_print_facs(facs);
2578e6a8737SNate Lawson 
258c83f0f99SNate Lawson 	if (fadt_revision == 1)
259986dffafSJohn Baldwin 		dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt);
260773b6454SNate Lawson 	else
261986dffafSJohn Baldwin 		dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt);
262986dffafSJohn Baldwin 	if (acpi_checksum(dsdp, dsdp->Length))
263945137d9SNate Lawson 		errx(1, "DSDT is corrupt");
264945137d9SNate Lawson 	acpi_print_dsdt(dsdp);
265c62f1cccSMitsuru IWASAKI }
266c62f1cccSMitsuru IWASAKI 
267c62f1cccSMitsuru IWASAKI static void
268986dffafSJohn Baldwin acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
269986dffafSJohn Baldwin     void (*action)(ACPI_SUBTABLE_HEADER *))
270986dffafSJohn Baldwin {
271986dffafSJohn Baldwin 	ACPI_SUBTABLE_HEADER *subtable;
272986dffafSJohn Baldwin 	char *end;
273986dffafSJohn Baldwin 
274986dffafSJohn Baldwin 	subtable = first;
275986dffafSJohn Baldwin 	end = (char *)table + table->Length;
276986dffafSJohn Baldwin 	while ((char *)subtable < end) {
277986dffafSJohn Baldwin 		printf("\n");
278f5d0a8f7SEd Maste 		if (subtable->Length < sizeof(ACPI_SUBTABLE_HEADER)) {
279f5d0a8f7SEd Maste 			warnx("invalid subtable length %u", subtable->Length);
280f5d0a8f7SEd Maste 			return;
281f5d0a8f7SEd Maste 		}
282986dffafSJohn Baldwin 		action(subtable);
283986dffafSJohn Baldwin 		subtable = (ACPI_SUBTABLE_HEADER *)((char *)subtable +
284986dffafSJohn Baldwin 		    subtable->Length);
285986dffafSJohn Baldwin 	}
286986dffafSJohn Baldwin }
287986dffafSJohn Baldwin 
288986dffafSJohn Baldwin static void
289340c0022SEd Maste acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first,
290340c0022SEd Maste     void (*action)(ACPI_NFIT_HEADER *))
291340c0022SEd Maste {
292340c0022SEd Maste 	ACPI_NFIT_HEADER *subtable;
293340c0022SEd Maste 	char *end;
294340c0022SEd Maste 
295340c0022SEd Maste 	subtable = first;
296340c0022SEd Maste 	end = (char *)table + table->Length;
297340c0022SEd Maste 	while ((char *)subtable < end) {
298340c0022SEd Maste 		printf("\n");
299340c0022SEd Maste 		if (subtable->Length < sizeof(ACPI_NFIT_HEADER)) {
300340c0022SEd Maste 			warnx("invalid subtable length %u", subtable->Length);
301340c0022SEd Maste 			return;
302340c0022SEd Maste 		}
303340c0022SEd Maste 		action(subtable);
304340c0022SEd Maste 		subtable = (ACPI_NFIT_HEADER *)((char *)subtable +
305340c0022SEd Maste 		    subtable->Length);
306340c0022SEd Maste 	}
307340c0022SEd Maste }
308340c0022SEd Maste 
309340c0022SEd Maste static void
3100a473124SJohn Baldwin acpi_print_cpu(u_char cpu_id)
3110a473124SJohn Baldwin {
3120a473124SJohn Baldwin 
3130a473124SJohn Baldwin 	printf("\tACPI CPU=");
3140a473124SJohn Baldwin 	if (cpu_id == 0xff)
3150a473124SJohn Baldwin 		printf("ALL\n");
3160a473124SJohn Baldwin 	else
3170a473124SJohn Baldwin 		printf("%d\n", (u_int)cpu_id);
3180a473124SJohn Baldwin }
3190a473124SJohn Baldwin 
3200a473124SJohn Baldwin static void
321986dffafSJohn Baldwin acpi_print_cpu_uid(uint32_t uid, char *uid_string)
3220a473124SJohn Baldwin {
323986dffafSJohn Baldwin 
324986dffafSJohn Baldwin 	printf("\tUID=%d", uid);
325986dffafSJohn Baldwin 	if (uid_string != NULL)
326986dffafSJohn Baldwin 		printf(" (%s)", uid_string);
327986dffafSJohn Baldwin 	printf("\n");
328986dffafSJohn Baldwin }
329986dffafSJohn Baldwin 
330986dffafSJohn Baldwin static void
331986dffafSJohn Baldwin acpi_print_local_apic(uint32_t apic_id, uint32_t flags)
332986dffafSJohn Baldwin {
333986dffafSJohn Baldwin 
3340a473124SJohn Baldwin 	printf("\tFlags={");
335986dffafSJohn Baldwin 	if (flags & ACPI_MADT_ENABLED)
3360a473124SJohn Baldwin 		printf("ENABLED");
3370a473124SJohn Baldwin 	else
3380a473124SJohn Baldwin 		printf("DISABLED");
3390a473124SJohn Baldwin 	printf("}\n");
340986dffafSJohn Baldwin 	printf("\tAPIC ID=%d\n", apic_id);
3410a473124SJohn Baldwin }
3420a473124SJohn Baldwin 
3430a473124SJohn Baldwin static void
344986dffafSJohn Baldwin acpi_print_io_apic(uint32_t apic_id, uint32_t int_base, uint64_t apic_addr)
3450a473124SJohn Baldwin {
346986dffafSJohn Baldwin 
347986dffafSJohn Baldwin 	printf("\tAPIC ID=%d\n", apic_id);
3480a473124SJohn Baldwin 	printf("\tINT BASE=%d\n", int_base);
349986dffafSJohn Baldwin 	printf("\tADDR=0x%016jx\n", (uintmax_t)apic_addr);
3500a473124SJohn Baldwin }
3510a473124SJohn Baldwin 
3520a473124SJohn Baldwin static void
353986dffafSJohn Baldwin acpi_print_mps_flags(uint16_t flags)
3540a473124SJohn Baldwin {
3550a473124SJohn Baldwin 
3560a473124SJohn Baldwin 	printf("\tFlags={Polarity=");
357986dffafSJohn Baldwin 	switch (flags & ACPI_MADT_POLARITY_MASK) {
358986dffafSJohn Baldwin 	case ACPI_MADT_POLARITY_CONFORMS:
3590a473124SJohn Baldwin 		printf("conforming");
3600a473124SJohn Baldwin 		break;
361986dffafSJohn Baldwin 	case ACPI_MADT_POLARITY_ACTIVE_HIGH:
3620a473124SJohn Baldwin 		printf("active-hi");
3630a473124SJohn Baldwin 		break;
364986dffafSJohn Baldwin 	case ACPI_MADT_POLARITY_ACTIVE_LOW:
3650a473124SJohn Baldwin 		printf("active-lo");
3660a473124SJohn Baldwin 		break;
3670a473124SJohn Baldwin 	default:
368986dffafSJohn Baldwin 		printf("0x%x", flags & ACPI_MADT_POLARITY_MASK);
3690a473124SJohn Baldwin 		break;
3700a473124SJohn Baldwin 	}
3710a473124SJohn Baldwin 	printf(", Trigger=");
372986dffafSJohn Baldwin 	switch (flags & ACPI_MADT_TRIGGER_MASK) {
373986dffafSJohn Baldwin 	case ACPI_MADT_TRIGGER_CONFORMS:
3740a473124SJohn Baldwin 		printf("conforming");
3750a473124SJohn Baldwin 		break;
376986dffafSJohn Baldwin 	case ACPI_MADT_TRIGGER_EDGE:
3770a473124SJohn Baldwin 		printf("edge");
3780a473124SJohn Baldwin 		break;
379986dffafSJohn Baldwin 	case ACPI_MADT_TRIGGER_LEVEL:
3800a473124SJohn Baldwin 		printf("level");
3810a473124SJohn Baldwin 		break;
3820a473124SJohn Baldwin 	default:
383986dffafSJohn Baldwin 		printf("0x%x", (flags & ACPI_MADT_TRIGGER_MASK) >> 2);
3840a473124SJohn Baldwin 	}
3850a473124SJohn Baldwin 	printf("}\n");
3860a473124SJohn Baldwin }
3870a473124SJohn Baldwin 
3880a473124SJohn Baldwin static void
3892b2b1f42SAndrew Turner acpi_print_gicc_flags(uint32_t flags)
3902b2b1f42SAndrew Turner {
3912b2b1f42SAndrew Turner 
3922b2b1f42SAndrew Turner 	printf("\tFlags={Performance intr=");
3932b2b1f42SAndrew Turner 	if (flags & ACPI_MADT_PERFORMANCE_IRQ_MODE)
3942b2b1f42SAndrew Turner 		printf("edge");
3952b2b1f42SAndrew Turner 	else
3962b2b1f42SAndrew Turner 		printf("level");
3972b2b1f42SAndrew Turner 	printf(", VGIC intr=");
3982b2b1f42SAndrew Turner 	if (flags & ACPI_MADT_VGIC_IRQ_MODE)
3992b2b1f42SAndrew Turner 		printf("edge");
4002b2b1f42SAndrew Turner 	else
4012b2b1f42SAndrew Turner 		printf("level");
4022b2b1f42SAndrew Turner 	printf("}\n");
4032b2b1f42SAndrew Turner }
4042b2b1f42SAndrew Turner 
4052b2b1f42SAndrew Turner static void
406986dffafSJohn Baldwin acpi_print_intr(uint32_t intr, uint16_t mps_flags)
4070a473124SJohn Baldwin {
4080a473124SJohn Baldwin 
409986dffafSJohn Baldwin 	printf("\tINTR=%d\n", intr);
410986dffafSJohn Baldwin 	acpi_print_mps_flags(mps_flags);
411986dffafSJohn Baldwin }
412986dffafSJohn Baldwin 
413986dffafSJohn Baldwin static void
414986dffafSJohn Baldwin acpi_print_local_nmi(u_int lint, uint16_t mps_flags)
415986dffafSJohn Baldwin {
416986dffafSJohn Baldwin 
417986dffafSJohn Baldwin 	printf("\tLINT Pin=%d\n", lint);
4180a473124SJohn Baldwin 	acpi_print_mps_flags(mps_flags);
4190a473124SJohn Baldwin }
4200a473124SJohn Baldwin 
42127941afaSEd Maste static const char *apic_types[] = {
42227941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_APIC] = "Local APIC",
42327941afaSEd Maste     [ACPI_MADT_TYPE_IO_APIC] = "IO APIC",
42427941afaSEd Maste     [ACPI_MADT_TYPE_INTERRUPT_OVERRIDE] = "INT Override",
42527941afaSEd Maste     [ACPI_MADT_TYPE_NMI_SOURCE] = "NMI",
42627941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_APIC_NMI] = "Local APIC NMI",
42727941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE] = "Local APIC Override",
42827941afaSEd Maste     [ACPI_MADT_TYPE_IO_SAPIC] = "IO SAPIC",
42927941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_SAPIC] = "Local SAPIC",
43027941afaSEd Maste     [ACPI_MADT_TYPE_INTERRUPT_SOURCE] = "Platform Interrupt",
43127941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_X2APIC] = "Local X2APIC",
43227941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_X2APIC_NMI] = "Local X2APIC NMI",
43327941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_INTERRUPT] = "GIC CPU Interface Structure",
43427941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR] = "GIC Distributor Structure",
43527941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_MSI_FRAME] = "GICv2m MSI Frame",
43627941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR] = "GIC Redistributor Structure",
43727941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_TRANSLATOR] = "GIC ITS Structure"
43827941afaSEd Maste };
43927941afaSEd Maste 
440bf70beceSEd Schouten static const char *platform_int_types[] = { "0 (unknown)", "PMI", "INIT",
4410a473124SJohn Baldwin 					    "Corrected Platform Error" };
4420a473124SJohn Baldwin 
4430a473124SJohn Baldwin static void
444986dffafSJohn Baldwin acpi_print_madt(ACPI_SUBTABLE_HEADER *mp)
4450a473124SJohn Baldwin {
446986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_APIC *lapic;
447986dffafSJohn Baldwin 	ACPI_MADT_IO_APIC *ioapic;
448986dffafSJohn Baldwin 	ACPI_MADT_INTERRUPT_OVERRIDE *over;
449986dffafSJohn Baldwin 	ACPI_MADT_NMI_SOURCE *nmi;
450986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_APIC_NMI *lapic_nmi;
451986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic_over;
452986dffafSJohn Baldwin 	ACPI_MADT_IO_SAPIC *iosapic;
453986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_SAPIC *lsapic;
454986dffafSJohn Baldwin 	ACPI_MADT_INTERRUPT_SOURCE *isrc;
455986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_X2APIC *x2apic;
456986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_X2APIC_NMI *x2apic_nmi;
4572b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_INTERRUPT *gicc;
4582b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_DISTRIBUTOR *gicd;
4592b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_REDISTRIBUTOR *gicr;
4602b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_TRANSLATOR *gict;
4610a473124SJohn Baldwin 
462c86932b6SMarcelo Araujo 	if (mp->Type < nitems(apic_types))
463986dffafSJohn Baldwin 		printf("\tType=%s\n", apic_types[mp->Type]);
464a0333ad1SJohn Baldwin 	else
465986dffafSJohn Baldwin 		printf("\tType=%d (unknown)\n", mp->Type);
466986dffafSJohn Baldwin 	switch (mp->Type) {
467986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_APIC:
468986dffafSJohn Baldwin 		lapic = (ACPI_MADT_LOCAL_APIC *)mp;
469986dffafSJohn Baldwin 		acpi_print_cpu(lapic->ProcessorId);
470986dffafSJohn Baldwin 		acpi_print_local_apic(lapic->Id, lapic->LapicFlags);
4710a473124SJohn Baldwin 		break;
472986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_IO_APIC:
473986dffafSJohn Baldwin 		ioapic = (ACPI_MADT_IO_APIC *)mp;
474986dffafSJohn Baldwin 		acpi_print_io_apic(ioapic->Id, ioapic->GlobalIrqBase,
475986dffafSJohn Baldwin 		    ioapic->Address);
4760a473124SJohn Baldwin 		break;
477986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
478986dffafSJohn Baldwin 		over = (ACPI_MADT_INTERRUPT_OVERRIDE *)mp;
479986dffafSJohn Baldwin 		printf("\tBUS=%d\n", (u_int)over->Bus);
480986dffafSJohn Baldwin 		printf("\tIRQ=%d\n", (u_int)over->SourceIrq);
481986dffafSJohn Baldwin 		acpi_print_intr(over->GlobalIrq, over->IntiFlags);
4820a473124SJohn Baldwin 		break;
483986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_NMI_SOURCE:
484986dffafSJohn Baldwin 		nmi = (ACPI_MADT_NMI_SOURCE *)mp;
485986dffafSJohn Baldwin 		acpi_print_intr(nmi->GlobalIrq, nmi->IntiFlags);
4860a473124SJohn Baldwin 		break;
487986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
488986dffafSJohn Baldwin 		lapic_nmi = (ACPI_MADT_LOCAL_APIC_NMI *)mp;
489986dffafSJohn Baldwin 		acpi_print_cpu(lapic_nmi->ProcessorId);
490986dffafSJohn Baldwin 		acpi_print_local_nmi(lapic_nmi->Lint, lapic_nmi->IntiFlags);
4910a473124SJohn Baldwin 		break;
492986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
493986dffafSJohn Baldwin 		lapic_over = (ACPI_MADT_LOCAL_APIC_OVERRIDE *)mp;
494945137d9SNate Lawson 		printf("\tLocal APIC ADDR=0x%016jx\n",
495986dffafSJohn Baldwin 		    (uintmax_t)lapic_over->Address);
4960a473124SJohn Baldwin 		break;
497986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_IO_SAPIC:
498986dffafSJohn Baldwin 		iosapic = (ACPI_MADT_IO_SAPIC *)mp;
499986dffafSJohn Baldwin 		acpi_print_io_apic(iosapic->Id, iosapic->GlobalIrqBase,
500986dffafSJohn Baldwin 		    iosapic->Address);
5010a473124SJohn Baldwin 		break;
502986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_SAPIC:
503986dffafSJohn Baldwin 		lsapic = (ACPI_MADT_LOCAL_SAPIC *)mp;
504986dffafSJohn Baldwin 		acpi_print_cpu(lsapic->ProcessorId);
505986dffafSJohn Baldwin 		acpi_print_local_apic(lsapic->Id, lsapic->LapicFlags);
506986dffafSJohn Baldwin 		printf("\tAPIC EID=%d\n", (u_int)lsapic->Eid);
507986dffafSJohn Baldwin 		if (mp->Length > __offsetof(ACPI_MADT_LOCAL_SAPIC, Uid))
508986dffafSJohn Baldwin 			acpi_print_cpu_uid(lsapic->Uid, lsapic->UidString);
5090a473124SJohn Baldwin 		break;
510986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
511986dffafSJohn Baldwin 		isrc = (ACPI_MADT_INTERRUPT_SOURCE *)mp;
512c86932b6SMarcelo Araujo 		if (isrc->Type < nitems(platform_int_types))
513986dffafSJohn Baldwin 			printf("\tType=%s\n", platform_int_types[isrc->Type]);
514986dffafSJohn Baldwin 		else
515986dffafSJohn Baldwin 			printf("\tType=%d (unknown)\n", isrc->Type);
516986dffafSJohn Baldwin 		printf("\tAPIC ID=%d\n", (u_int)isrc->Id);
517986dffafSJohn Baldwin 		printf("\tAPIC EID=%d\n", (u_int)isrc->Eid);
518986dffafSJohn Baldwin 		printf("\tSAPIC Vector=%d\n", (u_int)isrc->IoSapicVector);
519986dffafSJohn Baldwin 		acpi_print_intr(isrc->GlobalIrq, isrc->IntiFlags);
520986dffafSJohn Baldwin 		break;
521986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_X2APIC:
522986dffafSJohn Baldwin 		x2apic = (ACPI_MADT_LOCAL_X2APIC *)mp;
523986dffafSJohn Baldwin 		acpi_print_cpu_uid(x2apic->Uid, NULL);
524986dffafSJohn Baldwin 		acpi_print_local_apic(x2apic->LocalApicId, x2apic->LapicFlags);
525986dffafSJohn Baldwin 		break;
526986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
527986dffafSJohn Baldwin 		x2apic_nmi = (ACPI_MADT_LOCAL_X2APIC_NMI *)mp;
528986dffafSJohn Baldwin 		acpi_print_cpu_uid(x2apic_nmi->Uid, NULL);
529986dffafSJohn Baldwin 		acpi_print_local_nmi(x2apic_nmi->Lint, x2apic_nmi->IntiFlags);
5300a473124SJohn Baldwin 		break;
5312b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
5322b2b1f42SAndrew Turner 		gicc = (ACPI_MADT_GENERIC_INTERRUPT *)mp;
5332b2b1f42SAndrew Turner 		acpi_print_cpu_uid(gicc->Uid, NULL);
5342b2b1f42SAndrew Turner 		printf("\tCPU INTERFACE=%x\n", gicc->CpuInterfaceNumber);
5352b2b1f42SAndrew Turner 		acpi_print_gicc_flags(gicc->Flags);
5362b2b1f42SAndrew Turner 		printf("\tParking Protocol Version=%x\n", gicc->ParkingVersion);
5372b2b1f42SAndrew Turner 		printf("\tPERF INTR=%d\n", gicc->PerformanceInterrupt);
5382b2b1f42SAndrew Turner 		printf("\tParked ADDR=%016jx\n",
5392b2b1f42SAndrew Turner 		    (uintmax_t)gicc->ParkedAddress);
5402b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicc->BaseAddress);
5412b2b1f42SAndrew Turner 		printf("\tGICV=%016jx\n", (uintmax_t)gicc->GicvBaseAddress);
5422b2b1f42SAndrew Turner 		printf("\tGICH=%016jx\n", (uintmax_t)gicc->GichBaseAddress);
5432b2b1f42SAndrew Turner 		printf("\tVGIC INTR=%d\n", gicc->VgicInterrupt);
5442b2b1f42SAndrew Turner 		printf("\tGICR ADDR=%016jx\n",
5452b2b1f42SAndrew Turner 		    (uintmax_t)gicc->GicrBaseAddress);
5462b2b1f42SAndrew Turner 		printf("\tMPIDR=%jx\n", (uintmax_t)gicc->ArmMpidr);
5472b2b1f42SAndrew Turner 		printf("\tEfficency Class=%d\n", (u_int)gicc->EfficiencyClass);
5482b2b1f42SAndrew Turner 		break;
5492b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
5502b2b1f42SAndrew Turner 		gicd = (ACPI_MADT_GENERIC_DISTRIBUTOR *)mp;
5512b2b1f42SAndrew Turner 		printf("\tGIC ID=%d\n", (u_int)gicd->GicId);
5522b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicd->BaseAddress);
5532b2b1f42SAndrew Turner 		printf("\tVector Base=%d\n", gicd->GlobalIrqBase);
5542b2b1f42SAndrew Turner 		printf("\tGIC VERSION=%d\n", (u_int)gicd->Version);
5552b2b1f42SAndrew Turner 		break;
5562b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
5572b2b1f42SAndrew Turner 		gicr = (ACPI_MADT_GENERIC_REDISTRIBUTOR *)mp;
5582b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicr->BaseAddress);
5592b2b1f42SAndrew Turner 		printf("\tLength=%08x\n", gicr->Length);
5602b2b1f42SAndrew Turner 		break;
5612b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
5622b2b1f42SAndrew Turner 		gict = (ACPI_MADT_GENERIC_TRANSLATOR *)mp;
5632b2b1f42SAndrew Turner 		printf("\tGIC ITS ID=%d\n", gict->TranslationId);
5642b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gict->BaseAddress);
5652b2b1f42SAndrew Turner 		break;
5660a473124SJohn Baldwin 	}
5670a473124SJohn Baldwin }
5680a473124SJohn Baldwin 
5690a473124SJohn Baldwin static void
570986dffafSJohn Baldwin acpi_handle_madt(ACPI_TABLE_HEADER *sdp)
5710a473124SJohn Baldwin {
572986dffafSJohn Baldwin 	ACPI_TABLE_MADT *madt;
5730a473124SJohn Baldwin 
574773b6454SNate Lawson 	printf(BEGIN_COMMENT);
575773b6454SNate Lawson 	acpi_print_sdt(sdp);
576986dffafSJohn Baldwin 	madt = (ACPI_TABLE_MADT *)sdp;
577986dffafSJohn Baldwin 	printf("\tLocal APIC ADDR=0x%08x\n", madt->Address);
5780a473124SJohn Baldwin 	printf("\tFlags={");
579986dffafSJohn Baldwin 	if (madt->Flags & ACPI_MADT_PCAT_COMPAT)
5800a473124SJohn Baldwin 		printf("PC-AT");
5810a473124SJohn Baldwin 	printf("}\n");
582986dffafSJohn Baldwin 	acpi_walk_subtables(sdp, (madt + 1), acpi_print_madt);
5830a473124SJohn Baldwin 	printf(END_COMMENT);
5840a473124SJohn Baldwin }
5850a473124SJohn Baldwin 
5860a473124SJohn Baldwin static void
587986dffafSJohn Baldwin acpi_handle_hpet(ACPI_TABLE_HEADER *sdp)
58879d7565cSPeter Wemm {
589986dffafSJohn Baldwin 	ACPI_TABLE_HPET *hpet;
59079d7565cSPeter Wemm 
591773b6454SNate Lawson 	printf(BEGIN_COMMENT);
592773b6454SNate Lawson 	acpi_print_sdt(sdp);
593986dffafSJohn Baldwin 	hpet = (ACPI_TABLE_HPET *)sdp;
594986dffafSJohn Baldwin 	printf("\tHPET Number=%d\n", hpet->Sequence);
59587f9f09aSTakanori Watanabe 	printf("\tADDR=");
596986dffafSJohn Baldwin 	acpi_print_gas(&hpet->Address);
597986dffafSJohn Baldwin 	printf("\tHW Rev=0x%x\n", hpet->Id & ACPI_HPET_ID_HARDWARE_REV_ID);
598986dffafSJohn Baldwin 	printf("\tComparators=%d\n", (hpet->Id & ACPI_HPET_ID_COMPARATORS) >>
599986dffafSJohn Baldwin 	    8);
600986dffafSJohn Baldwin 	printf("\tCounter Size=%d\n", hpet->Id & ACPI_HPET_ID_COUNT_SIZE_CAP ?
601986dffafSJohn Baldwin 	    1 : 0);
60279d7565cSPeter Wemm 	printf("\tLegacy IRQ routing capable={");
603986dffafSJohn Baldwin 	if (hpet->Id & ACPI_HPET_ID_LEGACY_CAPABLE)
60479d7565cSPeter Wemm 		printf("TRUE}\n");
60579d7565cSPeter Wemm 	else
60679d7565cSPeter Wemm 		printf("FALSE}\n");
607986dffafSJohn Baldwin 	printf("\tPCI Vendor ID=0x%04x\n", hpet->Id >> 16);
608986dffafSJohn Baldwin 	printf("\tMinimal Tick=%d\n", hpet->MinimumTick);
6099785e979SNeel Natu 	printf("\tFlags=0x%02x\n", hpet->Flags);
61079d7565cSPeter Wemm 	printf(END_COMMENT);
61179d7565cSPeter Wemm }
61279d7565cSPeter Wemm 
61379d7565cSPeter Wemm static void
614986dffafSJohn Baldwin acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp)
61555d7ff9eSNate Lawson {
616986dffafSJohn Baldwin 	ACPI_TABLE_ECDT *ecdt;
61755d7ff9eSNate Lawson 
61855d7ff9eSNate Lawson 	printf(BEGIN_COMMENT);
61955d7ff9eSNate Lawson 	acpi_print_sdt(sdp);
620986dffafSJohn Baldwin 	ecdt = (ACPI_TABLE_ECDT *)sdp;
62155d7ff9eSNate Lawson 	printf("\tEC_CONTROL=");
622986dffafSJohn Baldwin 	acpi_print_gas(&ecdt->Control);
62355d7ff9eSNate Lawson 	printf("\n\tEC_DATA=");
624986dffafSJohn Baldwin 	acpi_print_gas(&ecdt->Data);
625986dffafSJohn Baldwin 	printf("\n\tUID=%#x, ", ecdt->Uid);
626986dffafSJohn Baldwin 	printf("GPE_BIT=%#x\n", ecdt->Gpe);
627986dffafSJohn Baldwin 	printf("\tEC_ID=%s\n", ecdt->Id);
62855d7ff9eSNate Lawson 	printf(END_COMMENT);
62955d7ff9eSNate Lawson }
63055d7ff9eSNate Lawson 
63155d7ff9eSNate Lawson static void
632986dffafSJohn Baldwin acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp)
633a47e681bSScott Long {
634986dffafSJohn Baldwin 	ACPI_TABLE_MCFG *mcfg;
635986dffafSJohn Baldwin 	ACPI_MCFG_ALLOCATION *alloc;
636986dffafSJohn Baldwin 	u_int i, entries;
637a47e681bSScott Long 
638a47e681bSScott Long 	printf(BEGIN_COMMENT);
639a47e681bSScott Long 	acpi_print_sdt(sdp);
640986dffafSJohn Baldwin 	mcfg = (ACPI_TABLE_MCFG *)sdp;
641986dffafSJohn Baldwin 	entries = (sdp->Length - sizeof(ACPI_TABLE_MCFG)) /
642986dffafSJohn Baldwin 	    sizeof(ACPI_MCFG_ALLOCATION);
643986dffafSJohn Baldwin 	alloc = (ACPI_MCFG_ALLOCATION *)(mcfg + 1);
644986dffafSJohn Baldwin 	for (i = 0; i < entries; i++, alloc++) {
645a47e681bSScott Long 		printf("\n");
6460c10b85aSJung-uk Kim 		printf("\tBase Address=0x%016jx\n", (uintmax_t)alloc->Address);
647986dffafSJohn Baldwin 		printf("\tSegment Group=0x%04x\n", alloc->PciSegment);
648986dffafSJohn Baldwin 		printf("\tStart Bus=%d\n", alloc->StartBusNumber);
649986dffafSJohn Baldwin 		printf("\tEnd Bus=%d\n", alloc->EndBusNumber);
650a47e681bSScott Long 	}
651a47e681bSScott Long 	printf(END_COMMENT);
652a47e681bSScott Long }
653a47e681bSScott Long 
654a47e681bSScott Long static void
65533866658SJohn Baldwin acpi_handle_slit(ACPI_TABLE_HEADER *sdp)
65633866658SJohn Baldwin {
65733866658SJohn Baldwin 	ACPI_TABLE_SLIT *slit;
65833866658SJohn Baldwin 	UINT64 i, j;
65933866658SJohn Baldwin 
66033866658SJohn Baldwin 	printf(BEGIN_COMMENT);
66133866658SJohn Baldwin 	acpi_print_sdt(sdp);
66233866658SJohn Baldwin 	slit = (ACPI_TABLE_SLIT *)sdp;
6630c10b85aSJung-uk Kim 	printf("\tLocality Count=%ju\n", (uintmax_t)slit->LocalityCount);
66433866658SJohn Baldwin 	printf("\n\t      ");
66533866658SJohn Baldwin 	for (i = 0; i < slit->LocalityCount; i++)
6660c10b85aSJung-uk Kim 		printf(" %3ju", (uintmax_t)i);
66733866658SJohn Baldwin 	printf("\n\t     +");
66833866658SJohn Baldwin 	for (i = 0; i < slit->LocalityCount; i++)
66933866658SJohn Baldwin 		printf("----");
67033866658SJohn Baldwin 	printf("\n");
67133866658SJohn Baldwin 	for (i = 0; i < slit->LocalityCount; i++) {
6720c10b85aSJung-uk Kim 		printf("\t %3ju |", (uintmax_t)i);
67333866658SJohn Baldwin 		for (j = 0; j < slit->LocalityCount; j++)
67433866658SJohn Baldwin 			printf(" %3d",
67533866658SJohn Baldwin 			    slit->Entry[i * slit->LocalityCount + j]);
67633866658SJohn Baldwin 		printf("\n");
67733866658SJohn Baldwin 	}
67833866658SJohn Baldwin 	printf(END_COMMENT);
67933866658SJohn Baldwin }
68033866658SJohn Baldwin 
68133866658SJohn Baldwin static void
682a0333ad1SJohn Baldwin acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain,
683a0333ad1SJohn Baldwin     uint32_t flags)
684a0333ad1SJohn Baldwin {
685a0333ad1SJohn Baldwin 
686a0333ad1SJohn Baldwin 	printf("\tFlags={");
687a0333ad1SJohn Baldwin 	if (flags & ACPI_SRAT_CPU_ENABLED)
688a0333ad1SJohn Baldwin 		printf("ENABLED");
689a0333ad1SJohn Baldwin 	else
690a0333ad1SJohn Baldwin 		printf("DISABLED");
691a0333ad1SJohn Baldwin 	printf("}\n");
692a0333ad1SJohn Baldwin 	printf("\tAPIC ID=%d\n", apic_id);
693a0333ad1SJohn Baldwin 	printf("\tProximity Domain=%d\n", proximity_domain);
694a0333ad1SJohn Baldwin }
695a0333ad1SJohn Baldwin 
696c031c93bSTakanori Watanabe static char *
697c031c93bSTakanori Watanabe acpi_tcpa_evname(struct TCPAevent *event)
698c031c93bSTakanori Watanabe {
699c031c93bSTakanori Watanabe 	struct TCPApc_event *pc_event;
700c031c93bSTakanori Watanabe 	char *eventname = NULL;
701c031c93bSTakanori Watanabe 
702c031c93bSTakanori Watanabe 	pc_event = (struct TCPApc_event *)(event + 1);
703c031c93bSTakanori Watanabe 
704c031c93bSTakanori Watanabe 	switch(event->event_type) {
705c031c93bSTakanori Watanabe 	case PREBOOT:
706c031c93bSTakanori Watanabe 	case POST_CODE:
707c031c93bSTakanori Watanabe 	case UNUSED:
708c031c93bSTakanori Watanabe 	case NO_ACTION:
709c031c93bSTakanori Watanabe 	case SEPARATOR:
710c031c93bSTakanori Watanabe 	case SCRTM_CONTENTS:
711c031c93bSTakanori Watanabe 	case SCRTM_VERSION:
712c031c93bSTakanori Watanabe 	case CPU_MICROCODE:
713c031c93bSTakanori Watanabe 	case PLATFORM_CONFIG_FLAGS:
714c031c93bSTakanori Watanabe 	case TABLE_OF_DEVICES:
715c031c93bSTakanori Watanabe 	case COMPACT_HASH:
716c031c93bSTakanori Watanabe 	case IPL:
717c031c93bSTakanori Watanabe 	case IPL_PARTITION_DATA:
718c031c93bSTakanori Watanabe 	case NONHOST_CODE:
719c031c93bSTakanori Watanabe 	case NONHOST_CONFIG:
720c031c93bSTakanori Watanabe 	case NONHOST_INFO:
721c031c93bSTakanori Watanabe 		asprintf(&eventname, "%s",
722c031c93bSTakanori Watanabe 		    tcpa_event_type_strings[event->event_type]);
723c031c93bSTakanori Watanabe 		break;
724c031c93bSTakanori Watanabe 
725c031c93bSTakanori Watanabe 	case ACTION:
726c031c93bSTakanori Watanabe 		eventname = calloc(event->event_size + 1, sizeof(char));
727c031c93bSTakanori Watanabe 		memcpy(eventname, pc_event, event->event_size);
728c031c93bSTakanori Watanabe 		break;
729c031c93bSTakanori Watanabe 
730c031c93bSTakanori Watanabe 	case EVENT_TAG:
731c031c93bSTakanori Watanabe 		switch (pc_event->event_id) {
732c031c93bSTakanori Watanabe 		case SMBIOS:
733c031c93bSTakanori Watanabe 		case BIS_CERT:
734c031c93bSTakanori Watanabe 		case CMOS:
735c031c93bSTakanori Watanabe 		case NVRAM:
736c031c93bSTakanori Watanabe 		case OPTION_ROM_EXEC:
737c031c93bSTakanori Watanabe 		case OPTION_ROM_CONFIG:
738c031c93bSTakanori Watanabe 		case S_CRTM_VERSION:
739c031c93bSTakanori Watanabe 		case POST_BIOS_ROM:
740c031c93bSTakanori Watanabe 		case ESCD:
741c031c93bSTakanori Watanabe 		case OPTION_ROM_MICROCODE:
742c031c93bSTakanori Watanabe 		case S_CRTM_CONTENTS:
743c031c93bSTakanori Watanabe 		case POST_CONTENTS:
744c031c93bSTakanori Watanabe 			asprintf(&eventname, "%s",
745c031c93bSTakanori Watanabe 			    TCPA_pcclient_strings[pc_event->event_id]);
746c031c93bSTakanori Watanabe 			break;
747c031c93bSTakanori Watanabe 
748c031c93bSTakanori Watanabe 		default:
749c031c93bSTakanori Watanabe 			asprintf(&eventname, "<unknown tag 0x%02x>",
750c031c93bSTakanori Watanabe 			    pc_event->event_id);
751c031c93bSTakanori Watanabe 			break;
752c031c93bSTakanori Watanabe 		}
753c031c93bSTakanori Watanabe 		break;
754c031c93bSTakanori Watanabe 
755c031c93bSTakanori Watanabe 	default:
756c031c93bSTakanori Watanabe 		asprintf(&eventname, "<unknown 0x%02x>", event->event_type);
757c031c93bSTakanori Watanabe 		break;
758c031c93bSTakanori Watanabe 	}
759c031c93bSTakanori Watanabe 
760c031c93bSTakanori Watanabe 	return eventname;
761c031c93bSTakanori Watanabe }
762c031c93bSTakanori Watanabe 
763c031c93bSTakanori Watanabe static void
764c031c93bSTakanori Watanabe acpi_print_tcpa(struct TCPAevent *event)
765c031c93bSTakanori Watanabe {
766c031c93bSTakanori Watanabe 	int i;
767c031c93bSTakanori Watanabe 	char *eventname;
768c031c93bSTakanori Watanabe 
769c031c93bSTakanori Watanabe 	eventname = acpi_tcpa_evname(event);
770c031c93bSTakanori Watanabe 
771c031c93bSTakanori Watanabe 	printf("\t%d", event->pcr_index);
772c031c93bSTakanori Watanabe 	printf(" 0x");
773c031c93bSTakanori Watanabe 	for (i = 0; i < 20; i++)
774c031c93bSTakanori Watanabe 		printf("%02x", event->pcr_value[i]);
775c031c93bSTakanori Watanabe 	printf(" [%s]\n", eventname ? eventname : "<unknown>");
776c031c93bSTakanori Watanabe 
777c031c93bSTakanori Watanabe 	free(eventname);
778c031c93bSTakanori Watanabe }
779c031c93bSTakanori Watanabe 
780c031c93bSTakanori Watanabe static void
781c031c93bSTakanori Watanabe acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp)
782c031c93bSTakanori Watanabe {
783c031c93bSTakanori Watanabe 	struct TCPAbody *tcpa;
784c031c93bSTakanori Watanabe 	struct TCPAevent *event;
785977fd9daSTakanori Watanabe 	uintmax_t len, paddr;
786c031c93bSTakanori Watanabe 	unsigned char *vaddr = NULL;
787c031c93bSTakanori Watanabe 	unsigned char *vend = NULL;
788c031c93bSTakanori Watanabe 
789c031c93bSTakanori Watanabe 	printf(BEGIN_COMMENT);
790c031c93bSTakanori Watanabe 	acpi_print_sdt(sdp);
791c031c93bSTakanori Watanabe 	tcpa = (struct TCPAbody *) sdp;
792c031c93bSTakanori Watanabe 
793c031c93bSTakanori Watanabe 	switch (tcpa->platform_class) {
794c031c93bSTakanori Watanabe 	case ACPI_TCPA_BIOS_CLIENT:
795c031c93bSTakanori Watanabe 		len = tcpa->client.log_max_len;
796c031c93bSTakanori Watanabe 		paddr = tcpa->client.log_start_addr;
797c031c93bSTakanori Watanabe 		break;
798c031c93bSTakanori Watanabe 
799c031c93bSTakanori Watanabe 	case ACPI_TCPA_BIOS_SERVER:
800c031c93bSTakanori Watanabe 		len = tcpa->server.log_max_len;
801c031c93bSTakanori Watanabe 		paddr = tcpa->server.log_start_addr;
802c031c93bSTakanori Watanabe 		break;
803c031c93bSTakanori Watanabe 
804c031c93bSTakanori Watanabe 	default:
805c031c93bSTakanori Watanabe 		printf("XXX");
806c031c93bSTakanori Watanabe 		printf(END_COMMENT);
807c031c93bSTakanori Watanabe 		return;
808c031c93bSTakanori Watanabe 	}
8090e1982f4STakanori Watanabe 	printf("\tClass %u Base Address 0x%jx Length %ju\n\n",
810c031c93bSTakanori Watanabe 	    tcpa->platform_class, paddr, len);
811c031c93bSTakanori Watanabe 
812c031c93bSTakanori Watanabe 	if (len == 0) {
813c031c93bSTakanori Watanabe 		printf("\tEmpty TCPA table\n");
814c031c93bSTakanori Watanabe 		printf(END_COMMENT);
815c031c93bSTakanori Watanabe 		return;
816c031c93bSTakanori Watanabe 	}
8172ef23c6dSTakanori Watanabe 	if(sdp->Revision == 1){
8182ef23c6dSTakanori Watanabe 		printf("\tOLD TCPA spec log found. Dumping not supported.\n");
8192ef23c6dSTakanori Watanabe 		printf(END_COMMENT);
8202ef23c6dSTakanori Watanabe 		return;
8212ef23c6dSTakanori Watanabe 	}
822c031c93bSTakanori Watanabe 
823c031c93bSTakanori Watanabe 	vaddr = (unsigned char *)acpi_map_physical(paddr, len);
824c031c93bSTakanori Watanabe 	vend = vaddr + len;
825c031c93bSTakanori Watanabe 
826c031c93bSTakanori Watanabe 	while (vaddr != NULL) {
8272ef23c6dSTakanori Watanabe 		if ((vaddr + sizeof(struct TCPAevent) >= vend)||
8282ef23c6dSTakanori Watanabe 		    (vaddr + sizeof(struct TCPAevent) < vaddr))
829c031c93bSTakanori Watanabe 			break;
8300e1982f4STakanori Watanabe 		event = (struct TCPAevent *)(void *)vaddr;
831c031c93bSTakanori Watanabe 		if (vaddr + event->event_size >= vend)
832c031c93bSTakanori Watanabe 			break;
8332ef23c6dSTakanori Watanabe 		if (vaddr + event->event_size < vaddr)
8342ef23c6dSTakanori Watanabe 			break;
835c031c93bSTakanori Watanabe 		if (event->event_type == 0 && event->event_size == 0)
836c031c93bSTakanori Watanabe 			break;
837c031c93bSTakanori Watanabe #if 0
838c031c93bSTakanori Watanabe 		{
839c031c93bSTakanori Watanabe 		unsigned int i, j, k;
840c031c93bSTakanori Watanabe 
841c031c93bSTakanori Watanabe 		printf("\n\tsize %d\n\t\t%p ", event->event_size, vaddr);
842c031c93bSTakanori Watanabe 		for (j = 0, i = 0; i <
843c031c93bSTakanori Watanabe 		    sizeof(struct TCPAevent) + event->event_size; i++) {
844c031c93bSTakanori Watanabe 			printf("%02x ", vaddr[i]);
845c031c93bSTakanori Watanabe 			if ((i+1) % 8 == 0) {
846c031c93bSTakanori Watanabe 				for (k = 0; k < 8; k++)
847c031c93bSTakanori Watanabe 					printf("%c", isprint(vaddr[j+k]) ?
848c031c93bSTakanori Watanabe 					    vaddr[j+k] : '.');
849c031c93bSTakanori Watanabe 				printf("\n\t\t%p ", &vaddr[i + 1]);
850c031c93bSTakanori Watanabe 				j = i + 1;
851c031c93bSTakanori Watanabe 			}
852c031c93bSTakanori Watanabe 		}
853c031c93bSTakanori Watanabe 		printf("\n"); }
854c031c93bSTakanori Watanabe #endif
855c031c93bSTakanori Watanabe 		acpi_print_tcpa(event);
856c031c93bSTakanori Watanabe 
857c031c93bSTakanori Watanabe 		vaddr += sizeof(struct TCPAevent) + event->event_size;
858c031c93bSTakanori Watanabe 	}
859c031c93bSTakanori Watanabe 
860c031c93bSTakanori Watanabe 	printf(END_COMMENT);
861c031c93bSTakanori Watanabe }
862c031c93bSTakanori Watanabe 
863ec650989SNeel Natu static const char *
864ec650989SNeel Natu devscope_type2str(int type)
865ec650989SNeel Natu {
866ec650989SNeel Natu 	static char typebuf[16];
867ec650989SNeel Natu 
868ec650989SNeel Natu 	switch (type) {
869ec650989SNeel Natu 	case 1:
870ec650989SNeel Natu 		return ("PCI Endpoint Device");
871ec650989SNeel Natu 	case 2:
872ec650989SNeel Natu 		return ("PCI Sub-Hierarchy");
873ec650989SNeel Natu 	case 3:
874ec650989SNeel Natu 		return ("IOAPIC");
875ec650989SNeel Natu 	case 4:
876ec650989SNeel Natu 		return ("HPET");
877ec650989SNeel Natu 	default:
878ec650989SNeel Natu 		snprintf(typebuf, sizeof(typebuf), "%d", type);
879ec650989SNeel Natu 		return (typebuf);
880ec650989SNeel Natu 	}
881ec650989SNeel Natu }
882ec650989SNeel Natu 
883ec650989SNeel Natu static int
884ec650989SNeel Natu acpi_handle_dmar_devscope(void *addr, int remaining)
885ec650989SNeel Natu {
886ec650989SNeel Natu 	char sep;
887ec650989SNeel Natu 	int pathlen;
888ec650989SNeel Natu 	ACPI_DMAR_PCI_PATH *path, *pathend;
889ec650989SNeel Natu 	ACPI_DMAR_DEVICE_SCOPE *devscope = addr;
890ec650989SNeel Natu 
891ec650989SNeel Natu 	if (remaining < (int)sizeof(ACPI_DMAR_DEVICE_SCOPE))
892ec650989SNeel Natu 		return (-1);
893ec650989SNeel Natu 
894ec650989SNeel Natu 	if (remaining < devscope->Length)
895ec650989SNeel Natu 		return (-1);
896ec650989SNeel Natu 
897ec650989SNeel Natu 	printf("\n");
898ec650989SNeel Natu 	printf("\t\tType=%s\n", devscope_type2str(devscope->EntryType));
899ec650989SNeel Natu 	printf("\t\tLength=%d\n", devscope->Length);
900ec650989SNeel Natu 	printf("\t\tEnumerationId=%d\n", devscope->EnumerationId);
901ec650989SNeel Natu 	printf("\t\tStartBusNumber=%d\n", devscope->Bus);
902ec650989SNeel Natu 
903ec650989SNeel Natu 	path = (ACPI_DMAR_PCI_PATH *)(devscope + 1);
904ec650989SNeel Natu 	pathlen = devscope->Length - sizeof(ACPI_DMAR_DEVICE_SCOPE);
905ec650989SNeel Natu 	pathend = path + pathlen / sizeof(ACPI_DMAR_PCI_PATH);
906ec650989SNeel Natu 	if (path < pathend) {
907ec650989SNeel Natu 		sep = '{';
908ec650989SNeel Natu 		printf("\t\tPath=");
909ec650989SNeel Natu 		do {
910ec650989SNeel Natu 			printf("%c%d:%d", sep, path->Device, path->Function);
911ec650989SNeel Natu 			sep=',';
912ec650989SNeel Natu 			path++;
913ec650989SNeel Natu 		} while (path < pathend);
914ec650989SNeel Natu 		printf("}\n");
915ec650989SNeel Natu 	}
916ec650989SNeel Natu 
917ec650989SNeel Natu 	return (devscope->Length);
918ec650989SNeel Natu }
919ec650989SNeel Natu 
920ec650989SNeel Natu static void
921ec650989SNeel Natu acpi_handle_dmar_drhd(ACPI_DMAR_HARDWARE_UNIT *drhd)
922ec650989SNeel Natu {
923ec650989SNeel Natu 	char *cp;
924ec650989SNeel Natu 	int remaining, consumed;
925ec650989SNeel Natu 
926ec650989SNeel Natu 	printf("\n");
927ec650989SNeel Natu 	printf("\tType=DRHD\n");
928ec650989SNeel Natu 	printf("\tLength=%d\n", drhd->Header.Length);
929ec650989SNeel Natu 
930ec650989SNeel Natu #define	PRINTFLAG(var, flag)	printflag((var), ACPI_DMAR_## flag, #flag)
931ec650989SNeel Natu 
932ec650989SNeel Natu 	printf("\tFlags=");
933ec650989SNeel Natu 	PRINTFLAG(drhd->Flags, INCLUDE_ALL);
934ec650989SNeel Natu 	PRINTFLAG_END();
935ec650989SNeel Natu 
936ec650989SNeel Natu #undef PRINTFLAG
937ec650989SNeel Natu 
938ec650989SNeel Natu 	printf("\tSegment=%d\n", drhd->Segment);
9397d369c6eSJung-uk Kim 	printf("\tAddress=0x%016jx\n", (uintmax_t)drhd->Address);
940ec650989SNeel Natu 
941ec650989SNeel Natu 	remaining = drhd->Header.Length - sizeof(ACPI_DMAR_HARDWARE_UNIT);
942ec650989SNeel Natu 	if (remaining > 0)
943ec650989SNeel Natu 		printf("\tDevice Scope:");
944ec650989SNeel Natu 	while (remaining > 0) {
945ec650989SNeel Natu 		cp = (char *)drhd + drhd->Header.Length - remaining;
946ec650989SNeel Natu 		consumed = acpi_handle_dmar_devscope(cp, remaining);
947ec650989SNeel Natu 		if (consumed <= 0)
948ec650989SNeel Natu 			break;
949ec650989SNeel Natu 		else
950ec650989SNeel Natu 			remaining -= consumed;
951ec650989SNeel Natu 	}
952ec650989SNeel Natu }
953ec650989SNeel Natu 
954ec650989SNeel Natu static void
955ec650989SNeel Natu acpi_handle_dmar_rmrr(ACPI_DMAR_RESERVED_MEMORY *rmrr)
956ec650989SNeel Natu {
957ec650989SNeel Natu 	char *cp;
958ec650989SNeel Natu 	int remaining, consumed;
959ec650989SNeel Natu 
960ec650989SNeel Natu 	printf("\n");
961ec650989SNeel Natu 	printf("\tType=RMRR\n");
962ec650989SNeel Natu 	printf("\tLength=%d\n", rmrr->Header.Length);
963ec650989SNeel Natu 	printf("\tSegment=%d\n", rmrr->Segment);
9647d369c6eSJung-uk Kim 	printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rmrr->BaseAddress);
9657d369c6eSJung-uk Kim 	printf("\tLimitAddress=0x%016jx\n", (uintmax_t)rmrr->EndAddress);
966ec650989SNeel Natu 
967ec650989SNeel Natu 	remaining = rmrr->Header.Length - sizeof(ACPI_DMAR_RESERVED_MEMORY);
968ec650989SNeel Natu 	if (remaining > 0)
969ec650989SNeel Natu 		printf("\tDevice Scope:");
970ec650989SNeel Natu 	while (remaining > 0) {
971ec650989SNeel Natu 		cp = (char *)rmrr + rmrr->Header.Length - remaining;
972ec650989SNeel Natu 		consumed = acpi_handle_dmar_devscope(cp, remaining);
973ec650989SNeel Natu 		if (consumed <= 0)
974ec650989SNeel Natu 			break;
975ec650989SNeel Natu 		else
976ec650989SNeel Natu 			remaining -= consumed;
977ec650989SNeel Natu 	}
978ec650989SNeel Natu }
979ec650989SNeel Natu 
980ec650989SNeel Natu static void
981ec650989SNeel Natu acpi_handle_dmar_atsr(ACPI_DMAR_ATSR *atsr)
982ec650989SNeel Natu {
983ec650989SNeel Natu 	char *cp;
984ec650989SNeel Natu 	int remaining, consumed;
985ec650989SNeel Natu 
986ec650989SNeel Natu 	printf("\n");
987ec650989SNeel Natu 	printf("\tType=ATSR\n");
988ec650989SNeel Natu 	printf("\tLength=%d\n", atsr->Header.Length);
989ec650989SNeel Natu 
990ec650989SNeel Natu #define	PRINTFLAG(var, flag)	printflag((var), ACPI_DMAR_## flag, #flag)
991ec650989SNeel Natu 
992ec650989SNeel Natu 	printf("\tFlags=");
993ec650989SNeel Natu 	PRINTFLAG(atsr->Flags, ALL_PORTS);
994ec650989SNeel Natu 	PRINTFLAG_END();
995ec650989SNeel Natu 
996ec650989SNeel Natu #undef PRINTFLAG
997ec650989SNeel Natu 
998ec650989SNeel Natu 	printf("\tSegment=%d\n", atsr->Segment);
999ec650989SNeel Natu 
1000ec650989SNeel Natu 	remaining = atsr->Header.Length - sizeof(ACPI_DMAR_ATSR);
1001ec650989SNeel Natu 	if (remaining > 0)
1002ec650989SNeel Natu 		printf("\tDevice Scope:");
1003ec650989SNeel Natu 	while (remaining > 0) {
1004ec650989SNeel Natu 		cp = (char *)atsr + atsr->Header.Length - remaining;
1005ec650989SNeel Natu 		consumed = acpi_handle_dmar_devscope(cp, remaining);
1006ec650989SNeel Natu 		if (consumed <= 0)
1007ec650989SNeel Natu 			break;
1008ec650989SNeel Natu 		else
1009ec650989SNeel Natu 			remaining -= consumed;
1010ec650989SNeel Natu 	}
1011ec650989SNeel Natu }
1012ec650989SNeel Natu 
1013ec650989SNeel Natu static void
1014ec650989SNeel Natu acpi_handle_dmar_rhsa(ACPI_DMAR_RHSA *rhsa)
1015ec650989SNeel Natu {
1016ec650989SNeel Natu 
1017ec650989SNeel Natu 	printf("\n");
1018ec650989SNeel Natu 	printf("\tType=RHSA\n");
1019ec650989SNeel Natu 	printf("\tLength=%d\n", rhsa->Header.Length);
10207d369c6eSJung-uk Kim 	printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rhsa->BaseAddress);
1021ec650989SNeel Natu 	printf("\tProximityDomain=0x%08x\n", rhsa->ProximityDomain);
1022ec650989SNeel Natu }
1023ec650989SNeel Natu 
1024ec650989SNeel Natu static int
1025ec650989SNeel Natu acpi_handle_dmar_remapping_structure(void *addr, int remaining)
1026ec650989SNeel Natu {
1027ec650989SNeel Natu 	ACPI_DMAR_HEADER *hdr = addr;
1028ec650989SNeel Natu 
1029ec650989SNeel Natu 	if (remaining < (int)sizeof(ACPI_DMAR_HEADER))
1030ec650989SNeel Natu 		return (-1);
1031ec650989SNeel Natu 
1032ec650989SNeel Natu 	if (remaining < hdr->Length)
1033ec650989SNeel Natu 		return (-1);
1034ec650989SNeel Natu 
1035ec650989SNeel Natu 	switch (hdr->Type) {
1036ec650989SNeel Natu 	case ACPI_DMAR_TYPE_HARDWARE_UNIT:
1037ec650989SNeel Natu 		acpi_handle_dmar_drhd(addr);
1038ec650989SNeel Natu 		break;
1039ec650989SNeel Natu 	case ACPI_DMAR_TYPE_RESERVED_MEMORY:
1040ec650989SNeel Natu 		acpi_handle_dmar_rmrr(addr);
1041ec650989SNeel Natu 		break;
1042313a0c13SJung-uk Kim 	case ACPI_DMAR_TYPE_ROOT_ATS:
1043ec650989SNeel Natu 		acpi_handle_dmar_atsr(addr);
1044ec650989SNeel Natu 		break;
1045313a0c13SJung-uk Kim 	case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
1046ec650989SNeel Natu 		acpi_handle_dmar_rhsa(addr);
1047ec650989SNeel Natu 		break;
1048ec650989SNeel Natu 	default:
1049ec650989SNeel Natu 		printf("\n");
1050ec650989SNeel Natu 		printf("\tType=%d\n", hdr->Type);
1051ec650989SNeel Natu 		printf("\tLength=%d\n", hdr->Length);
1052ec650989SNeel Natu 		break;
1053ec650989SNeel Natu 	}
1054ec650989SNeel Natu 	return (hdr->Length);
1055ec650989SNeel Natu }
1056ec650989SNeel Natu 
1057ec650989SNeel Natu #ifndef ACPI_DMAR_X2APIC_OPT_OUT
1058ec650989SNeel Natu #define	ACPI_DMAR_X2APIC_OPT_OUT	(0x2)
1059ec650989SNeel Natu #endif
1060ec650989SNeel Natu 
1061ec650989SNeel Natu static void
1062ec650989SNeel Natu acpi_handle_dmar(ACPI_TABLE_HEADER *sdp)
1063ec650989SNeel Natu {
1064ec650989SNeel Natu 	char *cp;
1065ec650989SNeel Natu 	int remaining, consumed;
1066ec650989SNeel Natu 	ACPI_TABLE_DMAR *dmar;
1067ec650989SNeel Natu 
1068ec650989SNeel Natu 	printf(BEGIN_COMMENT);
1069ec650989SNeel Natu 	acpi_print_sdt(sdp);
1070ec650989SNeel Natu 	dmar = (ACPI_TABLE_DMAR *)sdp;
1071ec650989SNeel Natu 	printf("\tHost Address Width=%d\n", dmar->Width + 1);
1072ec650989SNeel Natu 
1073ec650989SNeel Natu #define PRINTFLAG(var, flag)	printflag((var), ACPI_DMAR_## flag, #flag)
1074ec650989SNeel Natu 
1075ec650989SNeel Natu 	printf("\tFlags=");
1076ec650989SNeel Natu 	PRINTFLAG(dmar->Flags, INTR_REMAP);
1077ec650989SNeel Natu 	PRINTFLAG(dmar->Flags, X2APIC_OPT_OUT);
1078ec650989SNeel Natu 	PRINTFLAG_END();
1079ec650989SNeel Natu 
1080ec650989SNeel Natu #undef PRINTFLAG
1081ec650989SNeel Natu 
1082ec650989SNeel Natu 	remaining = sdp->Length - sizeof(ACPI_TABLE_DMAR);
1083ec650989SNeel Natu 	while (remaining > 0) {
1084ec650989SNeel Natu 		cp = (char *)sdp + sdp->Length - remaining;
1085ec650989SNeel Natu 		consumed = acpi_handle_dmar_remapping_structure(cp, remaining);
1086ec650989SNeel Natu 		if (consumed <= 0)
1087ec650989SNeel Natu 			break;
1088ec650989SNeel Natu 		else
1089ec650989SNeel Natu 			remaining -= consumed;
1090ec650989SNeel Natu 	}
1091ec650989SNeel Natu 
1092ec650989SNeel Natu 	printf(END_COMMENT);
1093ec650989SNeel Natu }
1094ec650989SNeel Natu 
1095a0333ad1SJohn Baldwin static void
1096986dffafSJohn Baldwin acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp)
1097a0333ad1SJohn Baldwin {
1098a0333ad1SJohn Baldwin 
1099a0333ad1SJohn Baldwin 	printf("\tFlags={");
1100986dffafSJohn Baldwin 	if (mp->Flags & ACPI_SRAT_MEM_ENABLED)
1101a0333ad1SJohn Baldwin 		printf("ENABLED");
1102a0333ad1SJohn Baldwin 	else
1103a0333ad1SJohn Baldwin 		printf("DISABLED");
1104986dffafSJohn Baldwin 	if (mp->Flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)
1105a0333ad1SJohn Baldwin 		printf(",HOT_PLUGGABLE");
1106986dffafSJohn Baldwin 	if (mp->Flags & ACPI_SRAT_MEM_NON_VOLATILE)
1107a0333ad1SJohn Baldwin 		printf(",NON_VOLATILE");
1108a0333ad1SJohn Baldwin 	printf("}\n");
1109986dffafSJohn Baldwin 	printf("\tBase Address=0x%016jx\n", (uintmax_t)mp->BaseAddress);
1110986dffafSJohn Baldwin 	printf("\tLength=0x%016jx\n", (uintmax_t)mp->Length);
1111986dffafSJohn Baldwin 	printf("\tProximity Domain=%d\n", mp->ProximityDomain);
1112a0333ad1SJohn Baldwin }
1113a0333ad1SJohn Baldwin 
111427941afaSEd Maste static const char *srat_types[] = {
111527941afaSEd Maste     [ACPI_SRAT_TYPE_CPU_AFFINITY] = "CPU",
111627941afaSEd Maste     [ACPI_SRAT_TYPE_MEMORY_AFFINITY] = "Memory",
111727941afaSEd Maste     [ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY] = "X2APIC",
1118cebb7b19SEd Maste     [ACPI_SRAT_TYPE_GICC_AFFINITY] = "GICC",
1119cebb7b19SEd Maste     [ACPI_SRAT_TYPE_GIC_ITS_AFFINITY] = "GIC ITS",
112027941afaSEd Maste };
1121a0333ad1SJohn Baldwin 
1122a0333ad1SJohn Baldwin static void
1123986dffafSJohn Baldwin acpi_print_srat(ACPI_SUBTABLE_HEADER *srat)
1124a0333ad1SJohn Baldwin {
1125986dffafSJohn Baldwin 	ACPI_SRAT_CPU_AFFINITY *cpu;
1126986dffafSJohn Baldwin 	ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic;
11272b2b1f42SAndrew Turner 	ACPI_SRAT_GICC_AFFINITY *gic;
1128a0333ad1SJohn Baldwin 
1129c86932b6SMarcelo Araujo 	if (srat->Type < nitems(srat_types))
1130986dffafSJohn Baldwin 		printf("\tType=%s\n", srat_types[srat->Type]);
1131a0333ad1SJohn Baldwin 	else
1132986dffafSJohn Baldwin 		printf("\tType=%d (unknown)\n", srat->Type);
1133986dffafSJohn Baldwin 	switch (srat->Type) {
1134a0333ad1SJohn Baldwin 	case ACPI_SRAT_TYPE_CPU_AFFINITY:
1135986dffafSJohn Baldwin 		cpu = (ACPI_SRAT_CPU_AFFINITY *)srat;
1136986dffafSJohn Baldwin 		acpi_print_srat_cpu(cpu->ApicId,
1137986dffafSJohn Baldwin 		    cpu->ProximityDomainHi[2] << 24 |
1138986dffafSJohn Baldwin 		    cpu->ProximityDomainHi[1] << 16 |
1139986dffafSJohn Baldwin 		    cpu->ProximityDomainHi[0] << 0 |
1140986dffafSJohn Baldwin 		    cpu->ProximityDomainLo, cpu->Flags);
1141a0333ad1SJohn Baldwin 		break;
1142a0333ad1SJohn Baldwin 	case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
1143986dffafSJohn Baldwin 		acpi_print_srat_memory((ACPI_SRAT_MEM_AFFINITY *)srat);
1144a0333ad1SJohn Baldwin 		break;
1145a0333ad1SJohn Baldwin 	case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
1146986dffafSJohn Baldwin 		x2apic = (ACPI_SRAT_X2APIC_CPU_AFFINITY *)srat;
1147986dffafSJohn Baldwin 		acpi_print_srat_cpu(x2apic->ApicId, x2apic->ProximityDomain,
1148986dffafSJohn Baldwin 		    x2apic->Flags);
1149a0333ad1SJohn Baldwin 		break;
11502b2b1f42SAndrew Turner 	case ACPI_SRAT_TYPE_GICC_AFFINITY:
11512b2b1f42SAndrew Turner 		gic = (ACPI_SRAT_GICC_AFFINITY *)srat;
11522b2b1f42SAndrew Turner 		acpi_print_srat_cpu(gic->AcpiProcessorUid, gic->ProximityDomain,
11532b2b1f42SAndrew Turner 		    gic->Flags);
11542b2b1f42SAndrew Turner 		break;
1155a0333ad1SJohn Baldwin 	}
1156a0333ad1SJohn Baldwin }
1157a0333ad1SJohn Baldwin 
1158a0333ad1SJohn Baldwin static void
1159986dffafSJohn Baldwin acpi_handle_srat(ACPI_TABLE_HEADER *sdp)
1160a0333ad1SJohn Baldwin {
1161986dffafSJohn Baldwin 	ACPI_TABLE_SRAT *srat;
1162a0333ad1SJohn Baldwin 
1163a0333ad1SJohn Baldwin 	printf(BEGIN_COMMENT);
1164a0333ad1SJohn Baldwin 	acpi_print_sdt(sdp);
1165986dffafSJohn Baldwin 	srat = (ACPI_TABLE_SRAT *)sdp;
1166986dffafSJohn Baldwin 	printf("\tTable Revision=%d\n", srat->TableRevision);
1167986dffafSJohn Baldwin 	acpi_walk_subtables(sdp, (srat + 1), acpi_print_srat);
1168a0333ad1SJohn Baldwin 	printf(END_COMMENT);
1169a0333ad1SJohn Baldwin }
1170a0333ad1SJohn Baldwin 
1171340c0022SEd Maste static const char *nfit_types[] = {
1172340c0022SEd Maste     [ACPI_NFIT_TYPE_SYSTEM_ADDRESS] = "System Address",
1173340c0022SEd Maste     [ACPI_NFIT_TYPE_MEMORY_MAP] = "Memory Map",
1174340c0022SEd Maste     [ACPI_NFIT_TYPE_INTERLEAVE] = "Interleave",
1175340c0022SEd Maste     [ACPI_NFIT_TYPE_SMBIOS] = "SMBIOS",
1176340c0022SEd Maste     [ACPI_NFIT_TYPE_CONTROL_REGION] = "Control Region",
1177340c0022SEd Maste     [ACPI_NFIT_TYPE_DATA_REGION] = "Data Region",
1178340c0022SEd Maste     [ACPI_NFIT_TYPE_FLUSH_ADDRESS] = "Flush Address"
1179340c0022SEd Maste };
1180340c0022SEd Maste 
1181340c0022SEd Maste 
1182340c0022SEd Maste static void
1183340c0022SEd Maste acpi_print_nfit(ACPI_NFIT_HEADER *nfit)
1184340c0022SEd Maste {
1185340c0022SEd Maste 	char *uuidstr;
1186340c0022SEd Maste 	uint32_t status;
1187340c0022SEd Maste 
1188340c0022SEd Maste 	ACPI_NFIT_SYSTEM_ADDRESS *sysaddr;
1189340c0022SEd Maste 	ACPI_NFIT_MEMORY_MAP *mmap;
1190340c0022SEd Maste 	ACPI_NFIT_INTERLEAVE *ileave;
1191340c0022SEd Maste 	ACPI_NFIT_SMBIOS *smbios;
1192340c0022SEd Maste 	ACPI_NFIT_CONTROL_REGION *ctlreg;
1193340c0022SEd Maste 	ACPI_NFIT_DATA_REGION *datareg;
1194340c0022SEd Maste 	ACPI_NFIT_FLUSH_ADDRESS *fladdr;
1195340c0022SEd Maste 
1196340c0022SEd Maste 	if (nfit->Type < nitems(nfit_types))
1197340c0022SEd Maste 		printf("\tType=%s\n", nfit_types[nfit->Type]);
1198340c0022SEd Maste 	else
1199340c0022SEd Maste 		printf("\tType=%u (unknown)\n", nfit->Type);
1200340c0022SEd Maste 	switch (nfit->Type) {
1201340c0022SEd Maste 	case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
1202340c0022SEd Maste 		sysaddr = (ACPI_NFIT_SYSTEM_ADDRESS *)nfit;
1203340c0022SEd Maste 		printf("\tRangeIndex=%u\n", (u_int)sysaddr->RangeIndex);
1204340c0022SEd Maste 		printf("\tProximityDomain=%u\n",
1205340c0022SEd Maste 		    (u_int)sysaddr->ProximityDomain);
1206340c0022SEd Maste 		uuid_to_string((uuid_t *)(sysaddr->RangeGuid),
1207340c0022SEd Maste 		    &uuidstr, &status);
1208340c0022SEd Maste 		if (status != uuid_s_ok)
1209340c0022SEd Maste 			errx(1, "uuid_to_string: status=%u", status);
1210340c0022SEd Maste 		printf("\tRangeGuid=%s\n", uuidstr);
1211340c0022SEd Maste 		free(uuidstr);
1212340c0022SEd Maste 		printf("\tAddress=0x%016jx\n", (uintmax_t)sysaddr->Address);
1213340c0022SEd Maste 		printf("\tLength=0x%016jx\n", (uintmax_t)sysaddr->Length);
1214340c0022SEd Maste 		printf("\tMemoryMapping=0x%016jx\n",
1215340c0022SEd Maste 		    (uintmax_t)sysaddr->MemoryMapping);
1216340c0022SEd Maste 
1217340c0022SEd Maste #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_## flag, #flag)
1218340c0022SEd Maste 
1219340c0022SEd Maste 		printf("\tFlags=");
1220340c0022SEd Maste 		PRINTFLAG(sysaddr->Flags, ADD_ONLINE_ONLY);
1221340c0022SEd Maste 		PRINTFLAG(sysaddr->Flags, PROXIMITY_VALID);
1222340c0022SEd Maste 		PRINTFLAG_END();
1223340c0022SEd Maste 
1224340c0022SEd Maste #undef PRINTFLAG
1225340c0022SEd Maste 
1226340c0022SEd Maste 		break;
1227340c0022SEd Maste 	case ACPI_NFIT_TYPE_MEMORY_MAP:
1228340c0022SEd Maste 		mmap = (ACPI_NFIT_MEMORY_MAP *)nfit;
1229340c0022SEd Maste 		printf("\tDeviceHandle=%u\n", (u_int)mmap->DeviceHandle);
1230340c0022SEd Maste 		printf("\tPhysicalId=%u\n", (u_int)mmap->PhysicalId);
1231340c0022SEd Maste 		printf("\tRegionId=%u\n", (u_int)mmap->RegionId);
1232340c0022SEd Maste 		printf("\tRangeIndex=%u\n", (u_int)mmap->RangeIndex);
1233340c0022SEd Maste 		printf("\tRegionIndex=%u\n", (u_int)mmap->RegionIndex);
1234340c0022SEd Maste 		printf("\tRegionSize=0x%016jx\n", (uintmax_t)mmap->RegionSize);
1235340c0022SEd Maste 		printf("\tRegionOffset=0x%016jx\n",
1236340c0022SEd Maste 		    (uintmax_t)mmap->RegionOffset);
1237340c0022SEd Maste 		printf("\tAddress=0x%016jx\n", (uintmax_t)mmap->Address);
1238340c0022SEd Maste 		printf("\tInterleaveIndex=%u\n", (u_int)mmap->InterleaveIndex);
1239fb1cf2a9SAlexander Motin 		printf("\tInterleaveWays=%u\n", (u_int)mmap->InterleaveWays);
1240340c0022SEd Maste 
1241340c0022SEd Maste #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_MEM_## flag, #flag)
1242340c0022SEd Maste 
1243340c0022SEd Maste 		printf("\tFlags=");
1244340c0022SEd Maste 		PRINTFLAG(mmap->Flags, SAVE_FAILED);
1245340c0022SEd Maste 		PRINTFLAG(mmap->Flags, RESTORE_FAILED);
1246340c0022SEd Maste 		PRINTFLAG(mmap->Flags, FLUSH_FAILED);
1247340c0022SEd Maste 		PRINTFLAG(mmap->Flags, NOT_ARMED);
1248340c0022SEd Maste 		PRINTFLAG(mmap->Flags, HEALTH_OBSERVED);
1249340c0022SEd Maste 		PRINTFLAG(mmap->Flags, HEALTH_ENABLED);
1250340c0022SEd Maste 		PRINTFLAG(mmap->Flags, MAP_FAILED);
1251340c0022SEd Maste 		PRINTFLAG_END();
1252340c0022SEd Maste 
1253340c0022SEd Maste #undef PRINTFLAG
1254340c0022SEd Maste 
1255340c0022SEd Maste 		break;
1256340c0022SEd Maste 	case ACPI_NFIT_TYPE_INTERLEAVE:
1257340c0022SEd Maste 		ileave = (ACPI_NFIT_INTERLEAVE *)nfit;
1258340c0022SEd Maste 		printf("\tInterleaveIndex=%u\n",
1259340c0022SEd Maste 		    (u_int)ileave->InterleaveIndex);
1260340c0022SEd Maste 		printf("\tLineCount=%u\n", (u_int)ileave->LineCount);
1261340c0022SEd Maste 		printf("\tLineSize=%u\n", (u_int)ileave->LineSize);
1262340c0022SEd Maste 		/* XXX ileave->LineOffset[i] output is not supported */
1263340c0022SEd Maste 		break;
1264340c0022SEd Maste 	case ACPI_NFIT_TYPE_SMBIOS:
1265340c0022SEd Maste 		smbios = (ACPI_NFIT_SMBIOS *)nfit;
1266340c0022SEd Maste 		/* XXX smbios->Data[x] output is not supported */
1267340c0022SEd Maste 		break;
1268340c0022SEd Maste 	case ACPI_NFIT_TYPE_CONTROL_REGION:
1269340c0022SEd Maste 		ctlreg = (ACPI_NFIT_CONTROL_REGION *)nfit;
1270340c0022SEd Maste 		printf("\tRegionIndex=%u\n", (u_int)ctlreg->RegionIndex);
1271340c0022SEd Maste 		printf("\tVendorId=0x%04x\n", (u_int)ctlreg->VendorId);
1272340c0022SEd Maste 		printf("\tDeviceId=0x%04x\n", (u_int)ctlreg->DeviceId);
1273340c0022SEd Maste 		printf("\tRevisionId=%u\n", (u_int)ctlreg->RevisionId);
1274340c0022SEd Maste 		printf("\tSubsystemVendorId=0x%04x\n",
1275340c0022SEd Maste 		    (u_int)ctlreg->SubsystemVendorId);
1276340c0022SEd Maste 		printf("\tSubsystemDeviceId=0x%04x\n",
1277340c0022SEd Maste 		    (u_int)ctlreg->SubsystemDeviceId);
1278340c0022SEd Maste 		printf("\tSubsystemRevisionId=%u\n",
1279340c0022SEd Maste 		    (u_int)ctlreg->SubsystemRevisionId);
1280*d4c2de2eSAlexander Motin 		printf("\tValidFields=0x%02x\n", (u_int)ctlreg->ValidFields);
1281340c0022SEd Maste 		printf("\tManufacturingLocation=%u\n",
1282340c0022SEd Maste 		    (u_int)ctlreg->ManufacturingLocation);
1283340c0022SEd Maste 		printf("\tManufacturingDate=%u\n",
1284340c0022SEd Maste 		    (u_int)ctlreg->ManufacturingDate);
1285340c0022SEd Maste 		printf("\tSerialNumber=%u\n",
1286340c0022SEd Maste 		    (u_int)ctlreg->SerialNumber);
1287fb1cf2a9SAlexander Motin 		printf("\tCode=0x%04x\n", (u_int)ctlreg->Code);
1288340c0022SEd Maste 		printf("\tWindows=%u\n", (u_int)ctlreg->Windows);
1289340c0022SEd Maste 		printf("\tWindowSize=0x%016jx\n",
1290340c0022SEd Maste 		    (uintmax_t)ctlreg->WindowSize);
1291340c0022SEd Maste 		printf("\tCommandOffset=0x%016jx\n",
1292340c0022SEd Maste 		    (uintmax_t)ctlreg->CommandOffset);
1293340c0022SEd Maste 		printf("\tCommandSize=0x%016jx\n",
1294340c0022SEd Maste 		    (uintmax_t)ctlreg->CommandSize);
1295340c0022SEd Maste 		printf("\tStatusOffset=0x%016jx\n",
1296340c0022SEd Maste 		    (uintmax_t)ctlreg->StatusOffset);
1297340c0022SEd Maste 		printf("\tStatusSize=0x%016jx\n",
1298340c0022SEd Maste 		    (uintmax_t)ctlreg->StatusSize);
1299340c0022SEd Maste 
1300340c0022SEd Maste #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_## flag, #flag)
1301340c0022SEd Maste 
1302340c0022SEd Maste 		printf("\tFlags=");
1303*d4c2de2eSAlexander Motin 		PRINTFLAG(ctlreg->Flags, CONTROL_BUFFERED);
1304340c0022SEd Maste 		PRINTFLAG_END();
1305340c0022SEd Maste 
1306340c0022SEd Maste #undef PRINTFLAG
1307340c0022SEd Maste 
1308340c0022SEd Maste 		break;
1309340c0022SEd Maste 	case ACPI_NFIT_TYPE_DATA_REGION:
1310340c0022SEd Maste 		datareg = (ACPI_NFIT_DATA_REGION *)nfit;
1311340c0022SEd Maste 		printf("\tRegionIndex=%u\n", (u_int)datareg->RegionIndex);
1312340c0022SEd Maste 		printf("\tWindows=%u\n", (u_int)datareg->Windows);
1313340c0022SEd Maste 		printf("\tOffset=0x%016jx\n", (uintmax_t)datareg->Offset);
1314340c0022SEd Maste 		printf("\tSize=0x%016jx\n", (uintmax_t)datareg->Size);
1315340c0022SEd Maste 		printf("\tCapacity=0x%016jx\n", (uintmax_t)datareg->Capacity);
1316340c0022SEd Maste 		printf("\tStartAddress=0x%016jx\n",
1317340c0022SEd Maste 		    (uintmax_t)datareg->StartAddress);
1318340c0022SEd Maste 		break;
1319340c0022SEd Maste 	case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
1320340c0022SEd Maste 		fladdr = (ACPI_NFIT_FLUSH_ADDRESS *)nfit;
1321340c0022SEd Maste 		printf("\tDeviceHandle=%u\n", (u_int)fladdr->DeviceHandle);
1322340c0022SEd Maste 		printf("\tHintCount=%u\n", (u_int)fladdr->HintCount);
1323340c0022SEd Maste 		/* XXX fladdr->HintAddress[i] output is not supported */
1324340c0022SEd Maste 		break;
1325340c0022SEd Maste 	}
1326340c0022SEd Maste }
1327340c0022SEd Maste 
1328340c0022SEd Maste static void
1329340c0022SEd Maste acpi_handle_nfit(ACPI_TABLE_HEADER *sdp)
1330340c0022SEd Maste {
1331340c0022SEd Maste 	ACPI_TABLE_NFIT *nfit;
1332340c0022SEd Maste 
1333340c0022SEd Maste 	printf(BEGIN_COMMENT);
1334340c0022SEd Maste 	acpi_print_sdt(sdp);
1335340c0022SEd Maste 	nfit = (ACPI_TABLE_NFIT *)sdp;
1336340c0022SEd Maste 	acpi_walk_nfit(sdp, (nfit + 1), acpi_print_nfit);
1337340c0022SEd Maste 	printf(END_COMMENT);
1338340c0022SEd Maste }
1339340c0022SEd Maste 
1340a0333ad1SJohn Baldwin static void
1341986dffafSJohn Baldwin acpi_print_sdt(ACPI_TABLE_HEADER *sdp)
1342c62f1cccSMitsuru IWASAKI {
1343773b6454SNate Lawson 	printf("  ");
1344986dffafSJohn Baldwin 	acpi_print_string(sdp->Signature, ACPI_NAME_SIZE);
1345c62f1cccSMitsuru IWASAKI 	printf(": Length=%d, Revision=%d, Checksum=%d,\n",
1346986dffafSJohn Baldwin 	       sdp->Length, sdp->Revision, sdp->Checksum);
1347e1e9a4bfSMitsuru IWASAKI 	printf("\tOEMID=");
1348986dffafSJohn Baldwin 	acpi_print_string(sdp->OemId, ACPI_OEM_ID_SIZE);
1349e1e9a4bfSMitsuru IWASAKI 	printf(", OEM Table ID=");
1350986dffafSJohn Baldwin 	acpi_print_string(sdp->OemTableId, ACPI_OEM_TABLE_ID_SIZE);
1351986dffafSJohn Baldwin 	printf(", OEM Revision=0x%x,\n", sdp->OemRevision);
1352e1e9a4bfSMitsuru IWASAKI 	printf("\tCreator ID=");
1353986dffafSJohn Baldwin 	acpi_print_string(sdp->AslCompilerId, ACPI_NAME_SIZE);
1354986dffafSJohn Baldwin 	printf(", Creator Revision=0x%x\n", sdp->AslCompilerRevision);
1355e1e9a4bfSMitsuru IWASAKI }
1356e1e9a4bfSMitsuru IWASAKI 
1357945137d9SNate Lawson static void
1358986dffafSJohn Baldwin acpi_print_rsdt(ACPI_TABLE_HEADER *rsdp)
1359e1e9a4bfSMitsuru IWASAKI {
1360986dffafSJohn Baldwin 	ACPI_TABLE_RSDT *rsdt;
1361986dffafSJohn Baldwin 	ACPI_TABLE_XSDT *xsdt;
1362e1e9a4bfSMitsuru IWASAKI 	int	i, entries;
1363e1e9a4bfSMitsuru IWASAKI 
1364986dffafSJohn Baldwin 	rsdt = (ACPI_TABLE_RSDT *)rsdp;
1365986dffafSJohn Baldwin 	xsdt = (ACPI_TABLE_XSDT *)rsdp;
1366773b6454SNate Lawson 	printf(BEGIN_COMMENT);
1367773b6454SNate Lawson 	acpi_print_sdt(rsdp);
1368986dffafSJohn Baldwin 	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
1369e1e9a4bfSMitsuru IWASAKI 	printf("\tEntries={ ");
1370e1e9a4bfSMitsuru IWASAKI 	for (i = 0; i < entries; i++) {
1371e1e9a4bfSMitsuru IWASAKI 		if (i > 0)
1372e1e9a4bfSMitsuru IWASAKI 			printf(", ");
1373fe1d0c2dSJung-uk Kim 		if (addr_size == 4)
13747d369c6eSJung-uk Kim 			printf("0x%08x", le32toh(rsdt->TableOffsetEntry[i]));
1375fe1d0c2dSJung-uk Kim 		else
13767d369c6eSJung-uk Kim 			printf("0x%016jx",
13777d369c6eSJung-uk Kim 			    (uintmax_t)le64toh(xsdt->TableOffsetEntry[i]));
1378e1e9a4bfSMitsuru IWASAKI 	}
1379e1e9a4bfSMitsuru IWASAKI 	printf(" }\n");
1380c62f1cccSMitsuru IWASAKI 	printf(END_COMMENT);
1381e1e9a4bfSMitsuru IWASAKI }
1382e1e9a4bfSMitsuru IWASAKI 
13838e6a8737SNate Lawson static const char *acpi_pm_profiles[] = {
13848e6a8737SNate Lawson 	"Unspecified", "Desktop", "Mobile", "Workstation",
13858e6a8737SNate Lawson 	"Enterprise Server", "SOHO Server", "Appliance PC"
13868e6a8737SNate Lawson };
13878e6a8737SNate Lawson 
1388945137d9SNate Lawson static void
1389986dffafSJohn Baldwin acpi_print_fadt(ACPI_TABLE_HEADER *sdp)
1390e1e9a4bfSMitsuru IWASAKI {
1391986dffafSJohn Baldwin 	ACPI_TABLE_FADT *fadt;
13928e6a8737SNate Lawson 	const char *pm;
1393e1e9a4bfSMitsuru IWASAKI 
1394986dffafSJohn Baldwin 	fadt = (ACPI_TABLE_FADT *)sdp;
1395c62f1cccSMitsuru IWASAKI 	printf(BEGIN_COMMENT);
13962177d4e6SNate Lawson 	acpi_print_sdt(sdp);
1397986dffafSJohn Baldwin 	printf(" \tFACS=0x%x, DSDT=0x%x\n", fadt->Facs,
1398986dffafSJohn Baldwin 	       fadt->Dsdt);
1399986dffafSJohn Baldwin 	printf("\tINT_MODEL=%s\n", fadt->Model ? "APIC" : "PIC");
1400986dffafSJohn Baldwin 	if (fadt->PreferredProfile >= sizeof(acpi_pm_profiles) / sizeof(char *))
14018e6a8737SNate Lawson 		pm = "Reserved";
14028e6a8737SNate Lawson 	else
1403986dffafSJohn Baldwin 		pm = acpi_pm_profiles[fadt->PreferredProfile];
1404986dffafSJohn Baldwin 	printf("\tPreferred_PM_Profile=%s (%d)\n", pm, fadt->PreferredProfile);
1405986dffafSJohn Baldwin 	printf("\tSCI_INT=%d\n", fadt->SciInterrupt);
1406986dffafSJohn Baldwin 	printf("\tSMI_CMD=0x%x, ", fadt->SmiCommand);
1407986dffafSJohn Baldwin 	printf("ACPI_ENABLE=0x%x, ", fadt->AcpiEnable);
1408986dffafSJohn Baldwin 	printf("ACPI_DISABLE=0x%x, ", fadt->AcpiDisable);
1409986dffafSJohn Baldwin 	printf("S4BIOS_REQ=0x%x\n", fadt->S4BiosRequest);
1410986dffafSJohn Baldwin 	printf("\tPSTATE_CNT=0x%x\n", fadt->PstateControl);
1411e1e9a4bfSMitsuru IWASAKI 	printf("\tPM1a_EVT_BLK=0x%x-0x%x\n",
1412986dffafSJohn Baldwin 	       fadt->Pm1aEventBlock,
1413986dffafSJohn Baldwin 	       fadt->Pm1aEventBlock + fadt->Pm1EventLength - 1);
1414986dffafSJohn Baldwin 	if (fadt->Pm1bEventBlock != 0)
1415e1e9a4bfSMitsuru IWASAKI 		printf("\tPM1b_EVT_BLK=0x%x-0x%x\n",
1416986dffafSJohn Baldwin 		       fadt->Pm1bEventBlock,
1417986dffafSJohn Baldwin 		       fadt->Pm1bEventBlock + fadt->Pm1EventLength - 1);
1418e1e9a4bfSMitsuru IWASAKI 	printf("\tPM1a_CNT_BLK=0x%x-0x%x\n",
1419986dffafSJohn Baldwin 	       fadt->Pm1aControlBlock,
1420986dffafSJohn Baldwin 	       fadt->Pm1aControlBlock + fadt->Pm1ControlLength - 1);
1421986dffafSJohn Baldwin 	if (fadt->Pm1bControlBlock != 0)
1422e1e9a4bfSMitsuru IWASAKI 		printf("\tPM1b_CNT_BLK=0x%x-0x%x\n",
1423986dffafSJohn Baldwin 		       fadt->Pm1bControlBlock,
1424986dffafSJohn Baldwin 		       fadt->Pm1bControlBlock + fadt->Pm1ControlLength - 1);
1425986dffafSJohn Baldwin 	if (fadt->Pm2ControlBlock != 0)
1426e1e9a4bfSMitsuru IWASAKI 		printf("\tPM2_CNT_BLK=0x%x-0x%x\n",
1427986dffafSJohn Baldwin 		       fadt->Pm2ControlBlock,
1428986dffafSJohn Baldwin 		       fadt->Pm2ControlBlock + fadt->Pm2ControlLength - 1);
1429c08c4e81SNate Lawson 	printf("\tPM_TMR_BLK=0x%x-0x%x\n",
1430986dffafSJohn Baldwin 	       fadt->PmTimerBlock,
1431986dffafSJohn Baldwin 	       fadt->PmTimerBlock + fadt->PmTimerLength - 1);
1432986dffafSJohn Baldwin 	if (fadt->Gpe0Block != 0)
14338e6a8737SNate Lawson 		printf("\tGPE0_BLK=0x%x-0x%x\n",
1434986dffafSJohn Baldwin 		       fadt->Gpe0Block,
1435986dffafSJohn Baldwin 		       fadt->Gpe0Block + fadt->Gpe0BlockLength - 1);
1436986dffafSJohn Baldwin 	if (fadt->Gpe1Block != 0)
14378e6a8737SNate Lawson 		printf("\tGPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n",
1438986dffafSJohn Baldwin 		       fadt->Gpe1Block,
1439986dffafSJohn Baldwin 		       fadt->Gpe1Block + fadt->Gpe1BlockLength - 1,
1440986dffafSJohn Baldwin 		       fadt->Gpe1Base);
1441986dffafSJohn Baldwin 	if (fadt->CstControl != 0)
1442986dffafSJohn Baldwin 		printf("\tCST_CNT=0x%x\n", fadt->CstControl);
144351c1824fSNate Lawson 	printf("\tP_LVL2_LAT=%d us, P_LVL3_LAT=%d us\n",
1444986dffafSJohn Baldwin 	       fadt->C2Latency, fadt->C3Latency);
1445e1e9a4bfSMitsuru IWASAKI 	printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n",
1446986dffafSJohn Baldwin 	       fadt->FlushSize, fadt->FlushStride);
1447e1e9a4bfSMitsuru IWASAKI 	printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n",
1448986dffafSJohn Baldwin 	       fadt->DutyOffset, fadt->DutyWidth);
1449e1e9a4bfSMitsuru IWASAKI 	printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n",
1450986dffafSJohn Baldwin 	       fadt->DayAlarm, fadt->MonthAlarm, fadt->Century);
1451e1e9a4bfSMitsuru IWASAKI 
1452ec650989SNeel Natu #define PRINTFLAG(var, flag)	printflag((var), ACPI_FADT_## flag, #flag)
1453e1e9a4bfSMitsuru IWASAKI 
14548e6a8737SNate Lawson 	printf("\tIAPC_BOOT_ARCH=");
1455986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, LEGACY_DEVICES);
1456986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, 8042);
1457986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, NO_VGA);
1458986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, NO_MSI);
1459986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, NO_ASPM);
1460f6469ce1SAndrew Turner 	PRINTFLAG(fadt->BootFlags, NO_CMOS_RTC);
1461ec650989SNeel Natu 	PRINTFLAG_END();
14628e6a8737SNate Lawson 
14638e6a8737SNate Lawson 	printf("\tFlags=");
1464986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, WBINVD);
1465986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, WBINVD_FLUSH);
1466986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, C1_SUPPORTED);
1467986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, C2_MP_SUPPORTED);
1468986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, POWER_BUTTON);
1469986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, SLEEP_BUTTON);
1470986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, FIXED_RTC);
1471986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, S4_RTC_WAKE);
1472986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, 32BIT_TIMER);
1473986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, DOCKING_SUPPORTED);
1474986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, RESET_REGISTER);
1475986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, SEALED_CASE);
1476986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, HEADLESS);
1477986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, SLEEP_TYPE);
1478986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, PCI_EXPRESS_WAKE);
1479986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, PLATFORM_CLOCK);
1480986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, S4_RTC_VALID);
1481986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, REMOTE_POWER_ON);
1482986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, APIC_CLUSTER);
1483986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, APIC_PHYSICAL);
1484f6469ce1SAndrew Turner 	PRINTFLAG(fadt->Flags, HW_REDUCED);
1485f6469ce1SAndrew Turner 	PRINTFLAG(fadt->Flags, LOW_POWER_S0);
1486ec650989SNeel Natu 	PRINTFLAG_END();
1487e1e9a4bfSMitsuru IWASAKI 
1488e1e9a4bfSMitsuru IWASAKI #undef PRINTFLAG
1489e1e9a4bfSMitsuru IWASAKI 
1490986dffafSJohn Baldwin 	if (fadt->Flags & ACPI_FADT_RESET_REGISTER) {
14918e6a8737SNate Lawson 		printf("\tRESET_REG=");
1492986dffafSJohn Baldwin 		acpi_print_gas(&fadt->ResetRegister);
1493986dffafSJohn Baldwin 		printf(", RESET_VALUE=%#x\n", fadt->ResetValue);
14948e6a8737SNate Lawson 	}
1495c2962974SNate Lawson 	if (acpi_get_fadt_revision(fadt) > 1) {
14967d369c6eSJung-uk Kim 		printf("\tX_FACS=0x%016jx, ", (uintmax_t)fadt->XFacs);
14977d369c6eSJung-uk Kim 		printf("X_DSDT=0x%016jx\n", (uintmax_t)fadt->XDsdt);
1498c08c4e81SNate Lawson 		printf("\tX_PM1a_EVT_BLK=");
1499986dffafSJohn Baldwin 		acpi_print_gas(&fadt->XPm1aEventBlock);
1500986dffafSJohn Baldwin 		if (fadt->XPm1bEventBlock.Address != 0) {
1501c08c4e81SNate Lawson 			printf("\n\tX_PM1b_EVT_BLK=");
1502986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XPm1bEventBlock);
1503c08c4e81SNate Lawson 		}
1504c08c4e81SNate Lawson 		printf("\n\tX_PM1a_CNT_BLK=");
1505986dffafSJohn Baldwin 		acpi_print_gas(&fadt->XPm1aControlBlock);
1506986dffafSJohn Baldwin 		if (fadt->XPm1bControlBlock.Address != 0) {
1507c08c4e81SNate Lawson 			printf("\n\tX_PM1b_CNT_BLK=");
1508986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XPm1bControlBlock);
1509c08c4e81SNate Lawson 		}
1510986dffafSJohn Baldwin 		if (fadt->XPm2ControlBlock.Address != 0) {
1511773b6454SNate Lawson 			printf("\n\tX_PM2_CNT_BLK=");
1512986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XPm2ControlBlock);
1513c08c4e81SNate Lawson 		}
1514773b6454SNate Lawson 		printf("\n\tX_PM_TMR_BLK=");
1515986dffafSJohn Baldwin 		acpi_print_gas(&fadt->XPmTimerBlock);
1516986dffafSJohn Baldwin 		if (fadt->XGpe0Block.Address != 0) {
1517773b6454SNate Lawson 			printf("\n\tX_GPE0_BLK=");
1518986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XGpe0Block);
1519c08c4e81SNate Lawson 		}
1520986dffafSJohn Baldwin 		if (fadt->XGpe1Block.Address != 0) {
1521773b6454SNate Lawson 			printf("\n\tX_GPE1_BLK=");
1522986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XGpe1Block);
1523c08c4e81SNate Lawson 		}
1524773b6454SNate Lawson 		printf("\n");
1525773b6454SNate Lawson 	}
15268e6a8737SNate Lawson 
15278e6a8737SNate Lawson 	printf(END_COMMENT);
15288e6a8737SNate Lawson }
15298e6a8737SNate Lawson 
15308e6a8737SNate Lawson static void
1531986dffafSJohn Baldwin acpi_print_facs(ACPI_TABLE_FACS *facs)
15328e6a8737SNate Lawson {
15338e6a8737SNate Lawson 	printf(BEGIN_COMMENT);
1534986dffafSJohn Baldwin 	printf("  FACS:\tLength=%u, ", facs->Length);
1535986dffafSJohn Baldwin 	printf("HwSig=0x%08x, ", facs->HardwareSignature);
1536986dffafSJohn Baldwin 	printf("Firm_Wake_Vec=0x%08x\n", facs->FirmwareWakingVector);
15378e6a8737SNate Lawson 
1538773b6454SNate Lawson 	printf("\tGlobal_Lock=");
1539986dffafSJohn Baldwin 	if (facs->GlobalLock != 0) {
1540986dffafSJohn Baldwin 		if (facs->GlobalLock & ACPI_GLOCK_PENDING)
15418e6a8737SNate Lawson 			printf("PENDING,");
1542986dffafSJohn Baldwin 		if (facs->GlobalLock & ACPI_GLOCK_OWNED)
15438e6a8737SNate Lawson 			printf("OWNED");
15448e6a8737SNate Lawson 	}
1545773b6454SNate Lawson 	printf("\n");
15468e6a8737SNate Lawson 
1547773b6454SNate Lawson 	printf("\tFlags=");
1548986dffafSJohn Baldwin 	if (facs->Flags & ACPI_FACS_S4_BIOS_PRESENT)
15498e6a8737SNate Lawson 		printf("S4BIOS");
1550773b6454SNate Lawson 	printf("\n");
15518e6a8737SNate Lawson 
15527d369c6eSJung-uk Kim 	if (facs->XFirmwareWakingVector != 0)
15537d369c6eSJung-uk Kim 		printf("\tX_Firm_Wake_Vec=%016jx\n",
15547d369c6eSJung-uk Kim 		    (uintmax_t)facs->XFirmwareWakingVector);
1555986dffafSJohn Baldwin 	printf("\tVersion=%u\n", facs->Version);
15568e6a8737SNate Lawson 
1557c62f1cccSMitsuru IWASAKI 	printf(END_COMMENT);
1558e1e9a4bfSMitsuru IWASAKI }
1559e1e9a4bfSMitsuru IWASAKI 
1560945137d9SNate Lawson static void
1561986dffafSJohn Baldwin acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp)
1562e1e9a4bfSMitsuru IWASAKI {
1563773b6454SNate Lawson 	printf(BEGIN_COMMENT);
1564773b6454SNate Lawson 	acpi_print_sdt(dsdp);
1565773b6454SNate Lawson 	printf(END_COMMENT);
1566e1e9a4bfSMitsuru IWASAKI }
1567e1e9a4bfSMitsuru IWASAKI 
1568e1e9a4bfSMitsuru IWASAKI int
1569e1e9a4bfSMitsuru IWASAKI acpi_checksum(void *p, size_t length)
1570e1e9a4bfSMitsuru IWASAKI {
1571986dffafSJohn Baldwin 	uint8_t *bp;
1572986dffafSJohn Baldwin 	uint8_t sum;
1573e1e9a4bfSMitsuru IWASAKI 
1574e1e9a4bfSMitsuru IWASAKI 	bp = p;
1575e1e9a4bfSMitsuru IWASAKI 	sum = 0;
1576e1e9a4bfSMitsuru IWASAKI 	while (length--)
1577e1e9a4bfSMitsuru IWASAKI 		sum += *bp++;
1578e1e9a4bfSMitsuru IWASAKI 
1579e1e9a4bfSMitsuru IWASAKI 	return (sum);
1580e1e9a4bfSMitsuru IWASAKI }
1581e1e9a4bfSMitsuru IWASAKI 
1582986dffafSJohn Baldwin static ACPI_TABLE_HEADER *
1583e1e9a4bfSMitsuru IWASAKI acpi_map_sdt(vm_offset_t pa)
1584e1e9a4bfSMitsuru IWASAKI {
1585986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *sp;
1586e1e9a4bfSMitsuru IWASAKI 
1587986dffafSJohn Baldwin 	sp = acpi_map_physical(pa, sizeof(ACPI_TABLE_HEADER));
1588986dffafSJohn Baldwin 	sp = acpi_map_physical(pa, sp->Length);
1589e1e9a4bfSMitsuru IWASAKI 	return (sp);
1590e1e9a4bfSMitsuru IWASAKI }
1591e1e9a4bfSMitsuru IWASAKI 
1592945137d9SNate Lawson static void
1593986dffafSJohn Baldwin acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp)
1594e1e9a4bfSMitsuru IWASAKI {
1595c62f1cccSMitsuru IWASAKI 	printf(BEGIN_COMMENT);
1596a74172abSNate Lawson 	printf("  RSD PTR: OEM=");
1597986dffafSJohn Baldwin 	acpi_print_string(rp->OemId, ACPI_OEM_ID_SIZE);
1598986dffafSJohn Baldwin 	printf(", ACPI_Rev=%s (%d)\n", rp->Revision < 2 ? "1.0x" : "2.0x",
1599986dffafSJohn Baldwin 	       rp->Revision);
1600986dffafSJohn Baldwin 	if (rp->Revision < 2) {
1601986dffafSJohn Baldwin 		printf("\tRSDT=0x%08x, cksum=%u\n", rp->RsdtPhysicalAddress,
1602986dffafSJohn Baldwin 		    rp->Checksum);
1603a74172abSNate Lawson 	} else {
16047d369c6eSJung-uk Kim 		printf("\tXSDT=0x%016jx, length=%u, cksum=%u\n",
16057d369c6eSJung-uk Kim 		    (uintmax_t)rp->XsdtPhysicalAddress, rp->Length,
1606986dffafSJohn Baldwin 		    rp->ExtendedChecksum);
1607a74172abSNate Lawson 	}
1608c62f1cccSMitsuru IWASAKI 	printf(END_COMMENT);
1609e1e9a4bfSMitsuru IWASAKI }
1610e1e9a4bfSMitsuru IWASAKI 
1611945137d9SNate Lawson static void
1612986dffafSJohn Baldwin acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp)
1613e1e9a4bfSMitsuru IWASAKI {
1614986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *sdp;
1615986dffafSJohn Baldwin 	ACPI_TABLE_RSDT *rsdt;
1616986dffafSJohn Baldwin 	ACPI_TABLE_XSDT *xsdt;
1617a74172abSNate Lawson 	vm_offset_t addr;
1618a74172abSNate Lawson 	int entries, i;
1619e1e9a4bfSMitsuru IWASAKI 
1620e1e9a4bfSMitsuru IWASAKI 	acpi_print_rsdt(rsdp);
1621986dffafSJohn Baldwin 	rsdt = (ACPI_TABLE_RSDT *)rsdp;
1622986dffafSJohn Baldwin 	xsdt = (ACPI_TABLE_XSDT *)rsdp;
1623986dffafSJohn Baldwin 	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
1624e1e9a4bfSMitsuru IWASAKI 	for (i = 0; i < entries; i++) {
1625fe1d0c2dSJung-uk Kim 		if (addr_size == 4)
1626986dffafSJohn Baldwin 			addr = le32toh(rsdt->TableOffsetEntry[i]);
1627fe1d0c2dSJung-uk Kim 		else
1628986dffafSJohn Baldwin 			addr = le64toh(xsdt->TableOffsetEntry[i]);
1629fe1d0c2dSJung-uk Kim 		if (addr == 0)
1630fe1d0c2dSJung-uk Kim 			continue;
1631986dffafSJohn Baldwin 		sdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
1632986dffafSJohn Baldwin 		if (acpi_checksum(sdp, sdp->Length)) {
16335cf6d493SNate Lawson 			warnx("RSDT entry %d (sig %.4s) is corrupt", i,
1634986dffafSJohn Baldwin 			    sdp->Signature);
16355cf6d493SNate Lawson 			continue;
16365cf6d493SNate Lawson 		}
1637986dffafSJohn Baldwin 		if (!memcmp(sdp->Signature, ACPI_SIG_FADT, 4))
16382177d4e6SNate Lawson 			acpi_handle_fadt(sdp);
1639986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_MADT, 4))
1640986dffafSJohn Baldwin 			acpi_handle_madt(sdp);
1641986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_HPET, 4))
164279d7565cSPeter Wemm 			acpi_handle_hpet(sdp);
1643986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_ECDT, 4))
164455d7ff9eSNate Lawson 			acpi_handle_ecdt(sdp);
1645986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_MCFG, 4))
1646a47e681bSScott Long 			acpi_handle_mcfg(sdp);
164733866658SJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_SLIT, 4))
164833866658SJohn Baldwin 			acpi_handle_slit(sdp);
1649986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_SRAT, 4))
1650a0333ad1SJohn Baldwin 			acpi_handle_srat(sdp);
1651c031c93bSTakanori Watanabe 		else if (!memcmp(sdp->Signature, ACPI_SIG_TCPA, 4))
1652c031c93bSTakanori Watanabe 			acpi_handle_tcpa(sdp);
1653ec650989SNeel Natu 		else if (!memcmp(sdp->Signature, ACPI_SIG_DMAR, 4))
1654ec650989SNeel Natu 			acpi_handle_dmar(sdp);
1655340c0022SEd Maste 		else if (!memcmp(sdp->Signature, ACPI_SIG_NFIT, 4))
1656340c0022SEd Maste 			acpi_handle_nfit(sdp);
1657773b6454SNate Lawson 		else {
1658773b6454SNate Lawson 			printf(BEGIN_COMMENT);
1659773b6454SNate Lawson 			acpi_print_sdt(sdp);
1660773b6454SNate Lawson 			printf(END_COMMENT);
1661773b6454SNate Lawson 		}
1662e1e9a4bfSMitsuru IWASAKI 	}
1663e1e9a4bfSMitsuru IWASAKI }
1664c62f1cccSMitsuru IWASAKI 
1665986dffafSJohn Baldwin ACPI_TABLE_HEADER *
1666476daaecSDag-Erling Smørgrav sdt_load_devmem(void)
1667945137d9SNate Lawson {
1668986dffafSJohn Baldwin 	ACPI_TABLE_RSDP *rp;
1669986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *rsdp;
1670945137d9SNate Lawson 
1671945137d9SNate Lawson 	rp = acpi_find_rsd_ptr();
1672945137d9SNate Lawson 	if (!rp)
1673945137d9SNate Lawson 		errx(1, "Can't find ACPI information");
1674945137d9SNate Lawson 
1675945137d9SNate Lawson 	if (tflag)
1676945137d9SNate Lawson 		acpi_print_rsd_ptr(rp);
1677986dffafSJohn Baldwin 	if (rp->Revision < 2) {
1678986dffafSJohn Baldwin 		rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->RsdtPhysicalAddress);
1679986dffafSJohn Baldwin 		if (memcmp(rsdp->Signature, "RSDT", 4) != 0 ||
1680986dffafSJohn Baldwin 		    acpi_checksum(rsdp, rsdp->Length) != 0)
1681945137d9SNate Lawson 			errx(1, "RSDT is corrupted");
1682a74172abSNate Lawson 		addr_size = sizeof(uint32_t);
1683a74172abSNate Lawson 	} else {
1684986dffafSJohn Baldwin 		rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->XsdtPhysicalAddress);
1685986dffafSJohn Baldwin 		if (memcmp(rsdp->Signature, "XSDT", 4) != 0 ||
1686986dffafSJohn Baldwin 		    acpi_checksum(rsdp, rsdp->Length) != 0)
1687a74172abSNate Lawson 			errx(1, "XSDT is corrupted");
1688a74172abSNate Lawson 		addr_size = sizeof(uint64_t);
1689a74172abSNate Lawson 	}
1690945137d9SNate Lawson 	return (rsdp);
1691945137d9SNate Lawson }
1692c62f1cccSMitsuru IWASAKI 
169362c7bde1SNate Lawson /* Write the DSDT to a file, concatenating any SSDTs (if present). */
1694bfa3f012SMarcel Moolenaar static int
1695986dffafSJohn Baldwin write_dsdt(int fd, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdt)
1696bfa3f012SMarcel Moolenaar {
1697986dffafSJohn Baldwin 	ACPI_TABLE_HEADER sdt;
1698986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *ssdt;
1699bfa3f012SMarcel Moolenaar 	uint8_t sum;
1700bfa3f012SMarcel Moolenaar 
170162c7bde1SNate Lawson 	/* Create a new checksum to account for the DSDT and any SSDTs. */
1702bfa3f012SMarcel Moolenaar 	sdt = *dsdt;
1703bfa3f012SMarcel Moolenaar 	if (rsdt != NULL) {
1704986dffafSJohn Baldwin 		sdt.Checksum = 0;
1705986dffafSJohn Baldwin 		sum = acpi_checksum(dsdt + 1, dsdt->Length -
1706986dffafSJohn Baldwin 		    sizeof(ACPI_TABLE_HEADER));
1707986dffafSJohn Baldwin 		ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, NULL);
1708f7675a56SNate Lawson 		while (ssdt != NULL) {
1709986dffafSJohn Baldwin 			sdt.Length += ssdt->Length - sizeof(ACPI_TABLE_HEADER);
1710986dffafSJohn Baldwin 			sum += acpi_checksum(ssdt + 1,
1711986dffafSJohn Baldwin 			    ssdt->Length - sizeof(ACPI_TABLE_HEADER));
1712986dffafSJohn Baldwin 			ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, ssdt);
1713bfa3f012SMarcel Moolenaar 		}
1714986dffafSJohn Baldwin 		sum += acpi_checksum(&sdt, sizeof(ACPI_TABLE_HEADER));
1715986dffafSJohn Baldwin 		sdt.Checksum -= sum;
1716bfa3f012SMarcel Moolenaar 	}
171762c7bde1SNate Lawson 
171862c7bde1SNate Lawson 	/* Write out the DSDT header and body. */
1719986dffafSJohn Baldwin 	write(fd, &sdt, sizeof(ACPI_TABLE_HEADER));
1720986dffafSJohn Baldwin 	write(fd, dsdt + 1, dsdt->Length - sizeof(ACPI_TABLE_HEADER));
172162c7bde1SNate Lawson 
1722b64e1b67SNate Lawson 	/* Write out any SSDTs (if present.) */
1723f7675a56SNate Lawson 	if (rsdt != NULL) {
1724bfa3f012SMarcel Moolenaar 		ssdt = sdt_from_rsdt(rsdt, "SSDT", NULL);
1725bfa3f012SMarcel Moolenaar 		while (ssdt != NULL) {
1726986dffafSJohn Baldwin 			write(fd, ssdt + 1, ssdt->Length -
1727986dffafSJohn Baldwin 			    sizeof(ACPI_TABLE_HEADER));
1728bfa3f012SMarcel Moolenaar 			ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt);
1729bfa3f012SMarcel Moolenaar 		}
1730bfa3f012SMarcel Moolenaar 	}
1731bfa3f012SMarcel Moolenaar 	return (0);
1732bfa3f012SMarcel Moolenaar }
1733bfa3f012SMarcel Moolenaar 
1734c62f1cccSMitsuru IWASAKI void
1735986dffafSJohn Baldwin dsdt_save_file(char *outfile, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
1736c62f1cccSMitsuru IWASAKI {
1737945137d9SNate Lawson 	int	fd;
1738945137d9SNate Lawson 	mode_t	mode;
1739945137d9SNate Lawson 
1740945137d9SNate Lawson 	assert(outfile != NULL);
1741945137d9SNate Lawson 	mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
1742945137d9SNate Lawson 	fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, mode);
1743945137d9SNate Lawson 	if (fd == -1) {
1744945137d9SNate Lawson 		perror("dsdt_save_file");
1745945137d9SNate Lawson 		return;
1746945137d9SNate Lawson 	}
1747bfa3f012SMarcel Moolenaar 	write_dsdt(fd, rsdt, dsdp);
1748945137d9SNate Lawson 	close(fd);
1749c62f1cccSMitsuru IWASAKI }
1750c62f1cccSMitsuru IWASAKI 
1751945137d9SNate Lawson void
1752986dffafSJohn Baldwin aml_disassemble(ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
1753c62f1cccSMitsuru IWASAKI {
17547e2cc014SDon Lewis 	char buf[PATH_MAX], tmpstr[PATH_MAX], wrkdir[PATH_MAX];
17557e2cc014SDon Lewis 	const char *iname = "/acpdump.din";
17567e2cc014SDon Lewis 	const char *oname = "/acpdump.dsl";
175799065116SJung-uk Kim 	const char *tmpdir;
1758945137d9SNate Lawson 	FILE *fp;
175999065116SJung-uk Kim 	size_t len;
17607e2cc014SDon Lewis 	int fd, status;
17617e2cc014SDon Lewis 	pid_t pid;
1762945137d9SNate Lawson 
176399065116SJung-uk Kim 	tmpdir = getenv("TMPDIR");
176499065116SJung-uk Kim 	if (tmpdir == NULL)
176599065116SJung-uk Kim 		tmpdir = _PATH_TMP;
17667e2cc014SDon Lewis 	if (realpath(tmpdir, buf) == NULL) {
1767d6a6e590SJung-uk Kim 		perror("realpath tmp dir");
176899065116SJung-uk Kim 		return;
176999065116SJung-uk Kim 	}
17707e2cc014SDon Lewis 	len = sizeof(wrkdir) - strlen(iname);
17717e2cc014SDon Lewis 	if ((size_t)snprintf(wrkdir, len, "%s/acpidump.XXXXXX", buf) > len-1 ) {
17727e2cc014SDon Lewis 		fprintf(stderr, "$TMPDIR too long\n");
17737e2cc014SDon Lewis 		return;
17747e2cc014SDon Lewis 	}
17757e2cc014SDon Lewis 	if  (mkdtemp(wrkdir) == NULL) {
17767e2cc014SDon Lewis 		perror("mkdtemp tmp working dir");
17777e2cc014SDon Lewis 		return;
17787e2cc014SDon Lewis 	}
177930bebccaSMaxim Konovalov 	len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, iname);
178030bebccaSMaxim Konovalov 	assert(len <= sizeof(tmpstr) - 1);
17817e2cc014SDon Lewis 	fd = open(tmpstr, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
1782945137d9SNate Lawson 	if (fd < 0) {
1783945137d9SNate Lawson 		perror("iasl tmp file");
1784945137d9SNate Lawson 		return;
1785c62f1cccSMitsuru IWASAKI 	}
1786bfa3f012SMarcel Moolenaar 	write_dsdt(fd, rsdt, dsdp);
1787945137d9SNate Lawson 	close(fd);
1788945137d9SNate Lawson 
1789945137d9SNate Lawson 	/* Run iasl -d on the temp file */
17907e2cc014SDon Lewis 	if ((pid = fork()) == 0) {
1791945137d9SNate Lawson 		close(STDOUT_FILENO);
1792945137d9SNate Lawson 		if (vflag == 0)
1793945137d9SNate Lawson 			close(STDERR_FILENO);
179499065116SJung-uk Kim 		execl("/usr/sbin/iasl", "iasl", "-d", tmpstr, NULL);
1795945137d9SNate Lawson 		err(1, "exec");
1796c62f1cccSMitsuru IWASAKI 	}
17977e2cc014SDon Lewis 	if (pid > 0)
17987e2cc014SDon Lewis 		wait(&status);
17997e2cc014SDon Lewis 	if (unlink(tmpstr) < 0) {
18007e2cc014SDon Lewis 		perror("unlink");
18017e2cc014SDon Lewis 		goto out;
18027e2cc014SDon Lewis 	}
18037e2cc014SDon Lewis 	if (pid < 0) {
18047e2cc014SDon Lewis 		perror("fork");
18057e2cc014SDon Lewis 		goto out;
18067e2cc014SDon Lewis 	}
18077e2cc014SDon Lewis 	if (status != 0) {
18087e2cc014SDon Lewis 		fprintf(stderr, "iast exit status = %d\n", status);
18097e2cc014SDon Lewis 	}
1810945137d9SNate Lawson 
1811945137d9SNate Lawson 	/* Dump iasl's output to stdout */
181230bebccaSMaxim Konovalov 	len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, oname);
181330bebccaSMaxim Konovalov 	assert(len <= sizeof(tmpstr) - 1);
181499065116SJung-uk Kim 	fp = fopen(tmpstr, "r");
18157e2cc014SDon Lewis 	if (unlink(tmpstr) < 0) {
18167e2cc014SDon Lewis 		perror("unlink");
18177e2cc014SDon Lewis 		goto out;
18187e2cc014SDon Lewis 	}
1819945137d9SNate Lawson 	if (fp == NULL) {
1820945137d9SNate Lawson 		perror("iasl tmp file (read)");
18217e2cc014SDon Lewis 		goto out;
1822945137d9SNate Lawson 	}
1823945137d9SNate Lawson 	while ((len = fread(buf, 1, sizeof(buf), fp)) > 0)
1824945137d9SNate Lawson 		fwrite(buf, 1, len, stdout);
1825945137d9SNate Lawson 	fclose(fp);
18267e2cc014SDon Lewis 
18277e2cc014SDon Lewis     out:
18287e2cc014SDon Lewis 	if (rmdir(wrkdir) < 0)
18297e2cc014SDon Lewis 		perror("rmdir");
1830c62f1cccSMitsuru IWASAKI }
1831c62f1cccSMitsuru IWASAKI 
1832945137d9SNate Lawson void
1833986dffafSJohn Baldwin sdt_print_all(ACPI_TABLE_HEADER *rsdp)
1834c62f1cccSMitsuru IWASAKI {
1835945137d9SNate Lawson 	acpi_handle_rsdt(rsdp);
1836c62f1cccSMitsuru IWASAKI }
1837c62f1cccSMitsuru IWASAKI 
1838bfa3f012SMarcel Moolenaar /* Fetch a table matching the given signature via the RSDT. */
1839986dffafSJohn Baldwin ACPI_TABLE_HEADER *
1840986dffafSJohn Baldwin sdt_from_rsdt(ACPI_TABLE_HEADER *rsdp, const char *sig, ACPI_TABLE_HEADER *last)
1841c62f1cccSMitsuru IWASAKI {
1842986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *sdt;
1843986dffafSJohn Baldwin 	ACPI_TABLE_RSDT *rsdt;
1844986dffafSJohn Baldwin 	ACPI_TABLE_XSDT *xsdt;
1845a74172abSNate Lawson 	vm_offset_t addr;
1846a74172abSNate Lawson 	int entries, i;
1847945137d9SNate Lawson 
1848986dffafSJohn Baldwin 	rsdt = (ACPI_TABLE_RSDT *)rsdp;
1849986dffafSJohn Baldwin 	xsdt = (ACPI_TABLE_XSDT *)rsdp;
1850986dffafSJohn Baldwin 	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
1851945137d9SNate Lawson 	for (i = 0; i < entries; i++) {
1852fe1d0c2dSJung-uk Kim 		if (addr_size == 4)
1853986dffafSJohn Baldwin 			addr = le32toh(rsdt->TableOffsetEntry[i]);
1854fe1d0c2dSJung-uk Kim 		else
1855986dffafSJohn Baldwin 			addr = le64toh(xsdt->TableOffsetEntry[i]);
1856fe1d0c2dSJung-uk Kim 		if (addr == 0)
1857fe1d0c2dSJung-uk Kim 			continue;
1858986dffafSJohn Baldwin 		sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
1859bfa3f012SMarcel Moolenaar 		if (last != NULL) {
1860bfa3f012SMarcel Moolenaar 			if (sdt == last)
1861bfa3f012SMarcel Moolenaar 				last = NULL;
1862bfa3f012SMarcel Moolenaar 			continue;
1863bfa3f012SMarcel Moolenaar 		}
1864986dffafSJohn Baldwin 		if (memcmp(sdt->Signature, sig, strlen(sig)))
1865a74172abSNate Lawson 			continue;
1866986dffafSJohn Baldwin 		if (acpi_checksum(sdt, sdt->Length))
1867945137d9SNate Lawson 			errx(1, "RSDT entry %d is corrupt", i);
1868945137d9SNate Lawson 		return (sdt);
1869c62f1cccSMitsuru IWASAKI 	}
1870c62f1cccSMitsuru IWASAKI 
1871945137d9SNate Lawson 	return (NULL);
1872c62f1cccSMitsuru IWASAKI }
1873c62f1cccSMitsuru IWASAKI 
1874986dffafSJohn Baldwin ACPI_TABLE_HEADER *
1875986dffafSJohn Baldwin dsdt_from_fadt(ACPI_TABLE_FADT *fadt)
1876c62f1cccSMitsuru IWASAKI {
1877986dffafSJohn Baldwin 	ACPI_TABLE_HEADER	*sdt;
1878c62f1cccSMitsuru IWASAKI 
1879986dffafSJohn Baldwin 	/* Use the DSDT address if it is version 1, otherwise use XDSDT. */
1880c2962974SNate Lawson 	if (acpi_get_fadt_revision(fadt) == 1)
1881986dffafSJohn Baldwin 		sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt);
18822e71eb12SNate Lawson 	else
1883986dffafSJohn Baldwin 		sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt);
1884986dffafSJohn Baldwin 	if (acpi_checksum(sdt, sdt->Length))
1885945137d9SNate Lawson 		errx(1, "DSDT is corrupt\n");
1886945137d9SNate Lawson 	return (sdt);
1887c62f1cccSMitsuru IWASAKI }
1888