xref: /freebsd/usr.sbin/acpi/acpidump/acpi.c (revision 278f0de60d655b6b28d4c92affe3603a49228645)
1e1e9a4bfSMitsuru IWASAKI /*-
21de7b4b8SPedro F. Giffuni  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
31de7b4b8SPedro F. Giffuni  *
4e1e9a4bfSMitsuru IWASAKI  * Copyright (c) 1998 Doug Rabson
5e1e9a4bfSMitsuru IWASAKI  * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
6e1e9a4bfSMitsuru IWASAKI  * All rights reserved.
7e1e9a4bfSMitsuru IWASAKI  *
8e1e9a4bfSMitsuru IWASAKI  * Redistribution and use in source and binary forms, with or without
9e1e9a4bfSMitsuru IWASAKI  * modification, are permitted provided that the following conditions
10e1e9a4bfSMitsuru IWASAKI  * are met:
11e1e9a4bfSMitsuru IWASAKI  * 1. Redistributions of source code must retain the above copyright
12e1e9a4bfSMitsuru IWASAKI  *    notice, this list of conditions and the following disclaimer.
13e1e9a4bfSMitsuru IWASAKI  * 2. Redistributions in binary form must reproduce the above copyright
14e1e9a4bfSMitsuru IWASAKI  *    notice, this list of conditions and the following disclaimer in the
15e1e9a4bfSMitsuru IWASAKI  *    documentation and/or other materials provided with the distribution.
16e1e9a4bfSMitsuru IWASAKI  *
17e1e9a4bfSMitsuru IWASAKI  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18e1e9a4bfSMitsuru IWASAKI  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19e1e9a4bfSMitsuru IWASAKI  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20e1e9a4bfSMitsuru IWASAKI  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21e1e9a4bfSMitsuru IWASAKI  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22e1e9a4bfSMitsuru IWASAKI  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23e1e9a4bfSMitsuru IWASAKI  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24e1e9a4bfSMitsuru IWASAKI  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25e1e9a4bfSMitsuru IWASAKI  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26e1e9a4bfSMitsuru IWASAKI  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27e1e9a4bfSMitsuru IWASAKI  * SUCH DAMAGE.
28e1e9a4bfSMitsuru IWASAKI  *
29e1e9a4bfSMitsuru IWASAKI  *	$FreeBSD$
30e1e9a4bfSMitsuru IWASAKI  */
31e1e9a4bfSMitsuru IWASAKI 
32e1e9a4bfSMitsuru IWASAKI #include <sys/param.h>
33a74172abSNate Lawson #include <sys/endian.h>
34e1e9a4bfSMitsuru IWASAKI #include <sys/stat.h>
35945137d9SNate Lawson #include <sys/wait.h>
36e1e9a4bfSMitsuru IWASAKI #include <assert.h>
37e1e9a4bfSMitsuru IWASAKI #include <err.h>
38e1e9a4bfSMitsuru IWASAKI #include <fcntl.h>
3999065116SJung-uk Kim #include <paths.h>
40e1e9a4bfSMitsuru IWASAKI #include <stdio.h>
41a0333ad1SJohn Baldwin #include <stdint.h>
4299065116SJung-uk Kim #include <stdlib.h>
43945137d9SNate Lawson #include <string.h>
44e1e9a4bfSMitsuru IWASAKI #include <unistd.h>
45340c0022SEd Maste #include <uuid.h>
46e1e9a4bfSMitsuru IWASAKI 
47e1e9a4bfSMitsuru IWASAKI #include "acpidump.h"
48e1e9a4bfSMitsuru IWASAKI 
49c62f1cccSMitsuru IWASAKI #define BEGIN_COMMENT	"/*\n"
50c62f1cccSMitsuru IWASAKI #define END_COMMENT	" */\n"
51c62f1cccSMitsuru IWASAKI 
52945137d9SNate Lawson static void	acpi_print_string(char *s, size_t length);
53986dffafSJohn Baldwin static void	acpi_print_gas(ACPI_GENERIC_ADDRESS *gas);
54986dffafSJohn Baldwin static int	acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt);
55986dffafSJohn Baldwin static void	acpi_handle_fadt(ACPI_TABLE_HEADER *fadt);
56945137d9SNate Lawson static void	acpi_print_cpu(u_char cpu_id);
57986dffafSJohn Baldwin static void	acpi_print_cpu_uid(uint32_t uid, char *uid_string);
58986dffafSJohn Baldwin static void	acpi_print_local_apic(uint32_t apic_id, uint32_t flags);
59986dffafSJohn Baldwin static void	acpi_print_io_apic(uint32_t apic_id, uint32_t int_base,
60986dffafSJohn Baldwin 		    uint64_t apic_addr);
61986dffafSJohn Baldwin static void	acpi_print_mps_flags(uint16_t flags);
62986dffafSJohn Baldwin static void	acpi_print_intr(uint32_t intr, uint16_t mps_flags);
63986dffafSJohn Baldwin static void	acpi_print_local_nmi(u_int lint, uint16_t mps_flags);
64986dffafSJohn Baldwin static void	acpi_print_madt(ACPI_SUBTABLE_HEADER *mp);
65986dffafSJohn Baldwin static void	acpi_handle_madt(ACPI_TABLE_HEADER *sdp);
66986dffafSJohn Baldwin static void	acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp);
67986dffafSJohn Baldwin static void	acpi_handle_hpet(ACPI_TABLE_HEADER *sdp);
68986dffafSJohn Baldwin static void	acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp);
6933866658SJohn Baldwin static void	acpi_handle_slit(ACPI_TABLE_HEADER *sdp);
70ed26c389SScott Long static void	acpi_handle_wddt(ACPI_TABLE_HEADER *sdp);
715857fba5SBen Widawsky static void	acpi_handle_lpit(ACPI_TABLE_HEADER *sdp);
72a0333ad1SJohn Baldwin static void	acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain,
73a0333ad1SJohn Baldwin 		    uint32_t flags);
74986dffafSJohn Baldwin static void	acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp);
75986dffafSJohn Baldwin static void	acpi_print_srat(ACPI_SUBTABLE_HEADER *srat);
76986dffafSJohn Baldwin static void	acpi_handle_srat(ACPI_TABLE_HEADER *sdp);
77c031c93bSTakanori Watanabe static void	acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp);
78340c0022SEd Maste static void	acpi_print_nfit(ACPI_NFIT_HEADER *nfit);
79340c0022SEd Maste static void	acpi_handle_nfit(ACPI_TABLE_HEADER *sdp);
80986dffafSJohn Baldwin static void	acpi_print_sdt(ACPI_TABLE_HEADER *sdp);
81986dffafSJohn Baldwin static void	acpi_print_fadt(ACPI_TABLE_HEADER *sdp);
82986dffafSJohn Baldwin static void	acpi_print_facs(ACPI_TABLE_FACS *facs);
83986dffafSJohn Baldwin static void	acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp);
84986dffafSJohn Baldwin static ACPI_TABLE_HEADER *acpi_map_sdt(vm_offset_t pa);
85986dffafSJohn Baldwin static void	acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp);
86986dffafSJohn Baldwin static void	acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp);
87986dffafSJohn Baldwin static void	acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
88986dffafSJohn Baldwin 		    void (*action)(ACPI_SUBTABLE_HEADER *));
89340c0022SEd Maste static void	acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first,
90340c0022SEd Maste 		    void (*action)(ACPI_NFIT_HEADER *));
91c62f1cccSMitsuru IWASAKI 
92773b6454SNate Lawson /* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up. */
93a74172abSNate Lawson static int addr_size;
94a74172abSNate Lawson 
95c031c93bSTakanori Watanabe /* Strings used in the TCPA table */
96c031c93bSTakanori Watanabe static const char *tcpa_event_type_strings[] = {
97c031c93bSTakanori Watanabe 	"PREBOOT Certificate",
98c031c93bSTakanori Watanabe 	"POST Code",
99c031c93bSTakanori Watanabe 	"Unused",
100c031c93bSTakanori Watanabe 	"No Action",
101c031c93bSTakanori Watanabe 	"Separator",
102c031c93bSTakanori Watanabe 	"Action",
103c031c93bSTakanori Watanabe 	"Event Tag",
104c031c93bSTakanori Watanabe 	"S-CRTM Contents",
105c031c93bSTakanori Watanabe 	"S-CRTM Version",
106c031c93bSTakanori Watanabe 	"CPU Microcode",
107c031c93bSTakanori Watanabe 	"Platform Config Flags",
108c031c93bSTakanori Watanabe 	"Table of Devices",
109c031c93bSTakanori Watanabe 	"Compact Hash",
110c031c93bSTakanori Watanabe 	"IPL",
111c031c93bSTakanori Watanabe 	"IPL Partition Data",
112c031c93bSTakanori Watanabe 	"Non-Host Code",
113c031c93bSTakanori Watanabe 	"Non-Host Config",
114c031c93bSTakanori Watanabe 	"Non-Host Info"
115c031c93bSTakanori Watanabe };
116c031c93bSTakanori Watanabe 
117c031c93bSTakanori Watanabe static const char *TCPA_pcclient_strings[] = {
118c031c93bSTakanori Watanabe 	"<undefined>",
119c031c93bSTakanori Watanabe 	"SMBIOS",
120c031c93bSTakanori Watanabe 	"BIS Certificate",
121c031c93bSTakanori Watanabe 	"POST BIOS ROM Strings",
122c031c93bSTakanori Watanabe 	"ESCD",
123c031c93bSTakanori Watanabe 	"CMOS",
124c031c93bSTakanori Watanabe 	"NVRAM",
125c031c93bSTakanori Watanabe 	"Option ROM Execute",
126c031c93bSTakanori Watanabe 	"Option ROM Configurateion",
127c031c93bSTakanori Watanabe 	"<undefined>",
128c031c93bSTakanori Watanabe 	"Option ROM Microcode Update ",
129c031c93bSTakanori Watanabe 	"S-CRTM Version String",
130c031c93bSTakanori Watanabe 	"S-CRTM Contents",
131c031c93bSTakanori Watanabe 	"POST Contents",
132c031c93bSTakanori Watanabe 	"Table of Devices",
133c031c93bSTakanori Watanabe };
134c031c93bSTakanori Watanabe 
135ec650989SNeel Natu #define	PRINTFLAG_END()		printflag_end()
136ec650989SNeel Natu 
137ec650989SNeel Natu static char pf_sep = '{';
138ec650989SNeel Natu 
139ec650989SNeel Natu static void
140ec650989SNeel Natu printflag_end(void)
141ec650989SNeel Natu {
142ec650989SNeel Natu 
143ec650989SNeel Natu 	if (pf_sep != '{') {
144ec650989SNeel Natu 		printf("}");
145ec650989SNeel Natu 		pf_sep = '{';
146ec650989SNeel Natu 	}
147ec650989SNeel Natu 	printf("\n");
148ec650989SNeel Natu }
149ec650989SNeel Natu 
150ec650989SNeel Natu static void
151ec650989SNeel Natu printflag(uint64_t var, uint64_t mask, const char *name)
152ec650989SNeel Natu {
153ec650989SNeel Natu 
154ec650989SNeel Natu 	if (var & mask) {
155ec650989SNeel Natu 		printf("%c%s", pf_sep, name);
156ec650989SNeel Natu 		pf_sep = ',';
157ec650989SNeel Natu 	}
158ec650989SNeel Natu }
159ec650989SNeel Natu 
160e1e9a4bfSMitsuru IWASAKI static void
161e1e9a4bfSMitsuru IWASAKI acpi_print_string(char *s, size_t length)
162e1e9a4bfSMitsuru IWASAKI {
163e1e9a4bfSMitsuru IWASAKI 	int	c;
164e1e9a4bfSMitsuru IWASAKI 
165e1e9a4bfSMitsuru IWASAKI 	/* Trim trailing spaces and NULLs */
166e1e9a4bfSMitsuru IWASAKI 	while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0'))
167e1e9a4bfSMitsuru IWASAKI 		length--;
168e1e9a4bfSMitsuru IWASAKI 
169e1e9a4bfSMitsuru IWASAKI 	while (length--) {
170e1e9a4bfSMitsuru IWASAKI 		c = *s++;
171e1e9a4bfSMitsuru IWASAKI 		putchar(c);
172e1e9a4bfSMitsuru IWASAKI 	}
173e1e9a4bfSMitsuru IWASAKI }
174e1e9a4bfSMitsuru IWASAKI 
175e1e9a4bfSMitsuru IWASAKI static void
176986dffafSJohn Baldwin acpi_print_gas(ACPI_GENERIC_ADDRESS *gas)
1778e6a8737SNate Lawson {
178986dffafSJohn Baldwin 	switch(gas->SpaceId) {
1798e6a8737SNate Lawson 	case ACPI_GAS_MEMORY:
1807d369c6eSJung-uk Kim 		if (gas->BitWidth <= 32)
1817d369c6eSJung-uk Kim 			printf("0x%08x:%u[%u] (Memory)",
1827d369c6eSJung-uk Kim 			    (u_int)gas->Address, gas->BitOffset,
1837d369c6eSJung-uk Kim 			    gas->BitWidth);
1847d369c6eSJung-uk Kim 		else
1857d369c6eSJung-uk Kim 			printf("0x%016jx:%u[%u] (Memory)",
1867d369c6eSJung-uk Kim 			    (uintmax_t)gas->Address, gas->BitOffset,
1877d369c6eSJung-uk Kim 			    gas->BitWidth);
1888e6a8737SNate Lawson 		break;
1898e6a8737SNate Lawson 	case ACPI_GAS_IO:
1907d369c6eSJung-uk Kim 		printf("0x%02x:%u[%u] (IO)", (u_int)gas->Address,
191986dffafSJohn Baldwin 		    gas->BitOffset, gas->BitWidth);
1928e6a8737SNate Lawson 		break;
1938e6a8737SNate Lawson 	case ACPI_GAS_PCI:
194986dffafSJohn Baldwin 		printf("%x:%x+0x%x (PCI)", (uint16_t)(gas->Address >> 32),
195986dffafSJohn Baldwin 		       (uint16_t)((gas->Address >> 16) & 0xffff),
196986dffafSJohn Baldwin 		       (uint16_t)gas->Address);
1978e6a8737SNate Lawson 		break;
1988e6a8737SNate Lawson 	/* XXX How to handle these below? */
1998e6a8737SNate Lawson 	case ACPI_GAS_EMBEDDED:
200986dffafSJohn Baldwin 		printf("0x%x:%u[%u] (EC)", (uint16_t)gas->Address,
201986dffafSJohn Baldwin 		       gas->BitOffset, gas->BitWidth);
2028e6a8737SNate Lawson 		break;
2038e6a8737SNate Lawson 	case ACPI_GAS_SMBUS:
204986dffafSJohn Baldwin 		printf("0x%x:%u[%u] (SMBus)", (uint16_t)gas->Address,
205986dffafSJohn Baldwin 		       gas->BitOffset, gas->BitWidth);
2068e6a8737SNate Lawson 		break;
207986dffafSJohn Baldwin 	case ACPI_GAS_CMOS:
208986dffafSJohn Baldwin 	case ACPI_GAS_PCIBAR:
209986dffafSJohn Baldwin 	case ACPI_GAS_DATATABLE:
2108e6a8737SNate Lawson 	case ACPI_GAS_FIXED:
2118e6a8737SNate Lawson 	default:
2127d369c6eSJung-uk Kim 		printf("0x%016jx (?)", (uintmax_t)gas->Address);
2138e6a8737SNate Lawson 		break;
2148e6a8737SNate Lawson 	}
2158e6a8737SNate Lawson }
2168e6a8737SNate Lawson 
217c2962974SNate Lawson /* The FADT revision indicates whether we use the DSDT or X_DSDT addresses. */
218c2962974SNate Lawson static int
219986dffafSJohn Baldwin acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt)
220e1e9a4bfSMitsuru IWASAKI {
221c2962974SNate Lawson 	int fadt_revision;
222e1e9a4bfSMitsuru IWASAKI 
223c83f0f99SNate Lawson 	/* Set the FADT revision separately from the RSDP version. */
224c83f0f99SNate Lawson 	if (addr_size == 8) {
225c83f0f99SNate Lawson 		fadt_revision = 2;
2268e6a8737SNate Lawson 
227773b6454SNate Lawson 		/*
228c83f0f99SNate Lawson 		 * A few systems (e.g., IBM T23) have an RSDP that claims
229c83f0f99SNate Lawson 		 * revision 2 but the 64 bit addresses are invalid.  If
230c83f0f99SNate Lawson 		 * revision 2 and the 32 bit address is non-zero but the
231c83f0f99SNate Lawson 		 * 32 and 64 bit versions don't match, prefer the 32 bit
232c83f0f99SNate Lawson 		 * version for all subsequent tables.
233773b6454SNate Lawson 		 */
234986dffafSJohn Baldwin 		if (fadt->Facs != 0 &&
235986dffafSJohn Baldwin 		    (fadt->XFacs & 0xffffffff) != fadt->Facs)
236c83f0f99SNate Lawson 			fadt_revision = 1;
237c2962974SNate Lawson 	} else
238c83f0f99SNate Lawson 		fadt_revision = 1;
239c2962974SNate Lawson 	return (fadt_revision);
240c83f0f99SNate Lawson }
241c2962974SNate Lawson 
242c2962974SNate Lawson static void
243986dffafSJohn Baldwin acpi_handle_fadt(ACPI_TABLE_HEADER *sdp)
244c2962974SNate Lawson {
245986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *dsdp;
246986dffafSJohn Baldwin 	ACPI_TABLE_FACS	*facs;
247986dffafSJohn Baldwin 	ACPI_TABLE_FADT *fadt;
248c2962974SNate Lawson 	int		fadt_revision;
249c2962974SNate Lawson 
250986dffafSJohn Baldwin 	fadt = (ACPI_TABLE_FADT *)sdp;
2512177d4e6SNate Lawson 	acpi_print_fadt(sdp);
252c83f0f99SNate Lawson 
253c2962974SNate Lawson 	fadt_revision = acpi_get_fadt_revision(fadt);
254c83f0f99SNate Lawson 	if (fadt_revision == 1)
255986dffafSJohn Baldwin 		facs = (ACPI_TABLE_FACS *)acpi_map_sdt(fadt->Facs);
256773b6454SNate Lawson 	else
257986dffafSJohn Baldwin 		facs = (ACPI_TABLE_FACS *)acpi_map_sdt(fadt->XFacs);
258986dffafSJohn Baldwin 	if (memcmp(facs->Signature, ACPI_SIG_FACS, 4) != 0 || facs->Length < 64)
2598e6a8737SNate Lawson 		errx(1, "FACS is corrupt");
2608e6a8737SNate Lawson 	acpi_print_facs(facs);
2618e6a8737SNate Lawson 
262c83f0f99SNate Lawson 	if (fadt_revision == 1)
263986dffafSJohn Baldwin 		dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt);
264773b6454SNate Lawson 	else
265986dffafSJohn Baldwin 		dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt);
266986dffafSJohn Baldwin 	if (acpi_checksum(dsdp, dsdp->Length))
267945137d9SNate Lawson 		errx(1, "DSDT is corrupt");
268945137d9SNate Lawson 	acpi_print_dsdt(dsdp);
269c62f1cccSMitsuru IWASAKI }
270c62f1cccSMitsuru IWASAKI 
271c62f1cccSMitsuru IWASAKI static void
272986dffafSJohn Baldwin acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
273986dffafSJohn Baldwin     void (*action)(ACPI_SUBTABLE_HEADER *))
274986dffafSJohn Baldwin {
275986dffafSJohn Baldwin 	ACPI_SUBTABLE_HEADER *subtable;
276986dffafSJohn Baldwin 	char *end;
277986dffafSJohn Baldwin 
278986dffafSJohn Baldwin 	subtable = first;
279986dffafSJohn Baldwin 	end = (char *)table + table->Length;
280986dffafSJohn Baldwin 	while ((char *)subtable < end) {
281986dffafSJohn Baldwin 		printf("\n");
282f5d0a8f7SEd Maste 		if (subtable->Length < sizeof(ACPI_SUBTABLE_HEADER)) {
283f5d0a8f7SEd Maste 			warnx("invalid subtable length %u", subtable->Length);
284f5d0a8f7SEd Maste 			return;
285f5d0a8f7SEd Maste 		}
286986dffafSJohn Baldwin 		action(subtable);
287986dffafSJohn Baldwin 		subtable = (ACPI_SUBTABLE_HEADER *)((char *)subtable +
288986dffafSJohn Baldwin 		    subtable->Length);
289986dffafSJohn Baldwin 	}
290986dffafSJohn Baldwin }
291986dffafSJohn Baldwin 
292986dffafSJohn Baldwin static void
293340c0022SEd Maste acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first,
294340c0022SEd Maste     void (*action)(ACPI_NFIT_HEADER *))
295340c0022SEd Maste {
296340c0022SEd Maste 	ACPI_NFIT_HEADER *subtable;
297340c0022SEd Maste 	char *end;
298340c0022SEd Maste 
299340c0022SEd Maste 	subtable = first;
300340c0022SEd Maste 	end = (char *)table + table->Length;
301340c0022SEd Maste 	while ((char *)subtable < end) {
302340c0022SEd Maste 		printf("\n");
303340c0022SEd Maste 		if (subtable->Length < sizeof(ACPI_NFIT_HEADER)) {
304340c0022SEd Maste 			warnx("invalid subtable length %u", subtable->Length);
305340c0022SEd Maste 			return;
306340c0022SEd Maste 		}
307340c0022SEd Maste 		action(subtable);
308340c0022SEd Maste 		subtable = (ACPI_NFIT_HEADER *)((char *)subtable +
309340c0022SEd Maste 		    subtable->Length);
310340c0022SEd Maste 	}
311340c0022SEd Maste }
312340c0022SEd Maste 
313340c0022SEd Maste static void
3140a473124SJohn Baldwin acpi_print_cpu(u_char cpu_id)
3150a473124SJohn Baldwin {
3160a473124SJohn Baldwin 
3170a473124SJohn Baldwin 	printf("\tACPI CPU=");
3180a473124SJohn Baldwin 	if (cpu_id == 0xff)
3190a473124SJohn Baldwin 		printf("ALL\n");
3200a473124SJohn Baldwin 	else
3210a473124SJohn Baldwin 		printf("%d\n", (u_int)cpu_id);
3220a473124SJohn Baldwin }
3230a473124SJohn Baldwin 
3240a473124SJohn Baldwin static void
325986dffafSJohn Baldwin acpi_print_cpu_uid(uint32_t uid, char *uid_string)
3260a473124SJohn Baldwin {
327986dffafSJohn Baldwin 
328986dffafSJohn Baldwin 	printf("\tUID=%d", uid);
329986dffafSJohn Baldwin 	if (uid_string != NULL)
330986dffafSJohn Baldwin 		printf(" (%s)", uid_string);
331986dffafSJohn Baldwin 	printf("\n");
332986dffafSJohn Baldwin }
333986dffafSJohn Baldwin 
334986dffafSJohn Baldwin static void
335986dffafSJohn Baldwin acpi_print_local_apic(uint32_t apic_id, uint32_t flags)
336986dffafSJohn Baldwin {
337986dffafSJohn Baldwin 
3380a473124SJohn Baldwin 	printf("\tFlags={");
339986dffafSJohn Baldwin 	if (flags & ACPI_MADT_ENABLED)
3400a473124SJohn Baldwin 		printf("ENABLED");
3410a473124SJohn Baldwin 	else
3420a473124SJohn Baldwin 		printf("DISABLED");
3430a473124SJohn Baldwin 	printf("}\n");
344986dffafSJohn Baldwin 	printf("\tAPIC ID=%d\n", apic_id);
3450a473124SJohn Baldwin }
3460a473124SJohn Baldwin 
3470a473124SJohn Baldwin static void
348986dffafSJohn Baldwin acpi_print_io_apic(uint32_t apic_id, uint32_t int_base, uint64_t apic_addr)
3490a473124SJohn Baldwin {
350986dffafSJohn Baldwin 
351986dffafSJohn Baldwin 	printf("\tAPIC ID=%d\n", apic_id);
3520a473124SJohn Baldwin 	printf("\tINT BASE=%d\n", int_base);
353986dffafSJohn Baldwin 	printf("\tADDR=0x%016jx\n", (uintmax_t)apic_addr);
3540a473124SJohn Baldwin }
3550a473124SJohn Baldwin 
3560a473124SJohn Baldwin static void
357986dffafSJohn Baldwin acpi_print_mps_flags(uint16_t flags)
3580a473124SJohn Baldwin {
3590a473124SJohn Baldwin 
3600a473124SJohn Baldwin 	printf("\tFlags={Polarity=");
361986dffafSJohn Baldwin 	switch (flags & ACPI_MADT_POLARITY_MASK) {
362986dffafSJohn Baldwin 	case ACPI_MADT_POLARITY_CONFORMS:
3630a473124SJohn Baldwin 		printf("conforming");
3640a473124SJohn Baldwin 		break;
365986dffafSJohn Baldwin 	case ACPI_MADT_POLARITY_ACTIVE_HIGH:
3660a473124SJohn Baldwin 		printf("active-hi");
3670a473124SJohn Baldwin 		break;
368986dffafSJohn Baldwin 	case ACPI_MADT_POLARITY_ACTIVE_LOW:
3690a473124SJohn Baldwin 		printf("active-lo");
3700a473124SJohn Baldwin 		break;
3710a473124SJohn Baldwin 	default:
372986dffafSJohn Baldwin 		printf("0x%x", flags & ACPI_MADT_POLARITY_MASK);
3730a473124SJohn Baldwin 		break;
3740a473124SJohn Baldwin 	}
3750a473124SJohn Baldwin 	printf(", Trigger=");
376986dffafSJohn Baldwin 	switch (flags & ACPI_MADT_TRIGGER_MASK) {
377986dffafSJohn Baldwin 	case ACPI_MADT_TRIGGER_CONFORMS:
3780a473124SJohn Baldwin 		printf("conforming");
3790a473124SJohn Baldwin 		break;
380986dffafSJohn Baldwin 	case ACPI_MADT_TRIGGER_EDGE:
3810a473124SJohn Baldwin 		printf("edge");
3820a473124SJohn Baldwin 		break;
383986dffafSJohn Baldwin 	case ACPI_MADT_TRIGGER_LEVEL:
3840a473124SJohn Baldwin 		printf("level");
3850a473124SJohn Baldwin 		break;
3860a473124SJohn Baldwin 	default:
387986dffafSJohn Baldwin 		printf("0x%x", (flags & ACPI_MADT_TRIGGER_MASK) >> 2);
3880a473124SJohn Baldwin 	}
3890a473124SJohn Baldwin 	printf("}\n");
3900a473124SJohn Baldwin }
3910a473124SJohn Baldwin 
3920a473124SJohn Baldwin static void
3932b2b1f42SAndrew Turner acpi_print_gicc_flags(uint32_t flags)
3942b2b1f42SAndrew Turner {
3952b2b1f42SAndrew Turner 
3962b2b1f42SAndrew Turner 	printf("\tFlags={Performance intr=");
3972b2b1f42SAndrew Turner 	if (flags & ACPI_MADT_PERFORMANCE_IRQ_MODE)
3982b2b1f42SAndrew Turner 		printf("edge");
3992b2b1f42SAndrew Turner 	else
4002b2b1f42SAndrew Turner 		printf("level");
4012b2b1f42SAndrew Turner 	printf(", VGIC intr=");
4022b2b1f42SAndrew Turner 	if (flags & ACPI_MADT_VGIC_IRQ_MODE)
4032b2b1f42SAndrew Turner 		printf("edge");
4042b2b1f42SAndrew Turner 	else
4052b2b1f42SAndrew Turner 		printf("level");
4062b2b1f42SAndrew Turner 	printf("}\n");
4072b2b1f42SAndrew Turner }
4082b2b1f42SAndrew Turner 
4092b2b1f42SAndrew Turner static void
410986dffafSJohn Baldwin acpi_print_intr(uint32_t intr, uint16_t mps_flags)
4110a473124SJohn Baldwin {
4120a473124SJohn Baldwin 
413986dffafSJohn Baldwin 	printf("\tINTR=%d\n", intr);
414986dffafSJohn Baldwin 	acpi_print_mps_flags(mps_flags);
415986dffafSJohn Baldwin }
416986dffafSJohn Baldwin 
417986dffafSJohn Baldwin static void
418986dffafSJohn Baldwin acpi_print_local_nmi(u_int lint, uint16_t mps_flags)
419986dffafSJohn Baldwin {
420986dffafSJohn Baldwin 
421986dffafSJohn Baldwin 	printf("\tLINT Pin=%d\n", lint);
4220a473124SJohn Baldwin 	acpi_print_mps_flags(mps_flags);
4230a473124SJohn Baldwin }
4240a473124SJohn Baldwin 
42527941afaSEd Maste static const char *apic_types[] = {
42627941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_APIC] = "Local APIC",
42727941afaSEd Maste     [ACPI_MADT_TYPE_IO_APIC] = "IO APIC",
42827941afaSEd Maste     [ACPI_MADT_TYPE_INTERRUPT_OVERRIDE] = "INT Override",
42927941afaSEd Maste     [ACPI_MADT_TYPE_NMI_SOURCE] = "NMI",
43027941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_APIC_NMI] = "Local APIC NMI",
43127941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE] = "Local APIC Override",
43227941afaSEd Maste     [ACPI_MADT_TYPE_IO_SAPIC] = "IO SAPIC",
43327941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_SAPIC] = "Local SAPIC",
43427941afaSEd Maste     [ACPI_MADT_TYPE_INTERRUPT_SOURCE] = "Platform Interrupt",
43527941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_X2APIC] = "Local X2APIC",
43627941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_X2APIC_NMI] = "Local X2APIC NMI",
43727941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_INTERRUPT] = "GIC CPU Interface Structure",
43827941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR] = "GIC Distributor Structure",
43927941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_MSI_FRAME] = "GICv2m MSI Frame",
44027941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR] = "GIC Redistributor Structure",
44127941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_TRANSLATOR] = "GIC ITS Structure"
44227941afaSEd Maste };
44327941afaSEd Maste 
444bf70beceSEd Schouten static const char *platform_int_types[] = { "0 (unknown)", "PMI", "INIT",
4450a473124SJohn Baldwin 					    "Corrected Platform Error" };
4460a473124SJohn Baldwin 
4470a473124SJohn Baldwin static void
448986dffafSJohn Baldwin acpi_print_madt(ACPI_SUBTABLE_HEADER *mp)
4490a473124SJohn Baldwin {
450986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_APIC *lapic;
451986dffafSJohn Baldwin 	ACPI_MADT_IO_APIC *ioapic;
452986dffafSJohn Baldwin 	ACPI_MADT_INTERRUPT_OVERRIDE *over;
453986dffafSJohn Baldwin 	ACPI_MADT_NMI_SOURCE *nmi;
454986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_APIC_NMI *lapic_nmi;
455986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic_over;
456986dffafSJohn Baldwin 	ACPI_MADT_IO_SAPIC *iosapic;
457986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_SAPIC *lsapic;
458986dffafSJohn Baldwin 	ACPI_MADT_INTERRUPT_SOURCE *isrc;
459986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_X2APIC *x2apic;
460986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_X2APIC_NMI *x2apic_nmi;
4612b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_INTERRUPT *gicc;
4622b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_DISTRIBUTOR *gicd;
4632b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_REDISTRIBUTOR *gicr;
4642b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_TRANSLATOR *gict;
4650a473124SJohn Baldwin 
466c86932b6SMarcelo Araujo 	if (mp->Type < nitems(apic_types))
467986dffafSJohn Baldwin 		printf("\tType=%s\n", apic_types[mp->Type]);
468a0333ad1SJohn Baldwin 	else
469986dffafSJohn Baldwin 		printf("\tType=%d (unknown)\n", mp->Type);
470986dffafSJohn Baldwin 	switch (mp->Type) {
471986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_APIC:
472986dffafSJohn Baldwin 		lapic = (ACPI_MADT_LOCAL_APIC *)mp;
473986dffafSJohn Baldwin 		acpi_print_cpu(lapic->ProcessorId);
474986dffafSJohn Baldwin 		acpi_print_local_apic(lapic->Id, lapic->LapicFlags);
4750a473124SJohn Baldwin 		break;
476986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_IO_APIC:
477986dffafSJohn Baldwin 		ioapic = (ACPI_MADT_IO_APIC *)mp;
478986dffafSJohn Baldwin 		acpi_print_io_apic(ioapic->Id, ioapic->GlobalIrqBase,
479986dffafSJohn Baldwin 		    ioapic->Address);
4800a473124SJohn Baldwin 		break;
481986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
482986dffafSJohn Baldwin 		over = (ACPI_MADT_INTERRUPT_OVERRIDE *)mp;
483986dffafSJohn Baldwin 		printf("\tBUS=%d\n", (u_int)over->Bus);
484986dffafSJohn Baldwin 		printf("\tIRQ=%d\n", (u_int)over->SourceIrq);
485986dffafSJohn Baldwin 		acpi_print_intr(over->GlobalIrq, over->IntiFlags);
4860a473124SJohn Baldwin 		break;
487986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_NMI_SOURCE:
488986dffafSJohn Baldwin 		nmi = (ACPI_MADT_NMI_SOURCE *)mp;
489986dffafSJohn Baldwin 		acpi_print_intr(nmi->GlobalIrq, nmi->IntiFlags);
4900a473124SJohn Baldwin 		break;
491986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
492986dffafSJohn Baldwin 		lapic_nmi = (ACPI_MADT_LOCAL_APIC_NMI *)mp;
493986dffafSJohn Baldwin 		acpi_print_cpu(lapic_nmi->ProcessorId);
494986dffafSJohn Baldwin 		acpi_print_local_nmi(lapic_nmi->Lint, lapic_nmi->IntiFlags);
4950a473124SJohn Baldwin 		break;
496986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
497986dffafSJohn Baldwin 		lapic_over = (ACPI_MADT_LOCAL_APIC_OVERRIDE *)mp;
498945137d9SNate Lawson 		printf("\tLocal APIC ADDR=0x%016jx\n",
499986dffafSJohn Baldwin 		    (uintmax_t)lapic_over->Address);
5000a473124SJohn Baldwin 		break;
501986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_IO_SAPIC:
502986dffafSJohn Baldwin 		iosapic = (ACPI_MADT_IO_SAPIC *)mp;
503986dffafSJohn Baldwin 		acpi_print_io_apic(iosapic->Id, iosapic->GlobalIrqBase,
504986dffafSJohn Baldwin 		    iosapic->Address);
5050a473124SJohn Baldwin 		break;
506986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_SAPIC:
507986dffafSJohn Baldwin 		lsapic = (ACPI_MADT_LOCAL_SAPIC *)mp;
508986dffafSJohn Baldwin 		acpi_print_cpu(lsapic->ProcessorId);
509986dffafSJohn Baldwin 		acpi_print_local_apic(lsapic->Id, lsapic->LapicFlags);
510986dffafSJohn Baldwin 		printf("\tAPIC EID=%d\n", (u_int)lsapic->Eid);
511986dffafSJohn Baldwin 		if (mp->Length > __offsetof(ACPI_MADT_LOCAL_SAPIC, Uid))
512986dffafSJohn Baldwin 			acpi_print_cpu_uid(lsapic->Uid, lsapic->UidString);
5130a473124SJohn Baldwin 		break;
514986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
515986dffafSJohn Baldwin 		isrc = (ACPI_MADT_INTERRUPT_SOURCE *)mp;
516c86932b6SMarcelo Araujo 		if (isrc->Type < nitems(platform_int_types))
517986dffafSJohn Baldwin 			printf("\tType=%s\n", platform_int_types[isrc->Type]);
518986dffafSJohn Baldwin 		else
519986dffafSJohn Baldwin 			printf("\tType=%d (unknown)\n", isrc->Type);
520986dffafSJohn Baldwin 		printf("\tAPIC ID=%d\n", (u_int)isrc->Id);
521986dffafSJohn Baldwin 		printf("\tAPIC EID=%d\n", (u_int)isrc->Eid);
522986dffafSJohn Baldwin 		printf("\tSAPIC Vector=%d\n", (u_int)isrc->IoSapicVector);
523986dffafSJohn Baldwin 		acpi_print_intr(isrc->GlobalIrq, isrc->IntiFlags);
524986dffafSJohn Baldwin 		break;
525986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_X2APIC:
526986dffafSJohn Baldwin 		x2apic = (ACPI_MADT_LOCAL_X2APIC *)mp;
527986dffafSJohn Baldwin 		acpi_print_cpu_uid(x2apic->Uid, NULL);
528986dffafSJohn Baldwin 		acpi_print_local_apic(x2apic->LocalApicId, x2apic->LapicFlags);
529986dffafSJohn Baldwin 		break;
530986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
531986dffafSJohn Baldwin 		x2apic_nmi = (ACPI_MADT_LOCAL_X2APIC_NMI *)mp;
532986dffafSJohn Baldwin 		acpi_print_cpu_uid(x2apic_nmi->Uid, NULL);
533986dffafSJohn Baldwin 		acpi_print_local_nmi(x2apic_nmi->Lint, x2apic_nmi->IntiFlags);
5340a473124SJohn Baldwin 		break;
5352b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
5362b2b1f42SAndrew Turner 		gicc = (ACPI_MADT_GENERIC_INTERRUPT *)mp;
5372b2b1f42SAndrew Turner 		acpi_print_cpu_uid(gicc->Uid, NULL);
5382b2b1f42SAndrew Turner 		printf("\tCPU INTERFACE=%x\n", gicc->CpuInterfaceNumber);
5392b2b1f42SAndrew Turner 		acpi_print_gicc_flags(gicc->Flags);
5402b2b1f42SAndrew Turner 		printf("\tParking Protocol Version=%x\n", gicc->ParkingVersion);
5412b2b1f42SAndrew Turner 		printf("\tPERF INTR=%d\n", gicc->PerformanceInterrupt);
5422b2b1f42SAndrew Turner 		printf("\tParked ADDR=%016jx\n",
5432b2b1f42SAndrew Turner 		    (uintmax_t)gicc->ParkedAddress);
5442b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicc->BaseAddress);
5452b2b1f42SAndrew Turner 		printf("\tGICV=%016jx\n", (uintmax_t)gicc->GicvBaseAddress);
5462b2b1f42SAndrew Turner 		printf("\tGICH=%016jx\n", (uintmax_t)gicc->GichBaseAddress);
5472b2b1f42SAndrew Turner 		printf("\tVGIC INTR=%d\n", gicc->VgicInterrupt);
5482b2b1f42SAndrew Turner 		printf("\tGICR ADDR=%016jx\n",
5492b2b1f42SAndrew Turner 		    (uintmax_t)gicc->GicrBaseAddress);
5502b2b1f42SAndrew Turner 		printf("\tMPIDR=%jx\n", (uintmax_t)gicc->ArmMpidr);
5512b2b1f42SAndrew Turner 		printf("\tEfficency Class=%d\n", (u_int)gicc->EfficiencyClass);
5522b2b1f42SAndrew Turner 		break;
5532b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
5542b2b1f42SAndrew Turner 		gicd = (ACPI_MADT_GENERIC_DISTRIBUTOR *)mp;
5552b2b1f42SAndrew Turner 		printf("\tGIC ID=%d\n", (u_int)gicd->GicId);
5562b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicd->BaseAddress);
5572b2b1f42SAndrew Turner 		printf("\tVector Base=%d\n", gicd->GlobalIrqBase);
5582b2b1f42SAndrew Turner 		printf("\tGIC VERSION=%d\n", (u_int)gicd->Version);
5592b2b1f42SAndrew Turner 		break;
5602b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
5612b2b1f42SAndrew Turner 		gicr = (ACPI_MADT_GENERIC_REDISTRIBUTOR *)mp;
5622b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicr->BaseAddress);
5632b2b1f42SAndrew Turner 		printf("\tLength=%08x\n", gicr->Length);
5642b2b1f42SAndrew Turner 		break;
5652b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
5662b2b1f42SAndrew Turner 		gict = (ACPI_MADT_GENERIC_TRANSLATOR *)mp;
5672b2b1f42SAndrew Turner 		printf("\tGIC ITS ID=%d\n", gict->TranslationId);
5682b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gict->BaseAddress);
5692b2b1f42SAndrew Turner 		break;
5700a473124SJohn Baldwin 	}
5710a473124SJohn Baldwin }
5720a473124SJohn Baldwin 
5730a473124SJohn Baldwin static void
574986dffafSJohn Baldwin acpi_handle_madt(ACPI_TABLE_HEADER *sdp)
5750a473124SJohn Baldwin {
576986dffafSJohn Baldwin 	ACPI_TABLE_MADT *madt;
5770a473124SJohn Baldwin 
578773b6454SNate Lawson 	printf(BEGIN_COMMENT);
579773b6454SNate Lawson 	acpi_print_sdt(sdp);
580986dffafSJohn Baldwin 	madt = (ACPI_TABLE_MADT *)sdp;
581986dffafSJohn Baldwin 	printf("\tLocal APIC ADDR=0x%08x\n", madt->Address);
5820a473124SJohn Baldwin 	printf("\tFlags={");
583986dffafSJohn Baldwin 	if (madt->Flags & ACPI_MADT_PCAT_COMPAT)
5840a473124SJohn Baldwin 		printf("PC-AT");
5850a473124SJohn Baldwin 	printf("}\n");
586986dffafSJohn Baldwin 	acpi_walk_subtables(sdp, (madt + 1), acpi_print_madt);
5870a473124SJohn Baldwin 	printf(END_COMMENT);
5880a473124SJohn Baldwin }
5890a473124SJohn Baldwin 
5900a473124SJohn Baldwin static void
591986dffafSJohn Baldwin acpi_handle_hpet(ACPI_TABLE_HEADER *sdp)
59279d7565cSPeter Wemm {
593986dffafSJohn Baldwin 	ACPI_TABLE_HPET *hpet;
59479d7565cSPeter Wemm 
595773b6454SNate Lawson 	printf(BEGIN_COMMENT);
596773b6454SNate Lawson 	acpi_print_sdt(sdp);
597986dffafSJohn Baldwin 	hpet = (ACPI_TABLE_HPET *)sdp;
598986dffafSJohn Baldwin 	printf("\tHPET Number=%d\n", hpet->Sequence);
59987f9f09aSTakanori Watanabe 	printf("\tADDR=");
600986dffafSJohn Baldwin 	acpi_print_gas(&hpet->Address);
601986dffafSJohn Baldwin 	printf("\tHW Rev=0x%x\n", hpet->Id & ACPI_HPET_ID_HARDWARE_REV_ID);
602986dffafSJohn Baldwin 	printf("\tComparators=%d\n", (hpet->Id & ACPI_HPET_ID_COMPARATORS) >>
603986dffafSJohn Baldwin 	    8);
604986dffafSJohn Baldwin 	printf("\tCounter Size=%d\n", hpet->Id & ACPI_HPET_ID_COUNT_SIZE_CAP ?
605986dffafSJohn Baldwin 	    1 : 0);
60679d7565cSPeter Wemm 	printf("\tLegacy IRQ routing capable={");
607986dffafSJohn Baldwin 	if (hpet->Id & ACPI_HPET_ID_LEGACY_CAPABLE)
60879d7565cSPeter Wemm 		printf("TRUE}\n");
60979d7565cSPeter Wemm 	else
61079d7565cSPeter Wemm 		printf("FALSE}\n");
611986dffafSJohn Baldwin 	printf("\tPCI Vendor ID=0x%04x\n", hpet->Id >> 16);
612986dffafSJohn Baldwin 	printf("\tMinimal Tick=%d\n", hpet->MinimumTick);
6139785e979SNeel Natu 	printf("\tFlags=0x%02x\n", hpet->Flags);
61479d7565cSPeter Wemm 	printf(END_COMMENT);
61579d7565cSPeter Wemm }
61679d7565cSPeter Wemm 
61779d7565cSPeter Wemm static void
618986dffafSJohn Baldwin acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp)
61955d7ff9eSNate Lawson {
620986dffafSJohn Baldwin 	ACPI_TABLE_ECDT *ecdt;
62155d7ff9eSNate Lawson 
62255d7ff9eSNate Lawson 	printf(BEGIN_COMMENT);
62355d7ff9eSNate Lawson 	acpi_print_sdt(sdp);
624986dffafSJohn Baldwin 	ecdt = (ACPI_TABLE_ECDT *)sdp;
62555d7ff9eSNate Lawson 	printf("\tEC_CONTROL=");
626986dffafSJohn Baldwin 	acpi_print_gas(&ecdt->Control);
62755d7ff9eSNate Lawson 	printf("\n\tEC_DATA=");
628986dffafSJohn Baldwin 	acpi_print_gas(&ecdt->Data);
629986dffafSJohn Baldwin 	printf("\n\tUID=%#x, ", ecdt->Uid);
630986dffafSJohn Baldwin 	printf("GPE_BIT=%#x\n", ecdt->Gpe);
631986dffafSJohn Baldwin 	printf("\tEC_ID=%s\n", ecdt->Id);
63255d7ff9eSNate Lawson 	printf(END_COMMENT);
63355d7ff9eSNate Lawson }
63455d7ff9eSNate Lawson 
63555d7ff9eSNate Lawson static void
636986dffafSJohn Baldwin acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp)
637a47e681bSScott Long {
638986dffafSJohn Baldwin 	ACPI_TABLE_MCFG *mcfg;
639986dffafSJohn Baldwin 	ACPI_MCFG_ALLOCATION *alloc;
640986dffafSJohn Baldwin 	u_int i, entries;
641a47e681bSScott Long 
642a47e681bSScott Long 	printf(BEGIN_COMMENT);
643a47e681bSScott Long 	acpi_print_sdt(sdp);
644986dffafSJohn Baldwin 	mcfg = (ACPI_TABLE_MCFG *)sdp;
645986dffafSJohn Baldwin 	entries = (sdp->Length - sizeof(ACPI_TABLE_MCFG)) /
646986dffafSJohn Baldwin 	    sizeof(ACPI_MCFG_ALLOCATION);
647986dffafSJohn Baldwin 	alloc = (ACPI_MCFG_ALLOCATION *)(mcfg + 1);
648986dffafSJohn Baldwin 	for (i = 0; i < entries; i++, alloc++) {
649a47e681bSScott Long 		printf("\n");
6500c10b85aSJung-uk Kim 		printf("\tBase Address=0x%016jx\n", (uintmax_t)alloc->Address);
651986dffafSJohn Baldwin 		printf("\tSegment Group=0x%04x\n", alloc->PciSegment);
652986dffafSJohn Baldwin 		printf("\tStart Bus=%d\n", alloc->StartBusNumber);
653986dffafSJohn Baldwin 		printf("\tEnd Bus=%d\n", alloc->EndBusNumber);
654a47e681bSScott Long 	}
655a47e681bSScott Long 	printf(END_COMMENT);
656a47e681bSScott Long }
657a47e681bSScott Long 
658a47e681bSScott Long static void
65933866658SJohn Baldwin acpi_handle_slit(ACPI_TABLE_HEADER *sdp)
66033866658SJohn Baldwin {
66133866658SJohn Baldwin 	ACPI_TABLE_SLIT *slit;
66233866658SJohn Baldwin 	UINT64 i, j;
66333866658SJohn Baldwin 
66433866658SJohn Baldwin 	printf(BEGIN_COMMENT);
66533866658SJohn Baldwin 	acpi_print_sdt(sdp);
66633866658SJohn Baldwin 	slit = (ACPI_TABLE_SLIT *)sdp;
6670c10b85aSJung-uk Kim 	printf("\tLocality Count=%ju\n", (uintmax_t)slit->LocalityCount);
66833866658SJohn Baldwin 	printf("\n\t      ");
66933866658SJohn Baldwin 	for (i = 0; i < slit->LocalityCount; i++)
6700c10b85aSJung-uk Kim 		printf(" %3ju", (uintmax_t)i);
67133866658SJohn Baldwin 	printf("\n\t     +");
67233866658SJohn Baldwin 	for (i = 0; i < slit->LocalityCount; i++)
67333866658SJohn Baldwin 		printf("----");
67433866658SJohn Baldwin 	printf("\n");
67533866658SJohn Baldwin 	for (i = 0; i < slit->LocalityCount; i++) {
6760c10b85aSJung-uk Kim 		printf("\t %3ju |", (uintmax_t)i);
67733866658SJohn Baldwin 		for (j = 0; j < slit->LocalityCount; j++)
67833866658SJohn Baldwin 			printf(" %3d",
67933866658SJohn Baldwin 			    slit->Entry[i * slit->LocalityCount + j]);
68033866658SJohn Baldwin 		printf("\n");
68133866658SJohn Baldwin 	}
68233866658SJohn Baldwin 	printf(END_COMMENT);
68333866658SJohn Baldwin }
68433866658SJohn Baldwin 
68533866658SJohn Baldwin static void
686ed26c389SScott Long acpi_handle_wddt(ACPI_TABLE_HEADER *sdp)
687ed26c389SScott Long {
688ed26c389SScott Long 	ACPI_TABLE_WDDT *wddt;
689ed26c389SScott Long 
690ed26c389SScott Long 	printf(BEGIN_COMMENT);
691ed26c389SScott Long 	acpi_print_sdt(sdp);
692ed26c389SScott Long 	wddt = (ACPI_TABLE_WDDT *)sdp;
693ed26c389SScott Long 	printf("\tSpecVersion=0x%04x, TableVersion=0x%04x\n",
694ed26c389SScott Long 	    wddt->SpecVersion, wddt->TableVersion);
695ed26c389SScott Long 	printf("\tPciVendorId=0x%04x, Address=", wddt->PciVendorId);
696ed26c389SScott Long 	acpi_print_gas(&wddt->Address);
697ed26c389SScott Long 	printf("\n\tMaxCount=%u, MinCount=%u, Period=%ums\n",
698ed26c389SScott Long 	    wddt->MaxCount, wddt->MinCount, wddt->Period);
699ed26c389SScott Long 
700ed26c389SScott Long #define	PRINTFLAG(var, flag)	printflag((var), ACPI_WDDT_## flag, #flag)
701ed26c389SScott Long 	printf("\tStatus=");
702ed26c389SScott Long 	PRINTFLAG(wddt->Status, AVAILABLE);
703ed26c389SScott Long 	PRINTFLAG(wddt->Status, ACTIVE);
704ed26c389SScott Long 	PRINTFLAG(wddt->Status, TCO_OS_OWNED);
705ed26c389SScott Long 	PRINTFLAG(wddt->Status, USER_RESET);
706ed26c389SScott Long 	PRINTFLAG(wddt->Status, WDT_RESET);
707ed26c389SScott Long 	PRINTFLAG(wddt->Status, POWER_FAIL);
708ed26c389SScott Long 	PRINTFLAG(wddt->Status, UNKNOWN_RESET);
709ed26c389SScott Long 	PRINTFLAG_END();
710ed26c389SScott Long 	printf("\tCapability=");
711ed26c389SScott Long 	PRINTFLAG(wddt->Capability, AUTO_RESET);
712ed26c389SScott Long 	PRINTFLAG(wddt->Capability, ALERT_SUPPORT);
713ed26c389SScott Long 	PRINTFLAG_END();
714ed26c389SScott Long #undef PRINTFLAG
715ed26c389SScott Long 
716ed26c389SScott Long 	printf(END_COMMENT);
717ed26c389SScott Long }
718ed26c389SScott Long 
719ed26c389SScott Long static void
7205857fba5SBen Widawsky acpi_print_native_lpit(ACPI_LPIT_NATIVE *nl)
7215857fba5SBen Widawsky {
7225857fba5SBen Widawsky 	printf("\tEntryTrigger=");
7235857fba5SBen Widawsky 	acpi_print_gas(&nl->EntryTrigger);
7245857fba5SBen Widawsky 	printf("\tResidency=%u\n", nl->Residency);
7255857fba5SBen Widawsky 	printf("\tLatency=%u\n", nl->Latency);
7265857fba5SBen Widawsky 	if (nl->Header.Flags & ACPI_LPIT_NO_COUNTER)
7275857fba5SBen Widawsky 		printf("\tResidencyCounter=Not Present");
7285857fba5SBen Widawsky 	else {
7295857fba5SBen Widawsky 		printf("\tResidencyCounter=");
7305857fba5SBen Widawsky 		acpi_print_gas(&nl->ResidencyCounter);
7315857fba5SBen Widawsky 	}
7325857fba5SBen Widawsky 	if (nl->CounterFrequency)
7335857fba5SBen Widawsky 		printf("\tCounterFrequency=%ju\n", nl->CounterFrequency);
7345857fba5SBen Widawsky 	else
7355857fba5SBen Widawsky 		printf("\tCounterFrequency=TSC\n");
7365857fba5SBen Widawsky }
7375857fba5SBen Widawsky 
7385857fba5SBen Widawsky static void
7395857fba5SBen Widawsky acpi_print_lpit(ACPI_LPIT_HEADER *lpit)
7405857fba5SBen Widawsky {
7415857fba5SBen Widawsky 	if (lpit->Type == ACPI_LPIT_TYPE_NATIVE_CSTATE)
7425857fba5SBen Widawsky 		printf("\tType=ACPI_LPIT_TYPE_NATIVE_CSTATE\n");
7435857fba5SBen Widawsky 	else
7445857fba5SBen Widawsky 		warnx("unknown LPIT type %u", lpit->Type);
7455857fba5SBen Widawsky 
7465857fba5SBen Widawsky 	printf("\tLength=%u\n", lpit->Length);
7475857fba5SBen Widawsky 	printf("\tUniqueId=0x%04x\n", lpit->UniqueId);
7485857fba5SBen Widawsky #define	PRINTFLAG(var, flag)	printflag((var), ACPI_LPIT_## flag, #flag)
7495857fba5SBen Widawsky 	printf("\tFlags=");
7505857fba5SBen Widawsky 	PRINTFLAG(lpit->Flags, STATE_DISABLED);
7515857fba5SBen Widawsky 	PRINTFLAG_END();
7525857fba5SBen Widawsky #undef PRINTFLAG
7535857fba5SBen Widawsky 
7545857fba5SBen Widawsky 	if (lpit->Type == ACPI_LPIT_TYPE_NATIVE_CSTATE)
7555857fba5SBen Widawsky 		return acpi_print_native_lpit((ACPI_LPIT_NATIVE *)lpit);
7565857fba5SBen Widawsky }
7575857fba5SBen Widawsky 
7585857fba5SBen Widawsky static void
7595857fba5SBen Widawsky acpi_walk_lpit(ACPI_TABLE_HEADER *table, void *first,
7605857fba5SBen Widawsky     void (*action)(ACPI_LPIT_HEADER *))
7615857fba5SBen Widawsky {
7625857fba5SBen Widawsky 	ACPI_LPIT_HEADER *subtable;
7635857fba5SBen Widawsky 	char *end;
7645857fba5SBen Widawsky 
7655857fba5SBen Widawsky 	subtable = first;
7665857fba5SBen Widawsky 	end = (char *)table + table->Length;
7675857fba5SBen Widawsky 	while ((char *)subtable < end) {
7685857fba5SBen Widawsky 		printf("\n");
7695857fba5SBen Widawsky 		if (subtable->Length < sizeof(ACPI_LPIT_HEADER)) {
7705857fba5SBen Widawsky 			warnx("invalid subtable length %u", subtable->Length);
7715857fba5SBen Widawsky 			return;
7725857fba5SBen Widawsky 		}
7735857fba5SBen Widawsky 		action(subtable);
7745857fba5SBen Widawsky 		subtable = (ACPI_LPIT_HEADER *)((char *)subtable +
7755857fba5SBen Widawsky 		    subtable->Length);
7765857fba5SBen Widawsky 	}
7775857fba5SBen Widawsky }
7785857fba5SBen Widawsky 
7795857fba5SBen Widawsky static void
7805857fba5SBen Widawsky acpi_handle_lpit(ACPI_TABLE_HEADER *sdp)
7815857fba5SBen Widawsky {
7825857fba5SBen Widawsky 	ACPI_TABLE_LPIT *lpit;
7835857fba5SBen Widawsky 
7845857fba5SBen Widawsky 	printf(BEGIN_COMMENT);
7855857fba5SBen Widawsky 	acpi_print_sdt(sdp);
7865857fba5SBen Widawsky 	lpit = (ACPI_TABLE_LPIT *)sdp;
7875857fba5SBen Widawsky 	acpi_walk_lpit(sdp, (lpit + 1), acpi_print_lpit);
7885857fba5SBen Widawsky 
7895857fba5SBen Widawsky 	printf(END_COMMENT);
7905857fba5SBen Widawsky }
7915857fba5SBen Widawsky 
7925857fba5SBen Widawsky static void
793a0333ad1SJohn Baldwin acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain,
794a0333ad1SJohn Baldwin     uint32_t flags)
795a0333ad1SJohn Baldwin {
796a0333ad1SJohn Baldwin 
797a0333ad1SJohn Baldwin 	printf("\tFlags={");
798a0333ad1SJohn Baldwin 	if (flags & ACPI_SRAT_CPU_ENABLED)
799a0333ad1SJohn Baldwin 		printf("ENABLED");
800a0333ad1SJohn Baldwin 	else
801a0333ad1SJohn Baldwin 		printf("DISABLED");
802a0333ad1SJohn Baldwin 	printf("}\n");
803a0333ad1SJohn Baldwin 	printf("\tAPIC ID=%d\n", apic_id);
804a0333ad1SJohn Baldwin 	printf("\tProximity Domain=%d\n", proximity_domain);
805a0333ad1SJohn Baldwin }
806a0333ad1SJohn Baldwin 
807c031c93bSTakanori Watanabe static char *
808c031c93bSTakanori Watanabe acpi_tcpa_evname(struct TCPAevent *event)
809c031c93bSTakanori Watanabe {
810c031c93bSTakanori Watanabe 	struct TCPApc_event *pc_event;
811c031c93bSTakanori Watanabe 	char *eventname = NULL;
812c031c93bSTakanori Watanabe 
813c031c93bSTakanori Watanabe 	pc_event = (struct TCPApc_event *)(event + 1);
814c031c93bSTakanori Watanabe 
815c031c93bSTakanori Watanabe 	switch(event->event_type) {
816c031c93bSTakanori Watanabe 	case PREBOOT:
817c031c93bSTakanori Watanabe 	case POST_CODE:
818c031c93bSTakanori Watanabe 	case UNUSED:
819c031c93bSTakanori Watanabe 	case NO_ACTION:
820c031c93bSTakanori Watanabe 	case SEPARATOR:
821c031c93bSTakanori Watanabe 	case SCRTM_CONTENTS:
822c031c93bSTakanori Watanabe 	case SCRTM_VERSION:
823c031c93bSTakanori Watanabe 	case CPU_MICROCODE:
824c031c93bSTakanori Watanabe 	case PLATFORM_CONFIG_FLAGS:
825c031c93bSTakanori Watanabe 	case TABLE_OF_DEVICES:
826c031c93bSTakanori Watanabe 	case COMPACT_HASH:
827c031c93bSTakanori Watanabe 	case IPL:
828c031c93bSTakanori Watanabe 	case IPL_PARTITION_DATA:
829c031c93bSTakanori Watanabe 	case NONHOST_CODE:
830c031c93bSTakanori Watanabe 	case NONHOST_CONFIG:
831c031c93bSTakanori Watanabe 	case NONHOST_INFO:
832c031c93bSTakanori Watanabe 		asprintf(&eventname, "%s",
833c031c93bSTakanori Watanabe 		    tcpa_event_type_strings[event->event_type]);
834c031c93bSTakanori Watanabe 		break;
835c031c93bSTakanori Watanabe 
836c031c93bSTakanori Watanabe 	case ACTION:
837c031c93bSTakanori Watanabe 		eventname = calloc(event->event_size + 1, sizeof(char));
838c031c93bSTakanori Watanabe 		memcpy(eventname, pc_event, event->event_size);
839c031c93bSTakanori Watanabe 		break;
840c031c93bSTakanori Watanabe 
841c031c93bSTakanori Watanabe 	case EVENT_TAG:
842c031c93bSTakanori Watanabe 		switch (pc_event->event_id) {
843c031c93bSTakanori Watanabe 		case SMBIOS:
844c031c93bSTakanori Watanabe 		case BIS_CERT:
845c031c93bSTakanori Watanabe 		case CMOS:
846c031c93bSTakanori Watanabe 		case NVRAM:
847c031c93bSTakanori Watanabe 		case OPTION_ROM_EXEC:
848c031c93bSTakanori Watanabe 		case OPTION_ROM_CONFIG:
849c031c93bSTakanori Watanabe 		case S_CRTM_VERSION:
850c031c93bSTakanori Watanabe 		case POST_BIOS_ROM:
851c031c93bSTakanori Watanabe 		case ESCD:
852c031c93bSTakanori Watanabe 		case OPTION_ROM_MICROCODE:
853c031c93bSTakanori Watanabe 		case S_CRTM_CONTENTS:
854c031c93bSTakanori Watanabe 		case POST_CONTENTS:
855c031c93bSTakanori Watanabe 			asprintf(&eventname, "%s",
856c031c93bSTakanori Watanabe 			    TCPA_pcclient_strings[pc_event->event_id]);
857c031c93bSTakanori Watanabe 			break;
858c031c93bSTakanori Watanabe 
859c031c93bSTakanori Watanabe 		default:
860c031c93bSTakanori Watanabe 			asprintf(&eventname, "<unknown tag 0x%02x>",
861c031c93bSTakanori Watanabe 			    pc_event->event_id);
862c031c93bSTakanori Watanabe 			break;
863c031c93bSTakanori Watanabe 		}
864c031c93bSTakanori Watanabe 		break;
865c031c93bSTakanori Watanabe 
866c031c93bSTakanori Watanabe 	default:
867c031c93bSTakanori Watanabe 		asprintf(&eventname, "<unknown 0x%02x>", event->event_type);
868c031c93bSTakanori Watanabe 		break;
869c031c93bSTakanori Watanabe 	}
870c031c93bSTakanori Watanabe 
871c031c93bSTakanori Watanabe 	return eventname;
872c031c93bSTakanori Watanabe }
873c031c93bSTakanori Watanabe 
874c031c93bSTakanori Watanabe static void
875c031c93bSTakanori Watanabe acpi_print_tcpa(struct TCPAevent *event)
876c031c93bSTakanori Watanabe {
877c031c93bSTakanori Watanabe 	int i;
878c031c93bSTakanori Watanabe 	char *eventname;
879c031c93bSTakanori Watanabe 
880c031c93bSTakanori Watanabe 	eventname = acpi_tcpa_evname(event);
881c031c93bSTakanori Watanabe 
882c031c93bSTakanori Watanabe 	printf("\t%d", event->pcr_index);
883c031c93bSTakanori Watanabe 	printf(" 0x");
884c031c93bSTakanori Watanabe 	for (i = 0; i < 20; i++)
885c031c93bSTakanori Watanabe 		printf("%02x", event->pcr_value[i]);
886c031c93bSTakanori Watanabe 	printf(" [%s]\n", eventname ? eventname : "<unknown>");
887c031c93bSTakanori Watanabe 
888c031c93bSTakanori Watanabe 	free(eventname);
889c031c93bSTakanori Watanabe }
890c031c93bSTakanori Watanabe 
891c031c93bSTakanori Watanabe static void
892c031c93bSTakanori Watanabe acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp)
893c031c93bSTakanori Watanabe {
894c031c93bSTakanori Watanabe 	struct TCPAbody *tcpa;
895c031c93bSTakanori Watanabe 	struct TCPAevent *event;
896977fd9daSTakanori Watanabe 	uintmax_t len, paddr;
897c031c93bSTakanori Watanabe 	unsigned char *vaddr = NULL;
898c031c93bSTakanori Watanabe 	unsigned char *vend = NULL;
899c031c93bSTakanori Watanabe 
900c031c93bSTakanori Watanabe 	printf(BEGIN_COMMENT);
901c031c93bSTakanori Watanabe 	acpi_print_sdt(sdp);
902c031c93bSTakanori Watanabe 	tcpa = (struct TCPAbody *) sdp;
903c031c93bSTakanori Watanabe 
904c031c93bSTakanori Watanabe 	switch (tcpa->platform_class) {
905c031c93bSTakanori Watanabe 	case ACPI_TCPA_BIOS_CLIENT:
906c031c93bSTakanori Watanabe 		len = tcpa->client.log_max_len;
907c031c93bSTakanori Watanabe 		paddr = tcpa->client.log_start_addr;
908c031c93bSTakanori Watanabe 		break;
909c031c93bSTakanori Watanabe 
910c031c93bSTakanori Watanabe 	case ACPI_TCPA_BIOS_SERVER:
911c031c93bSTakanori Watanabe 		len = tcpa->server.log_max_len;
912c031c93bSTakanori Watanabe 		paddr = tcpa->server.log_start_addr;
913c031c93bSTakanori Watanabe 		break;
914c031c93bSTakanori Watanabe 
915c031c93bSTakanori Watanabe 	default:
916c031c93bSTakanori Watanabe 		printf("XXX");
917c031c93bSTakanori Watanabe 		printf(END_COMMENT);
918c031c93bSTakanori Watanabe 		return;
919c031c93bSTakanori Watanabe 	}
9200e1982f4STakanori Watanabe 	printf("\tClass %u Base Address 0x%jx Length %ju\n\n",
921c031c93bSTakanori Watanabe 	    tcpa->platform_class, paddr, len);
922c031c93bSTakanori Watanabe 
923c031c93bSTakanori Watanabe 	if (len == 0) {
924c031c93bSTakanori Watanabe 		printf("\tEmpty TCPA table\n");
925c031c93bSTakanori Watanabe 		printf(END_COMMENT);
926c031c93bSTakanori Watanabe 		return;
927c031c93bSTakanori Watanabe 	}
9282ef23c6dSTakanori Watanabe 	if(sdp->Revision == 1){
9292ef23c6dSTakanori Watanabe 		printf("\tOLD TCPA spec log found. Dumping not supported.\n");
9302ef23c6dSTakanori Watanabe 		printf(END_COMMENT);
9312ef23c6dSTakanori Watanabe 		return;
9322ef23c6dSTakanori Watanabe 	}
933c031c93bSTakanori Watanabe 
934c031c93bSTakanori Watanabe 	vaddr = (unsigned char *)acpi_map_physical(paddr, len);
935c031c93bSTakanori Watanabe 	vend = vaddr + len;
936c031c93bSTakanori Watanabe 
937c031c93bSTakanori Watanabe 	while (vaddr != NULL) {
9382ef23c6dSTakanori Watanabe 		if ((vaddr + sizeof(struct TCPAevent) >= vend)||
9392ef23c6dSTakanori Watanabe 		    (vaddr + sizeof(struct TCPAevent) < vaddr))
940c031c93bSTakanori Watanabe 			break;
9410e1982f4STakanori Watanabe 		event = (struct TCPAevent *)(void *)vaddr;
942c031c93bSTakanori Watanabe 		if (vaddr + event->event_size >= vend)
943c031c93bSTakanori Watanabe 			break;
9442ef23c6dSTakanori Watanabe 		if (vaddr + event->event_size < vaddr)
9452ef23c6dSTakanori Watanabe 			break;
946c031c93bSTakanori Watanabe 		if (event->event_type == 0 && event->event_size == 0)
947c031c93bSTakanori Watanabe 			break;
948c031c93bSTakanori Watanabe #if 0
949c031c93bSTakanori Watanabe 		{
950c031c93bSTakanori Watanabe 		unsigned int i, j, k;
951c031c93bSTakanori Watanabe 
952c031c93bSTakanori Watanabe 		printf("\n\tsize %d\n\t\t%p ", event->event_size, vaddr);
953c031c93bSTakanori Watanabe 		for (j = 0, i = 0; i <
954c031c93bSTakanori Watanabe 		    sizeof(struct TCPAevent) + event->event_size; i++) {
955c031c93bSTakanori Watanabe 			printf("%02x ", vaddr[i]);
956c031c93bSTakanori Watanabe 			if ((i+1) % 8 == 0) {
957c031c93bSTakanori Watanabe 				for (k = 0; k < 8; k++)
958c031c93bSTakanori Watanabe 					printf("%c", isprint(vaddr[j+k]) ?
959c031c93bSTakanori Watanabe 					    vaddr[j+k] : '.');
960c031c93bSTakanori Watanabe 				printf("\n\t\t%p ", &vaddr[i + 1]);
961c031c93bSTakanori Watanabe 				j = i + 1;
962c031c93bSTakanori Watanabe 			}
963c031c93bSTakanori Watanabe 		}
964c031c93bSTakanori Watanabe 		printf("\n"); }
965c031c93bSTakanori Watanabe #endif
966c031c93bSTakanori Watanabe 		acpi_print_tcpa(event);
967c031c93bSTakanori Watanabe 
968c031c93bSTakanori Watanabe 		vaddr += sizeof(struct TCPAevent) + event->event_size;
969c031c93bSTakanori Watanabe 	}
970c031c93bSTakanori Watanabe 
971c031c93bSTakanori Watanabe 	printf(END_COMMENT);
972c031c93bSTakanori Watanabe }
973877fc2e3STakanori Watanabe static void acpi_handle_tpm2(ACPI_TABLE_HEADER *sdp)
974877fc2e3STakanori Watanabe {
975877fc2e3STakanori Watanabe 	ACPI_TABLE_TPM2 *tpm2;
976877fc2e3STakanori Watanabe 
977877fc2e3STakanori Watanabe 	printf (BEGIN_COMMENT);
978877fc2e3STakanori Watanabe 	acpi_print_sdt(sdp);
979877fc2e3STakanori Watanabe 	tpm2 = (ACPI_TABLE_TPM2 *) sdp;
9807aef7138SCy Schubert 	printf ("\t\tControlArea=%jx\n", tpm2->ControlAddress);
981877fc2e3STakanori Watanabe 	printf ("\t\tStartMethod=%x\n", tpm2->StartMethod);
982877fc2e3STakanori Watanabe 	printf (END_COMMENT);
983877fc2e3STakanori Watanabe }
984c031c93bSTakanori Watanabe 
985ec650989SNeel Natu static const char *
986ec650989SNeel Natu devscope_type2str(int type)
987ec650989SNeel Natu {
988ec650989SNeel Natu 	static char typebuf[16];
989ec650989SNeel Natu 
990ec650989SNeel Natu 	switch (type) {
991ec650989SNeel Natu 	case 1:
992ec650989SNeel Natu 		return ("PCI Endpoint Device");
993ec650989SNeel Natu 	case 2:
994ec650989SNeel Natu 		return ("PCI Sub-Hierarchy");
995ec650989SNeel Natu 	case 3:
996ec650989SNeel Natu 		return ("IOAPIC");
997ec650989SNeel Natu 	case 4:
998ec650989SNeel Natu 		return ("HPET");
999ec650989SNeel Natu 	default:
1000ec650989SNeel Natu 		snprintf(typebuf, sizeof(typebuf), "%d", type);
1001ec650989SNeel Natu 		return (typebuf);
1002ec650989SNeel Natu 	}
1003ec650989SNeel Natu }
1004ec650989SNeel Natu 
1005ec650989SNeel Natu static int
1006ec650989SNeel Natu acpi_handle_dmar_devscope(void *addr, int remaining)
1007ec650989SNeel Natu {
1008ec650989SNeel Natu 	char sep;
1009ec650989SNeel Natu 	int pathlen;
1010ec650989SNeel Natu 	ACPI_DMAR_PCI_PATH *path, *pathend;
1011ec650989SNeel Natu 	ACPI_DMAR_DEVICE_SCOPE *devscope = addr;
1012ec650989SNeel Natu 
1013ec650989SNeel Natu 	if (remaining < (int)sizeof(ACPI_DMAR_DEVICE_SCOPE))
1014ec650989SNeel Natu 		return (-1);
1015ec650989SNeel Natu 
1016ec650989SNeel Natu 	if (remaining < devscope->Length)
1017ec650989SNeel Natu 		return (-1);
1018ec650989SNeel Natu 
1019ec650989SNeel Natu 	printf("\n");
1020ec650989SNeel Natu 	printf("\t\tType=%s\n", devscope_type2str(devscope->EntryType));
1021ec650989SNeel Natu 	printf("\t\tLength=%d\n", devscope->Length);
1022ec650989SNeel Natu 	printf("\t\tEnumerationId=%d\n", devscope->EnumerationId);
1023ec650989SNeel Natu 	printf("\t\tStartBusNumber=%d\n", devscope->Bus);
1024ec650989SNeel Natu 
1025ec650989SNeel Natu 	path = (ACPI_DMAR_PCI_PATH *)(devscope + 1);
1026ec650989SNeel Natu 	pathlen = devscope->Length - sizeof(ACPI_DMAR_DEVICE_SCOPE);
1027ec650989SNeel Natu 	pathend = path + pathlen / sizeof(ACPI_DMAR_PCI_PATH);
1028ec650989SNeel Natu 	if (path < pathend) {
1029ec650989SNeel Natu 		sep = '{';
1030ec650989SNeel Natu 		printf("\t\tPath=");
1031ec650989SNeel Natu 		do {
1032ec650989SNeel Natu 			printf("%c%d:%d", sep, path->Device, path->Function);
1033ec650989SNeel Natu 			sep=',';
1034ec650989SNeel Natu 			path++;
1035ec650989SNeel Natu 		} while (path < pathend);
1036ec650989SNeel Natu 		printf("}\n");
1037ec650989SNeel Natu 	}
1038ec650989SNeel Natu 
1039ec650989SNeel Natu 	return (devscope->Length);
1040ec650989SNeel Natu }
1041ec650989SNeel Natu 
1042ec650989SNeel Natu static void
1043ec650989SNeel Natu acpi_handle_dmar_drhd(ACPI_DMAR_HARDWARE_UNIT *drhd)
1044ec650989SNeel Natu {
1045ec650989SNeel Natu 	char *cp;
1046ec650989SNeel Natu 	int remaining, consumed;
1047ec650989SNeel Natu 
1048ec650989SNeel Natu 	printf("\n");
1049ec650989SNeel Natu 	printf("\tType=DRHD\n");
1050ec650989SNeel Natu 	printf("\tLength=%d\n", drhd->Header.Length);
1051ec650989SNeel Natu 
1052ec650989SNeel Natu #define	PRINTFLAG(var, flag)	printflag((var), ACPI_DMAR_## flag, #flag)
1053ec650989SNeel Natu 
1054ec650989SNeel Natu 	printf("\tFlags=");
1055ec650989SNeel Natu 	PRINTFLAG(drhd->Flags, INCLUDE_ALL);
1056ec650989SNeel Natu 	PRINTFLAG_END();
1057ec650989SNeel Natu 
1058ec650989SNeel Natu #undef PRINTFLAG
1059ec650989SNeel Natu 
1060ec650989SNeel Natu 	printf("\tSegment=%d\n", drhd->Segment);
10617d369c6eSJung-uk Kim 	printf("\tAddress=0x%016jx\n", (uintmax_t)drhd->Address);
1062ec650989SNeel Natu 
1063ec650989SNeel Natu 	remaining = drhd->Header.Length - sizeof(ACPI_DMAR_HARDWARE_UNIT);
1064ec650989SNeel Natu 	if (remaining > 0)
1065ec650989SNeel Natu 		printf("\tDevice Scope:");
1066ec650989SNeel Natu 	while (remaining > 0) {
1067ec650989SNeel Natu 		cp = (char *)drhd + drhd->Header.Length - remaining;
1068ec650989SNeel Natu 		consumed = acpi_handle_dmar_devscope(cp, remaining);
1069ec650989SNeel Natu 		if (consumed <= 0)
1070ec650989SNeel Natu 			break;
1071ec650989SNeel Natu 		else
1072ec650989SNeel Natu 			remaining -= consumed;
1073ec650989SNeel Natu 	}
1074ec650989SNeel Natu }
1075ec650989SNeel Natu 
1076ec650989SNeel Natu static void
1077ec650989SNeel Natu acpi_handle_dmar_rmrr(ACPI_DMAR_RESERVED_MEMORY *rmrr)
1078ec650989SNeel Natu {
1079ec650989SNeel Natu 	char *cp;
1080ec650989SNeel Natu 	int remaining, consumed;
1081ec650989SNeel Natu 
1082ec650989SNeel Natu 	printf("\n");
1083ec650989SNeel Natu 	printf("\tType=RMRR\n");
1084ec650989SNeel Natu 	printf("\tLength=%d\n", rmrr->Header.Length);
1085ec650989SNeel Natu 	printf("\tSegment=%d\n", rmrr->Segment);
10867d369c6eSJung-uk Kim 	printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rmrr->BaseAddress);
10877d369c6eSJung-uk Kim 	printf("\tLimitAddress=0x%016jx\n", (uintmax_t)rmrr->EndAddress);
1088ec650989SNeel Natu 
1089ec650989SNeel Natu 	remaining = rmrr->Header.Length - sizeof(ACPI_DMAR_RESERVED_MEMORY);
1090ec650989SNeel Natu 	if (remaining > 0)
1091ec650989SNeel Natu 		printf("\tDevice Scope:");
1092ec650989SNeel Natu 	while (remaining > 0) {
1093ec650989SNeel Natu 		cp = (char *)rmrr + rmrr->Header.Length - remaining;
1094ec650989SNeel Natu 		consumed = acpi_handle_dmar_devscope(cp, remaining);
1095ec650989SNeel Natu 		if (consumed <= 0)
1096ec650989SNeel Natu 			break;
1097ec650989SNeel Natu 		else
1098ec650989SNeel Natu 			remaining -= consumed;
1099ec650989SNeel Natu 	}
1100ec650989SNeel Natu }
1101ec650989SNeel Natu 
1102ec650989SNeel Natu static void
1103ec650989SNeel Natu acpi_handle_dmar_atsr(ACPI_DMAR_ATSR *atsr)
1104ec650989SNeel Natu {
1105ec650989SNeel Natu 	char *cp;
1106ec650989SNeel Natu 	int remaining, consumed;
1107ec650989SNeel Natu 
1108ec650989SNeel Natu 	printf("\n");
1109ec650989SNeel Natu 	printf("\tType=ATSR\n");
1110ec650989SNeel Natu 	printf("\tLength=%d\n", atsr->Header.Length);
1111ec650989SNeel Natu 
1112ec650989SNeel Natu #define	PRINTFLAG(var, flag)	printflag((var), ACPI_DMAR_## flag, #flag)
1113ec650989SNeel Natu 
1114ec650989SNeel Natu 	printf("\tFlags=");
1115ec650989SNeel Natu 	PRINTFLAG(atsr->Flags, ALL_PORTS);
1116ec650989SNeel Natu 	PRINTFLAG_END();
1117ec650989SNeel Natu 
1118ec650989SNeel Natu #undef PRINTFLAG
1119ec650989SNeel Natu 
1120ec650989SNeel Natu 	printf("\tSegment=%d\n", atsr->Segment);
1121ec650989SNeel Natu 
1122ec650989SNeel Natu 	remaining = atsr->Header.Length - sizeof(ACPI_DMAR_ATSR);
1123ec650989SNeel Natu 	if (remaining > 0)
1124ec650989SNeel Natu 		printf("\tDevice Scope:");
1125ec650989SNeel Natu 	while (remaining > 0) {
1126ec650989SNeel Natu 		cp = (char *)atsr + atsr->Header.Length - remaining;
1127ec650989SNeel Natu 		consumed = acpi_handle_dmar_devscope(cp, remaining);
1128ec650989SNeel Natu 		if (consumed <= 0)
1129ec650989SNeel Natu 			break;
1130ec650989SNeel Natu 		else
1131ec650989SNeel Natu 			remaining -= consumed;
1132ec650989SNeel Natu 	}
1133ec650989SNeel Natu }
1134ec650989SNeel Natu 
1135ec650989SNeel Natu static void
1136ec650989SNeel Natu acpi_handle_dmar_rhsa(ACPI_DMAR_RHSA *rhsa)
1137ec650989SNeel Natu {
1138ec650989SNeel Natu 
1139ec650989SNeel Natu 	printf("\n");
1140ec650989SNeel Natu 	printf("\tType=RHSA\n");
1141ec650989SNeel Natu 	printf("\tLength=%d\n", rhsa->Header.Length);
11427d369c6eSJung-uk Kim 	printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rhsa->BaseAddress);
1143ec650989SNeel Natu 	printf("\tProximityDomain=0x%08x\n", rhsa->ProximityDomain);
1144ec650989SNeel Natu }
1145ec650989SNeel Natu 
1146ec650989SNeel Natu static int
1147ec650989SNeel Natu acpi_handle_dmar_remapping_structure(void *addr, int remaining)
1148ec650989SNeel Natu {
1149ec650989SNeel Natu 	ACPI_DMAR_HEADER *hdr = addr;
1150ec650989SNeel Natu 
1151ec650989SNeel Natu 	if (remaining < (int)sizeof(ACPI_DMAR_HEADER))
1152ec650989SNeel Natu 		return (-1);
1153ec650989SNeel Natu 
1154ec650989SNeel Natu 	if (remaining < hdr->Length)
1155ec650989SNeel Natu 		return (-1);
1156ec650989SNeel Natu 
1157ec650989SNeel Natu 	switch (hdr->Type) {
1158ec650989SNeel Natu 	case ACPI_DMAR_TYPE_HARDWARE_UNIT:
1159ec650989SNeel Natu 		acpi_handle_dmar_drhd(addr);
1160ec650989SNeel Natu 		break;
1161ec650989SNeel Natu 	case ACPI_DMAR_TYPE_RESERVED_MEMORY:
1162ec650989SNeel Natu 		acpi_handle_dmar_rmrr(addr);
1163ec650989SNeel Natu 		break;
1164313a0c13SJung-uk Kim 	case ACPI_DMAR_TYPE_ROOT_ATS:
1165ec650989SNeel Natu 		acpi_handle_dmar_atsr(addr);
1166ec650989SNeel Natu 		break;
1167313a0c13SJung-uk Kim 	case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
1168ec650989SNeel Natu 		acpi_handle_dmar_rhsa(addr);
1169ec650989SNeel Natu 		break;
1170ec650989SNeel Natu 	default:
1171ec650989SNeel Natu 		printf("\n");
1172ec650989SNeel Natu 		printf("\tType=%d\n", hdr->Type);
1173ec650989SNeel Natu 		printf("\tLength=%d\n", hdr->Length);
1174ec650989SNeel Natu 		break;
1175ec650989SNeel Natu 	}
1176ec650989SNeel Natu 	return (hdr->Length);
1177ec650989SNeel Natu }
1178ec650989SNeel Natu 
1179ec650989SNeel Natu #ifndef ACPI_DMAR_X2APIC_OPT_OUT
1180ec650989SNeel Natu #define	ACPI_DMAR_X2APIC_OPT_OUT	(0x2)
1181ec650989SNeel Natu #endif
1182ec650989SNeel Natu 
1183ec650989SNeel Natu static void
1184ec650989SNeel Natu acpi_handle_dmar(ACPI_TABLE_HEADER *sdp)
1185ec650989SNeel Natu {
1186ec650989SNeel Natu 	char *cp;
1187ec650989SNeel Natu 	int remaining, consumed;
1188ec650989SNeel Natu 	ACPI_TABLE_DMAR *dmar;
1189ec650989SNeel Natu 
1190ec650989SNeel Natu 	printf(BEGIN_COMMENT);
1191ec650989SNeel Natu 	acpi_print_sdt(sdp);
1192ec650989SNeel Natu 	dmar = (ACPI_TABLE_DMAR *)sdp;
1193ec650989SNeel Natu 	printf("\tHost Address Width=%d\n", dmar->Width + 1);
1194ec650989SNeel Natu 
1195ec650989SNeel Natu #define PRINTFLAG(var, flag)	printflag((var), ACPI_DMAR_## flag, #flag)
1196ec650989SNeel Natu 
1197ec650989SNeel Natu 	printf("\tFlags=");
1198ec650989SNeel Natu 	PRINTFLAG(dmar->Flags, INTR_REMAP);
1199ec650989SNeel Natu 	PRINTFLAG(dmar->Flags, X2APIC_OPT_OUT);
1200ec650989SNeel Natu 	PRINTFLAG_END();
1201ec650989SNeel Natu 
1202ec650989SNeel Natu #undef PRINTFLAG
1203ec650989SNeel Natu 
1204ec650989SNeel Natu 	remaining = sdp->Length - sizeof(ACPI_TABLE_DMAR);
1205ec650989SNeel Natu 	while (remaining > 0) {
1206ec650989SNeel Natu 		cp = (char *)sdp + sdp->Length - remaining;
1207ec650989SNeel Natu 		consumed = acpi_handle_dmar_remapping_structure(cp, remaining);
1208ec650989SNeel Natu 		if (consumed <= 0)
1209ec650989SNeel Natu 			break;
1210ec650989SNeel Natu 		else
1211ec650989SNeel Natu 			remaining -= consumed;
1212ec650989SNeel Natu 	}
1213ec650989SNeel Natu 
1214ec650989SNeel Natu 	printf(END_COMMENT);
1215ec650989SNeel Natu }
1216ec650989SNeel Natu 
1217a0333ad1SJohn Baldwin static void
1218986dffafSJohn Baldwin acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp)
1219a0333ad1SJohn Baldwin {
1220a0333ad1SJohn Baldwin 
1221a0333ad1SJohn Baldwin 	printf("\tFlags={");
1222986dffafSJohn Baldwin 	if (mp->Flags & ACPI_SRAT_MEM_ENABLED)
1223a0333ad1SJohn Baldwin 		printf("ENABLED");
1224a0333ad1SJohn Baldwin 	else
1225a0333ad1SJohn Baldwin 		printf("DISABLED");
1226986dffafSJohn Baldwin 	if (mp->Flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)
1227a0333ad1SJohn Baldwin 		printf(",HOT_PLUGGABLE");
1228986dffafSJohn Baldwin 	if (mp->Flags & ACPI_SRAT_MEM_NON_VOLATILE)
1229a0333ad1SJohn Baldwin 		printf(",NON_VOLATILE");
1230a0333ad1SJohn Baldwin 	printf("}\n");
1231986dffafSJohn Baldwin 	printf("\tBase Address=0x%016jx\n", (uintmax_t)mp->BaseAddress);
1232986dffafSJohn Baldwin 	printf("\tLength=0x%016jx\n", (uintmax_t)mp->Length);
1233986dffafSJohn Baldwin 	printf("\tProximity Domain=%d\n", mp->ProximityDomain);
1234a0333ad1SJohn Baldwin }
1235a0333ad1SJohn Baldwin 
123627941afaSEd Maste static const char *srat_types[] = {
123727941afaSEd Maste     [ACPI_SRAT_TYPE_CPU_AFFINITY] = "CPU",
123827941afaSEd Maste     [ACPI_SRAT_TYPE_MEMORY_AFFINITY] = "Memory",
123927941afaSEd Maste     [ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY] = "X2APIC",
1240cebb7b19SEd Maste     [ACPI_SRAT_TYPE_GICC_AFFINITY] = "GICC",
1241cebb7b19SEd Maste     [ACPI_SRAT_TYPE_GIC_ITS_AFFINITY] = "GIC ITS",
124227941afaSEd Maste };
1243a0333ad1SJohn Baldwin 
1244a0333ad1SJohn Baldwin static void
1245986dffafSJohn Baldwin acpi_print_srat(ACPI_SUBTABLE_HEADER *srat)
1246a0333ad1SJohn Baldwin {
1247986dffafSJohn Baldwin 	ACPI_SRAT_CPU_AFFINITY *cpu;
1248986dffafSJohn Baldwin 	ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic;
12492b2b1f42SAndrew Turner 	ACPI_SRAT_GICC_AFFINITY *gic;
1250a0333ad1SJohn Baldwin 
1251c86932b6SMarcelo Araujo 	if (srat->Type < nitems(srat_types))
1252986dffafSJohn Baldwin 		printf("\tType=%s\n", srat_types[srat->Type]);
1253a0333ad1SJohn Baldwin 	else
1254986dffafSJohn Baldwin 		printf("\tType=%d (unknown)\n", srat->Type);
1255986dffafSJohn Baldwin 	switch (srat->Type) {
1256a0333ad1SJohn Baldwin 	case ACPI_SRAT_TYPE_CPU_AFFINITY:
1257986dffafSJohn Baldwin 		cpu = (ACPI_SRAT_CPU_AFFINITY *)srat;
1258986dffafSJohn Baldwin 		acpi_print_srat_cpu(cpu->ApicId,
1259986dffafSJohn Baldwin 		    cpu->ProximityDomainHi[2] << 24 |
1260986dffafSJohn Baldwin 		    cpu->ProximityDomainHi[1] << 16 |
1261986dffafSJohn Baldwin 		    cpu->ProximityDomainHi[0] << 0 |
1262986dffafSJohn Baldwin 		    cpu->ProximityDomainLo, cpu->Flags);
1263a0333ad1SJohn Baldwin 		break;
1264a0333ad1SJohn Baldwin 	case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
1265986dffafSJohn Baldwin 		acpi_print_srat_memory((ACPI_SRAT_MEM_AFFINITY *)srat);
1266a0333ad1SJohn Baldwin 		break;
1267a0333ad1SJohn Baldwin 	case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
1268986dffafSJohn Baldwin 		x2apic = (ACPI_SRAT_X2APIC_CPU_AFFINITY *)srat;
1269986dffafSJohn Baldwin 		acpi_print_srat_cpu(x2apic->ApicId, x2apic->ProximityDomain,
1270986dffafSJohn Baldwin 		    x2apic->Flags);
1271a0333ad1SJohn Baldwin 		break;
12722b2b1f42SAndrew Turner 	case ACPI_SRAT_TYPE_GICC_AFFINITY:
12732b2b1f42SAndrew Turner 		gic = (ACPI_SRAT_GICC_AFFINITY *)srat;
12742b2b1f42SAndrew Turner 		acpi_print_srat_cpu(gic->AcpiProcessorUid, gic->ProximityDomain,
12752b2b1f42SAndrew Turner 		    gic->Flags);
12762b2b1f42SAndrew Turner 		break;
1277a0333ad1SJohn Baldwin 	}
1278a0333ad1SJohn Baldwin }
1279a0333ad1SJohn Baldwin 
1280a0333ad1SJohn Baldwin static void
1281986dffafSJohn Baldwin acpi_handle_srat(ACPI_TABLE_HEADER *sdp)
1282a0333ad1SJohn Baldwin {
1283986dffafSJohn Baldwin 	ACPI_TABLE_SRAT *srat;
1284a0333ad1SJohn Baldwin 
1285a0333ad1SJohn Baldwin 	printf(BEGIN_COMMENT);
1286a0333ad1SJohn Baldwin 	acpi_print_sdt(sdp);
1287986dffafSJohn Baldwin 	srat = (ACPI_TABLE_SRAT *)sdp;
1288986dffafSJohn Baldwin 	printf("\tTable Revision=%d\n", srat->TableRevision);
1289986dffafSJohn Baldwin 	acpi_walk_subtables(sdp, (srat + 1), acpi_print_srat);
1290a0333ad1SJohn Baldwin 	printf(END_COMMENT);
1291a0333ad1SJohn Baldwin }
1292a0333ad1SJohn Baldwin 
1293340c0022SEd Maste static const char *nfit_types[] = {
1294340c0022SEd Maste     [ACPI_NFIT_TYPE_SYSTEM_ADDRESS] = "System Address",
1295340c0022SEd Maste     [ACPI_NFIT_TYPE_MEMORY_MAP] = "Memory Map",
1296340c0022SEd Maste     [ACPI_NFIT_TYPE_INTERLEAVE] = "Interleave",
1297340c0022SEd Maste     [ACPI_NFIT_TYPE_SMBIOS] = "SMBIOS",
1298340c0022SEd Maste     [ACPI_NFIT_TYPE_CONTROL_REGION] = "Control Region",
1299340c0022SEd Maste     [ACPI_NFIT_TYPE_DATA_REGION] = "Data Region",
1300340c0022SEd Maste     [ACPI_NFIT_TYPE_FLUSH_ADDRESS] = "Flush Address"
1301340c0022SEd Maste };
1302340c0022SEd Maste 
1303340c0022SEd Maste 
1304340c0022SEd Maste static void
1305340c0022SEd Maste acpi_print_nfit(ACPI_NFIT_HEADER *nfit)
1306340c0022SEd Maste {
1307340c0022SEd Maste 	char *uuidstr;
1308340c0022SEd Maste 	uint32_t status;
1309340c0022SEd Maste 
1310340c0022SEd Maste 	ACPI_NFIT_SYSTEM_ADDRESS *sysaddr;
1311340c0022SEd Maste 	ACPI_NFIT_MEMORY_MAP *mmap;
1312340c0022SEd Maste 	ACPI_NFIT_INTERLEAVE *ileave;
1313340c0022SEd Maste 	ACPI_NFIT_SMBIOS *smbios;
1314340c0022SEd Maste 	ACPI_NFIT_CONTROL_REGION *ctlreg;
1315340c0022SEd Maste 	ACPI_NFIT_DATA_REGION *datareg;
1316340c0022SEd Maste 	ACPI_NFIT_FLUSH_ADDRESS *fladdr;
1317340c0022SEd Maste 
1318340c0022SEd Maste 	if (nfit->Type < nitems(nfit_types))
1319340c0022SEd Maste 		printf("\tType=%s\n", nfit_types[nfit->Type]);
1320340c0022SEd Maste 	else
1321340c0022SEd Maste 		printf("\tType=%u (unknown)\n", nfit->Type);
1322340c0022SEd Maste 	switch (nfit->Type) {
1323340c0022SEd Maste 	case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
1324340c0022SEd Maste 		sysaddr = (ACPI_NFIT_SYSTEM_ADDRESS *)nfit;
1325340c0022SEd Maste 		printf("\tRangeIndex=%u\n", (u_int)sysaddr->RangeIndex);
1326340c0022SEd Maste 		printf("\tProximityDomain=%u\n",
1327340c0022SEd Maste 		    (u_int)sysaddr->ProximityDomain);
1328340c0022SEd Maste 		uuid_to_string((uuid_t *)(sysaddr->RangeGuid),
1329340c0022SEd Maste 		    &uuidstr, &status);
1330340c0022SEd Maste 		if (status != uuid_s_ok)
1331340c0022SEd Maste 			errx(1, "uuid_to_string: status=%u", status);
1332340c0022SEd Maste 		printf("\tRangeGuid=%s\n", uuidstr);
1333340c0022SEd Maste 		free(uuidstr);
1334340c0022SEd Maste 		printf("\tAddress=0x%016jx\n", (uintmax_t)sysaddr->Address);
1335340c0022SEd Maste 		printf("\tLength=0x%016jx\n", (uintmax_t)sysaddr->Length);
1336340c0022SEd Maste 		printf("\tMemoryMapping=0x%016jx\n",
1337340c0022SEd Maste 		    (uintmax_t)sysaddr->MemoryMapping);
1338340c0022SEd Maste 
1339340c0022SEd Maste #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_## flag, #flag)
1340340c0022SEd Maste 
1341340c0022SEd Maste 		printf("\tFlags=");
1342340c0022SEd Maste 		PRINTFLAG(sysaddr->Flags, ADD_ONLINE_ONLY);
1343340c0022SEd Maste 		PRINTFLAG(sysaddr->Flags, PROXIMITY_VALID);
1344340c0022SEd Maste 		PRINTFLAG_END();
1345340c0022SEd Maste 
1346340c0022SEd Maste #undef PRINTFLAG
1347340c0022SEd Maste 
1348340c0022SEd Maste 		break;
1349340c0022SEd Maste 	case ACPI_NFIT_TYPE_MEMORY_MAP:
1350340c0022SEd Maste 		mmap = (ACPI_NFIT_MEMORY_MAP *)nfit;
1351340c0022SEd Maste 		printf("\tDeviceHandle=%u\n", (u_int)mmap->DeviceHandle);
1352340c0022SEd Maste 		printf("\tPhysicalId=%u\n", (u_int)mmap->PhysicalId);
1353340c0022SEd Maste 		printf("\tRegionId=%u\n", (u_int)mmap->RegionId);
1354340c0022SEd Maste 		printf("\tRangeIndex=%u\n", (u_int)mmap->RangeIndex);
1355340c0022SEd Maste 		printf("\tRegionIndex=%u\n", (u_int)mmap->RegionIndex);
1356340c0022SEd Maste 		printf("\tRegionSize=0x%016jx\n", (uintmax_t)mmap->RegionSize);
1357340c0022SEd Maste 		printf("\tRegionOffset=0x%016jx\n",
1358340c0022SEd Maste 		    (uintmax_t)mmap->RegionOffset);
1359340c0022SEd Maste 		printf("\tAddress=0x%016jx\n", (uintmax_t)mmap->Address);
1360340c0022SEd Maste 		printf("\tInterleaveIndex=%u\n", (u_int)mmap->InterleaveIndex);
1361fb1cf2a9SAlexander Motin 		printf("\tInterleaveWays=%u\n", (u_int)mmap->InterleaveWays);
1362340c0022SEd Maste 
1363340c0022SEd Maste #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_MEM_## flag, #flag)
1364340c0022SEd Maste 
1365340c0022SEd Maste 		printf("\tFlags=");
1366340c0022SEd Maste 		PRINTFLAG(mmap->Flags, SAVE_FAILED);
1367340c0022SEd Maste 		PRINTFLAG(mmap->Flags, RESTORE_FAILED);
1368340c0022SEd Maste 		PRINTFLAG(mmap->Flags, FLUSH_FAILED);
1369340c0022SEd Maste 		PRINTFLAG(mmap->Flags, NOT_ARMED);
1370340c0022SEd Maste 		PRINTFLAG(mmap->Flags, HEALTH_OBSERVED);
1371340c0022SEd Maste 		PRINTFLAG(mmap->Flags, HEALTH_ENABLED);
1372340c0022SEd Maste 		PRINTFLAG(mmap->Flags, MAP_FAILED);
1373340c0022SEd Maste 		PRINTFLAG_END();
1374340c0022SEd Maste 
1375340c0022SEd Maste #undef PRINTFLAG
1376340c0022SEd Maste 
1377340c0022SEd Maste 		break;
1378340c0022SEd Maste 	case ACPI_NFIT_TYPE_INTERLEAVE:
1379340c0022SEd Maste 		ileave = (ACPI_NFIT_INTERLEAVE *)nfit;
1380340c0022SEd Maste 		printf("\tInterleaveIndex=%u\n",
1381340c0022SEd Maste 		    (u_int)ileave->InterleaveIndex);
1382340c0022SEd Maste 		printf("\tLineCount=%u\n", (u_int)ileave->LineCount);
1383340c0022SEd Maste 		printf("\tLineSize=%u\n", (u_int)ileave->LineSize);
1384340c0022SEd Maste 		/* XXX ileave->LineOffset[i] output is not supported */
1385340c0022SEd Maste 		break;
1386340c0022SEd Maste 	case ACPI_NFIT_TYPE_SMBIOS:
1387340c0022SEd Maste 		smbios = (ACPI_NFIT_SMBIOS *)nfit;
1388340c0022SEd Maste 		/* XXX smbios->Data[x] output is not supported */
1389340c0022SEd Maste 		break;
1390340c0022SEd Maste 	case ACPI_NFIT_TYPE_CONTROL_REGION:
1391340c0022SEd Maste 		ctlreg = (ACPI_NFIT_CONTROL_REGION *)nfit;
1392340c0022SEd Maste 		printf("\tRegionIndex=%u\n", (u_int)ctlreg->RegionIndex);
1393340c0022SEd Maste 		printf("\tVendorId=0x%04x\n", (u_int)ctlreg->VendorId);
1394340c0022SEd Maste 		printf("\tDeviceId=0x%04x\n", (u_int)ctlreg->DeviceId);
1395340c0022SEd Maste 		printf("\tRevisionId=%u\n", (u_int)ctlreg->RevisionId);
1396340c0022SEd Maste 		printf("\tSubsystemVendorId=0x%04x\n",
1397340c0022SEd Maste 		    (u_int)ctlreg->SubsystemVendorId);
1398340c0022SEd Maste 		printf("\tSubsystemDeviceId=0x%04x\n",
1399340c0022SEd Maste 		    (u_int)ctlreg->SubsystemDeviceId);
1400340c0022SEd Maste 		printf("\tSubsystemRevisionId=%u\n",
1401340c0022SEd Maste 		    (u_int)ctlreg->SubsystemRevisionId);
1402d4c2de2eSAlexander Motin 		printf("\tValidFields=0x%02x\n", (u_int)ctlreg->ValidFields);
1403340c0022SEd Maste 		printf("\tManufacturingLocation=%u\n",
1404340c0022SEd Maste 		    (u_int)ctlreg->ManufacturingLocation);
1405340c0022SEd Maste 		printf("\tManufacturingDate=%u\n",
1406340c0022SEd Maste 		    (u_int)ctlreg->ManufacturingDate);
1407340c0022SEd Maste 		printf("\tSerialNumber=%u\n",
1408340c0022SEd Maste 		    (u_int)ctlreg->SerialNumber);
1409fb1cf2a9SAlexander Motin 		printf("\tCode=0x%04x\n", (u_int)ctlreg->Code);
1410340c0022SEd Maste 		printf("\tWindows=%u\n", (u_int)ctlreg->Windows);
1411340c0022SEd Maste 		printf("\tWindowSize=0x%016jx\n",
1412340c0022SEd Maste 		    (uintmax_t)ctlreg->WindowSize);
1413340c0022SEd Maste 		printf("\tCommandOffset=0x%016jx\n",
1414340c0022SEd Maste 		    (uintmax_t)ctlreg->CommandOffset);
1415340c0022SEd Maste 		printf("\tCommandSize=0x%016jx\n",
1416340c0022SEd Maste 		    (uintmax_t)ctlreg->CommandSize);
1417340c0022SEd Maste 		printf("\tStatusOffset=0x%016jx\n",
1418340c0022SEd Maste 		    (uintmax_t)ctlreg->StatusOffset);
1419340c0022SEd Maste 		printf("\tStatusSize=0x%016jx\n",
1420340c0022SEd Maste 		    (uintmax_t)ctlreg->StatusSize);
1421340c0022SEd Maste 
1422340c0022SEd Maste #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_## flag, #flag)
1423340c0022SEd Maste 
1424340c0022SEd Maste 		printf("\tFlags=");
1425d4c2de2eSAlexander Motin 		PRINTFLAG(ctlreg->Flags, CONTROL_BUFFERED);
1426340c0022SEd Maste 		PRINTFLAG_END();
1427340c0022SEd Maste 
1428340c0022SEd Maste #undef PRINTFLAG
1429340c0022SEd Maste 
1430340c0022SEd Maste 		break;
1431340c0022SEd Maste 	case ACPI_NFIT_TYPE_DATA_REGION:
1432340c0022SEd Maste 		datareg = (ACPI_NFIT_DATA_REGION *)nfit;
1433340c0022SEd Maste 		printf("\tRegionIndex=%u\n", (u_int)datareg->RegionIndex);
1434340c0022SEd Maste 		printf("\tWindows=%u\n", (u_int)datareg->Windows);
1435340c0022SEd Maste 		printf("\tOffset=0x%016jx\n", (uintmax_t)datareg->Offset);
1436340c0022SEd Maste 		printf("\tSize=0x%016jx\n", (uintmax_t)datareg->Size);
1437340c0022SEd Maste 		printf("\tCapacity=0x%016jx\n", (uintmax_t)datareg->Capacity);
1438340c0022SEd Maste 		printf("\tStartAddress=0x%016jx\n",
1439340c0022SEd Maste 		    (uintmax_t)datareg->StartAddress);
1440340c0022SEd Maste 		break;
1441340c0022SEd Maste 	case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
1442340c0022SEd Maste 		fladdr = (ACPI_NFIT_FLUSH_ADDRESS *)nfit;
1443340c0022SEd Maste 		printf("\tDeviceHandle=%u\n", (u_int)fladdr->DeviceHandle);
1444340c0022SEd Maste 		printf("\tHintCount=%u\n", (u_int)fladdr->HintCount);
1445340c0022SEd Maste 		/* XXX fladdr->HintAddress[i] output is not supported */
1446340c0022SEd Maste 		break;
1447340c0022SEd Maste 	}
1448340c0022SEd Maste }
1449340c0022SEd Maste 
1450340c0022SEd Maste static void
1451340c0022SEd Maste acpi_handle_nfit(ACPI_TABLE_HEADER *sdp)
1452340c0022SEd Maste {
1453340c0022SEd Maste 	ACPI_TABLE_NFIT *nfit;
1454340c0022SEd Maste 
1455340c0022SEd Maste 	printf(BEGIN_COMMENT);
1456340c0022SEd Maste 	acpi_print_sdt(sdp);
1457340c0022SEd Maste 	nfit = (ACPI_TABLE_NFIT *)sdp;
1458340c0022SEd Maste 	acpi_walk_nfit(sdp, (nfit + 1), acpi_print_nfit);
1459340c0022SEd Maste 	printf(END_COMMENT);
1460340c0022SEd Maste }
1461340c0022SEd Maste 
1462a0333ad1SJohn Baldwin static void
1463986dffafSJohn Baldwin acpi_print_sdt(ACPI_TABLE_HEADER *sdp)
1464c62f1cccSMitsuru IWASAKI {
1465773b6454SNate Lawson 	printf("  ");
1466*278f0de6SJung-uk Kim 	acpi_print_string(sdp->Signature, ACPI_NAMESEG_SIZE);
1467c62f1cccSMitsuru IWASAKI 	printf(": Length=%d, Revision=%d, Checksum=%d,\n",
1468986dffafSJohn Baldwin 	       sdp->Length, sdp->Revision, sdp->Checksum);
1469e1e9a4bfSMitsuru IWASAKI 	printf("\tOEMID=");
1470986dffafSJohn Baldwin 	acpi_print_string(sdp->OemId, ACPI_OEM_ID_SIZE);
1471e1e9a4bfSMitsuru IWASAKI 	printf(", OEM Table ID=");
1472986dffafSJohn Baldwin 	acpi_print_string(sdp->OemTableId, ACPI_OEM_TABLE_ID_SIZE);
1473986dffafSJohn Baldwin 	printf(", OEM Revision=0x%x,\n", sdp->OemRevision);
1474e1e9a4bfSMitsuru IWASAKI 	printf("\tCreator ID=");
1475*278f0de6SJung-uk Kim 	acpi_print_string(sdp->AslCompilerId, ACPI_NAMESEG_SIZE);
1476986dffafSJohn Baldwin 	printf(", Creator Revision=0x%x\n", sdp->AslCompilerRevision);
1477e1e9a4bfSMitsuru IWASAKI }
1478e1e9a4bfSMitsuru IWASAKI 
1479945137d9SNate Lawson static void
1480986dffafSJohn Baldwin acpi_print_rsdt(ACPI_TABLE_HEADER *rsdp)
1481e1e9a4bfSMitsuru IWASAKI {
1482986dffafSJohn Baldwin 	ACPI_TABLE_RSDT *rsdt;
1483986dffafSJohn Baldwin 	ACPI_TABLE_XSDT *xsdt;
1484e1e9a4bfSMitsuru IWASAKI 	int	i, entries;
1485e1e9a4bfSMitsuru IWASAKI 
1486986dffafSJohn Baldwin 	rsdt = (ACPI_TABLE_RSDT *)rsdp;
1487986dffafSJohn Baldwin 	xsdt = (ACPI_TABLE_XSDT *)rsdp;
1488773b6454SNate Lawson 	printf(BEGIN_COMMENT);
1489773b6454SNate Lawson 	acpi_print_sdt(rsdp);
1490986dffafSJohn Baldwin 	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
1491e1e9a4bfSMitsuru IWASAKI 	printf("\tEntries={ ");
1492e1e9a4bfSMitsuru IWASAKI 	for (i = 0; i < entries; i++) {
1493e1e9a4bfSMitsuru IWASAKI 		if (i > 0)
1494e1e9a4bfSMitsuru IWASAKI 			printf(", ");
1495fe1d0c2dSJung-uk Kim 		if (addr_size == 4)
14967d369c6eSJung-uk Kim 			printf("0x%08x", le32toh(rsdt->TableOffsetEntry[i]));
1497fe1d0c2dSJung-uk Kim 		else
14987d369c6eSJung-uk Kim 			printf("0x%016jx",
14997d369c6eSJung-uk Kim 			    (uintmax_t)le64toh(xsdt->TableOffsetEntry[i]));
1500e1e9a4bfSMitsuru IWASAKI 	}
1501e1e9a4bfSMitsuru IWASAKI 	printf(" }\n");
1502c62f1cccSMitsuru IWASAKI 	printf(END_COMMENT);
1503e1e9a4bfSMitsuru IWASAKI }
1504e1e9a4bfSMitsuru IWASAKI 
15058e6a8737SNate Lawson static const char *acpi_pm_profiles[] = {
15068e6a8737SNate Lawson 	"Unspecified", "Desktop", "Mobile", "Workstation",
15078e6a8737SNate Lawson 	"Enterprise Server", "SOHO Server", "Appliance PC"
15088e6a8737SNate Lawson };
15098e6a8737SNate Lawson 
1510945137d9SNate Lawson static void
1511986dffafSJohn Baldwin acpi_print_fadt(ACPI_TABLE_HEADER *sdp)
1512e1e9a4bfSMitsuru IWASAKI {
1513986dffafSJohn Baldwin 	ACPI_TABLE_FADT *fadt;
15148e6a8737SNate Lawson 	const char *pm;
1515e1e9a4bfSMitsuru IWASAKI 
1516986dffafSJohn Baldwin 	fadt = (ACPI_TABLE_FADT *)sdp;
1517c62f1cccSMitsuru IWASAKI 	printf(BEGIN_COMMENT);
15182177d4e6SNate Lawson 	acpi_print_sdt(sdp);
1519986dffafSJohn Baldwin 	printf(" \tFACS=0x%x, DSDT=0x%x\n", fadt->Facs,
1520986dffafSJohn Baldwin 	       fadt->Dsdt);
1521986dffafSJohn Baldwin 	printf("\tINT_MODEL=%s\n", fadt->Model ? "APIC" : "PIC");
1522986dffafSJohn Baldwin 	if (fadt->PreferredProfile >= sizeof(acpi_pm_profiles) / sizeof(char *))
15238e6a8737SNate Lawson 		pm = "Reserved";
15248e6a8737SNate Lawson 	else
1525986dffafSJohn Baldwin 		pm = acpi_pm_profiles[fadt->PreferredProfile];
1526986dffafSJohn Baldwin 	printf("\tPreferred_PM_Profile=%s (%d)\n", pm, fadt->PreferredProfile);
1527986dffafSJohn Baldwin 	printf("\tSCI_INT=%d\n", fadt->SciInterrupt);
1528986dffafSJohn Baldwin 	printf("\tSMI_CMD=0x%x, ", fadt->SmiCommand);
1529986dffafSJohn Baldwin 	printf("ACPI_ENABLE=0x%x, ", fadt->AcpiEnable);
1530986dffafSJohn Baldwin 	printf("ACPI_DISABLE=0x%x, ", fadt->AcpiDisable);
1531986dffafSJohn Baldwin 	printf("S4BIOS_REQ=0x%x\n", fadt->S4BiosRequest);
1532986dffafSJohn Baldwin 	printf("\tPSTATE_CNT=0x%x\n", fadt->PstateControl);
1533e1e9a4bfSMitsuru IWASAKI 	printf("\tPM1a_EVT_BLK=0x%x-0x%x\n",
1534986dffafSJohn Baldwin 	       fadt->Pm1aEventBlock,
1535986dffafSJohn Baldwin 	       fadt->Pm1aEventBlock + fadt->Pm1EventLength - 1);
1536986dffafSJohn Baldwin 	if (fadt->Pm1bEventBlock != 0)
1537e1e9a4bfSMitsuru IWASAKI 		printf("\tPM1b_EVT_BLK=0x%x-0x%x\n",
1538986dffafSJohn Baldwin 		       fadt->Pm1bEventBlock,
1539986dffafSJohn Baldwin 		       fadt->Pm1bEventBlock + fadt->Pm1EventLength - 1);
1540e1e9a4bfSMitsuru IWASAKI 	printf("\tPM1a_CNT_BLK=0x%x-0x%x\n",
1541986dffafSJohn Baldwin 	       fadt->Pm1aControlBlock,
1542986dffafSJohn Baldwin 	       fadt->Pm1aControlBlock + fadt->Pm1ControlLength - 1);
1543986dffafSJohn Baldwin 	if (fadt->Pm1bControlBlock != 0)
1544e1e9a4bfSMitsuru IWASAKI 		printf("\tPM1b_CNT_BLK=0x%x-0x%x\n",
1545986dffafSJohn Baldwin 		       fadt->Pm1bControlBlock,
1546986dffafSJohn Baldwin 		       fadt->Pm1bControlBlock + fadt->Pm1ControlLength - 1);
1547986dffafSJohn Baldwin 	if (fadt->Pm2ControlBlock != 0)
1548e1e9a4bfSMitsuru IWASAKI 		printf("\tPM2_CNT_BLK=0x%x-0x%x\n",
1549986dffafSJohn Baldwin 		       fadt->Pm2ControlBlock,
1550986dffafSJohn Baldwin 		       fadt->Pm2ControlBlock + fadt->Pm2ControlLength - 1);
1551c08c4e81SNate Lawson 	printf("\tPM_TMR_BLK=0x%x-0x%x\n",
1552986dffafSJohn Baldwin 	       fadt->PmTimerBlock,
1553986dffafSJohn Baldwin 	       fadt->PmTimerBlock + fadt->PmTimerLength - 1);
1554986dffafSJohn Baldwin 	if (fadt->Gpe0Block != 0)
15558e6a8737SNate Lawson 		printf("\tGPE0_BLK=0x%x-0x%x\n",
1556986dffafSJohn Baldwin 		       fadt->Gpe0Block,
1557986dffafSJohn Baldwin 		       fadt->Gpe0Block + fadt->Gpe0BlockLength - 1);
1558986dffafSJohn Baldwin 	if (fadt->Gpe1Block != 0)
15598e6a8737SNate Lawson 		printf("\tGPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n",
1560986dffafSJohn Baldwin 		       fadt->Gpe1Block,
1561986dffafSJohn Baldwin 		       fadt->Gpe1Block + fadt->Gpe1BlockLength - 1,
1562986dffafSJohn Baldwin 		       fadt->Gpe1Base);
1563986dffafSJohn Baldwin 	if (fadt->CstControl != 0)
1564986dffafSJohn Baldwin 		printf("\tCST_CNT=0x%x\n", fadt->CstControl);
156551c1824fSNate Lawson 	printf("\tP_LVL2_LAT=%d us, P_LVL3_LAT=%d us\n",
1566986dffafSJohn Baldwin 	       fadt->C2Latency, fadt->C3Latency);
1567e1e9a4bfSMitsuru IWASAKI 	printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n",
1568986dffafSJohn Baldwin 	       fadt->FlushSize, fadt->FlushStride);
1569e1e9a4bfSMitsuru IWASAKI 	printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n",
1570986dffafSJohn Baldwin 	       fadt->DutyOffset, fadt->DutyWidth);
1571e1e9a4bfSMitsuru IWASAKI 	printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n",
1572986dffafSJohn Baldwin 	       fadt->DayAlarm, fadt->MonthAlarm, fadt->Century);
1573e1e9a4bfSMitsuru IWASAKI 
1574ec650989SNeel Natu #define PRINTFLAG(var, flag)	printflag((var), ACPI_FADT_## flag, #flag)
1575e1e9a4bfSMitsuru IWASAKI 
15768e6a8737SNate Lawson 	printf("\tIAPC_BOOT_ARCH=");
1577986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, LEGACY_DEVICES);
1578986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, 8042);
1579986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, NO_VGA);
1580986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, NO_MSI);
1581986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, NO_ASPM);
1582f6469ce1SAndrew Turner 	PRINTFLAG(fadt->BootFlags, NO_CMOS_RTC);
1583ec650989SNeel Natu 	PRINTFLAG_END();
15848e6a8737SNate Lawson 
15858e6a8737SNate Lawson 	printf("\tFlags=");
1586986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, WBINVD);
1587986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, WBINVD_FLUSH);
1588986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, C1_SUPPORTED);
1589986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, C2_MP_SUPPORTED);
1590986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, POWER_BUTTON);
1591986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, SLEEP_BUTTON);
1592986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, FIXED_RTC);
1593986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, S4_RTC_WAKE);
1594986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, 32BIT_TIMER);
1595986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, DOCKING_SUPPORTED);
1596986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, RESET_REGISTER);
1597986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, SEALED_CASE);
1598986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, HEADLESS);
1599986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, SLEEP_TYPE);
1600986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, PCI_EXPRESS_WAKE);
1601986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, PLATFORM_CLOCK);
1602986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, S4_RTC_VALID);
1603986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, REMOTE_POWER_ON);
1604986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, APIC_CLUSTER);
1605986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, APIC_PHYSICAL);
1606f6469ce1SAndrew Turner 	PRINTFLAG(fadt->Flags, HW_REDUCED);
1607f6469ce1SAndrew Turner 	PRINTFLAG(fadt->Flags, LOW_POWER_S0);
1608ec650989SNeel Natu 	PRINTFLAG_END();
1609e1e9a4bfSMitsuru IWASAKI 
1610e1e9a4bfSMitsuru IWASAKI #undef PRINTFLAG
1611e1e9a4bfSMitsuru IWASAKI 
1612986dffafSJohn Baldwin 	if (fadt->Flags & ACPI_FADT_RESET_REGISTER) {
16138e6a8737SNate Lawson 		printf("\tRESET_REG=");
1614986dffafSJohn Baldwin 		acpi_print_gas(&fadt->ResetRegister);
1615986dffafSJohn Baldwin 		printf(", RESET_VALUE=%#x\n", fadt->ResetValue);
16168e6a8737SNate Lawson 	}
1617c2962974SNate Lawson 	if (acpi_get_fadt_revision(fadt) > 1) {
16187d369c6eSJung-uk Kim 		printf("\tX_FACS=0x%016jx, ", (uintmax_t)fadt->XFacs);
16197d369c6eSJung-uk Kim 		printf("X_DSDT=0x%016jx\n", (uintmax_t)fadt->XDsdt);
1620c08c4e81SNate Lawson 		printf("\tX_PM1a_EVT_BLK=");
1621986dffafSJohn Baldwin 		acpi_print_gas(&fadt->XPm1aEventBlock);
1622986dffafSJohn Baldwin 		if (fadt->XPm1bEventBlock.Address != 0) {
1623c08c4e81SNate Lawson 			printf("\n\tX_PM1b_EVT_BLK=");
1624986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XPm1bEventBlock);
1625c08c4e81SNate Lawson 		}
1626c08c4e81SNate Lawson 		printf("\n\tX_PM1a_CNT_BLK=");
1627986dffafSJohn Baldwin 		acpi_print_gas(&fadt->XPm1aControlBlock);
1628986dffafSJohn Baldwin 		if (fadt->XPm1bControlBlock.Address != 0) {
1629c08c4e81SNate Lawson 			printf("\n\tX_PM1b_CNT_BLK=");
1630986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XPm1bControlBlock);
1631c08c4e81SNate Lawson 		}
1632986dffafSJohn Baldwin 		if (fadt->XPm2ControlBlock.Address != 0) {
1633773b6454SNate Lawson 			printf("\n\tX_PM2_CNT_BLK=");
1634986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XPm2ControlBlock);
1635c08c4e81SNate Lawson 		}
1636773b6454SNate Lawson 		printf("\n\tX_PM_TMR_BLK=");
1637986dffafSJohn Baldwin 		acpi_print_gas(&fadt->XPmTimerBlock);
1638986dffafSJohn Baldwin 		if (fadt->XGpe0Block.Address != 0) {
1639773b6454SNate Lawson 			printf("\n\tX_GPE0_BLK=");
1640986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XGpe0Block);
1641c08c4e81SNate Lawson 		}
1642986dffafSJohn Baldwin 		if (fadt->XGpe1Block.Address != 0) {
1643773b6454SNate Lawson 			printf("\n\tX_GPE1_BLK=");
1644986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XGpe1Block);
1645c08c4e81SNate Lawson 		}
1646773b6454SNate Lawson 		printf("\n");
1647773b6454SNate Lawson 	}
16488e6a8737SNate Lawson 
16498e6a8737SNate Lawson 	printf(END_COMMENT);
16508e6a8737SNate Lawson }
16518e6a8737SNate Lawson 
16528e6a8737SNate Lawson static void
1653986dffafSJohn Baldwin acpi_print_facs(ACPI_TABLE_FACS *facs)
16548e6a8737SNate Lawson {
16558e6a8737SNate Lawson 	printf(BEGIN_COMMENT);
1656986dffafSJohn Baldwin 	printf("  FACS:\tLength=%u, ", facs->Length);
1657986dffafSJohn Baldwin 	printf("HwSig=0x%08x, ", facs->HardwareSignature);
1658986dffafSJohn Baldwin 	printf("Firm_Wake_Vec=0x%08x\n", facs->FirmwareWakingVector);
16598e6a8737SNate Lawson 
1660773b6454SNate Lawson 	printf("\tGlobal_Lock=");
1661986dffafSJohn Baldwin 	if (facs->GlobalLock != 0) {
1662986dffafSJohn Baldwin 		if (facs->GlobalLock & ACPI_GLOCK_PENDING)
16638e6a8737SNate Lawson 			printf("PENDING,");
1664986dffafSJohn Baldwin 		if (facs->GlobalLock & ACPI_GLOCK_OWNED)
16658e6a8737SNate Lawson 			printf("OWNED");
16668e6a8737SNate Lawson 	}
1667773b6454SNate Lawson 	printf("\n");
16688e6a8737SNate Lawson 
1669773b6454SNate Lawson 	printf("\tFlags=");
1670986dffafSJohn Baldwin 	if (facs->Flags & ACPI_FACS_S4_BIOS_PRESENT)
16718e6a8737SNate Lawson 		printf("S4BIOS");
1672773b6454SNate Lawson 	printf("\n");
16738e6a8737SNate Lawson 
16747d369c6eSJung-uk Kim 	if (facs->XFirmwareWakingVector != 0)
16757d369c6eSJung-uk Kim 		printf("\tX_Firm_Wake_Vec=%016jx\n",
16767d369c6eSJung-uk Kim 		    (uintmax_t)facs->XFirmwareWakingVector);
1677986dffafSJohn Baldwin 	printf("\tVersion=%u\n", facs->Version);
16788e6a8737SNate Lawson 
1679c62f1cccSMitsuru IWASAKI 	printf(END_COMMENT);
1680e1e9a4bfSMitsuru IWASAKI }
1681e1e9a4bfSMitsuru IWASAKI 
1682945137d9SNate Lawson static void
1683986dffafSJohn Baldwin acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp)
1684e1e9a4bfSMitsuru IWASAKI {
1685773b6454SNate Lawson 	printf(BEGIN_COMMENT);
1686773b6454SNate Lawson 	acpi_print_sdt(dsdp);
1687773b6454SNate Lawson 	printf(END_COMMENT);
1688e1e9a4bfSMitsuru IWASAKI }
1689e1e9a4bfSMitsuru IWASAKI 
1690e1e9a4bfSMitsuru IWASAKI int
1691e1e9a4bfSMitsuru IWASAKI acpi_checksum(void *p, size_t length)
1692e1e9a4bfSMitsuru IWASAKI {
1693986dffafSJohn Baldwin 	uint8_t *bp;
1694986dffafSJohn Baldwin 	uint8_t sum;
1695e1e9a4bfSMitsuru IWASAKI 
1696e1e9a4bfSMitsuru IWASAKI 	bp = p;
1697e1e9a4bfSMitsuru IWASAKI 	sum = 0;
1698e1e9a4bfSMitsuru IWASAKI 	while (length--)
1699e1e9a4bfSMitsuru IWASAKI 		sum += *bp++;
1700e1e9a4bfSMitsuru IWASAKI 
1701e1e9a4bfSMitsuru IWASAKI 	return (sum);
1702e1e9a4bfSMitsuru IWASAKI }
1703e1e9a4bfSMitsuru IWASAKI 
1704986dffafSJohn Baldwin static ACPI_TABLE_HEADER *
1705e1e9a4bfSMitsuru IWASAKI acpi_map_sdt(vm_offset_t pa)
1706e1e9a4bfSMitsuru IWASAKI {
1707986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *sp;
1708e1e9a4bfSMitsuru IWASAKI 
1709986dffafSJohn Baldwin 	sp = acpi_map_physical(pa, sizeof(ACPI_TABLE_HEADER));
1710986dffafSJohn Baldwin 	sp = acpi_map_physical(pa, sp->Length);
1711e1e9a4bfSMitsuru IWASAKI 	return (sp);
1712e1e9a4bfSMitsuru IWASAKI }
1713e1e9a4bfSMitsuru IWASAKI 
1714945137d9SNate Lawson static void
1715986dffafSJohn Baldwin acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp)
1716e1e9a4bfSMitsuru IWASAKI {
1717c62f1cccSMitsuru IWASAKI 	printf(BEGIN_COMMENT);
1718a74172abSNate Lawson 	printf("  RSD PTR: OEM=");
1719986dffafSJohn Baldwin 	acpi_print_string(rp->OemId, ACPI_OEM_ID_SIZE);
1720986dffafSJohn Baldwin 	printf(", ACPI_Rev=%s (%d)\n", rp->Revision < 2 ? "1.0x" : "2.0x",
1721986dffafSJohn Baldwin 	       rp->Revision);
1722986dffafSJohn Baldwin 	if (rp->Revision < 2) {
1723986dffafSJohn Baldwin 		printf("\tRSDT=0x%08x, cksum=%u\n", rp->RsdtPhysicalAddress,
1724986dffafSJohn Baldwin 		    rp->Checksum);
1725a74172abSNate Lawson 	} else {
17267d369c6eSJung-uk Kim 		printf("\tXSDT=0x%016jx, length=%u, cksum=%u\n",
17277d369c6eSJung-uk Kim 		    (uintmax_t)rp->XsdtPhysicalAddress, rp->Length,
1728986dffafSJohn Baldwin 		    rp->ExtendedChecksum);
1729a74172abSNate Lawson 	}
1730c62f1cccSMitsuru IWASAKI 	printf(END_COMMENT);
1731e1e9a4bfSMitsuru IWASAKI }
1732e1e9a4bfSMitsuru IWASAKI 
1733945137d9SNate Lawson static void
1734986dffafSJohn Baldwin acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp)
1735e1e9a4bfSMitsuru IWASAKI {
1736986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *sdp;
1737986dffafSJohn Baldwin 	ACPI_TABLE_RSDT *rsdt;
1738986dffafSJohn Baldwin 	ACPI_TABLE_XSDT *xsdt;
1739a74172abSNate Lawson 	vm_offset_t addr;
1740a74172abSNate Lawson 	int entries, i;
1741e1e9a4bfSMitsuru IWASAKI 
1742e1e9a4bfSMitsuru IWASAKI 	acpi_print_rsdt(rsdp);
1743986dffafSJohn Baldwin 	rsdt = (ACPI_TABLE_RSDT *)rsdp;
1744986dffafSJohn Baldwin 	xsdt = (ACPI_TABLE_XSDT *)rsdp;
1745986dffafSJohn Baldwin 	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
1746e1e9a4bfSMitsuru IWASAKI 	for (i = 0; i < entries; i++) {
1747fe1d0c2dSJung-uk Kim 		if (addr_size == 4)
1748986dffafSJohn Baldwin 			addr = le32toh(rsdt->TableOffsetEntry[i]);
1749fe1d0c2dSJung-uk Kim 		else
1750986dffafSJohn Baldwin 			addr = le64toh(xsdt->TableOffsetEntry[i]);
1751fe1d0c2dSJung-uk Kim 		if (addr == 0)
1752fe1d0c2dSJung-uk Kim 			continue;
1753986dffafSJohn Baldwin 		sdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
1754986dffafSJohn Baldwin 		if (acpi_checksum(sdp, sdp->Length)) {
17555cf6d493SNate Lawson 			warnx("RSDT entry %d (sig %.4s) is corrupt", i,
1756986dffafSJohn Baldwin 			    sdp->Signature);
17575cf6d493SNate Lawson 			continue;
17585cf6d493SNate Lawson 		}
1759986dffafSJohn Baldwin 		if (!memcmp(sdp->Signature, ACPI_SIG_FADT, 4))
17602177d4e6SNate Lawson 			acpi_handle_fadt(sdp);
1761986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_MADT, 4))
1762986dffafSJohn Baldwin 			acpi_handle_madt(sdp);
1763986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_HPET, 4))
176479d7565cSPeter Wemm 			acpi_handle_hpet(sdp);
1765986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_ECDT, 4))
176655d7ff9eSNate Lawson 			acpi_handle_ecdt(sdp);
1767986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_MCFG, 4))
1768a47e681bSScott Long 			acpi_handle_mcfg(sdp);
176933866658SJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_SLIT, 4))
177033866658SJohn Baldwin 			acpi_handle_slit(sdp);
1771986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_SRAT, 4))
1772a0333ad1SJohn Baldwin 			acpi_handle_srat(sdp);
1773c031c93bSTakanori Watanabe 		else if (!memcmp(sdp->Signature, ACPI_SIG_TCPA, 4))
1774c031c93bSTakanori Watanabe 			acpi_handle_tcpa(sdp);
1775ec650989SNeel Natu 		else if (!memcmp(sdp->Signature, ACPI_SIG_DMAR, 4))
1776ec650989SNeel Natu 			acpi_handle_dmar(sdp);
1777340c0022SEd Maste 		else if (!memcmp(sdp->Signature, ACPI_SIG_NFIT, 4))
1778340c0022SEd Maste 			acpi_handle_nfit(sdp);
1779ed26c389SScott Long 		else if (!memcmp(sdp->Signature, ACPI_SIG_WDDT, 4))
1780ed26c389SScott Long 			acpi_handle_wddt(sdp);
17815857fba5SBen Widawsky 		else if (!memcmp(sdp->Signature, ACPI_SIG_LPIT, 4))
17825857fba5SBen Widawsky 			acpi_handle_lpit(sdp);
1783877fc2e3STakanori Watanabe 		else if (!memcmp(sdp->Signature, ACPI_SIG_TPM2, 4))
1784877fc2e3STakanori Watanabe 			acpi_handle_tpm2(sdp);
1785773b6454SNate Lawson 		else {
1786773b6454SNate Lawson 			printf(BEGIN_COMMENT);
1787773b6454SNate Lawson 			acpi_print_sdt(sdp);
1788773b6454SNate Lawson 			printf(END_COMMENT);
1789773b6454SNate Lawson 		}
1790e1e9a4bfSMitsuru IWASAKI 	}
1791e1e9a4bfSMitsuru IWASAKI }
1792c62f1cccSMitsuru IWASAKI 
1793986dffafSJohn Baldwin ACPI_TABLE_HEADER *
1794476daaecSDag-Erling Smørgrav sdt_load_devmem(void)
1795945137d9SNate Lawson {
1796986dffafSJohn Baldwin 	ACPI_TABLE_RSDP *rp;
1797986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *rsdp;
1798945137d9SNate Lawson 
1799945137d9SNate Lawson 	rp = acpi_find_rsd_ptr();
1800945137d9SNate Lawson 	if (!rp)
1801945137d9SNate Lawson 		errx(1, "Can't find ACPI information");
1802945137d9SNate Lawson 
1803945137d9SNate Lawson 	if (tflag)
1804945137d9SNate Lawson 		acpi_print_rsd_ptr(rp);
1805986dffafSJohn Baldwin 	if (rp->Revision < 2) {
1806986dffafSJohn Baldwin 		rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->RsdtPhysicalAddress);
1807986dffafSJohn Baldwin 		if (memcmp(rsdp->Signature, "RSDT", 4) != 0 ||
1808986dffafSJohn Baldwin 		    acpi_checksum(rsdp, rsdp->Length) != 0)
1809945137d9SNate Lawson 			errx(1, "RSDT is corrupted");
1810a74172abSNate Lawson 		addr_size = sizeof(uint32_t);
1811a74172abSNate Lawson 	} else {
1812986dffafSJohn Baldwin 		rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->XsdtPhysicalAddress);
1813986dffafSJohn Baldwin 		if (memcmp(rsdp->Signature, "XSDT", 4) != 0 ||
1814986dffafSJohn Baldwin 		    acpi_checksum(rsdp, rsdp->Length) != 0)
1815a74172abSNate Lawson 			errx(1, "XSDT is corrupted");
1816a74172abSNate Lawson 		addr_size = sizeof(uint64_t);
1817a74172abSNate Lawson 	}
1818945137d9SNate Lawson 	return (rsdp);
1819945137d9SNate Lawson }
1820c62f1cccSMitsuru IWASAKI 
182162c7bde1SNate Lawson /* Write the DSDT to a file, concatenating any SSDTs (if present). */
1822bfa3f012SMarcel Moolenaar static int
1823986dffafSJohn Baldwin write_dsdt(int fd, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdt)
1824bfa3f012SMarcel Moolenaar {
1825986dffafSJohn Baldwin 	ACPI_TABLE_HEADER sdt;
1826986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *ssdt;
1827bfa3f012SMarcel Moolenaar 	uint8_t sum;
1828bfa3f012SMarcel Moolenaar 
182962c7bde1SNate Lawson 	/* Create a new checksum to account for the DSDT and any SSDTs. */
1830bfa3f012SMarcel Moolenaar 	sdt = *dsdt;
1831bfa3f012SMarcel Moolenaar 	if (rsdt != NULL) {
1832986dffafSJohn Baldwin 		sdt.Checksum = 0;
1833986dffafSJohn Baldwin 		sum = acpi_checksum(dsdt + 1, dsdt->Length -
1834986dffafSJohn Baldwin 		    sizeof(ACPI_TABLE_HEADER));
1835986dffafSJohn Baldwin 		ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, NULL);
1836f7675a56SNate Lawson 		while (ssdt != NULL) {
1837986dffafSJohn Baldwin 			sdt.Length += ssdt->Length - sizeof(ACPI_TABLE_HEADER);
1838986dffafSJohn Baldwin 			sum += acpi_checksum(ssdt + 1,
1839986dffafSJohn Baldwin 			    ssdt->Length - sizeof(ACPI_TABLE_HEADER));
1840986dffafSJohn Baldwin 			ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, ssdt);
1841bfa3f012SMarcel Moolenaar 		}
1842986dffafSJohn Baldwin 		sum += acpi_checksum(&sdt, sizeof(ACPI_TABLE_HEADER));
1843986dffafSJohn Baldwin 		sdt.Checksum -= sum;
1844bfa3f012SMarcel Moolenaar 	}
184562c7bde1SNate Lawson 
184662c7bde1SNate Lawson 	/* Write out the DSDT header and body. */
1847986dffafSJohn Baldwin 	write(fd, &sdt, sizeof(ACPI_TABLE_HEADER));
1848986dffafSJohn Baldwin 	write(fd, dsdt + 1, dsdt->Length - sizeof(ACPI_TABLE_HEADER));
184962c7bde1SNate Lawson 
1850b64e1b67SNate Lawson 	/* Write out any SSDTs (if present.) */
1851f7675a56SNate Lawson 	if (rsdt != NULL) {
1852bfa3f012SMarcel Moolenaar 		ssdt = sdt_from_rsdt(rsdt, "SSDT", NULL);
1853bfa3f012SMarcel Moolenaar 		while (ssdt != NULL) {
1854986dffafSJohn Baldwin 			write(fd, ssdt + 1, ssdt->Length -
1855986dffafSJohn Baldwin 			    sizeof(ACPI_TABLE_HEADER));
1856bfa3f012SMarcel Moolenaar 			ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt);
1857bfa3f012SMarcel Moolenaar 		}
1858bfa3f012SMarcel Moolenaar 	}
1859bfa3f012SMarcel Moolenaar 	return (0);
1860bfa3f012SMarcel Moolenaar }
1861bfa3f012SMarcel Moolenaar 
1862c62f1cccSMitsuru IWASAKI void
1863986dffafSJohn Baldwin dsdt_save_file(char *outfile, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
1864c62f1cccSMitsuru IWASAKI {
1865945137d9SNate Lawson 	int	fd;
1866945137d9SNate Lawson 	mode_t	mode;
1867945137d9SNate Lawson 
1868945137d9SNate Lawson 	assert(outfile != NULL);
1869945137d9SNate Lawson 	mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
1870945137d9SNate Lawson 	fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, mode);
1871945137d9SNate Lawson 	if (fd == -1) {
1872945137d9SNate Lawson 		perror("dsdt_save_file");
1873945137d9SNate Lawson 		return;
1874945137d9SNate Lawson 	}
1875bfa3f012SMarcel Moolenaar 	write_dsdt(fd, rsdt, dsdp);
1876945137d9SNate Lawson 	close(fd);
1877c62f1cccSMitsuru IWASAKI }
1878c62f1cccSMitsuru IWASAKI 
1879945137d9SNate Lawson void
1880986dffafSJohn Baldwin aml_disassemble(ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
1881c62f1cccSMitsuru IWASAKI {
18827e2cc014SDon Lewis 	char buf[PATH_MAX], tmpstr[PATH_MAX], wrkdir[PATH_MAX];
18837e2cc014SDon Lewis 	const char *iname = "/acpdump.din";
18847e2cc014SDon Lewis 	const char *oname = "/acpdump.dsl";
188599065116SJung-uk Kim 	const char *tmpdir;
1886945137d9SNate Lawson 	FILE *fp;
188799065116SJung-uk Kim 	size_t len;
18887e2cc014SDon Lewis 	int fd, status;
18897e2cc014SDon Lewis 	pid_t pid;
1890945137d9SNate Lawson 
189199065116SJung-uk Kim 	tmpdir = getenv("TMPDIR");
189299065116SJung-uk Kim 	if (tmpdir == NULL)
189399065116SJung-uk Kim 		tmpdir = _PATH_TMP;
18947e2cc014SDon Lewis 	if (realpath(tmpdir, buf) == NULL) {
1895d6a6e590SJung-uk Kim 		perror("realpath tmp dir");
189699065116SJung-uk Kim 		return;
189799065116SJung-uk Kim 	}
18987e2cc014SDon Lewis 	len = sizeof(wrkdir) - strlen(iname);
18997e2cc014SDon Lewis 	if ((size_t)snprintf(wrkdir, len, "%s/acpidump.XXXXXX", buf) > len-1 ) {
19007e2cc014SDon Lewis 		fprintf(stderr, "$TMPDIR too long\n");
19017e2cc014SDon Lewis 		return;
19027e2cc014SDon Lewis 	}
19037e2cc014SDon Lewis 	if  (mkdtemp(wrkdir) == NULL) {
19047e2cc014SDon Lewis 		perror("mkdtemp tmp working dir");
19057e2cc014SDon Lewis 		return;
19067e2cc014SDon Lewis 	}
190730bebccaSMaxim Konovalov 	len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, iname);
190830bebccaSMaxim Konovalov 	assert(len <= sizeof(tmpstr) - 1);
19097e2cc014SDon Lewis 	fd = open(tmpstr, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
1910945137d9SNate Lawson 	if (fd < 0) {
1911945137d9SNate Lawson 		perror("iasl tmp file");
1912945137d9SNate Lawson 		return;
1913c62f1cccSMitsuru IWASAKI 	}
1914bfa3f012SMarcel Moolenaar 	write_dsdt(fd, rsdt, dsdp);
1915945137d9SNate Lawson 	close(fd);
1916945137d9SNate Lawson 
1917945137d9SNate Lawson 	/* Run iasl -d on the temp file */
19187e2cc014SDon Lewis 	if ((pid = fork()) == 0) {
1919945137d9SNate Lawson 		close(STDOUT_FILENO);
1920945137d9SNate Lawson 		if (vflag == 0)
1921945137d9SNate Lawson 			close(STDERR_FILENO);
192299065116SJung-uk Kim 		execl("/usr/sbin/iasl", "iasl", "-d", tmpstr, NULL);
1923945137d9SNate Lawson 		err(1, "exec");
1924c62f1cccSMitsuru IWASAKI 	}
19257e2cc014SDon Lewis 	if (pid > 0)
19267e2cc014SDon Lewis 		wait(&status);
19277e2cc014SDon Lewis 	if (unlink(tmpstr) < 0) {
19287e2cc014SDon Lewis 		perror("unlink");
19297e2cc014SDon Lewis 		goto out;
19307e2cc014SDon Lewis 	}
19317e2cc014SDon Lewis 	if (pid < 0) {
19327e2cc014SDon Lewis 		perror("fork");
19337e2cc014SDon Lewis 		goto out;
19347e2cc014SDon Lewis 	}
19357e2cc014SDon Lewis 	if (status != 0) {
19367e2cc014SDon Lewis 		fprintf(stderr, "iast exit status = %d\n", status);
19377e2cc014SDon Lewis 	}
1938945137d9SNate Lawson 
1939945137d9SNate Lawson 	/* Dump iasl's output to stdout */
194030bebccaSMaxim Konovalov 	len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, oname);
194130bebccaSMaxim Konovalov 	assert(len <= sizeof(tmpstr) - 1);
194299065116SJung-uk Kim 	fp = fopen(tmpstr, "r");
19437e2cc014SDon Lewis 	if (unlink(tmpstr) < 0) {
19447e2cc014SDon Lewis 		perror("unlink");
19457e2cc014SDon Lewis 		goto out;
19467e2cc014SDon Lewis 	}
1947945137d9SNate Lawson 	if (fp == NULL) {
1948945137d9SNate Lawson 		perror("iasl tmp file (read)");
19497e2cc014SDon Lewis 		goto out;
1950945137d9SNate Lawson 	}
1951945137d9SNate Lawson 	while ((len = fread(buf, 1, sizeof(buf), fp)) > 0)
1952945137d9SNate Lawson 		fwrite(buf, 1, len, stdout);
1953945137d9SNate Lawson 	fclose(fp);
19547e2cc014SDon Lewis 
19557e2cc014SDon Lewis     out:
19567e2cc014SDon Lewis 	if (rmdir(wrkdir) < 0)
19577e2cc014SDon Lewis 		perror("rmdir");
1958c62f1cccSMitsuru IWASAKI }
1959c62f1cccSMitsuru IWASAKI 
1960945137d9SNate Lawson void
1961986dffafSJohn Baldwin sdt_print_all(ACPI_TABLE_HEADER *rsdp)
1962c62f1cccSMitsuru IWASAKI {
1963945137d9SNate Lawson 	acpi_handle_rsdt(rsdp);
1964c62f1cccSMitsuru IWASAKI }
1965c62f1cccSMitsuru IWASAKI 
1966bfa3f012SMarcel Moolenaar /* Fetch a table matching the given signature via the RSDT. */
1967986dffafSJohn Baldwin ACPI_TABLE_HEADER *
1968986dffafSJohn Baldwin sdt_from_rsdt(ACPI_TABLE_HEADER *rsdp, const char *sig, ACPI_TABLE_HEADER *last)
1969c62f1cccSMitsuru IWASAKI {
1970986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *sdt;
1971986dffafSJohn Baldwin 	ACPI_TABLE_RSDT *rsdt;
1972986dffafSJohn Baldwin 	ACPI_TABLE_XSDT *xsdt;
1973a74172abSNate Lawson 	vm_offset_t addr;
1974a74172abSNate Lawson 	int entries, i;
1975945137d9SNate Lawson 
1976986dffafSJohn Baldwin 	rsdt = (ACPI_TABLE_RSDT *)rsdp;
1977986dffafSJohn Baldwin 	xsdt = (ACPI_TABLE_XSDT *)rsdp;
1978986dffafSJohn Baldwin 	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
1979945137d9SNate Lawson 	for (i = 0; i < entries; i++) {
1980fe1d0c2dSJung-uk Kim 		if (addr_size == 4)
1981986dffafSJohn Baldwin 			addr = le32toh(rsdt->TableOffsetEntry[i]);
1982fe1d0c2dSJung-uk Kim 		else
1983986dffafSJohn Baldwin 			addr = le64toh(xsdt->TableOffsetEntry[i]);
1984fe1d0c2dSJung-uk Kim 		if (addr == 0)
1985fe1d0c2dSJung-uk Kim 			continue;
1986986dffafSJohn Baldwin 		sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
1987bfa3f012SMarcel Moolenaar 		if (last != NULL) {
1988bfa3f012SMarcel Moolenaar 			if (sdt == last)
1989bfa3f012SMarcel Moolenaar 				last = NULL;
1990bfa3f012SMarcel Moolenaar 			continue;
1991bfa3f012SMarcel Moolenaar 		}
1992986dffafSJohn Baldwin 		if (memcmp(sdt->Signature, sig, strlen(sig)))
1993a74172abSNate Lawson 			continue;
1994986dffafSJohn Baldwin 		if (acpi_checksum(sdt, sdt->Length))
1995945137d9SNate Lawson 			errx(1, "RSDT entry %d is corrupt", i);
1996945137d9SNate Lawson 		return (sdt);
1997c62f1cccSMitsuru IWASAKI 	}
1998c62f1cccSMitsuru IWASAKI 
1999945137d9SNate Lawson 	return (NULL);
2000c62f1cccSMitsuru IWASAKI }
2001c62f1cccSMitsuru IWASAKI 
2002986dffafSJohn Baldwin ACPI_TABLE_HEADER *
2003986dffafSJohn Baldwin dsdt_from_fadt(ACPI_TABLE_FADT *fadt)
2004c62f1cccSMitsuru IWASAKI {
2005986dffafSJohn Baldwin 	ACPI_TABLE_HEADER	*sdt;
2006c62f1cccSMitsuru IWASAKI 
2007986dffafSJohn Baldwin 	/* Use the DSDT address if it is version 1, otherwise use XDSDT. */
2008c2962974SNate Lawson 	if (acpi_get_fadt_revision(fadt) == 1)
2009986dffafSJohn Baldwin 		sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt);
20102e71eb12SNate Lawson 	else
2011986dffafSJohn Baldwin 		sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt);
2012986dffafSJohn Baldwin 	if (acpi_checksum(sdt, sdt->Length))
2013945137d9SNate Lawson 		errx(1, "DSDT is corrupt\n");
2014945137d9SNate Lawson 	return (sdt);
2015c62f1cccSMitsuru IWASAKI }
2016