xref: /freebsd/usr.sbin/acpi/acpidump/acpi.c (revision 5d57fad876ee6b55761a7643f5b94e3d6d54e3e0)
1e1e9a4bfSMitsuru IWASAKI /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
31de7b4b8SPedro F. Giffuni  *
4e1e9a4bfSMitsuru IWASAKI  * Copyright (c) 1998 Doug Rabson
5e1e9a4bfSMitsuru IWASAKI  * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
6ebc22d04SAlexander Motin  * Copyright (c) 2020 Alexander Motin <mav@FreeBSD.org>
7f1519a82SKonstantin Belousov  * Copyright (c) 2024 The FreeBSD Foundation
8e1e9a4bfSMitsuru IWASAKI  * All rights reserved.
9e1e9a4bfSMitsuru IWASAKI  *
10f1519a82SKonstantin Belousov  * Portions of this software were developed by Konstantin Belousov
11f1519a82SKonstantin Belousov  * under sponsorship from the FreeBSD Foundation.
12f1519a82SKonstantin Belousov  *
13e1e9a4bfSMitsuru IWASAKI  * Redistribution and use in source and binary forms, with or without
14e1e9a4bfSMitsuru IWASAKI  * modification, are permitted provided that the following conditions
15e1e9a4bfSMitsuru IWASAKI  * are met:
16e1e9a4bfSMitsuru IWASAKI  * 1. Redistributions of source code must retain the above copyright
17e1e9a4bfSMitsuru IWASAKI  *    notice, this list of conditions and the following disclaimer.
18e1e9a4bfSMitsuru IWASAKI  * 2. Redistributions in binary form must reproduce the above copyright
19e1e9a4bfSMitsuru IWASAKI  *    notice, this list of conditions and the following disclaimer in the
20e1e9a4bfSMitsuru IWASAKI  *    documentation and/or other materials provided with the distribution.
21e1e9a4bfSMitsuru IWASAKI  *
22e1e9a4bfSMitsuru IWASAKI  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23e1e9a4bfSMitsuru IWASAKI  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24e1e9a4bfSMitsuru IWASAKI  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25e1e9a4bfSMitsuru IWASAKI  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26e1e9a4bfSMitsuru IWASAKI  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27e1e9a4bfSMitsuru IWASAKI  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28e1e9a4bfSMitsuru IWASAKI  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29e1e9a4bfSMitsuru IWASAKI  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30e1e9a4bfSMitsuru IWASAKI  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31e1e9a4bfSMitsuru IWASAKI  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32e1e9a4bfSMitsuru IWASAKI  * SUCH DAMAGE.
33e1e9a4bfSMitsuru IWASAKI  */
34e1e9a4bfSMitsuru IWASAKI 
35e1e9a4bfSMitsuru IWASAKI #include <sys/param.h>
36a74172abSNate Lawson #include <sys/endian.h>
37e1e9a4bfSMitsuru IWASAKI #include <sys/stat.h>
38945137d9SNate Lawson #include <sys/wait.h>
39e1e9a4bfSMitsuru IWASAKI #include <assert.h>
40e1e9a4bfSMitsuru IWASAKI #include <err.h>
41e1e9a4bfSMitsuru IWASAKI #include <fcntl.h>
4299065116SJung-uk Kim #include <paths.h>
436d789b61SKonstantin Belousov #include <stdbool.h>
44e1e9a4bfSMitsuru IWASAKI #include <stdio.h>
45a0333ad1SJohn Baldwin #include <stdint.h>
4699065116SJung-uk Kim #include <stdlib.h>
47945137d9SNate Lawson #include <string.h>
48e1e9a4bfSMitsuru IWASAKI #include <unistd.h>
49340c0022SEd Maste #include <uuid.h>
50e1e9a4bfSMitsuru IWASAKI 
51e1e9a4bfSMitsuru IWASAKI #include "acpidump.h"
52e1e9a4bfSMitsuru IWASAKI 
53c62f1cccSMitsuru IWASAKI #define BEGIN_COMMENT	"/*\n"
54c62f1cccSMitsuru IWASAKI #define END_COMMENT	" */\n"
55c62f1cccSMitsuru IWASAKI 
56945137d9SNate Lawson static void	acpi_print_string(char *s, size_t length);
57986dffafSJohn Baldwin static void	acpi_print_gas(ACPI_GENERIC_ADDRESS *gas);
58986dffafSJohn Baldwin static int	acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt);
59986dffafSJohn Baldwin static void	acpi_handle_fadt(ACPI_TABLE_HEADER *fadt);
60945137d9SNate Lawson static void	acpi_print_cpu(u_char cpu_id);
61986dffafSJohn Baldwin static void	acpi_print_cpu_uid(uint32_t uid, char *uid_string);
62986dffafSJohn Baldwin static void	acpi_print_local_apic(uint32_t apic_id, uint32_t flags);
63986dffafSJohn Baldwin static void	acpi_print_io_apic(uint32_t apic_id, uint32_t int_base,
64986dffafSJohn Baldwin 		    uint64_t apic_addr);
65986dffafSJohn Baldwin static void	acpi_print_mps_flags(uint16_t flags);
66986dffafSJohn Baldwin static void	acpi_print_intr(uint32_t intr, uint16_t mps_flags);
67986dffafSJohn Baldwin static void	acpi_print_local_nmi(u_int lint, uint16_t mps_flags);
68986dffafSJohn Baldwin static void	acpi_print_madt(ACPI_SUBTABLE_HEADER *mp);
69986dffafSJohn Baldwin static void	acpi_handle_madt(ACPI_TABLE_HEADER *sdp);
70986dffafSJohn Baldwin static void	acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp);
71986dffafSJohn Baldwin static void	acpi_handle_hpet(ACPI_TABLE_HEADER *sdp);
72986dffafSJohn Baldwin static void	acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp);
7333866658SJohn Baldwin static void	acpi_handle_slit(ACPI_TABLE_HEADER *sdp);
74ed26c389SScott Long static void	acpi_handle_wddt(ACPI_TABLE_HEADER *sdp);
755857fba5SBen Widawsky static void	acpi_handle_lpit(ACPI_TABLE_HEADER *sdp);
76a0333ad1SJohn Baldwin static void	acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain,
77a0333ad1SJohn Baldwin 		    uint32_t flags);
78986dffafSJohn Baldwin static void	acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp);
79986dffafSJohn Baldwin static void	acpi_print_srat(ACPI_SUBTABLE_HEADER *srat);
80986dffafSJohn Baldwin static void	acpi_handle_srat(ACPI_TABLE_HEADER *sdp);
81c031c93bSTakanori Watanabe static void	acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp);
82340c0022SEd Maste static void	acpi_print_nfit(ACPI_NFIT_HEADER *nfit);
83340c0022SEd Maste static void	acpi_handle_nfit(ACPI_TABLE_HEADER *sdp);
84986dffafSJohn Baldwin static void	acpi_print_sdt(ACPI_TABLE_HEADER *sdp);
85986dffafSJohn Baldwin static void	acpi_print_fadt(ACPI_TABLE_HEADER *sdp);
86986dffafSJohn Baldwin static void	acpi_print_facs(ACPI_TABLE_FACS *facs);
87986dffafSJohn Baldwin static void	acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp);
88986dffafSJohn Baldwin static ACPI_TABLE_HEADER *acpi_map_sdt(vm_offset_t pa);
89986dffafSJohn Baldwin static void	acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp);
90986dffafSJohn Baldwin static void	acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp);
91986dffafSJohn Baldwin static void	acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
92986dffafSJohn Baldwin 		    void (*action)(ACPI_SUBTABLE_HEADER *));
93340c0022SEd Maste static void	acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first,
94340c0022SEd Maste 		    void (*action)(ACPI_NFIT_HEADER *));
95c62f1cccSMitsuru IWASAKI 
96773b6454SNate Lawson /* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up. */
97a74172abSNate Lawson static int addr_size;
98a74172abSNate Lawson 
99c031c93bSTakanori Watanabe /* Strings used in the TCPA table */
100c031c93bSTakanori Watanabe static const char *tcpa_event_type_strings[] = {
101c031c93bSTakanori Watanabe 	"PREBOOT Certificate",
102c031c93bSTakanori Watanabe 	"POST Code",
103c031c93bSTakanori Watanabe 	"Unused",
104c031c93bSTakanori Watanabe 	"No Action",
105c031c93bSTakanori Watanabe 	"Separator",
106c031c93bSTakanori Watanabe 	"Action",
107c031c93bSTakanori Watanabe 	"Event Tag",
108c031c93bSTakanori Watanabe 	"S-CRTM Contents",
109c031c93bSTakanori Watanabe 	"S-CRTM Version",
110c031c93bSTakanori Watanabe 	"CPU Microcode",
111c031c93bSTakanori Watanabe 	"Platform Config Flags",
112c031c93bSTakanori Watanabe 	"Table of Devices",
113c031c93bSTakanori Watanabe 	"Compact Hash",
114c031c93bSTakanori Watanabe 	"IPL",
115c031c93bSTakanori Watanabe 	"IPL Partition Data",
116c031c93bSTakanori Watanabe 	"Non-Host Code",
117c031c93bSTakanori Watanabe 	"Non-Host Config",
118c031c93bSTakanori Watanabe 	"Non-Host Info"
119c031c93bSTakanori Watanabe };
120c031c93bSTakanori Watanabe 
121c031c93bSTakanori Watanabe static const char *TCPA_pcclient_strings[] = {
122c031c93bSTakanori Watanabe 	"<undefined>",
123c031c93bSTakanori Watanabe 	"SMBIOS",
124c031c93bSTakanori Watanabe 	"BIS Certificate",
125c031c93bSTakanori Watanabe 	"POST BIOS ROM Strings",
126c031c93bSTakanori Watanabe 	"ESCD",
127c031c93bSTakanori Watanabe 	"CMOS",
128c031c93bSTakanori Watanabe 	"NVRAM",
129c031c93bSTakanori Watanabe 	"Option ROM Execute",
130c031c93bSTakanori Watanabe 	"Option ROM Configurateion",
131c031c93bSTakanori Watanabe 	"<undefined>",
132c031c93bSTakanori Watanabe 	"Option ROM Microcode Update ",
133c031c93bSTakanori Watanabe 	"S-CRTM Version String",
134c031c93bSTakanori Watanabe 	"S-CRTM Contents",
135c031c93bSTakanori Watanabe 	"POST Contents",
136c031c93bSTakanori Watanabe 	"Table of Devices",
137c031c93bSTakanori Watanabe };
138c031c93bSTakanori Watanabe 
139ec650989SNeel Natu #define	PRINTFLAG_END()		printflag_end()
140ec650989SNeel Natu 
141ec650989SNeel Natu static char pf_sep = '{';
142ec650989SNeel Natu 
143ec650989SNeel Natu static void
144ec650989SNeel Natu printflag_end(void)
145ec650989SNeel Natu {
146ec650989SNeel Natu 
147ec650989SNeel Natu 	if (pf_sep != '{') {
148ec650989SNeel Natu 		printf("}");
149ec650989SNeel Natu 		pf_sep = '{';
150ec650989SNeel Natu 	}
151ec650989SNeel Natu 	printf("\n");
152ec650989SNeel Natu }
153ec650989SNeel Natu 
154ec650989SNeel Natu static void
155ec650989SNeel Natu printflag(uint64_t var, uint64_t mask, const char *name)
156ec650989SNeel Natu {
157ec650989SNeel Natu 
158ec650989SNeel Natu 	if (var & mask) {
159ec650989SNeel Natu 		printf("%c%s", pf_sep, name);
160ec650989SNeel Natu 		pf_sep = ',';
161ec650989SNeel Natu 	}
162ec650989SNeel Natu }
163ec650989SNeel Natu 
164e1e9a4bfSMitsuru IWASAKI static void
165969a4b8bSKonstantin Belousov printfield(uint64_t var, int lbit, int hbit, const char *name)
166969a4b8bSKonstantin Belousov {
167969a4b8bSKonstantin Belousov 	uint64_t mask;
168969a4b8bSKonstantin Belousov 	int len;
169969a4b8bSKonstantin Belousov 
170969a4b8bSKonstantin Belousov 	len = hbit - lbit + 1;
171969a4b8bSKonstantin Belousov 	mask = ((1 << (len + 1)) - 1) << lbit;
172969a4b8bSKonstantin Belousov 	printf("%c%s=%#jx", pf_sep, name, (uintmax_t)((var & mask) >> lbit));
173969a4b8bSKonstantin Belousov 	pf_sep = ',';
174969a4b8bSKonstantin Belousov }
175969a4b8bSKonstantin Belousov 
176969a4b8bSKonstantin Belousov static void
177e1e9a4bfSMitsuru IWASAKI acpi_print_string(char *s, size_t length)
178e1e9a4bfSMitsuru IWASAKI {
179e1e9a4bfSMitsuru IWASAKI 	int	c;
180e1e9a4bfSMitsuru IWASAKI 
181e1e9a4bfSMitsuru IWASAKI 	/* Trim trailing spaces and NULLs */
182e1e9a4bfSMitsuru IWASAKI 	while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0'))
183e1e9a4bfSMitsuru IWASAKI 		length--;
184e1e9a4bfSMitsuru IWASAKI 
185e1e9a4bfSMitsuru IWASAKI 	while (length--) {
186e1e9a4bfSMitsuru IWASAKI 		c = *s++;
187e1e9a4bfSMitsuru IWASAKI 		putchar(c);
188e1e9a4bfSMitsuru IWASAKI 	}
189e1e9a4bfSMitsuru IWASAKI }
190e1e9a4bfSMitsuru IWASAKI 
191e1e9a4bfSMitsuru IWASAKI static void
192986dffafSJohn Baldwin acpi_print_gas(ACPI_GENERIC_ADDRESS *gas)
1938e6a8737SNate Lawson {
194986dffafSJohn Baldwin 	switch(gas->SpaceId) {
1958e6a8737SNate Lawson 	case ACPI_GAS_MEMORY:
196ebc22d04SAlexander Motin 		printf("0x%016jx:%u[%u] (Memory)", (uintmax_t)gas->Address,
197ebc22d04SAlexander Motin 		    gas->BitOffset, gas->BitWidth);
1988e6a8737SNate Lawson 		break;
1998e6a8737SNate Lawson 	case ACPI_GAS_IO:
200ebc22d04SAlexander Motin 		printf("0x%02jx:%u[%u] (IO)", (uintmax_t)gas->Address,
201986dffafSJohn Baldwin 		    gas->BitOffset, gas->BitWidth);
2028e6a8737SNate Lawson 		break;
2038e6a8737SNate Lawson 	case ACPI_GAS_PCI:
204ebc22d04SAlexander Motin 		printf("%x:%x+0x%x:%u[%u] (PCI)", (uint16_t)(gas->Address >> 32),
205986dffafSJohn Baldwin 		       (uint16_t)((gas->Address >> 16) & 0xffff),
206ebc22d04SAlexander Motin 		       (uint16_t)gas->Address, gas->BitOffset, gas->BitWidth);
2078e6a8737SNate Lawson 		break;
2088e6a8737SNate Lawson 	/* XXX How to handle these below? */
2098e6a8737SNate Lawson 	case ACPI_GAS_EMBEDDED:
210986dffafSJohn Baldwin 		printf("0x%x:%u[%u] (EC)", (uint16_t)gas->Address,
211986dffafSJohn Baldwin 		       gas->BitOffset, gas->BitWidth);
2128e6a8737SNate Lawson 		break;
2138e6a8737SNate Lawson 	case ACPI_GAS_SMBUS:
214986dffafSJohn Baldwin 		printf("0x%x:%u[%u] (SMBus)", (uint16_t)gas->Address,
215986dffafSJohn Baldwin 		       gas->BitOffset, gas->BitWidth);
2168e6a8737SNate Lawson 		break;
217986dffafSJohn Baldwin 	case ACPI_GAS_CMOS:
218986dffafSJohn Baldwin 	case ACPI_GAS_PCIBAR:
219986dffafSJohn Baldwin 	case ACPI_GAS_DATATABLE:
2208e6a8737SNate Lawson 	case ACPI_GAS_FIXED:
2218e6a8737SNate Lawson 	default:
2227d369c6eSJung-uk Kim 		printf("0x%016jx (?)", (uintmax_t)gas->Address);
2238e6a8737SNate Lawson 		break;
2248e6a8737SNate Lawson 	}
2258e6a8737SNate Lawson }
2268e6a8737SNate Lawson 
227c2962974SNate Lawson /* The FADT revision indicates whether we use the DSDT or X_DSDT addresses. */
228c2962974SNate Lawson static int
2294262ad56SKonstantin Belousov acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt __unused)
230e1e9a4bfSMitsuru IWASAKI {
231c2962974SNate Lawson 	int fadt_revision;
232e1e9a4bfSMitsuru IWASAKI 
233c83f0f99SNate Lawson 	/* Set the FADT revision separately from the RSDP version. */
234c83f0f99SNate Lawson 	if (addr_size == 8) {
235c83f0f99SNate Lawson 		fadt_revision = 2;
2368e6a8737SNate Lawson 
23701593a0fSAndrew Turner #if defined(__i386__)
238773b6454SNate Lawson 		/*
239c83f0f99SNate Lawson 		 * A few systems (e.g., IBM T23) have an RSDP that claims
240c83f0f99SNate Lawson 		 * revision 2 but the 64 bit addresses are invalid.  If
241c83f0f99SNate Lawson 		 * revision 2 and the 32 bit address is non-zero but the
242c83f0f99SNate Lawson 		 * 32 and 64 bit versions don't match, prefer the 32 bit
243c83f0f99SNate Lawson 		 * version for all subsequent tables.
24401593a0fSAndrew Turner 		 *
24501593a0fSAndrew Turner 		 * The only known ACPI systems this affects are early
24601593a0fSAndrew Turner 		 * implementations on 32-bit x86. Because of this limit the
24701593a0fSAndrew Turner 		 * workaround to i386.
248773b6454SNate Lawson 		 */
249986dffafSJohn Baldwin 		if (fadt->Facs != 0 &&
250986dffafSJohn Baldwin 		    (fadt->XFacs & 0xffffffff) != fadt->Facs)
251c83f0f99SNate Lawson 			fadt_revision = 1;
25201593a0fSAndrew Turner #endif
253c2962974SNate Lawson 	} else
254c83f0f99SNate Lawson 		fadt_revision = 1;
255c2962974SNate Lawson 	return (fadt_revision);
256c83f0f99SNate Lawson }
257c2962974SNate Lawson 
258c2962974SNate Lawson static void
259986dffafSJohn Baldwin acpi_handle_fadt(ACPI_TABLE_HEADER *sdp)
260c2962974SNate Lawson {
261986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *dsdp;
262986dffafSJohn Baldwin 	ACPI_TABLE_FACS	*facs;
263986dffafSJohn Baldwin 	ACPI_TABLE_FADT *fadt;
264bc711181SAndrew Turner 	vm_offset_t	addr;
265c2962974SNate Lawson 	int		fadt_revision;
266c2962974SNate Lawson 
267986dffafSJohn Baldwin 	fadt = (ACPI_TABLE_FADT *)sdp;
2682177d4e6SNate Lawson 	acpi_print_fadt(sdp);
269c83f0f99SNate Lawson 
270c2962974SNate Lawson 	fadt_revision = acpi_get_fadt_revision(fadt);
271c83f0f99SNate Lawson 	if (fadt_revision == 1)
272bc711181SAndrew Turner 		addr = fadt->Facs;
273773b6454SNate Lawson 	else
274bc711181SAndrew Turner 		addr = fadt->XFacs;
275bc711181SAndrew Turner 	if (addr != 0) {
276bc711181SAndrew Turner 		facs = (ACPI_TABLE_FACS *)acpi_map_sdt(addr);
277bc711181SAndrew Turner 
278bc711181SAndrew Turner 		if (memcmp(facs->Signature, ACPI_SIG_FACS, 4) != 0 ||
279bc711181SAndrew Turner 		    facs->Length < 64)
2808e6a8737SNate Lawson 			errx(1, "FACS is corrupt");
2818e6a8737SNate Lawson 		acpi_print_facs(facs);
282bc711181SAndrew Turner 	}
2838e6a8737SNate Lawson 
284c83f0f99SNate Lawson 	if (fadt_revision == 1)
285986dffafSJohn Baldwin 		dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt);
286773b6454SNate Lawson 	else
287986dffafSJohn Baldwin 		dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt);
288986dffafSJohn Baldwin 	if (acpi_checksum(dsdp, dsdp->Length))
289945137d9SNate Lawson 		errx(1, "DSDT is corrupt");
290945137d9SNate Lawson 	acpi_print_dsdt(dsdp);
291c62f1cccSMitsuru IWASAKI }
292c62f1cccSMitsuru IWASAKI 
293c62f1cccSMitsuru IWASAKI static void
294986dffafSJohn Baldwin acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
295986dffafSJohn Baldwin     void (*action)(ACPI_SUBTABLE_HEADER *))
296986dffafSJohn Baldwin {
297986dffafSJohn Baldwin 	ACPI_SUBTABLE_HEADER *subtable;
298986dffafSJohn Baldwin 	char *end;
299986dffafSJohn Baldwin 
300986dffafSJohn Baldwin 	subtable = first;
301986dffafSJohn Baldwin 	end = (char *)table + table->Length;
302986dffafSJohn Baldwin 	while ((char *)subtable < end) {
303986dffafSJohn Baldwin 		printf("\n");
304f5d0a8f7SEd Maste 		if (subtable->Length < sizeof(ACPI_SUBTABLE_HEADER)) {
305f5d0a8f7SEd Maste 			warnx("invalid subtable length %u", subtable->Length);
306f5d0a8f7SEd Maste 			return;
307f5d0a8f7SEd Maste 		}
308986dffafSJohn Baldwin 		action(subtable);
309986dffafSJohn Baldwin 		subtable = (ACPI_SUBTABLE_HEADER *)((char *)subtable +
310986dffafSJohn Baldwin 		    subtable->Length);
311986dffafSJohn Baldwin 	}
312986dffafSJohn Baldwin }
313986dffafSJohn Baldwin 
314986dffafSJohn Baldwin static void
315340c0022SEd Maste acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first,
316340c0022SEd Maste     void (*action)(ACPI_NFIT_HEADER *))
317340c0022SEd Maste {
318340c0022SEd Maste 	ACPI_NFIT_HEADER *subtable;
319340c0022SEd Maste 	char *end;
320340c0022SEd Maste 
321340c0022SEd Maste 	subtable = first;
322340c0022SEd Maste 	end = (char *)table + table->Length;
323340c0022SEd Maste 	while ((char *)subtable < end) {
324340c0022SEd Maste 		printf("\n");
325340c0022SEd Maste 		if (subtable->Length < sizeof(ACPI_NFIT_HEADER)) {
326340c0022SEd Maste 			warnx("invalid subtable length %u", subtable->Length);
327340c0022SEd Maste 			return;
328340c0022SEd Maste 		}
329340c0022SEd Maste 		action(subtable);
330340c0022SEd Maste 		subtable = (ACPI_NFIT_HEADER *)((char *)subtable +
331340c0022SEd Maste 		    subtable->Length);
332340c0022SEd Maste 	}
333340c0022SEd Maste }
334340c0022SEd Maste 
335340c0022SEd Maste static void
3360a473124SJohn Baldwin acpi_print_cpu(u_char cpu_id)
3370a473124SJohn Baldwin {
3380a473124SJohn Baldwin 
3390a473124SJohn Baldwin 	printf("\tACPI CPU=");
3400a473124SJohn Baldwin 	if (cpu_id == 0xff)
3410a473124SJohn Baldwin 		printf("ALL\n");
3420a473124SJohn Baldwin 	else
3430a473124SJohn Baldwin 		printf("%d\n", (u_int)cpu_id);
3440a473124SJohn Baldwin }
3450a473124SJohn Baldwin 
3460a473124SJohn Baldwin static void
347986dffafSJohn Baldwin acpi_print_cpu_uid(uint32_t uid, char *uid_string)
3480a473124SJohn Baldwin {
349986dffafSJohn Baldwin 
350986dffafSJohn Baldwin 	printf("\tUID=%d", uid);
351986dffafSJohn Baldwin 	if (uid_string != NULL)
352986dffafSJohn Baldwin 		printf(" (%s)", uid_string);
353986dffafSJohn Baldwin 	printf("\n");
354986dffafSJohn Baldwin }
355986dffafSJohn Baldwin 
356986dffafSJohn Baldwin static void
357986dffafSJohn Baldwin acpi_print_local_apic(uint32_t apic_id, uint32_t flags)
358986dffafSJohn Baldwin {
359986dffafSJohn Baldwin 
3600a473124SJohn Baldwin 	printf("\tFlags={");
361986dffafSJohn Baldwin 	if (flags & ACPI_MADT_ENABLED)
3620a473124SJohn Baldwin 		printf("ENABLED");
3630a473124SJohn Baldwin 	else
3640a473124SJohn Baldwin 		printf("DISABLED");
3650a473124SJohn Baldwin 	printf("}\n");
366986dffafSJohn Baldwin 	printf("\tAPIC ID=%d\n", apic_id);
3670a473124SJohn Baldwin }
3680a473124SJohn Baldwin 
3690a473124SJohn Baldwin static void
370986dffafSJohn Baldwin acpi_print_io_apic(uint32_t apic_id, uint32_t int_base, uint64_t apic_addr)
3710a473124SJohn Baldwin {
372986dffafSJohn Baldwin 
373986dffafSJohn Baldwin 	printf("\tAPIC ID=%d\n", apic_id);
3740a473124SJohn Baldwin 	printf("\tINT BASE=%d\n", int_base);
375986dffafSJohn Baldwin 	printf("\tADDR=0x%016jx\n", (uintmax_t)apic_addr);
3760a473124SJohn Baldwin }
3770a473124SJohn Baldwin 
3780a473124SJohn Baldwin static void
379986dffafSJohn Baldwin acpi_print_mps_flags(uint16_t flags)
3800a473124SJohn Baldwin {
3810a473124SJohn Baldwin 
3820a473124SJohn Baldwin 	printf("\tFlags={Polarity=");
383986dffafSJohn Baldwin 	switch (flags & ACPI_MADT_POLARITY_MASK) {
384986dffafSJohn Baldwin 	case ACPI_MADT_POLARITY_CONFORMS:
3850a473124SJohn Baldwin 		printf("conforming");
3860a473124SJohn Baldwin 		break;
387986dffafSJohn Baldwin 	case ACPI_MADT_POLARITY_ACTIVE_HIGH:
3880a473124SJohn Baldwin 		printf("active-hi");
3890a473124SJohn Baldwin 		break;
390986dffafSJohn Baldwin 	case ACPI_MADT_POLARITY_ACTIVE_LOW:
3910a473124SJohn Baldwin 		printf("active-lo");
3920a473124SJohn Baldwin 		break;
3930a473124SJohn Baldwin 	default:
394986dffafSJohn Baldwin 		printf("0x%x", flags & ACPI_MADT_POLARITY_MASK);
3950a473124SJohn Baldwin 		break;
3960a473124SJohn Baldwin 	}
3970a473124SJohn Baldwin 	printf(", Trigger=");
398986dffafSJohn Baldwin 	switch (flags & ACPI_MADT_TRIGGER_MASK) {
399986dffafSJohn Baldwin 	case ACPI_MADT_TRIGGER_CONFORMS:
4000a473124SJohn Baldwin 		printf("conforming");
4010a473124SJohn Baldwin 		break;
402986dffafSJohn Baldwin 	case ACPI_MADT_TRIGGER_EDGE:
4030a473124SJohn Baldwin 		printf("edge");
4040a473124SJohn Baldwin 		break;
405986dffafSJohn Baldwin 	case ACPI_MADT_TRIGGER_LEVEL:
4060a473124SJohn Baldwin 		printf("level");
4070a473124SJohn Baldwin 		break;
4080a473124SJohn Baldwin 	default:
409986dffafSJohn Baldwin 		printf("0x%x", (flags & ACPI_MADT_TRIGGER_MASK) >> 2);
4100a473124SJohn Baldwin 	}
4110a473124SJohn Baldwin 	printf("}\n");
4120a473124SJohn Baldwin }
4130a473124SJohn Baldwin 
4140a473124SJohn Baldwin static void
4152b2b1f42SAndrew Turner acpi_print_gicc_flags(uint32_t flags)
4162b2b1f42SAndrew Turner {
4172b2b1f42SAndrew Turner 
4182b2b1f42SAndrew Turner 	printf("\tFlags={Performance intr=");
4192b2b1f42SAndrew Turner 	if (flags & ACPI_MADT_PERFORMANCE_IRQ_MODE)
4202b2b1f42SAndrew Turner 		printf("edge");
4212b2b1f42SAndrew Turner 	else
4222b2b1f42SAndrew Turner 		printf("level");
4232b2b1f42SAndrew Turner 	printf(", VGIC intr=");
4242b2b1f42SAndrew Turner 	if (flags & ACPI_MADT_VGIC_IRQ_MODE)
4252b2b1f42SAndrew Turner 		printf("edge");
4262b2b1f42SAndrew Turner 	else
4272b2b1f42SAndrew Turner 		printf("level");
4282b2b1f42SAndrew Turner 	printf("}\n");
4292b2b1f42SAndrew Turner }
4302b2b1f42SAndrew Turner 
4312b2b1f42SAndrew Turner static void
432986dffafSJohn Baldwin acpi_print_intr(uint32_t intr, uint16_t mps_flags)
4330a473124SJohn Baldwin {
4340a473124SJohn Baldwin 
435986dffafSJohn Baldwin 	printf("\tINTR=%d\n", intr);
436986dffafSJohn Baldwin 	acpi_print_mps_flags(mps_flags);
437986dffafSJohn Baldwin }
438986dffafSJohn Baldwin 
439986dffafSJohn Baldwin static void
440986dffafSJohn Baldwin acpi_print_local_nmi(u_int lint, uint16_t mps_flags)
441986dffafSJohn Baldwin {
442986dffafSJohn Baldwin 
443986dffafSJohn Baldwin 	printf("\tLINT Pin=%d\n", lint);
4440a473124SJohn Baldwin 	acpi_print_mps_flags(mps_flags);
4450a473124SJohn Baldwin }
4460a473124SJohn Baldwin 
44727941afaSEd Maste static const char *apic_types[] = {
44827941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_APIC] = "Local APIC",
44927941afaSEd Maste     [ACPI_MADT_TYPE_IO_APIC] = "IO APIC",
45027941afaSEd Maste     [ACPI_MADT_TYPE_INTERRUPT_OVERRIDE] = "INT Override",
45127941afaSEd Maste     [ACPI_MADT_TYPE_NMI_SOURCE] = "NMI",
45227941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_APIC_NMI] = "Local APIC NMI",
45327941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE] = "Local APIC Override",
45427941afaSEd Maste     [ACPI_MADT_TYPE_IO_SAPIC] = "IO SAPIC",
45527941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_SAPIC] = "Local SAPIC",
45627941afaSEd Maste     [ACPI_MADT_TYPE_INTERRUPT_SOURCE] = "Platform Interrupt",
45727941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_X2APIC] = "Local X2APIC",
45827941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_X2APIC_NMI] = "Local X2APIC NMI",
45927941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_INTERRUPT] = "GIC CPU Interface Structure",
46027941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR] = "GIC Distributor Structure",
46127941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_MSI_FRAME] = "GICv2m MSI Frame",
46227941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR] = "GIC Redistributor Structure",
46327941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_TRANSLATOR] = "GIC ITS Structure"
46427941afaSEd Maste };
46527941afaSEd Maste 
466bf70beceSEd Schouten static const char *platform_int_types[] = { "0 (unknown)", "PMI", "INIT",
4670a473124SJohn Baldwin 					    "Corrected Platform Error" };
4680a473124SJohn Baldwin 
4690a473124SJohn Baldwin static void
470986dffafSJohn Baldwin acpi_print_madt(ACPI_SUBTABLE_HEADER *mp)
4710a473124SJohn Baldwin {
472986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_APIC *lapic;
473986dffafSJohn Baldwin 	ACPI_MADT_IO_APIC *ioapic;
474986dffafSJohn Baldwin 	ACPI_MADT_INTERRUPT_OVERRIDE *over;
475986dffafSJohn Baldwin 	ACPI_MADT_NMI_SOURCE *nmi;
476986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_APIC_NMI *lapic_nmi;
477986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic_over;
478986dffafSJohn Baldwin 	ACPI_MADT_IO_SAPIC *iosapic;
479986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_SAPIC *lsapic;
480986dffafSJohn Baldwin 	ACPI_MADT_INTERRUPT_SOURCE *isrc;
481986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_X2APIC *x2apic;
482986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_X2APIC_NMI *x2apic_nmi;
4832b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_INTERRUPT *gicc;
4842b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_DISTRIBUTOR *gicd;
4852b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_REDISTRIBUTOR *gicr;
4862b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_TRANSLATOR *gict;
4870a473124SJohn Baldwin 
488c86932b6SMarcelo Araujo 	if (mp->Type < nitems(apic_types))
489986dffafSJohn Baldwin 		printf("\tType=%s\n", apic_types[mp->Type]);
490a0333ad1SJohn Baldwin 	else
491986dffafSJohn Baldwin 		printf("\tType=%d (unknown)\n", mp->Type);
492986dffafSJohn Baldwin 	switch (mp->Type) {
493986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_APIC:
494986dffafSJohn Baldwin 		lapic = (ACPI_MADT_LOCAL_APIC *)mp;
495986dffafSJohn Baldwin 		acpi_print_cpu(lapic->ProcessorId);
496986dffafSJohn Baldwin 		acpi_print_local_apic(lapic->Id, lapic->LapicFlags);
4970a473124SJohn Baldwin 		break;
498986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_IO_APIC:
499986dffafSJohn Baldwin 		ioapic = (ACPI_MADT_IO_APIC *)mp;
500986dffafSJohn Baldwin 		acpi_print_io_apic(ioapic->Id, ioapic->GlobalIrqBase,
501986dffafSJohn Baldwin 		    ioapic->Address);
5020a473124SJohn Baldwin 		break;
503986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
504986dffafSJohn Baldwin 		over = (ACPI_MADT_INTERRUPT_OVERRIDE *)mp;
505986dffafSJohn Baldwin 		printf("\tBUS=%d\n", (u_int)over->Bus);
506986dffafSJohn Baldwin 		printf("\tIRQ=%d\n", (u_int)over->SourceIrq);
507986dffafSJohn Baldwin 		acpi_print_intr(over->GlobalIrq, over->IntiFlags);
5080a473124SJohn Baldwin 		break;
509986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_NMI_SOURCE:
510986dffafSJohn Baldwin 		nmi = (ACPI_MADT_NMI_SOURCE *)mp;
511986dffafSJohn Baldwin 		acpi_print_intr(nmi->GlobalIrq, nmi->IntiFlags);
5120a473124SJohn Baldwin 		break;
513986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
514986dffafSJohn Baldwin 		lapic_nmi = (ACPI_MADT_LOCAL_APIC_NMI *)mp;
515986dffafSJohn Baldwin 		acpi_print_cpu(lapic_nmi->ProcessorId);
516986dffafSJohn Baldwin 		acpi_print_local_nmi(lapic_nmi->Lint, lapic_nmi->IntiFlags);
5170a473124SJohn Baldwin 		break;
518986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
519986dffafSJohn Baldwin 		lapic_over = (ACPI_MADT_LOCAL_APIC_OVERRIDE *)mp;
520945137d9SNate Lawson 		printf("\tLocal APIC ADDR=0x%016jx\n",
521986dffafSJohn Baldwin 		    (uintmax_t)lapic_over->Address);
5220a473124SJohn Baldwin 		break;
523986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_IO_SAPIC:
524986dffafSJohn Baldwin 		iosapic = (ACPI_MADT_IO_SAPIC *)mp;
525986dffafSJohn Baldwin 		acpi_print_io_apic(iosapic->Id, iosapic->GlobalIrqBase,
526986dffafSJohn Baldwin 		    iosapic->Address);
5270a473124SJohn Baldwin 		break;
528986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_SAPIC:
529986dffafSJohn Baldwin 		lsapic = (ACPI_MADT_LOCAL_SAPIC *)mp;
530986dffafSJohn Baldwin 		acpi_print_cpu(lsapic->ProcessorId);
531986dffafSJohn Baldwin 		acpi_print_local_apic(lsapic->Id, lsapic->LapicFlags);
532986dffafSJohn Baldwin 		printf("\tAPIC EID=%d\n", (u_int)lsapic->Eid);
533986dffafSJohn Baldwin 		if (mp->Length > __offsetof(ACPI_MADT_LOCAL_SAPIC, Uid))
534986dffafSJohn Baldwin 			acpi_print_cpu_uid(lsapic->Uid, lsapic->UidString);
5350a473124SJohn Baldwin 		break;
536986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
537986dffafSJohn Baldwin 		isrc = (ACPI_MADT_INTERRUPT_SOURCE *)mp;
538c86932b6SMarcelo Araujo 		if (isrc->Type < nitems(platform_int_types))
539986dffafSJohn Baldwin 			printf("\tType=%s\n", platform_int_types[isrc->Type]);
540986dffafSJohn Baldwin 		else
541986dffafSJohn Baldwin 			printf("\tType=%d (unknown)\n", isrc->Type);
542986dffafSJohn Baldwin 		printf("\tAPIC ID=%d\n", (u_int)isrc->Id);
543986dffafSJohn Baldwin 		printf("\tAPIC EID=%d\n", (u_int)isrc->Eid);
544986dffafSJohn Baldwin 		printf("\tSAPIC Vector=%d\n", (u_int)isrc->IoSapicVector);
545986dffafSJohn Baldwin 		acpi_print_intr(isrc->GlobalIrq, isrc->IntiFlags);
546986dffafSJohn Baldwin 		break;
547986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_X2APIC:
548986dffafSJohn Baldwin 		x2apic = (ACPI_MADT_LOCAL_X2APIC *)mp;
549986dffafSJohn Baldwin 		acpi_print_cpu_uid(x2apic->Uid, NULL);
550986dffafSJohn Baldwin 		acpi_print_local_apic(x2apic->LocalApicId, x2apic->LapicFlags);
551986dffafSJohn Baldwin 		break;
552986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
553986dffafSJohn Baldwin 		x2apic_nmi = (ACPI_MADT_LOCAL_X2APIC_NMI *)mp;
554986dffafSJohn Baldwin 		acpi_print_cpu_uid(x2apic_nmi->Uid, NULL);
555986dffafSJohn Baldwin 		acpi_print_local_nmi(x2apic_nmi->Lint, x2apic_nmi->IntiFlags);
5560a473124SJohn Baldwin 		break;
5572b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
5582b2b1f42SAndrew Turner 		gicc = (ACPI_MADT_GENERIC_INTERRUPT *)mp;
5592b2b1f42SAndrew Turner 		acpi_print_cpu_uid(gicc->Uid, NULL);
5602b2b1f42SAndrew Turner 		printf("\tCPU INTERFACE=%x\n", gicc->CpuInterfaceNumber);
5612b2b1f42SAndrew Turner 		acpi_print_gicc_flags(gicc->Flags);
5622b2b1f42SAndrew Turner 		printf("\tParking Protocol Version=%x\n", gicc->ParkingVersion);
5632b2b1f42SAndrew Turner 		printf("\tPERF INTR=%d\n", gicc->PerformanceInterrupt);
5642b2b1f42SAndrew Turner 		printf("\tParked ADDR=%016jx\n",
5652b2b1f42SAndrew Turner 		    (uintmax_t)gicc->ParkedAddress);
5662b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicc->BaseAddress);
5672b2b1f42SAndrew Turner 		printf("\tGICV=%016jx\n", (uintmax_t)gicc->GicvBaseAddress);
5682b2b1f42SAndrew Turner 		printf("\tGICH=%016jx\n", (uintmax_t)gicc->GichBaseAddress);
5692b2b1f42SAndrew Turner 		printf("\tVGIC INTR=%d\n", gicc->VgicInterrupt);
5702b2b1f42SAndrew Turner 		printf("\tGICR ADDR=%016jx\n",
5712b2b1f42SAndrew Turner 		    (uintmax_t)gicc->GicrBaseAddress);
5722b2b1f42SAndrew Turner 		printf("\tMPIDR=%jx\n", (uintmax_t)gicc->ArmMpidr);
5730b4302aaSGordon Bergling 		printf("\tEfficiency Class=%d\n", (u_int)gicc->EfficiencyClass);
574c363da4aSAndrew Turner 		printf("\tSPE INTR=%d\n", gicc->SpeInterrupt);
5752b2b1f42SAndrew Turner 		break;
5762b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
5772b2b1f42SAndrew Turner 		gicd = (ACPI_MADT_GENERIC_DISTRIBUTOR *)mp;
5782b2b1f42SAndrew Turner 		printf("\tGIC ID=%d\n", (u_int)gicd->GicId);
5792b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicd->BaseAddress);
5802b2b1f42SAndrew Turner 		printf("\tVector Base=%d\n", gicd->GlobalIrqBase);
5812b2b1f42SAndrew Turner 		printf("\tGIC VERSION=%d\n", (u_int)gicd->Version);
5822b2b1f42SAndrew Turner 		break;
5832b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
5842b2b1f42SAndrew Turner 		gicr = (ACPI_MADT_GENERIC_REDISTRIBUTOR *)mp;
5852b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicr->BaseAddress);
5862b2b1f42SAndrew Turner 		printf("\tLength=%08x\n", gicr->Length);
5872b2b1f42SAndrew Turner 		break;
5882b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
5892b2b1f42SAndrew Turner 		gict = (ACPI_MADT_GENERIC_TRANSLATOR *)mp;
5902b2b1f42SAndrew Turner 		printf("\tGIC ITS ID=%d\n", gict->TranslationId);
5912b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gict->BaseAddress);
5922b2b1f42SAndrew Turner 		break;
5930a473124SJohn Baldwin 	}
5940a473124SJohn Baldwin }
5950a473124SJohn Baldwin 
5960a473124SJohn Baldwin static void
597986dffafSJohn Baldwin acpi_handle_madt(ACPI_TABLE_HEADER *sdp)
5980a473124SJohn Baldwin {
599986dffafSJohn Baldwin 	ACPI_TABLE_MADT *madt;
6000a473124SJohn Baldwin 
601773b6454SNate Lawson 	printf(BEGIN_COMMENT);
602773b6454SNate Lawson 	acpi_print_sdt(sdp);
603986dffafSJohn Baldwin 	madt = (ACPI_TABLE_MADT *)sdp;
604986dffafSJohn Baldwin 	printf("\tLocal APIC ADDR=0x%08x\n", madt->Address);
6050a473124SJohn Baldwin 	printf("\tFlags={");
606986dffafSJohn Baldwin 	if (madt->Flags & ACPI_MADT_PCAT_COMPAT)
6070a473124SJohn Baldwin 		printf("PC-AT");
6080a473124SJohn Baldwin 	printf("}\n");
609986dffafSJohn Baldwin 	acpi_walk_subtables(sdp, (madt + 1), acpi_print_madt);
6100a473124SJohn Baldwin 	printf(END_COMMENT);
6110a473124SJohn Baldwin }
6120a473124SJohn Baldwin 
6130a473124SJohn Baldwin static void
614ebc22d04SAlexander Motin acpi_handle_bert(ACPI_TABLE_HEADER *sdp)
615ebc22d04SAlexander Motin {
616ebc22d04SAlexander Motin 	ACPI_TABLE_BERT *bert;
617ebc22d04SAlexander Motin 
618ebc22d04SAlexander Motin 	printf(BEGIN_COMMENT);
619ebc22d04SAlexander Motin 	acpi_print_sdt(sdp);
620ebc22d04SAlexander Motin 	bert = (ACPI_TABLE_BERT *)sdp;
621ebc22d04SAlexander Motin 	printf("\tRegionLength=%d\n", bert->RegionLength);
622ebc22d04SAlexander Motin 	printf("\tAddress=0x%016jx\n", bert->Address);
623ebc22d04SAlexander Motin 	printf(END_COMMENT);
624ebc22d04SAlexander Motin }
625ebc22d04SAlexander Motin 
626ebc22d04SAlexander Motin static void
627ebc22d04SAlexander Motin acpi_print_whea(ACPI_WHEA_HEADER *w)
628ebc22d04SAlexander Motin {
629ebc22d04SAlexander Motin 
630ebc22d04SAlexander Motin 	printf("\n\tAction=%d\n", w->Action);
631ebc22d04SAlexander Motin 	printf("\tInstruction=%d\n", w->Instruction);
632ebc22d04SAlexander Motin 	printf("\tFlags=%02x\n", w->Flags);
633ebc22d04SAlexander Motin 	printf("\tRegisterRegion=");
634ebc22d04SAlexander Motin 	acpi_print_gas(&w->RegisterRegion);
635ebc22d04SAlexander Motin 	printf("\n\tValue=0x%016jx\n", w->Value);
636ebc22d04SAlexander Motin 	printf("\tMask=0x%016jx\n", w->Mask);
637ebc22d04SAlexander Motin }
638ebc22d04SAlexander Motin 
639ebc22d04SAlexander Motin static void
640ebc22d04SAlexander Motin acpi_handle_einj(ACPI_TABLE_HEADER *sdp)
641ebc22d04SAlexander Motin {
642ebc22d04SAlexander Motin 	ACPI_TABLE_EINJ *einj;
643ebc22d04SAlexander Motin 	ACPI_WHEA_HEADER *w;
644ebc22d04SAlexander Motin 	u_int i;
645ebc22d04SAlexander Motin 
646ebc22d04SAlexander Motin 	printf(BEGIN_COMMENT);
647ebc22d04SAlexander Motin 	acpi_print_sdt(sdp);
648ebc22d04SAlexander Motin 	einj = (ACPI_TABLE_EINJ *)sdp;
649ebc22d04SAlexander Motin 	printf("\tHeaderLength=%d\n", einj->HeaderLength);
650ebc22d04SAlexander Motin 	printf("\tFlags=0x%02x\n", einj->Flags);
651ebc22d04SAlexander Motin 	printf("\tEntries=%d\n", einj->Entries);
652ebc22d04SAlexander Motin 	w = (ACPI_WHEA_HEADER *)(einj + 1);
653ebc22d04SAlexander Motin 	for (i = 0; i < MIN(einj->Entries, (sdp->Length -
654ebc22d04SAlexander Motin 	    sizeof(ACPI_TABLE_EINJ)) / sizeof(ACPI_WHEA_HEADER)); i++)
655ebc22d04SAlexander Motin 		acpi_print_whea(w + i);
656ebc22d04SAlexander Motin 	printf(END_COMMENT);
657ebc22d04SAlexander Motin }
658ebc22d04SAlexander Motin 
659ebc22d04SAlexander Motin static void
660ebc22d04SAlexander Motin acpi_handle_erst(ACPI_TABLE_HEADER *sdp)
661ebc22d04SAlexander Motin {
662ebc22d04SAlexander Motin 	ACPI_TABLE_ERST *erst;
663ebc22d04SAlexander Motin 	ACPI_WHEA_HEADER *w;
664ebc22d04SAlexander Motin 	u_int i;
665ebc22d04SAlexander Motin 
666ebc22d04SAlexander Motin 	printf(BEGIN_COMMENT);
667ebc22d04SAlexander Motin 	acpi_print_sdt(sdp);
668ebc22d04SAlexander Motin 	erst = (ACPI_TABLE_ERST *)sdp;
669ebc22d04SAlexander Motin 	printf("\tHeaderLength=%d\n", erst->HeaderLength);
670ebc22d04SAlexander Motin 	printf("\tEntries=%d\n", erst->Entries);
671ebc22d04SAlexander Motin 	w = (ACPI_WHEA_HEADER *)(erst + 1);
672ebc22d04SAlexander Motin 	for (i = 0; i < MIN(erst->Entries, (sdp->Length -
673ebc22d04SAlexander Motin 	    sizeof(ACPI_TABLE_ERST)) / sizeof(ACPI_WHEA_HEADER)); i++)
674ebc22d04SAlexander Motin 		acpi_print_whea(w + i);
675ebc22d04SAlexander Motin 	printf(END_COMMENT);
676ebc22d04SAlexander Motin }
677ebc22d04SAlexander Motin 
678ebc22d04SAlexander Motin static void
679ebc22d04SAlexander Motin acpi_print_hest_bank(ACPI_HEST_IA_ERROR_BANK *b)
680ebc22d04SAlexander Motin {
681ebc22d04SAlexander Motin 
682ebc22d04SAlexander Motin 	printf("\tBank:\n");
683ebc22d04SAlexander Motin 	printf("\t\tBankNumber=%d\n", b->BankNumber);
684ebc22d04SAlexander Motin 	printf("\t\tClearStatusOnInit=%d\n", b->ClearStatusOnInit);
685ebc22d04SAlexander Motin 	printf("\t\tStatusFormat=%d\n", b->StatusFormat);
686ebc22d04SAlexander Motin 	printf("\t\tControlRegister=%x\n", b->ControlRegister);
687ebc22d04SAlexander Motin 	printf("\t\tControlData=%jx\n", b->ControlData);
688ebc22d04SAlexander Motin 	printf("\t\tStatusRegister=%x\n", b->StatusRegister);
689ebc22d04SAlexander Motin 	printf("\t\tAddressRegister=%x\n", b->AddressRegister);
690ebc22d04SAlexander Motin 	printf("\t\tMiscRegister=%x\n", b->MiscRegister);
691ebc22d04SAlexander Motin }
692ebc22d04SAlexander Motin 
693ebc22d04SAlexander Motin static void
694ebc22d04SAlexander Motin acpi_print_hest_notify(ACPI_HEST_NOTIFY *n)
695ebc22d04SAlexander Motin {
696ebc22d04SAlexander Motin 
697ebc22d04SAlexander Motin 	printf("\t\tType=%d\n", n->Type);
698ebc22d04SAlexander Motin 	printf("\t\tLength=%d\n", n->Length);
699ebc22d04SAlexander Motin 	printf("\t\tConfigWriteEnable=%04x\n", n->ConfigWriteEnable);
700ebc22d04SAlexander Motin 	printf("\t\tPollInterval=%d\n", n->PollInterval);
701ebc22d04SAlexander Motin 	printf("\t\tVector=%d\n", n->Vector);
702ebc22d04SAlexander Motin 	printf("\t\tPollingThresholdValue=%d\n", n->PollingThresholdValue);
703ebc22d04SAlexander Motin 	printf("\t\tPollingThresholdWindow=%d\n", n->PollingThresholdWindow);
704ebc22d04SAlexander Motin 	printf("\t\tErrorThresholdValue=%d\n", n->ErrorThresholdValue);
705ebc22d04SAlexander Motin 	printf("\t\tErrorThresholdWindow=%d\n", n->ErrorThresholdWindow);
706ebc22d04SAlexander Motin }
707ebc22d04SAlexander Motin 
708ebc22d04SAlexander Motin static void
709ebc22d04SAlexander Motin acpi_print_hest_aer(ACPI_HEST_AER_COMMON *a)
710ebc22d04SAlexander Motin {
711ebc22d04SAlexander Motin 
712ebc22d04SAlexander Motin 	printf("\tFlags=%02x\n", a->Flags);
713ebc22d04SAlexander Motin 	printf("\tEnabled=%d\n", a->Enabled);
714ebc22d04SAlexander Motin 	printf("\tRecordsToPreallocate=%d\n", a->RecordsToPreallocate);
715ebc22d04SAlexander Motin 	printf("\tMaxSectionsPerRecord=%d\n", a->MaxSectionsPerRecord);
716ebc22d04SAlexander Motin 	printf("\tBus=%d\n", a->Bus);
717ebc22d04SAlexander Motin 	printf("\tDevice=%d\n", a->Device);
718ebc22d04SAlexander Motin 	printf("\tFunction=%d\n", a->Function);
719ebc22d04SAlexander Motin 	printf("\tDeviceControl=%d\n", a->DeviceControl);
720ebc22d04SAlexander Motin 	printf("\tUncorrectableMask=%d\n", a->UncorrectableMask);
721ebc22d04SAlexander Motin 	printf("\tUncorrectableSeverity=%d\n", a->UncorrectableSeverity);
722ebc22d04SAlexander Motin 	printf("\tCorrectableMask=%d\n", a->CorrectableMask);
723ebc22d04SAlexander Motin 	printf("\tAdvancedCapabilities=%d\n", a->AdvancedCapabilities);
724ebc22d04SAlexander Motin }
725ebc22d04SAlexander Motin 
726ebc22d04SAlexander Motin static int
727ebc22d04SAlexander Motin acpi_handle_hest_structure(void *addr, int remaining)
728ebc22d04SAlexander Motin {
729ebc22d04SAlexander Motin 	ACPI_HEST_HEADER *hdr = addr;
730ebc22d04SAlexander Motin 	int i;
731ebc22d04SAlexander Motin 
732ebc22d04SAlexander Motin 	if (remaining < (int)sizeof(ACPI_HEST_HEADER))
733ebc22d04SAlexander Motin 		return (-1);
734ebc22d04SAlexander Motin 
735ebc22d04SAlexander Motin 	printf("\n\tType=%d\n", hdr->Type);
736ebc22d04SAlexander Motin 	printf("\tSourceId=%d\n", hdr->SourceId);
737ebc22d04SAlexander Motin 	switch (hdr->Type) {
738ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_IA32_CHECK: {
739ebc22d04SAlexander Motin 		ACPI_HEST_IA_MACHINE_CHECK *s = addr;
740ebc22d04SAlexander Motin 		printf("\tFlags=%02x\n", s->Flags);
741ebc22d04SAlexander Motin 		printf("\tEnabled=%d\n", s->Enabled);
742ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
743ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
744ebc22d04SAlexander Motin 		printf("\tGlobalCapabilityData=%jd\n", s->GlobalCapabilityData);
745ebc22d04SAlexander Motin 		printf("\tGlobalControlData=%jd\n", s->GlobalControlData);
746ebc22d04SAlexander Motin 		printf("\tNumHardwareBanks=%d\n", s->NumHardwareBanks);
747ebc22d04SAlexander Motin 		for (i = 0; i < s->NumHardwareBanks; i++) {
748ebc22d04SAlexander Motin 			acpi_print_hest_bank((ACPI_HEST_IA_ERROR_BANK *)
749ebc22d04SAlexander Motin 			    (s + 1) + i);
750ebc22d04SAlexander Motin 		}
751ebc22d04SAlexander Motin 		return (sizeof(*s) + s->NumHardwareBanks *
752ebc22d04SAlexander Motin 		    sizeof(ACPI_HEST_IA_ERROR_BANK));
753ebc22d04SAlexander Motin 	}
754ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: {
755ebc22d04SAlexander Motin 		ACPI_HEST_IA_CORRECTED *s = addr;
756ebc22d04SAlexander Motin 		printf("\tFlags=%02x\n", s->Flags);
757ebc22d04SAlexander Motin 		printf("\tEnabled=%d\n", s->Enabled);
758ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
759ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
760ebc22d04SAlexander Motin 		printf("\tNotify:\n");
761ebc22d04SAlexander Motin 		acpi_print_hest_notify(&s->Notify);
762ebc22d04SAlexander Motin 		printf("\tNumHardwareBanks=%d\n", s->NumHardwareBanks);
763ebc22d04SAlexander Motin 		for (i = 0; i < s->NumHardwareBanks; i++) {
764ebc22d04SAlexander Motin 			acpi_print_hest_bank((ACPI_HEST_IA_ERROR_BANK *)
765ebc22d04SAlexander Motin 			    (s + 1) + i);
766ebc22d04SAlexander Motin 		}
767ebc22d04SAlexander Motin 		return (sizeof(*s) + s->NumHardwareBanks *
768ebc22d04SAlexander Motin 		    sizeof(ACPI_HEST_IA_ERROR_BANK));
769ebc22d04SAlexander Motin 	}
770ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_IA32_NMI: {
771ebc22d04SAlexander Motin 		ACPI_HEST_IA_NMI *s = addr;
772ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
773ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
774ebc22d04SAlexander Motin 		printf("\tMaxRawDataLength=%d\n", s->MaxRawDataLength);
775ebc22d04SAlexander Motin 		return (sizeof(*s));
776ebc22d04SAlexander Motin 	}
777ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_AER_ROOT_PORT: {
778ebc22d04SAlexander Motin 		ACPI_HEST_AER_ROOT *s = addr;
779ebc22d04SAlexander Motin 		acpi_print_hest_aer(&s->Aer);
780ebc22d04SAlexander Motin 		printf("\tRootErrorCommand=%d\n", s->RootErrorCommand);
781ebc22d04SAlexander Motin 		return (sizeof(*s));
782ebc22d04SAlexander Motin 	}
783ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_AER_ENDPOINT: {
784ebc22d04SAlexander Motin 		ACPI_HEST_AER *s = addr;
785ebc22d04SAlexander Motin 		acpi_print_hest_aer(&s->Aer);
786ebc22d04SAlexander Motin 		return (sizeof(*s));
787ebc22d04SAlexander Motin 	}
788ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_AER_BRIDGE: {
789ebc22d04SAlexander Motin 		ACPI_HEST_AER_BRIDGE *s = addr;
790ebc22d04SAlexander Motin 		acpi_print_hest_aer(&s->Aer);
791ebc22d04SAlexander Motin 		printf("\tUncorrectableMask2=%d\n", s->UncorrectableMask2);
792ebc22d04SAlexander Motin 		printf("\tUncorrectableSeverity2=%d\n", s->UncorrectableSeverity2);
793ebc22d04SAlexander Motin 		printf("\tAdvancedCapabilities2=%d\n", s->AdvancedCapabilities2);
794ebc22d04SAlexander Motin 		return (sizeof(*s));
795ebc22d04SAlexander Motin 	}
796ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_GENERIC_ERROR: {
797ebc22d04SAlexander Motin 		ACPI_HEST_GENERIC *s = addr;
798ebc22d04SAlexander Motin 		printf("\tRelatedSourceId=%d\n", s->RelatedSourceId);
799ebc22d04SAlexander Motin 		printf("\tEnabled=%d\n", s->Enabled);
800ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
801ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
802ebc22d04SAlexander Motin 		printf("\tMaxRawDataLength=%d\n", s->MaxRawDataLength);
803ebc22d04SAlexander Motin 		printf("\tErrorStatusAddress=");
804ebc22d04SAlexander Motin 		acpi_print_gas(&s->ErrorStatusAddress);
805ebc22d04SAlexander Motin 		printf("\n");
806ebc22d04SAlexander Motin 		printf("\tNotify:\n");
807ebc22d04SAlexander Motin 		acpi_print_hest_notify(&s->Notify);
808ebc22d04SAlexander Motin 		printf("\tErrorBlockLength=%d\n", s->ErrorBlockLength);
809ebc22d04SAlexander Motin 		return (sizeof(*s));
810ebc22d04SAlexander Motin 	}
811ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_GENERIC_ERROR_V2: {
812ebc22d04SAlexander Motin 		ACPI_HEST_GENERIC_V2 *s = addr;
813ebc22d04SAlexander Motin 		printf("\tRelatedSourceId=%d\n", s->RelatedSourceId);
814ebc22d04SAlexander Motin 		printf("\tEnabled=%d\n", s->Enabled);
815ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
816ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
817ebc22d04SAlexander Motin 		printf("\tMaxRawDataLength=%d\n", s->MaxRawDataLength);
818ebc22d04SAlexander Motin 		printf("\tErrorStatusAddress=");
819ebc22d04SAlexander Motin 		acpi_print_gas(&s->ErrorStatusAddress);
820ebc22d04SAlexander Motin 		printf("\n");
821ebc22d04SAlexander Motin 		printf("\tNotify:\n");
822ebc22d04SAlexander Motin 		acpi_print_hest_notify(&s->Notify);
823ebc22d04SAlexander Motin 		printf("\tErrorBlockLength=%d\n", s->ErrorBlockLength);
824ebc22d04SAlexander Motin 		printf("\tReadAckRegister=");
825ebc22d04SAlexander Motin 		acpi_print_gas(&s->ReadAckRegister);
826ebc22d04SAlexander Motin 		printf("\n");
827ebc22d04SAlexander Motin 		printf("\tReadAckPreserve=%jd\n", s->ReadAckPreserve);
828ebc22d04SAlexander Motin 		printf("\tReadAckWrite=%jd\n", s->ReadAckWrite);
829ebc22d04SAlexander Motin 		return (sizeof(*s));
830ebc22d04SAlexander Motin 	}
831ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: {
832ebc22d04SAlexander Motin 		ACPI_HEST_IA_DEFERRED_CHECK *s = addr;
833ebc22d04SAlexander Motin 		printf("\tFlags=%02x\n", s->Flags);
834ebc22d04SAlexander Motin 		printf("\tEnabled=%d\n", s->Enabled);
835ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
836ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
837ebc22d04SAlexander Motin 		printf("\tNotify:\n");
838ebc22d04SAlexander Motin 		acpi_print_hest_notify(&s->Notify);
839ebc22d04SAlexander Motin 		printf("\tNumHardwareBanks=%d\n", s->NumHardwareBanks);
840ebc22d04SAlexander Motin 		for (i = 0; i < s->NumHardwareBanks; i++) {
841ebc22d04SAlexander Motin 			acpi_print_hest_bank((ACPI_HEST_IA_ERROR_BANK *)
842ebc22d04SAlexander Motin 			    (s + 1) + i);
843ebc22d04SAlexander Motin 		}
844ebc22d04SAlexander Motin 		return (sizeof(*s) + s->NumHardwareBanks *
845ebc22d04SAlexander Motin 		    sizeof(ACPI_HEST_IA_ERROR_BANK));
846ebc22d04SAlexander Motin 	}
847ebc22d04SAlexander Motin 	default:
848ebc22d04SAlexander Motin 		return (-1);
849ebc22d04SAlexander Motin 	}
850ebc22d04SAlexander Motin }
851ebc22d04SAlexander Motin 
852ebc22d04SAlexander Motin static void
853ebc22d04SAlexander Motin acpi_handle_hest(ACPI_TABLE_HEADER *sdp)
854ebc22d04SAlexander Motin {
855ebc22d04SAlexander Motin 	char *cp;
856ebc22d04SAlexander Motin 	int remaining, consumed;
857ebc22d04SAlexander Motin 	ACPI_TABLE_HEST *hest;
858ebc22d04SAlexander Motin 
859ebc22d04SAlexander Motin 	printf(BEGIN_COMMENT);
860ebc22d04SAlexander Motin 	acpi_print_sdt(sdp);
861ebc22d04SAlexander Motin 	hest = (ACPI_TABLE_HEST *)sdp;
862ebc22d04SAlexander Motin 	printf("\tErrorSourceCount=%d\n", hest->ErrorSourceCount);
863ebc22d04SAlexander Motin 
864ebc22d04SAlexander Motin 	remaining = sdp->Length - sizeof(ACPI_TABLE_HEST);
865ebc22d04SAlexander Motin 	while (remaining > 0) {
866ebc22d04SAlexander Motin 		cp = (char *)sdp + sdp->Length - remaining;
867ebc22d04SAlexander Motin 		consumed = acpi_handle_hest_structure(cp, remaining);
868ebc22d04SAlexander Motin 		if (consumed <= 0)
869ebc22d04SAlexander Motin 			break;
870ebc22d04SAlexander Motin 		else
871ebc22d04SAlexander Motin 			remaining -= consumed;
872ebc22d04SAlexander Motin 	}
873ebc22d04SAlexander Motin 	printf(END_COMMENT);
874ebc22d04SAlexander Motin }
875ebc22d04SAlexander Motin 
876ebc22d04SAlexander Motin static void
877986dffafSJohn Baldwin acpi_handle_hpet(ACPI_TABLE_HEADER *sdp)
87879d7565cSPeter Wemm {
879986dffafSJohn Baldwin 	ACPI_TABLE_HPET *hpet;
88079d7565cSPeter Wemm 
881773b6454SNate Lawson 	printf(BEGIN_COMMENT);
882773b6454SNate Lawson 	acpi_print_sdt(sdp);
883986dffafSJohn Baldwin 	hpet = (ACPI_TABLE_HPET *)sdp;
884986dffafSJohn Baldwin 	printf("\tHPET Number=%d\n", hpet->Sequence);
88587f9f09aSTakanori Watanabe 	printf("\tADDR=");
886986dffafSJohn Baldwin 	acpi_print_gas(&hpet->Address);
887ebc22d04SAlexander Motin 	printf("\n\tHW Rev=0x%x\n", hpet->Id & ACPI_HPET_ID_HARDWARE_REV_ID);
888986dffafSJohn Baldwin 	printf("\tComparators=%d\n", (hpet->Id & ACPI_HPET_ID_COMPARATORS) >>
889986dffafSJohn Baldwin 	    8);
890986dffafSJohn Baldwin 	printf("\tCounter Size=%d\n", hpet->Id & ACPI_HPET_ID_COUNT_SIZE_CAP ?
891986dffafSJohn Baldwin 	    1 : 0);
89279d7565cSPeter Wemm 	printf("\tLegacy IRQ routing capable={");
893986dffafSJohn Baldwin 	if (hpet->Id & ACPI_HPET_ID_LEGACY_CAPABLE)
89479d7565cSPeter Wemm 		printf("TRUE}\n");
89579d7565cSPeter Wemm 	else
89679d7565cSPeter Wemm 		printf("FALSE}\n");
897986dffafSJohn Baldwin 	printf("\tPCI Vendor ID=0x%04x\n", hpet->Id >> 16);
898986dffafSJohn Baldwin 	printf("\tMinimal Tick=%d\n", hpet->MinimumTick);
8999785e979SNeel Natu 	printf("\tFlags=0x%02x\n", hpet->Flags);
90079d7565cSPeter Wemm 	printf(END_COMMENT);
90179d7565cSPeter Wemm }
90279d7565cSPeter Wemm 
90379d7565cSPeter Wemm static void
904986dffafSJohn Baldwin acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp)
90555d7ff9eSNate Lawson {
906986dffafSJohn Baldwin 	ACPI_TABLE_ECDT *ecdt;
90755d7ff9eSNate Lawson 
90855d7ff9eSNate Lawson 	printf(BEGIN_COMMENT);
90955d7ff9eSNate Lawson 	acpi_print_sdt(sdp);
910986dffafSJohn Baldwin 	ecdt = (ACPI_TABLE_ECDT *)sdp;
91155d7ff9eSNate Lawson 	printf("\tEC_CONTROL=");
912986dffafSJohn Baldwin 	acpi_print_gas(&ecdt->Control);
91355d7ff9eSNate Lawson 	printf("\n\tEC_DATA=");
914986dffafSJohn Baldwin 	acpi_print_gas(&ecdt->Data);
915986dffafSJohn Baldwin 	printf("\n\tUID=%#x, ", ecdt->Uid);
916986dffafSJohn Baldwin 	printf("GPE_BIT=%#x\n", ecdt->Gpe);
917986dffafSJohn Baldwin 	printf("\tEC_ID=%s\n", ecdt->Id);
91855d7ff9eSNate Lawson 	printf(END_COMMENT);
91955d7ff9eSNate Lawson }
92055d7ff9eSNate Lawson 
92155d7ff9eSNate Lawson static void
922986dffafSJohn Baldwin acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp)
923a47e681bSScott Long {
924986dffafSJohn Baldwin 	ACPI_TABLE_MCFG *mcfg;
925986dffafSJohn Baldwin 	ACPI_MCFG_ALLOCATION *alloc;
926986dffafSJohn Baldwin 	u_int i, entries;
927a47e681bSScott Long 
928a47e681bSScott Long 	printf(BEGIN_COMMENT);
929a47e681bSScott Long 	acpi_print_sdt(sdp);
930986dffafSJohn Baldwin 	mcfg = (ACPI_TABLE_MCFG *)sdp;
931986dffafSJohn Baldwin 	entries = (sdp->Length - sizeof(ACPI_TABLE_MCFG)) /
932986dffafSJohn Baldwin 	    sizeof(ACPI_MCFG_ALLOCATION);
933986dffafSJohn Baldwin 	alloc = (ACPI_MCFG_ALLOCATION *)(mcfg + 1);
934986dffafSJohn Baldwin 	for (i = 0; i < entries; i++, alloc++) {
935a47e681bSScott Long 		printf("\n");
9360c10b85aSJung-uk Kim 		printf("\tBase Address=0x%016jx\n", (uintmax_t)alloc->Address);
937986dffafSJohn Baldwin 		printf("\tSegment Group=0x%04x\n", alloc->PciSegment);
938986dffafSJohn Baldwin 		printf("\tStart Bus=%d\n", alloc->StartBusNumber);
939986dffafSJohn Baldwin 		printf("\tEnd Bus=%d\n", alloc->EndBusNumber);
940a47e681bSScott Long 	}
941a47e681bSScott Long 	printf(END_COMMENT);
942a47e681bSScott Long }
943a47e681bSScott Long 
944a47e681bSScott Long static void
94533866658SJohn Baldwin acpi_handle_slit(ACPI_TABLE_HEADER *sdp)
94633866658SJohn Baldwin {
94733866658SJohn Baldwin 	ACPI_TABLE_SLIT *slit;
94833866658SJohn Baldwin 	UINT64 i, j;
94933866658SJohn Baldwin 
95033866658SJohn Baldwin 	printf(BEGIN_COMMENT);
95133866658SJohn Baldwin 	acpi_print_sdt(sdp);
95233866658SJohn Baldwin 	slit = (ACPI_TABLE_SLIT *)sdp;
9530c10b85aSJung-uk Kim 	printf("\tLocality Count=%ju\n", (uintmax_t)slit->LocalityCount);
95433866658SJohn Baldwin 	printf("\n\t      ");
95533866658SJohn Baldwin 	for (i = 0; i < slit->LocalityCount; i++)
9560c10b85aSJung-uk Kim 		printf(" %3ju", (uintmax_t)i);
95733866658SJohn Baldwin 	printf("\n\t     +");
95833866658SJohn Baldwin 	for (i = 0; i < slit->LocalityCount; i++)
95933866658SJohn Baldwin 		printf("----");
96033866658SJohn Baldwin 	printf("\n");
96133866658SJohn Baldwin 	for (i = 0; i < slit->LocalityCount; i++) {
9620c10b85aSJung-uk Kim 		printf("\t %3ju |", (uintmax_t)i);
96333866658SJohn Baldwin 		for (j = 0; j < slit->LocalityCount; j++)
96433866658SJohn Baldwin 			printf(" %3d",
96533866658SJohn Baldwin 			    slit->Entry[i * slit->LocalityCount + j]);
96633866658SJohn Baldwin 		printf("\n");
96733866658SJohn Baldwin 	}
96833866658SJohn Baldwin 	printf(END_COMMENT);
96933866658SJohn Baldwin }
97033866658SJohn Baldwin 
97133866658SJohn Baldwin static void
972ed26c389SScott Long acpi_handle_wddt(ACPI_TABLE_HEADER *sdp)
973ed26c389SScott Long {
974ed26c389SScott Long 	ACPI_TABLE_WDDT *wddt;
975ed26c389SScott Long 
976ed26c389SScott Long 	printf(BEGIN_COMMENT);
977ed26c389SScott Long 	acpi_print_sdt(sdp);
978ed26c389SScott Long 	wddt = (ACPI_TABLE_WDDT *)sdp;
979ed26c389SScott Long 	printf("\tSpecVersion=0x%04x, TableVersion=0x%04x\n",
980ed26c389SScott Long 	    wddt->SpecVersion, wddt->TableVersion);
981ed26c389SScott Long 	printf("\tPciVendorId=0x%04x, Address=", wddt->PciVendorId);
982ed26c389SScott Long 	acpi_print_gas(&wddt->Address);
983ed26c389SScott Long 	printf("\n\tMaxCount=%u, MinCount=%u, Period=%ums\n",
984ed26c389SScott Long 	    wddt->MaxCount, wddt->MinCount, wddt->Period);
985ed26c389SScott Long 
986ed26c389SScott Long #define	PRINTFLAG(var, flag)	printflag((var), ACPI_WDDT_## flag, #flag)
987ed26c389SScott Long 	printf("\tStatus=");
988ed26c389SScott Long 	PRINTFLAG(wddt->Status, AVAILABLE);
989ed26c389SScott Long 	PRINTFLAG(wddt->Status, ACTIVE);
990ed26c389SScott Long 	PRINTFLAG(wddt->Status, TCO_OS_OWNED);
991ed26c389SScott Long 	PRINTFLAG(wddt->Status, USER_RESET);
992ed26c389SScott Long 	PRINTFLAG(wddt->Status, WDT_RESET);
993ed26c389SScott Long 	PRINTFLAG(wddt->Status, POWER_FAIL);
994ed26c389SScott Long 	PRINTFLAG(wddt->Status, UNKNOWN_RESET);
995ed26c389SScott Long 	PRINTFLAG_END();
996ed26c389SScott Long 	printf("\tCapability=");
997ed26c389SScott Long 	PRINTFLAG(wddt->Capability, AUTO_RESET);
998ed26c389SScott Long 	PRINTFLAG(wddt->Capability, ALERT_SUPPORT);
999ed26c389SScott Long 	PRINTFLAG_END();
1000ed26c389SScott Long #undef PRINTFLAG
1001ed26c389SScott Long 
1002ed26c389SScott Long 	printf(END_COMMENT);
1003ed26c389SScott Long }
1004ed26c389SScott Long 
1005ed26c389SScott Long static void
10065857fba5SBen Widawsky acpi_print_native_lpit(ACPI_LPIT_NATIVE *nl)
10075857fba5SBen Widawsky {
10085857fba5SBen Widawsky 	printf("\tEntryTrigger=");
10095857fba5SBen Widawsky 	acpi_print_gas(&nl->EntryTrigger);
1010ebc22d04SAlexander Motin 	printf("\n\tResidency=%u\n", nl->Residency);
10115857fba5SBen Widawsky 	printf("\tLatency=%u\n", nl->Latency);
10125857fba5SBen Widawsky 	if (nl->Header.Flags & ACPI_LPIT_NO_COUNTER)
10135857fba5SBen Widawsky 		printf("\tResidencyCounter=Not Present");
10145857fba5SBen Widawsky 	else {
10155857fba5SBen Widawsky 		printf("\tResidencyCounter=");
10165857fba5SBen Widawsky 		acpi_print_gas(&nl->ResidencyCounter);
1017ebc22d04SAlexander Motin 		printf("\n");
10185857fba5SBen Widawsky 	}
10195857fba5SBen Widawsky 	if (nl->CounterFrequency)
10205857fba5SBen Widawsky 		printf("\tCounterFrequency=%ju\n", nl->CounterFrequency);
10215857fba5SBen Widawsky 	else
10225857fba5SBen Widawsky 		printf("\tCounterFrequency=TSC\n");
10235857fba5SBen Widawsky }
10245857fba5SBen Widawsky 
10255857fba5SBen Widawsky static void
10265857fba5SBen Widawsky acpi_print_lpit(ACPI_LPIT_HEADER *lpit)
10275857fba5SBen Widawsky {
10285857fba5SBen Widawsky 	if (lpit->Type == ACPI_LPIT_TYPE_NATIVE_CSTATE)
10295857fba5SBen Widawsky 		printf("\tType=ACPI_LPIT_TYPE_NATIVE_CSTATE\n");
10305857fba5SBen Widawsky 	else
10315857fba5SBen Widawsky 		warnx("unknown LPIT type %u", lpit->Type);
10325857fba5SBen Widawsky 
10335857fba5SBen Widawsky 	printf("\tLength=%u\n", lpit->Length);
10345857fba5SBen Widawsky 	printf("\tUniqueId=0x%04x\n", lpit->UniqueId);
10355857fba5SBen Widawsky #define	PRINTFLAG(var, flag)	printflag((var), ACPI_LPIT_## flag, #flag)
10365857fba5SBen Widawsky 	printf("\tFlags=");
10375857fba5SBen Widawsky 	PRINTFLAG(lpit->Flags, STATE_DISABLED);
10385857fba5SBen Widawsky 	PRINTFLAG_END();
10395857fba5SBen Widawsky #undef PRINTFLAG
10405857fba5SBen Widawsky 
10415857fba5SBen Widawsky 	if (lpit->Type == ACPI_LPIT_TYPE_NATIVE_CSTATE)
10425857fba5SBen Widawsky 		return acpi_print_native_lpit((ACPI_LPIT_NATIVE *)lpit);
10435857fba5SBen Widawsky }
10445857fba5SBen Widawsky 
10455857fba5SBen Widawsky static void
10465857fba5SBen Widawsky acpi_walk_lpit(ACPI_TABLE_HEADER *table, void *first,
10475857fba5SBen Widawsky     void (*action)(ACPI_LPIT_HEADER *))
10485857fba5SBen Widawsky {
10495857fba5SBen Widawsky 	ACPI_LPIT_HEADER *subtable;
10505857fba5SBen Widawsky 	char *end;
10515857fba5SBen Widawsky 
10525857fba5SBen Widawsky 	subtable = first;
10535857fba5SBen Widawsky 	end = (char *)table + table->Length;
10545857fba5SBen Widawsky 	while ((char *)subtable < end) {
10555857fba5SBen Widawsky 		printf("\n");
10565857fba5SBen Widawsky 		if (subtable->Length < sizeof(ACPI_LPIT_HEADER)) {
10575857fba5SBen Widawsky 			warnx("invalid subtable length %u", subtable->Length);
10585857fba5SBen Widawsky 			return;
10595857fba5SBen Widawsky 		}
10605857fba5SBen Widawsky 		action(subtable);
10615857fba5SBen Widawsky 		subtable = (ACPI_LPIT_HEADER *)((char *)subtable +
10625857fba5SBen Widawsky 		    subtable->Length);
10635857fba5SBen Widawsky 	}
10645857fba5SBen Widawsky }
10655857fba5SBen Widawsky 
10665857fba5SBen Widawsky static void
10675857fba5SBen Widawsky acpi_handle_lpit(ACPI_TABLE_HEADER *sdp)
10685857fba5SBen Widawsky {
10695857fba5SBen Widawsky 	ACPI_TABLE_LPIT *lpit;
10705857fba5SBen Widawsky 
10715857fba5SBen Widawsky 	printf(BEGIN_COMMENT);
10725857fba5SBen Widawsky 	acpi_print_sdt(sdp);
10735857fba5SBen Widawsky 	lpit = (ACPI_TABLE_LPIT *)sdp;
10745857fba5SBen Widawsky 	acpi_walk_lpit(sdp, (lpit + 1), acpi_print_lpit);
10755857fba5SBen Widawsky 
10765857fba5SBen Widawsky 	printf(END_COMMENT);
10775857fba5SBen Widawsky }
10785857fba5SBen Widawsky 
10795857fba5SBen Widawsky static void
1080a0333ad1SJohn Baldwin acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain,
1081a0333ad1SJohn Baldwin     uint32_t flags)
1082a0333ad1SJohn Baldwin {
1083a0333ad1SJohn Baldwin 
1084a0333ad1SJohn Baldwin 	printf("\tFlags={");
1085a0333ad1SJohn Baldwin 	if (flags & ACPI_SRAT_CPU_ENABLED)
1086a0333ad1SJohn Baldwin 		printf("ENABLED");
1087a0333ad1SJohn Baldwin 	else
1088a0333ad1SJohn Baldwin 		printf("DISABLED");
1089a0333ad1SJohn Baldwin 	printf("}\n");
1090a0333ad1SJohn Baldwin 	printf("\tAPIC ID=%d\n", apic_id);
1091a0333ad1SJohn Baldwin 	printf("\tProximity Domain=%d\n", proximity_domain);
1092a0333ad1SJohn Baldwin }
1093a0333ad1SJohn Baldwin 
1094c031c93bSTakanori Watanabe static char *
1095c031c93bSTakanori Watanabe acpi_tcpa_evname(struct TCPAevent *event)
1096c031c93bSTakanori Watanabe {
1097c031c93bSTakanori Watanabe 	struct TCPApc_event *pc_event;
1098c031c93bSTakanori Watanabe 	char *eventname = NULL;
1099c031c93bSTakanori Watanabe 
1100c031c93bSTakanori Watanabe 	pc_event = (struct TCPApc_event *)(event + 1);
1101c031c93bSTakanori Watanabe 
1102c031c93bSTakanori Watanabe 	switch(event->event_type) {
1103c031c93bSTakanori Watanabe 	case PREBOOT:
1104c031c93bSTakanori Watanabe 	case POST_CODE:
1105c031c93bSTakanori Watanabe 	case UNUSED:
1106c031c93bSTakanori Watanabe 	case NO_ACTION:
1107c031c93bSTakanori Watanabe 	case SEPARATOR:
1108c031c93bSTakanori Watanabe 	case SCRTM_CONTENTS:
1109c031c93bSTakanori Watanabe 	case SCRTM_VERSION:
1110c031c93bSTakanori Watanabe 	case CPU_MICROCODE:
1111c031c93bSTakanori Watanabe 	case PLATFORM_CONFIG_FLAGS:
1112c031c93bSTakanori Watanabe 	case TABLE_OF_DEVICES:
1113c031c93bSTakanori Watanabe 	case COMPACT_HASH:
1114c031c93bSTakanori Watanabe 	case IPL:
1115c031c93bSTakanori Watanabe 	case IPL_PARTITION_DATA:
1116c031c93bSTakanori Watanabe 	case NONHOST_CODE:
1117c031c93bSTakanori Watanabe 	case NONHOST_CONFIG:
1118c031c93bSTakanori Watanabe 	case NONHOST_INFO:
1119c031c93bSTakanori Watanabe 		asprintf(&eventname, "%s",
1120c031c93bSTakanori Watanabe 		    tcpa_event_type_strings[event->event_type]);
1121c031c93bSTakanori Watanabe 		break;
1122c031c93bSTakanori Watanabe 
1123c031c93bSTakanori Watanabe 	case ACTION:
1124c031c93bSTakanori Watanabe 		eventname = calloc(event->event_size + 1, sizeof(char));
1125c031c93bSTakanori Watanabe 		memcpy(eventname, pc_event, event->event_size);
1126c031c93bSTakanori Watanabe 		break;
1127c031c93bSTakanori Watanabe 
1128c031c93bSTakanori Watanabe 	case EVENT_TAG:
1129c031c93bSTakanori Watanabe 		switch (pc_event->event_id) {
1130c031c93bSTakanori Watanabe 		case SMBIOS:
1131c031c93bSTakanori Watanabe 		case BIS_CERT:
1132c031c93bSTakanori Watanabe 		case CMOS:
1133c031c93bSTakanori Watanabe 		case NVRAM:
1134c031c93bSTakanori Watanabe 		case OPTION_ROM_EXEC:
1135c031c93bSTakanori Watanabe 		case OPTION_ROM_CONFIG:
1136c031c93bSTakanori Watanabe 		case S_CRTM_VERSION:
1137c031c93bSTakanori Watanabe 		case POST_BIOS_ROM:
1138c031c93bSTakanori Watanabe 		case ESCD:
1139c031c93bSTakanori Watanabe 		case OPTION_ROM_MICROCODE:
1140c031c93bSTakanori Watanabe 		case S_CRTM_CONTENTS:
1141c031c93bSTakanori Watanabe 		case POST_CONTENTS:
1142c031c93bSTakanori Watanabe 			asprintf(&eventname, "%s",
1143c031c93bSTakanori Watanabe 			    TCPA_pcclient_strings[pc_event->event_id]);
1144c031c93bSTakanori Watanabe 			break;
1145c031c93bSTakanori Watanabe 
1146c031c93bSTakanori Watanabe 		default:
1147c031c93bSTakanori Watanabe 			asprintf(&eventname, "<unknown tag 0x%02x>",
1148c031c93bSTakanori Watanabe 			    pc_event->event_id);
1149c031c93bSTakanori Watanabe 			break;
1150c031c93bSTakanori Watanabe 		}
1151c031c93bSTakanori Watanabe 		break;
1152c031c93bSTakanori Watanabe 
1153c031c93bSTakanori Watanabe 	default:
1154c031c93bSTakanori Watanabe 		asprintf(&eventname, "<unknown 0x%02x>", event->event_type);
1155c031c93bSTakanori Watanabe 		break;
1156c031c93bSTakanori Watanabe 	}
1157c031c93bSTakanori Watanabe 
1158c031c93bSTakanori Watanabe 	return eventname;
1159c031c93bSTakanori Watanabe }
1160c031c93bSTakanori Watanabe 
1161c031c93bSTakanori Watanabe static void
1162c031c93bSTakanori Watanabe acpi_print_tcpa(struct TCPAevent *event)
1163c031c93bSTakanori Watanabe {
1164c031c93bSTakanori Watanabe 	int i;
1165c031c93bSTakanori Watanabe 	char *eventname;
1166c031c93bSTakanori Watanabe 
1167c031c93bSTakanori Watanabe 	eventname = acpi_tcpa_evname(event);
1168c031c93bSTakanori Watanabe 
1169c031c93bSTakanori Watanabe 	printf("\t%d", event->pcr_index);
1170c031c93bSTakanori Watanabe 	printf(" 0x");
1171c031c93bSTakanori Watanabe 	for (i = 0; i < 20; i++)
1172c031c93bSTakanori Watanabe 		printf("%02x", event->pcr_value[i]);
1173c031c93bSTakanori Watanabe 	printf(" [%s]\n", eventname ? eventname : "<unknown>");
1174c031c93bSTakanori Watanabe 
1175c031c93bSTakanori Watanabe 	free(eventname);
1176c031c93bSTakanori Watanabe }
1177c031c93bSTakanori Watanabe 
1178c031c93bSTakanori Watanabe static void
1179c031c93bSTakanori Watanabe acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp)
1180c031c93bSTakanori Watanabe {
1181c031c93bSTakanori Watanabe 	struct TCPAbody *tcpa;
1182c031c93bSTakanori Watanabe 	struct TCPAevent *event;
1183977fd9daSTakanori Watanabe 	uintmax_t len, paddr;
1184c031c93bSTakanori Watanabe 	unsigned char *vaddr = NULL;
1185c031c93bSTakanori Watanabe 	unsigned char *vend = NULL;
1186c031c93bSTakanori Watanabe 
1187c031c93bSTakanori Watanabe 	printf(BEGIN_COMMENT);
1188c031c93bSTakanori Watanabe 	acpi_print_sdt(sdp);
1189c031c93bSTakanori Watanabe 	tcpa = (struct TCPAbody *) sdp;
1190c031c93bSTakanori Watanabe 
1191c031c93bSTakanori Watanabe 	switch (tcpa->platform_class) {
1192c031c93bSTakanori Watanabe 	case ACPI_TCPA_BIOS_CLIENT:
1193c031c93bSTakanori Watanabe 		len = tcpa->client.log_max_len;
1194c031c93bSTakanori Watanabe 		paddr = tcpa->client.log_start_addr;
1195c031c93bSTakanori Watanabe 		break;
1196c031c93bSTakanori Watanabe 
1197c031c93bSTakanori Watanabe 	case ACPI_TCPA_BIOS_SERVER:
1198c031c93bSTakanori Watanabe 		len = tcpa->server.log_max_len;
1199c031c93bSTakanori Watanabe 		paddr = tcpa->server.log_start_addr;
1200c031c93bSTakanori Watanabe 		break;
1201c031c93bSTakanori Watanabe 
1202c031c93bSTakanori Watanabe 	default:
1203c031c93bSTakanori Watanabe 		printf("XXX");
1204c031c93bSTakanori Watanabe 		printf(END_COMMENT);
1205c031c93bSTakanori Watanabe 		return;
1206c031c93bSTakanori Watanabe 	}
12070e1982f4STakanori Watanabe 	printf("\tClass %u Base Address 0x%jx Length %ju\n\n",
1208c031c93bSTakanori Watanabe 	    tcpa->platform_class, paddr, len);
1209c031c93bSTakanori Watanabe 
1210c031c93bSTakanori Watanabe 	if (len == 0) {
1211c031c93bSTakanori Watanabe 		printf("\tEmpty TCPA table\n");
1212c031c93bSTakanori Watanabe 		printf(END_COMMENT);
1213c031c93bSTakanori Watanabe 		return;
1214c031c93bSTakanori Watanabe 	}
12152ef23c6dSTakanori Watanabe 	if(sdp->Revision == 1){
12162ef23c6dSTakanori Watanabe 		printf("\tOLD TCPA spec log found. Dumping not supported.\n");
12172ef23c6dSTakanori Watanabe 		printf(END_COMMENT);
12182ef23c6dSTakanori Watanabe 		return;
12192ef23c6dSTakanori Watanabe 	}
1220c031c93bSTakanori Watanabe 
1221c031c93bSTakanori Watanabe 	vaddr = (unsigned char *)acpi_map_physical(paddr, len);
1222c031c93bSTakanori Watanabe 	vend = vaddr + len;
1223c031c93bSTakanori Watanabe 
1224c031c93bSTakanori Watanabe 	while (vaddr != NULL) {
12252ef23c6dSTakanori Watanabe 		if ((vaddr + sizeof(struct TCPAevent) >= vend)||
12262ef23c6dSTakanori Watanabe 		    (vaddr + sizeof(struct TCPAevent) < vaddr))
1227c031c93bSTakanori Watanabe 			break;
12280e1982f4STakanori Watanabe 		event = (struct TCPAevent *)(void *)vaddr;
1229c031c93bSTakanori Watanabe 		if (vaddr + event->event_size >= vend)
1230c031c93bSTakanori Watanabe 			break;
12312ef23c6dSTakanori Watanabe 		if (vaddr + event->event_size < vaddr)
12322ef23c6dSTakanori Watanabe 			break;
1233c031c93bSTakanori Watanabe 		if (event->event_type == 0 && event->event_size == 0)
1234c031c93bSTakanori Watanabe 			break;
1235c031c93bSTakanori Watanabe #if 0
1236c031c93bSTakanori Watanabe 		{
1237c031c93bSTakanori Watanabe 		unsigned int i, j, k;
1238c031c93bSTakanori Watanabe 
1239c031c93bSTakanori Watanabe 		printf("\n\tsize %d\n\t\t%p ", event->event_size, vaddr);
1240c031c93bSTakanori Watanabe 		for (j = 0, i = 0; i <
1241c031c93bSTakanori Watanabe 		    sizeof(struct TCPAevent) + event->event_size; i++) {
1242c031c93bSTakanori Watanabe 			printf("%02x ", vaddr[i]);
1243c031c93bSTakanori Watanabe 			if ((i+1) % 8 == 0) {
1244c031c93bSTakanori Watanabe 				for (k = 0; k < 8; k++)
1245c031c93bSTakanori Watanabe 					printf("%c", isprint(vaddr[j+k]) ?
1246c031c93bSTakanori Watanabe 					    vaddr[j+k] : '.');
1247c031c93bSTakanori Watanabe 				printf("\n\t\t%p ", &vaddr[i + 1]);
1248c031c93bSTakanori Watanabe 				j = i + 1;
1249c031c93bSTakanori Watanabe 			}
1250c031c93bSTakanori Watanabe 		}
1251c031c93bSTakanori Watanabe 		printf("\n"); }
1252c031c93bSTakanori Watanabe #endif
1253c031c93bSTakanori Watanabe 		acpi_print_tcpa(event);
1254c031c93bSTakanori Watanabe 
1255c031c93bSTakanori Watanabe 		vaddr += sizeof(struct TCPAevent) + event->event_size;
1256c031c93bSTakanori Watanabe 	}
1257c031c93bSTakanori Watanabe 
1258c031c93bSTakanori Watanabe 	printf(END_COMMENT);
1259c031c93bSTakanori Watanabe }
1260*5d57fad8SWarner Losh 
1261877fc2e3STakanori Watanabe static void acpi_handle_tpm2(ACPI_TABLE_HEADER *sdp)
1262877fc2e3STakanori Watanabe {
1263877fc2e3STakanori Watanabe 	ACPI_TABLE_TPM2 *tpm2;
1264877fc2e3STakanori Watanabe 
1265877fc2e3STakanori Watanabe 	printf (BEGIN_COMMENT);
1266877fc2e3STakanori Watanabe 	acpi_print_sdt(sdp);
1267877fc2e3STakanori Watanabe 	tpm2 = (ACPI_TABLE_TPM2 *) sdp;
12687aef7138SCy Schubert 	printf ("\t\tControlArea=%jx\n", tpm2->ControlAddress);
1269877fc2e3STakanori Watanabe 	printf ("\t\tStartMethod=%x\n", tpm2->StartMethod);
1270877fc2e3STakanori Watanabe 	printf (END_COMMENT);
1271877fc2e3STakanori Watanabe }
1272c031c93bSTakanori Watanabe 
1273*5d57fad8SWarner Losh static int spcr_xlate_baud(uint8_t r)
1274*5d57fad8SWarner Losh {
1275*5d57fad8SWarner Losh 	static int rates[] = { 9600, 19200, -1, 57600, 115200 };
1276*5d57fad8SWarner Losh 	_Static_assert(nitems(rates) == 7 - 3 + 1, "rates array size incorrect");
1277*5d57fad8SWarner Losh 
1278*5d57fad8SWarner Losh 	if (r == 0)
1279*5d57fad8SWarner Losh 		return (0);
1280*5d57fad8SWarner Losh 
1281*5d57fad8SWarner Losh 	if (r < 3 || r > 7)
1282*5d57fad8SWarner Losh 		return (-1);
1283*5d57fad8SWarner Losh 
1284*5d57fad8SWarner Losh 	return (rates[r - 3]);
1285*5d57fad8SWarner Losh }
1286*5d57fad8SWarner Losh 
1287*5d57fad8SWarner Losh static const char *spcr_interface_type(int ift)
1288*5d57fad8SWarner Losh {
1289*5d57fad8SWarner Losh 	static const char *if_names[] = {
1290*5d57fad8SWarner Losh 		[0x00] = "Fully 16550-compatible",
1291*5d57fad8SWarner Losh 		[0x01] = "16550 subset compatible with DBGP Revision 1",
1292*5d57fad8SWarner Losh 		[0x02] = "MAX311xE SPI UART",
1293*5d57fad8SWarner Losh 		[0x03] = "Arm PL011 UART",
1294*5d57fad8SWarner Losh 		[0x04] = "MSM8x60 (e.g. 8960)",
1295*5d57fad8SWarner Losh 		[0x05] = "Nvidia 16550",
1296*5d57fad8SWarner Losh 		[0x06] = "TI OMAP",
1297*5d57fad8SWarner Losh 		[0x07] = "Reserved (Do Not Use)",
1298*5d57fad8SWarner Losh 		[0x08] = "APM88xxxx",
1299*5d57fad8SWarner Losh 		[0x09] = "MSM8974",
1300*5d57fad8SWarner Losh 		[0x0a] = "SAM5250",
1301*5d57fad8SWarner Losh 		[0x0b] = "Intel USIF",
1302*5d57fad8SWarner Losh 		[0x0c] = "i.MX 6",
1303*5d57fad8SWarner Losh 		[0x0d] = "(deprecated) Arm SBSA (2.x only) Generic UART supporting only 32-bit accesses",
1304*5d57fad8SWarner Losh 		[0x0e] = "Arm SBSA Generic UART",
1305*5d57fad8SWarner Losh 		[0x0f] = "Arm DCC",
1306*5d57fad8SWarner Losh 		[0x10] = "BCM2835",
1307*5d57fad8SWarner Losh 		[0x11] = "SDM845 with clock rate of 1.8432 MHz",
1308*5d57fad8SWarner Losh 		[0x12] = "16550-compatible with parameters defined in Generic Address Structure",
1309*5d57fad8SWarner Losh 		[0x13] = "SDM845 with clock rate of 7.372 MHz",
1310*5d57fad8SWarner Losh 		[0x14] = "Intel LPSS",
1311*5d57fad8SWarner Losh 		[0x15] = "RISC-V SBI console (any supported SBI mechanism)",
1312*5d57fad8SWarner Losh 	};
1313*5d57fad8SWarner Losh 
1314*5d57fad8SWarner Losh 	if (ift >= (int)nitems(if_names) || if_names[ift] == NULL)
1315*5d57fad8SWarner Losh 		return ("Reserved");
1316*5d57fad8SWarner Losh 	return (if_names[ift]);
1317*5d57fad8SWarner Losh }
1318*5d57fad8SWarner Losh 
1319*5d57fad8SWarner Losh static const char *spcr_interrupt_type(int ift)
1320*5d57fad8SWarner Losh {
1321*5d57fad8SWarner Losh 	static char buf[100];
1322*5d57fad8SWarner Losh 
1323*5d57fad8SWarner Losh #define APPEND(b,s) \
1324*5d57fad8SWarner Losh 	if ((ift & (b)) != 0) { \
1325*5d57fad8SWarner Losh 		if (strlen(buf) > 0) \
1326*5d57fad8SWarner Losh 			strlcat(buf, ",", sizeof(buf)); \
1327*5d57fad8SWarner Losh 		strlcat(buf, s, sizeof(buf)); \
1328*5d57fad8SWarner Losh 	}
1329*5d57fad8SWarner Losh 
1330*5d57fad8SWarner Losh 	*buf = '\0';
1331*5d57fad8SWarner Losh 	APPEND(0x01, "PC/AT IRQ");
1332*5d57fad8SWarner Losh 	APPEND(0x02, "I/O APIC");
1333*5d57fad8SWarner Losh 	APPEND(0x04, "I/O SAPIC");
1334*5d57fad8SWarner Losh 	APPEND(0x08, "ARMH GIC");
1335*5d57fad8SWarner Losh 	APPEND(0x10, "RISC-V PLIC/APLIC");
1336*5d57fad8SWarner Losh 
1337*5d57fad8SWarner Losh #undef APPEND
1338*5d57fad8SWarner Losh 
1339*5d57fad8SWarner Losh 	return (buf);
1340*5d57fad8SWarner Losh }
1341*5d57fad8SWarner Losh 
1342*5d57fad8SWarner Losh static const char *spcr_terminal_type(int type)
1343*5d57fad8SWarner Losh {
1344*5d57fad8SWarner Losh 	static const char *term_names[] = {
1345*5d57fad8SWarner Losh 		[0] = "VT100",
1346*5d57fad8SWarner Losh 		[1] = "Extended VT100",
1347*5d57fad8SWarner Losh 		[2] = "VT-UTF8",
1348*5d57fad8SWarner Losh 		[3] = "ANSI",
1349*5d57fad8SWarner Losh 	};
1350*5d57fad8SWarner Losh 
1351*5d57fad8SWarner Losh 	if (type >= (int)nitems(term_names) || term_names[type] == NULL)
1352*5d57fad8SWarner Losh 		return ("Reserved");
1353*5d57fad8SWarner Losh 	return (term_names[type]);
1354*5d57fad8SWarner Losh }
1355*5d57fad8SWarner Losh 
1356*5d57fad8SWarner Losh static void acpi_handle_spcr(ACPI_TABLE_HEADER *sdp)
1357*5d57fad8SWarner Losh {
1358*5d57fad8SWarner Losh 	ACPI_TABLE_SPCR *spcr;
1359*5d57fad8SWarner Losh 
1360*5d57fad8SWarner Losh 	printf (BEGIN_COMMENT);
1361*5d57fad8SWarner Losh 	acpi_print_sdt(sdp);
1362*5d57fad8SWarner Losh 
1363*5d57fad8SWarner Losh 	/* Rev 1 and 2 are the same size */
1364*5d57fad8SWarner Losh 	spcr = (ACPI_TABLE_SPCR *) sdp;
1365*5d57fad8SWarner Losh 	printf ("\tInterfaceType=%d (%s)\n", spcr->InterfaceType,
1366*5d57fad8SWarner Losh 	    spcr_interface_type(spcr->InterfaceType));
1367*5d57fad8SWarner Losh 	printf ("\tSerialPort=");
1368*5d57fad8SWarner Losh 	acpi_print_gas(&spcr->SerialPort);
1369*5d57fad8SWarner Losh 	printf ("\n\tInterruptType=%#x (%s)\n", spcr->InterruptType,
1370*5d57fad8SWarner Losh 	    spcr_interrupt_type(spcr->InterruptType));
1371*5d57fad8SWarner Losh 	printf ("\tPcInterrupt=%d (%s)\n", spcr->PcInterrupt,
1372*5d57fad8SWarner Losh 	    (spcr->InterruptType & 0x1) ? "Valid" : "Invalid");
1373*5d57fad8SWarner Losh 	printf ("\tInterrupt=%d\n", spcr->Interrupt);
1374*5d57fad8SWarner Losh 	printf ("\tBaudRate=%d (%d)\n", spcr_xlate_baud(spcr->BaudRate), spcr->BaudRate);
1375*5d57fad8SWarner Losh 	printf ("\tParity=%d\n", spcr->Parity);
1376*5d57fad8SWarner Losh 	printf ("\tStopBits=%d\n", spcr->StopBits);
1377*5d57fad8SWarner Losh 	printf ("\tFlowControl=%d\n", spcr->FlowControl);
1378*5d57fad8SWarner Losh 	printf ("\tTerminalType=%d (%s)\n", spcr->TerminalType,
1379*5d57fad8SWarner Losh 	    spcr_terminal_type(spcr->TerminalType));
1380*5d57fad8SWarner Losh 	printf ("\tPciDeviceId=%#04x\n", spcr->PciDeviceId);
1381*5d57fad8SWarner Losh 	printf ("\tPciVendorId=%#04x\n", spcr->PciVendorId);
1382*5d57fad8SWarner Losh 	printf ("\tPciBus=%d\n", spcr->PciBus);
1383*5d57fad8SWarner Losh 	printf ("\tPciDevice=%d\n", spcr->PciDevice);
1384*5d57fad8SWarner Losh 	printf ("\tPciFunction=%d\n", spcr->PciFunction);
1385*5d57fad8SWarner Losh 	printf ("\tPciFlags=%d\n", spcr->PciFlags);
1386*5d57fad8SWarner Losh 	printf ("\tPciSegment=%d\n", spcr->PciSegment);
1387*5d57fad8SWarner Losh 
1388*5d57fad8SWarner Losh 	/* Rev 3 added UartClkFrequency */
1389*5d57fad8SWarner Losh 	if (sdp->Revision >= 3) {
1390*5d57fad8SWarner Losh 		printf("\tLanguage=%d\n", spcr->Language);
1391*5d57fad8SWarner Losh 		printf("\tUartClkFreq=%jd",
1392*5d57fad8SWarner Losh 		    (uintmax_t)spcr->UartClkFreq);
1393*5d57fad8SWarner Losh 	}
1394*5d57fad8SWarner Losh 
1395*5d57fad8SWarner Losh 	/* Rev 4 added PreciseBaudrate and NameSpace* */
1396*5d57fad8SWarner Losh 	if (sdp->Revision >= 4) {
1397*5d57fad8SWarner Losh 		printf("\tPreciseBaudrate=%jd",
1398*5d57fad8SWarner Losh 		    (uintmax_t)spcr->PreciseBaudrate);
1399*5d57fad8SWarner Losh 		if (spcr->NameSpaceStringLength > 0 &&
1400*5d57fad8SWarner Losh 		    spcr->NameSpaceStringOffset >= sizeof(*spcr) &&
1401*5d57fad8SWarner Losh 		    sdp->Length >= spcr->NameSpaceStringOffset +
1402*5d57fad8SWarner Losh 		        spcr->NameSpaceStringLength) {
1403*5d57fad8SWarner Losh 			printf ("\tNameSpaceString='%s'\n",
1404*5d57fad8SWarner Losh 			    (char *)sdp + spcr->NameSpaceStringOffset);
1405*5d57fad8SWarner Losh 		}
1406*5d57fad8SWarner Losh 	}
1407*5d57fad8SWarner Losh 
1408*5d57fad8SWarner Losh 	printf (END_COMMENT);
1409*5d57fad8SWarner Losh }
1410*5d57fad8SWarner Losh 
1411ec650989SNeel Natu static const char *
1412ec650989SNeel Natu devscope_type2str(int type)
1413ec650989SNeel Natu {
1414ec650989SNeel Natu 	static char typebuf[16];
1415ec650989SNeel Natu 
1416ec650989SNeel Natu 	switch (type) {
1417ec650989SNeel Natu 	case 1:
1418ec650989SNeel Natu 		return ("PCI Endpoint Device");
1419ec650989SNeel Natu 	case 2:
1420ec650989SNeel Natu 		return ("PCI Sub-Hierarchy");
1421ec650989SNeel Natu 	case 3:
1422ec650989SNeel Natu 		return ("IOAPIC");
1423ec650989SNeel Natu 	case 4:
1424ec650989SNeel Natu 		return ("HPET");
1425ec650989SNeel Natu 	default:
1426ec650989SNeel Natu 		snprintf(typebuf, sizeof(typebuf), "%d", type);
1427ec650989SNeel Natu 		return (typebuf);
1428ec650989SNeel Natu 	}
1429ec650989SNeel Natu }
1430ec650989SNeel Natu 
1431ec650989SNeel Natu static int
1432ec650989SNeel Natu acpi_handle_dmar_devscope(void *addr, int remaining)
1433ec650989SNeel Natu {
1434ec650989SNeel Natu 	char sep;
1435ec650989SNeel Natu 	int pathlen;
1436ec650989SNeel Natu 	ACPI_DMAR_PCI_PATH *path, *pathend;
1437ec650989SNeel Natu 	ACPI_DMAR_DEVICE_SCOPE *devscope = addr;
1438ec650989SNeel Natu 
1439ec650989SNeel Natu 	if (remaining < (int)sizeof(ACPI_DMAR_DEVICE_SCOPE))
1440ec650989SNeel Natu 		return (-1);
1441ec650989SNeel Natu 
1442ec650989SNeel Natu 	if (remaining < devscope->Length)
1443ec650989SNeel Natu 		return (-1);
1444ec650989SNeel Natu 
1445ec650989SNeel Natu 	printf("\n");
1446ec650989SNeel Natu 	printf("\t\tType=%s\n", devscope_type2str(devscope->EntryType));
1447ec650989SNeel Natu 	printf("\t\tLength=%d\n", devscope->Length);
1448ec650989SNeel Natu 	printf("\t\tEnumerationId=%d\n", devscope->EnumerationId);
1449ec650989SNeel Natu 	printf("\t\tStartBusNumber=%d\n", devscope->Bus);
1450ec650989SNeel Natu 
1451ec650989SNeel Natu 	path = (ACPI_DMAR_PCI_PATH *)(devscope + 1);
1452ec650989SNeel Natu 	pathlen = devscope->Length - sizeof(ACPI_DMAR_DEVICE_SCOPE);
1453ec650989SNeel Natu 	pathend = path + pathlen / sizeof(ACPI_DMAR_PCI_PATH);
1454ec650989SNeel Natu 	if (path < pathend) {
1455ec650989SNeel Natu 		sep = '{';
1456ec650989SNeel Natu 		printf("\t\tPath=");
1457ec650989SNeel Natu 		do {
1458ec650989SNeel Natu 			printf("%c%d:%d", sep, path->Device, path->Function);
1459ec650989SNeel Natu 			sep=',';
1460ec650989SNeel Natu 			path++;
1461ec650989SNeel Natu 		} while (path < pathend);
1462ec650989SNeel Natu 		printf("}\n");
1463ec650989SNeel Natu 	}
1464ec650989SNeel Natu 
1465ec650989SNeel Natu 	return (devscope->Length);
1466ec650989SNeel Natu }
1467ec650989SNeel Natu 
1468ec650989SNeel Natu static void
1469ec650989SNeel Natu acpi_handle_dmar_drhd(ACPI_DMAR_HARDWARE_UNIT *drhd)
1470ec650989SNeel Natu {
1471ec650989SNeel Natu 	char *cp;
1472ec650989SNeel Natu 	int remaining, consumed;
1473ec650989SNeel Natu 
1474ec650989SNeel Natu 	printf("\n");
1475ec650989SNeel Natu 	printf("\tType=DRHD\n");
1476ec650989SNeel Natu 	printf("\tLength=%d\n", drhd->Header.Length);
1477ec650989SNeel Natu 
1478ec650989SNeel Natu #define	PRINTFLAG(var, flag)	printflag((var), ACPI_DMAR_## flag, #flag)
1479ec650989SNeel Natu 
1480ec650989SNeel Natu 	printf("\tFlags=");
1481ec650989SNeel Natu 	PRINTFLAG(drhd->Flags, INCLUDE_ALL);
1482ec650989SNeel Natu 	PRINTFLAG_END();
1483ec650989SNeel Natu 
1484ec650989SNeel Natu #undef PRINTFLAG
1485ec650989SNeel Natu 
1486ec650989SNeel Natu 	printf("\tSegment=%d\n", drhd->Segment);
14877d369c6eSJung-uk Kim 	printf("\tAddress=0x%016jx\n", (uintmax_t)drhd->Address);
1488ec650989SNeel Natu 
1489ec650989SNeel Natu 	remaining = drhd->Header.Length - sizeof(ACPI_DMAR_HARDWARE_UNIT);
1490ec650989SNeel Natu 	if (remaining > 0)
1491ec650989SNeel Natu 		printf("\tDevice Scope:");
1492ec650989SNeel Natu 	while (remaining > 0) {
1493ec650989SNeel Natu 		cp = (char *)drhd + drhd->Header.Length - remaining;
1494ec650989SNeel Natu 		consumed = acpi_handle_dmar_devscope(cp, remaining);
1495ec650989SNeel Natu 		if (consumed <= 0)
1496ec650989SNeel Natu 			break;
1497ec650989SNeel Natu 		else
1498ec650989SNeel Natu 			remaining -= consumed;
1499ec650989SNeel Natu 	}
1500ec650989SNeel Natu }
1501ec650989SNeel Natu 
1502ec650989SNeel Natu static void
1503ec650989SNeel Natu acpi_handle_dmar_rmrr(ACPI_DMAR_RESERVED_MEMORY *rmrr)
1504ec650989SNeel Natu {
1505ec650989SNeel Natu 	char *cp;
1506ec650989SNeel Natu 	int remaining, consumed;
1507ec650989SNeel Natu 
1508ec650989SNeel Natu 	printf("\n");
1509ec650989SNeel Natu 	printf("\tType=RMRR\n");
1510ec650989SNeel Natu 	printf("\tLength=%d\n", rmrr->Header.Length);
1511ec650989SNeel Natu 	printf("\tSegment=%d\n", rmrr->Segment);
15127d369c6eSJung-uk Kim 	printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rmrr->BaseAddress);
15137d369c6eSJung-uk Kim 	printf("\tLimitAddress=0x%016jx\n", (uintmax_t)rmrr->EndAddress);
1514ec650989SNeel Natu 
1515ec650989SNeel Natu 	remaining = rmrr->Header.Length - sizeof(ACPI_DMAR_RESERVED_MEMORY);
1516ec650989SNeel Natu 	if (remaining > 0)
1517ec650989SNeel Natu 		printf("\tDevice Scope:");
1518ec650989SNeel Natu 	while (remaining > 0) {
1519ec650989SNeel Natu 		cp = (char *)rmrr + rmrr->Header.Length - remaining;
1520ec650989SNeel Natu 		consumed = acpi_handle_dmar_devscope(cp, remaining);
1521ec650989SNeel Natu 		if (consumed <= 0)
1522ec650989SNeel Natu 			break;
1523ec650989SNeel Natu 		else
1524ec650989SNeel Natu 			remaining -= consumed;
1525ec650989SNeel Natu 	}
1526ec650989SNeel Natu }
1527ec650989SNeel Natu 
1528ec650989SNeel Natu static void
1529ec650989SNeel Natu acpi_handle_dmar_atsr(ACPI_DMAR_ATSR *atsr)
1530ec650989SNeel Natu {
1531ec650989SNeel Natu 	char *cp;
1532ec650989SNeel Natu 	int remaining, consumed;
1533ec650989SNeel Natu 
1534ec650989SNeel Natu 	printf("\n");
1535ec650989SNeel Natu 	printf("\tType=ATSR\n");
1536ec650989SNeel Natu 	printf("\tLength=%d\n", atsr->Header.Length);
1537ec650989SNeel Natu 
1538ec650989SNeel Natu #define	PRINTFLAG(var, flag)	printflag((var), ACPI_DMAR_## flag, #flag)
1539ec650989SNeel Natu 
1540ec650989SNeel Natu 	printf("\tFlags=");
1541ec650989SNeel Natu 	PRINTFLAG(atsr->Flags, ALL_PORTS);
1542ec650989SNeel Natu 	PRINTFLAG_END();
1543ec650989SNeel Natu 
1544ec650989SNeel Natu #undef PRINTFLAG
1545ec650989SNeel Natu 
1546ec650989SNeel Natu 	printf("\tSegment=%d\n", atsr->Segment);
1547ec650989SNeel Natu 
1548ec650989SNeel Natu 	remaining = atsr->Header.Length - sizeof(ACPI_DMAR_ATSR);
1549ec650989SNeel Natu 	if (remaining > 0)
1550ec650989SNeel Natu 		printf("\tDevice Scope:");
1551ec650989SNeel Natu 	while (remaining > 0) {
1552ec650989SNeel Natu 		cp = (char *)atsr + atsr->Header.Length - remaining;
1553ec650989SNeel Natu 		consumed = acpi_handle_dmar_devscope(cp, remaining);
1554ec650989SNeel Natu 		if (consumed <= 0)
1555ec650989SNeel Natu 			break;
1556ec650989SNeel Natu 		else
1557ec650989SNeel Natu 			remaining -= consumed;
1558ec650989SNeel Natu 	}
1559ec650989SNeel Natu }
1560ec650989SNeel Natu 
1561ec650989SNeel Natu static void
1562ec650989SNeel Natu acpi_handle_dmar_rhsa(ACPI_DMAR_RHSA *rhsa)
1563ec650989SNeel Natu {
1564ec650989SNeel Natu 
1565ec650989SNeel Natu 	printf("\n");
1566ec650989SNeel Natu 	printf("\tType=RHSA\n");
1567ec650989SNeel Natu 	printf("\tLength=%d\n", rhsa->Header.Length);
15687d369c6eSJung-uk Kim 	printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rhsa->BaseAddress);
1569ec650989SNeel Natu 	printf("\tProximityDomain=0x%08x\n", rhsa->ProximityDomain);
1570ec650989SNeel Natu }
1571ec650989SNeel Natu 
1572ec650989SNeel Natu static int
1573ec650989SNeel Natu acpi_handle_dmar_remapping_structure(void *addr, int remaining)
1574ec650989SNeel Natu {
1575ec650989SNeel Natu 	ACPI_DMAR_HEADER *hdr = addr;
1576ec650989SNeel Natu 
1577ec650989SNeel Natu 	if (remaining < (int)sizeof(ACPI_DMAR_HEADER))
1578ec650989SNeel Natu 		return (-1);
1579ec650989SNeel Natu 
1580ec650989SNeel Natu 	if (remaining < hdr->Length)
1581ec650989SNeel Natu 		return (-1);
1582ec650989SNeel Natu 
1583ec650989SNeel Natu 	switch (hdr->Type) {
1584ec650989SNeel Natu 	case ACPI_DMAR_TYPE_HARDWARE_UNIT:
1585ec650989SNeel Natu 		acpi_handle_dmar_drhd(addr);
1586ec650989SNeel Natu 		break;
1587ec650989SNeel Natu 	case ACPI_DMAR_TYPE_RESERVED_MEMORY:
1588ec650989SNeel Natu 		acpi_handle_dmar_rmrr(addr);
1589ec650989SNeel Natu 		break;
1590313a0c13SJung-uk Kim 	case ACPI_DMAR_TYPE_ROOT_ATS:
1591ec650989SNeel Natu 		acpi_handle_dmar_atsr(addr);
1592ec650989SNeel Natu 		break;
1593313a0c13SJung-uk Kim 	case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
1594ec650989SNeel Natu 		acpi_handle_dmar_rhsa(addr);
1595ec650989SNeel Natu 		break;
1596ec650989SNeel Natu 	default:
1597ec650989SNeel Natu 		printf("\n");
1598ec650989SNeel Natu 		printf("\tType=%d\n", hdr->Type);
1599ec650989SNeel Natu 		printf("\tLength=%d\n", hdr->Length);
1600ec650989SNeel Natu 		break;
1601ec650989SNeel Natu 	}
1602ec650989SNeel Natu 	return (hdr->Length);
1603ec650989SNeel Natu }
1604ec650989SNeel Natu 
1605ec650989SNeel Natu #ifndef ACPI_DMAR_X2APIC_OPT_OUT
1606ec650989SNeel Natu #define	ACPI_DMAR_X2APIC_OPT_OUT	(0x2)
1607ec650989SNeel Natu #endif
1608ec650989SNeel Natu 
1609ec650989SNeel Natu static void
1610ec650989SNeel Natu acpi_handle_dmar(ACPI_TABLE_HEADER *sdp)
1611ec650989SNeel Natu {
1612ec650989SNeel Natu 	char *cp;
1613ec650989SNeel Natu 	int remaining, consumed;
1614ec650989SNeel Natu 	ACPI_TABLE_DMAR *dmar;
1615ec650989SNeel Natu 
1616ec650989SNeel Natu 	printf(BEGIN_COMMENT);
1617ec650989SNeel Natu 	acpi_print_sdt(sdp);
1618ec650989SNeel Natu 	dmar = (ACPI_TABLE_DMAR *)sdp;
1619ec650989SNeel Natu 	printf("\tHost Address Width=%d\n", dmar->Width + 1);
1620ec650989SNeel Natu 
1621ec650989SNeel Natu #define PRINTFLAG(var, flag)	printflag((var), ACPI_DMAR_## flag, #flag)
1622ec650989SNeel Natu 
1623ec650989SNeel Natu 	printf("\tFlags=");
1624ec650989SNeel Natu 	PRINTFLAG(dmar->Flags, INTR_REMAP);
1625ec650989SNeel Natu 	PRINTFLAG(dmar->Flags, X2APIC_OPT_OUT);
1626ec650989SNeel Natu 	PRINTFLAG_END();
1627ec650989SNeel Natu 
1628ec650989SNeel Natu #undef PRINTFLAG
1629ec650989SNeel Natu 
1630ec650989SNeel Natu 	remaining = sdp->Length - sizeof(ACPI_TABLE_DMAR);
1631ec650989SNeel Natu 	while (remaining > 0) {
1632ec650989SNeel Natu 		cp = (char *)sdp + sdp->Length - remaining;
1633ec650989SNeel Natu 		consumed = acpi_handle_dmar_remapping_structure(cp, remaining);
1634ec650989SNeel Natu 		if (consumed <= 0)
1635ec650989SNeel Natu 			break;
1636ec650989SNeel Natu 		else
1637ec650989SNeel Natu 			remaining -= consumed;
1638ec650989SNeel Natu 	}
1639ec650989SNeel Natu 
1640ec650989SNeel Natu 	printf(END_COMMENT);
1641ec650989SNeel Natu }
1642ec650989SNeel Natu 
1643a0333ad1SJohn Baldwin static void
16446d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_header(ACPI_IVRS_HEADER *addr)
16456d789b61SKonstantin Belousov {
16466cba29c0SKonstantin Belousov 	printf("\n\tIVHD Type=%#x IOMMU DeviceId=%#06x\n\tFlags=",
16476d789b61SKonstantin Belousov 	    addr->Type, addr->DeviceId);
16486d789b61SKonstantin Belousov #define PRINTFLAG(flag, name) printflag(addr->Flags, flag, #name)
16496d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVHD_TT_ENABLE, HtTunEn);
16506d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVHD_ISOC, PassPW);
16516d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVHD_RES_PASS_PW, ResPassPW);
16526d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVHD_ISOC, Isoc);
16536d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVHD_TT_ENABLE, IotlbSup);
16546d789b61SKonstantin Belousov 	PRINTFLAG((1 << 5), Coherent);
16556d789b61SKonstantin Belousov 	PRINTFLAG((1 << 6), PreFSup);
16566d789b61SKonstantin Belousov 	PRINTFLAG((1 << 7), PPRSup);
16576d789b61SKonstantin Belousov #undef PRINTFLAG
16586d789b61SKonstantin Belousov 	PRINTFLAG_END();
16596d789b61SKonstantin Belousov }
16606d789b61SKonstantin Belousov 
16616d789b61SKonstantin Belousov static void
16626d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_dte(UINT8 dte)
16636d789b61SKonstantin Belousov {
16646d789b61SKonstantin Belousov 	if (dte == 0) {
16656d789b61SKonstantin Belousov 		printf("\n");
16666d789b61SKonstantin Belousov 		return;
16676d789b61SKonstantin Belousov 	}
16686d789b61SKonstantin Belousov 	printf(" DTE=");
16696d789b61SKonstantin Belousov #define PRINTFLAG(flag, name) printflag(dte, flag, #name)
16706d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVHD_INIT_PASS, INITPass);
16716d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVHD_EINT_PASS, EIntPass);
16726d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVHD_NMI_PASS, NMIPass);
16736d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVHD_SYSTEM_MGMT, SysMgtPass);
16746d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVHD_LINT0_PASS, Lint0Pass);
16756d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVHD_LINT1_PASS, Lint1Pass);
16766d789b61SKonstantin Belousov #undef PRINTFLAG
16776d789b61SKonstantin Belousov 	PRINTFLAG_END();
16786d789b61SKonstantin Belousov }
16796d789b61SKonstantin Belousov 
16806d789b61SKonstantin Belousov static void
16816d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_edte(UINT32 edte)
16826d789b61SKonstantin Belousov {
16836d789b61SKonstantin Belousov 	if (edte == 0)
16846d789b61SKonstantin Belousov 		return;
16856d789b61SKonstantin Belousov 	printf("\t\t ExtDTE=");
16866d789b61SKonstantin Belousov #define PRINTFLAG(flag, name) printflag(edte, flag, #name)
16876d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVHD_ATS_DISABLED, AtsDisabled);
16886d789b61SKonstantin Belousov #undef PRINTFLAG
16896d789b61SKonstantin Belousov 	PRINTFLAG_END();
16906d789b61SKonstantin Belousov }
16916d789b61SKonstantin Belousov 
16926d789b61SKonstantin Belousov static const char *
16936d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_variety(UINT8 v)
16946d789b61SKonstantin Belousov {
16956d789b61SKonstantin Belousov 	switch (v) {
16966d789b61SKonstantin Belousov 	case ACPI_IVHD_IOAPIC:
16976d789b61SKonstantin Belousov 		return ("IOAPIC");
16986d789b61SKonstantin Belousov 	case ACPI_IVHD_HPET:
16996d789b61SKonstantin Belousov 		return ("HPET");
17006d789b61SKonstantin Belousov 	default:
17016d789b61SKonstantin Belousov 		return ("UNKNOWN");
17026d789b61SKonstantin Belousov 	}
17036d789b61SKonstantin Belousov }
17046d789b61SKonstantin Belousov 
17056d789b61SKonstantin Belousov static void
17066d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_devs(ACPI_IVRS_DE_HEADER *d, char *de)
17076d789b61SKonstantin Belousov {
17086d789b61SKonstantin Belousov 	char *db;
17096d789b61SKonstantin Belousov 	ACPI_IVRS_DEVICE4 *d4;
17106d789b61SKonstantin Belousov 	ACPI_IVRS_DEVICE8A *d8a;
17116d789b61SKonstantin Belousov 	ACPI_IVRS_DEVICE8B *d8b;
17126d789b61SKonstantin Belousov 	ACPI_IVRS_DEVICE8C *d8c;
17136d789b61SKonstantin Belousov 	ACPI_IVRS_DEVICE_HID *dh;
17146d789b61SKonstantin Belousov 	size_t len;
17156d789b61SKonstantin Belousov 	UINT32 x32;
17166d789b61SKonstantin Belousov 
17176d789b61SKonstantin Belousov 	for (; (char *)d < de; d = (ACPI_IVRS_DE_HEADER *)(db + len)) {
17186d789b61SKonstantin Belousov 		db = (char *)d;
17196d789b61SKonstantin Belousov 		if (d->Type == ACPI_IVRS_TYPE_PAD4) {
17206d789b61SKonstantin Belousov 			len = sizeof(*d4);
17216d789b61SKonstantin Belousov 		} else if (d->Type == ACPI_IVRS_TYPE_ALL) {
17226d789b61SKonstantin Belousov 			d4 = (ACPI_IVRS_DEVICE4 *)db;
17236d789b61SKonstantin Belousov 			len = sizeof(*d4);
17246d789b61SKonstantin Belousov 			printf("\t\tDev Type=%#x Id=ALL", d4->Header.Type);
17256d789b61SKonstantin Belousov 			acpi_handle_ivrs_ivhd_dte(d4->Header.DataSetting);
17266d789b61SKonstantin Belousov 		} else if (d->Type == ACPI_IVRS_TYPE_SELECT) {
17276d789b61SKonstantin Belousov 			d4 = (ACPI_IVRS_DEVICE4 *)db;
17286d789b61SKonstantin Belousov 			len = sizeof(*d4);
17296d789b61SKonstantin Belousov 			printf("\t\tDev Type=%#x Id=%#06x", d4->Header.Type,
17306d789b61SKonstantin Belousov 			    d4->Header.Id);
17316d789b61SKonstantin Belousov 			acpi_handle_ivrs_ivhd_dte(d4->Header.DataSetting);
17326d789b61SKonstantin Belousov 		} else if (d->Type == ACPI_IVRS_TYPE_START) {
17336d789b61SKonstantin Belousov 			d4 = (ACPI_IVRS_DEVICE4 *)db;
17346d789b61SKonstantin Belousov 			len = 2 * sizeof(*d4);
17356d789b61SKonstantin Belousov 			printf("\t\tDev Type=%#x Id=%#06x-%#06x",
17366d789b61SKonstantin Belousov 			    d4->Header.Type,
17376d789b61SKonstantin Belousov 			    d4->Header.Id, (d4 + 1)->Header.Id);
17386d789b61SKonstantin Belousov 			acpi_handle_ivrs_ivhd_dte(d4->Header.DataSetting);
17396d789b61SKonstantin Belousov 		} else if (d->Type == ACPI_IVRS_TYPE_END) {
17406d789b61SKonstantin Belousov 			d4 = (ACPI_IVRS_DEVICE4 *)db;
17416d789b61SKonstantin Belousov 			len = 2 * sizeof(*d4);
17426d789b61SKonstantin Belousov 			printf("\t\tDev Type=%#x Id=%#06x BIOS BUG\n",
17436d789b61SKonstantin Belousov 			    d4->Header.Type, d4->Header.Id);
17446d789b61SKonstantin Belousov 		} else if (d->Type == ACPI_IVRS_TYPE_PAD8) {
17456d789b61SKonstantin Belousov 			len = sizeof(*d8a);
17466d789b61SKonstantin Belousov 		} else if (d->Type == ACPI_IVRS_TYPE_ALIAS_SELECT) {
17476d789b61SKonstantin Belousov 			d8a = (ACPI_IVRS_DEVICE8A *)db;
17486d789b61SKonstantin Belousov 			len = sizeof(*d8a);
17496d789b61SKonstantin Belousov 			printf("\t\tDev Type=%#x Id=%#06x AliasId=%#06x",
17506d789b61SKonstantin Belousov 			    d8a->Header.Type, d8a->Header.Id, d8a->UsedId);
17516d789b61SKonstantin Belousov 			acpi_handle_ivrs_ivhd_dte(d8a->Header.DataSetting);
17526d789b61SKonstantin Belousov 		} else if (d->Type == ACPI_IVRS_TYPE_ALIAS_START) {
17536d789b61SKonstantin Belousov 			d8a = (ACPI_IVRS_DEVICE8A *)db;
17546d789b61SKonstantin Belousov 			d4 = (ACPI_IVRS_DEVICE4 *)(db + sizeof(*d8a));
17556d789b61SKonstantin Belousov 			len = sizeof(*d8a) + sizeof(*d4);
17566d789b61SKonstantin Belousov 			printf("\t\tDev Type=%#x Id=%#06x-%#06x AliasId=%#06x",
17576d789b61SKonstantin Belousov 			    d8a->Header.Type, d8a->Header.Id, d4->Header.Id,
17586d789b61SKonstantin Belousov 			    d8a->UsedId);
17596d789b61SKonstantin Belousov 			acpi_handle_ivrs_ivhd_dte(d8a->Header.DataSetting);
17606d789b61SKonstantin Belousov 		} else if (d->Type == ACPI_IVRS_TYPE_EXT_SELECT) {
17616d789b61SKonstantin Belousov 			d8b = (ACPI_IVRS_DEVICE8B *)db;
17626d789b61SKonstantin Belousov 			len = sizeof(*d8b);
17636d789b61SKonstantin Belousov 			printf("\t\tDev Type=%#x Id=%#06x",
17646d789b61SKonstantin Belousov 			    d8a->Header.Type, d8a->Header.Id);
17656d789b61SKonstantin Belousov 			acpi_handle_ivrs_ivhd_dte(d8b->Header.DataSetting);
17666d789b61SKonstantin Belousov 			printf("\t\t");
17676d789b61SKonstantin Belousov 			acpi_handle_ivrs_ivhd_edte(d8b->ExtendedData);
17686d789b61SKonstantin Belousov 		} else if (d->Type == ACPI_IVRS_TYPE_EXT_START) {
17696d789b61SKonstantin Belousov 			d8b = (ACPI_IVRS_DEVICE8B *)db;
17706d789b61SKonstantin Belousov 			len = sizeof(*d8b);
17711eb7099eSKonstantin Belousov 			d4 = (ACPI_IVRS_DEVICE4 *)(db + sizeof(*d8b));
17721eb7099eSKonstantin Belousov 			len = sizeof(*d8b) + sizeof(*d4);
17736d789b61SKonstantin Belousov 			printf("\t\tDev Type=%#x Id=%#06x-%#06x",
17746d789b61SKonstantin Belousov 			    d8a->Header.Type, d8a->Header.Id, d4->Header.Id);
17756d789b61SKonstantin Belousov 			acpi_handle_ivrs_ivhd_dte(d8b->Header.DataSetting);
17766d789b61SKonstantin Belousov 			acpi_handle_ivrs_ivhd_edte(d8b->ExtendedData);
17776d789b61SKonstantin Belousov 		} else if (d->Type == ACPI_IVRS_TYPE_SPECIAL) {
17786d789b61SKonstantin Belousov 			d8c = (ACPI_IVRS_DEVICE8C *)db;
17796d789b61SKonstantin Belousov 			len = sizeof(*d8c);
17806d789b61SKonstantin Belousov 			printf("\t\tDev Type=%#x Id=%#06x Handle=%#x "
17816d789b61SKonstantin Belousov 			    "Variety=%d(%s)",
17826d789b61SKonstantin Belousov 			    d8c->Header.Type, d8c->UsedId, d8c->Handle,
17836d789b61SKonstantin Belousov 			    d8c->Variety,
17846d789b61SKonstantin Belousov 			    acpi_handle_ivrs_ivhd_variety(d8c->Variety));
17856d789b61SKonstantin Belousov 			acpi_handle_ivrs_ivhd_dte(d8c->Header.DataSetting);
17866d789b61SKonstantin Belousov 		} else if (d->Type == ACPI_IVRS_TYPE_HID) {
17876d789b61SKonstantin Belousov 			dh = (ACPI_IVRS_DEVICE_HID *)db;
17886d789b61SKonstantin Belousov 			len = sizeof(*dh) + dh->UidLength;
17896d789b61SKonstantin Belousov 			printf("\t\tDev Type=%#x Id=%#06x HID=",
17906d789b61SKonstantin Belousov 			    dh->Header.Type, dh->Header.Id);
17916d789b61SKonstantin Belousov 			acpi_print_string((char *)&dh->AcpiHid,
17926d789b61SKonstantin Belousov 			    sizeof(dh->AcpiHid));
17936d789b61SKonstantin Belousov 			printf(" CID=");
17946d789b61SKonstantin Belousov 			acpi_print_string((char *)&dh->AcpiCid,
17956d789b61SKonstantin Belousov 			    sizeof(dh->AcpiCid));
17966d789b61SKonstantin Belousov 			printf(" UID=");
17976d789b61SKonstantin Belousov 			switch (dh->UidType) {
17986d789b61SKonstantin Belousov 			case ACPI_IVRS_UID_NOT_PRESENT:
17996d789b61SKonstantin Belousov 			default:
18006d789b61SKonstantin Belousov 				printf("none");
18016d789b61SKonstantin Belousov 				break;
18026d789b61SKonstantin Belousov 			case ACPI_IVRS_UID_IS_INTEGER:
18036d789b61SKonstantin Belousov 				memcpy(&x32, dh + 1, sizeof(x32));
18046d789b61SKonstantin Belousov 				printf("%#x", x32);
18056d789b61SKonstantin Belousov 				break;
18066d789b61SKonstantin Belousov 			case ACPI_IVRS_UID_IS_STRING:
18076d789b61SKonstantin Belousov 				acpi_print_string((char *)(dh + 1),
18086d789b61SKonstantin Belousov 				    dh->UidLength);
18096d789b61SKonstantin Belousov 				break;
18106d789b61SKonstantin Belousov 			}
18116d789b61SKonstantin Belousov 			acpi_handle_ivrs_ivhd_dte(dh->Header.DataSetting);
18126d789b61SKonstantin Belousov 		} else {
18136d789b61SKonstantin Belousov 			printf("\t\tDev Type=%#x Unknown\n", d->Type);
18146d789b61SKonstantin Belousov 			if (d->Type <= 63)
18156d789b61SKonstantin Belousov 				len = sizeof(*d4);
18166d789b61SKonstantin Belousov 			else if (d->Type <= 127)
18176d789b61SKonstantin Belousov 				len = sizeof(*d8a);
18186d789b61SKonstantin Belousov 			else {
18196d789b61SKonstantin Belousov 				printf("Abort, cannot advance iterator.\n");
18206d789b61SKonstantin Belousov 				return;
18216d789b61SKonstantin Belousov 			}
18226d789b61SKonstantin Belousov 		}
18236d789b61SKonstantin Belousov 	}
18246d789b61SKonstantin Belousov }
18256d789b61SKonstantin Belousov 
18266d789b61SKonstantin Belousov static void
18276d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_10(ACPI_IVRS_HARDWARE1 *addr, bool efrsup)
18286d789b61SKonstantin Belousov {
18296d789b61SKonstantin Belousov 	acpi_handle_ivrs_ivhd_header(&addr->Header);
18306d789b61SKonstantin Belousov 	printf("\tCapOffset=%#x Base=%#jx PCISeg=%#x Unit=%#x MSIlog=%d\n",
18316d789b61SKonstantin Belousov 	    addr->CapabilityOffset, (uintmax_t)addr->BaseAddress,
18326d789b61SKonstantin Belousov 	    addr->PciSegmentGroup, (addr->Info & ACPI_IVHD_UNIT_ID_MASK) >> 8,
18336d789b61SKonstantin Belousov 	    addr->Info & ACPI_IVHD_MSI_NUMBER_MASK);
18346d789b61SKonstantin Belousov 	if (efrsup) {
18356d789b61SKonstantin Belousov #define PRINTFLAG(flag, name) printflag(addr->FeatureReporting, flag, #name)
18366d789b61SKonstantin Belousov #define PRINTFIELD(lbit, hbit, name) \
18376d789b61SKonstantin Belousov     printfield(addr->FeatureReporting, lbit, hbit, #name)
18386d789b61SKonstantin Belousov 		PRINTFIELD(30, 31, HATS);
18396d789b61SKonstantin Belousov 		PRINTFIELD(28, 29, GATS);
18406d789b61SKonstantin Belousov 		PRINTFIELD(23, 27, MsiNumPPR);
18416d789b61SKonstantin Belousov 		PRINTFIELD(17, 22, PNBanks);
18426d789b61SKonstantin Belousov 		PRINTFIELD(13, 16, PNCounters);
18436d789b61SKonstantin Belousov 		PRINTFIELD(8, 12, PASmax);
18446d789b61SKonstantin Belousov 		PRINTFLAG(1 << 7, HESup);
18456d789b61SKonstantin Belousov 		PRINTFLAG(1 << 6, GASup);
18466d789b61SKonstantin Belousov 		PRINTFLAG(1 << 5, UASup);
18476d789b61SKonstantin Belousov 		PRINTFIELD(3, 2, GLXSup);
18486d789b61SKonstantin Belousov 		PRINTFLAG(1 << 1, NXSup);
18496d789b61SKonstantin Belousov 		PRINTFLAG(1 << 0, XTSup);
18506d789b61SKonstantin Belousov #undef PRINTFLAG
18516d789b61SKonstantin Belousov #undef PRINTFIELD
18526d789b61SKonstantin Belousov 		PRINTFLAG_END();
18536d789b61SKonstantin Belousov 	}
18546d789b61SKonstantin Belousov 	acpi_handle_ivrs_ivhd_devs((ACPI_IVRS_DE_HEADER *)(addr + 1),
18556d789b61SKonstantin Belousov 	    (char *)addr + addr->Header.Length);
18566d789b61SKonstantin Belousov }
18576d789b61SKonstantin Belousov 
18586d789b61SKonstantin Belousov static void
18596d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_info_11(ACPI_IVRS_HARDWARE2 *addr)
18606d789b61SKonstantin Belousov {
18616d789b61SKonstantin Belousov 	acpi_handle_ivrs_ivhd_header(&addr->Header);
18626d789b61SKonstantin Belousov 	printf("\tCapOffset=%#x Base=%#jx PCISeg=%#x Unit=%#x MSIlog=%d\n",
18636d789b61SKonstantin Belousov 	    addr->CapabilityOffset, (uintmax_t)addr->BaseAddress,
18646d789b61SKonstantin Belousov 	    addr->PciSegmentGroup, (addr->Info >> 8) & 0x1f,
18656d789b61SKonstantin Belousov 	    addr->Info & 0x5);
18666d789b61SKonstantin Belousov 	printf("\tAttr=");
18676d789b61SKonstantin Belousov #define PRINTFIELD(lbit, hbit, name) \
18686d789b61SKonstantin Belousov     printfield(addr->Attributes, lbit, hbit, #name)
18696d789b61SKonstantin Belousov 	PRINTFIELD(23, 27, MsiNumPPR);
18706d789b61SKonstantin Belousov 	PRINTFIELD(17, 22, PNBanks);
18716d789b61SKonstantin Belousov 	PRINTFIELD(13, 16, PNCounters);
18726d789b61SKonstantin Belousov #undef PRINTFIELD
18736d789b61SKonstantin Belousov 	PRINTFLAG_END();
18746d789b61SKonstantin Belousov }
18756d789b61SKonstantin Belousov 
18766d789b61SKonstantin Belousov static void
18776d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_11(ACPI_IVRS_HARDWARE2 *addr)
18786d789b61SKonstantin Belousov {
18796d789b61SKonstantin Belousov 	acpi_handle_ivrs_ivhd_info_11(addr);
18806d789b61SKonstantin Belousov 	printf("\tEFRreg=%#018jx\n", (uintmax_t)addr->EfrRegisterImage);
18816d789b61SKonstantin Belousov 	acpi_handle_ivrs_ivhd_devs((ACPI_IVRS_DE_HEADER *)(addr + 1),
18826d789b61SKonstantin Belousov 	    (char *)addr + addr->Header.Length);
18836d789b61SKonstantin Belousov }
18846d789b61SKonstantin Belousov 
18856d789b61SKonstantin Belousov static void
18866d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_40(ACPI_IVRS_HARDWARE2 *addr)
18876d789b61SKonstantin Belousov {
18886d789b61SKonstantin Belousov 	acpi_handle_ivrs_ivhd_info_11(addr);
18896d789b61SKonstantin Belousov 	printf("\tEFRreg=%#018jx EFR2reg=%#018jx\n",
18906d789b61SKonstantin Belousov 	    (uintmax_t)addr->EfrRegisterImage, (uintmax_t)addr->Reserved);
18916d789b61SKonstantin Belousov 	acpi_handle_ivrs_ivhd_devs((ACPI_IVRS_DE_HEADER *)(addr + 1),
18926d789b61SKonstantin Belousov 	    (char *)addr + addr->Header.Length);
18936d789b61SKonstantin Belousov }
18946d789b61SKonstantin Belousov 
18956d789b61SKonstantin Belousov static const char *
18966d789b61SKonstantin Belousov acpi_handle_ivrs_ivmd_type(ACPI_IVRS_MEMORY *addr)
18976d789b61SKonstantin Belousov {
18986d789b61SKonstantin Belousov 	switch (addr->Header.Type) {
18996d789b61SKonstantin Belousov 	case ACPI_IVRS_TYPE_MEMORY1:
19006d789b61SKonstantin Belousov 		return ("ALL");
19016d789b61SKonstantin Belousov 	case ACPI_IVRS_TYPE_MEMORY2:
19026d789b61SKonstantin Belousov 		return ("specified");
19036d789b61SKonstantin Belousov 	case ACPI_IVRS_TYPE_MEMORY3:
19046d789b61SKonstantin Belousov 		return ("range");
19056d789b61SKonstantin Belousov 	default:
19066d789b61SKonstantin Belousov 		return ("unknown");
19076d789b61SKonstantin Belousov 	}
19086d789b61SKonstantin Belousov }
19096d789b61SKonstantin Belousov 
19106d789b61SKonstantin Belousov static void
19116d789b61SKonstantin Belousov acpi_handle_ivrs_ivmd(ACPI_IVRS_MEMORY *addr)
19126d789b61SKonstantin Belousov {
19136d789b61SKonstantin Belousov 	printf("\tMem Type=%#x(%s) ",
19146d789b61SKonstantin Belousov 	    addr->Header.Type, acpi_handle_ivrs_ivmd_type(addr));
19156d789b61SKonstantin Belousov 	switch (addr->Header.Type) {
19166d789b61SKonstantin Belousov 	case ACPI_IVRS_TYPE_MEMORY2:
19176d789b61SKonstantin Belousov 		printf("Id=%#06x PCISeg=%#x ", addr->Header.DeviceId,
19186d789b61SKonstantin Belousov 		    *(UINT16 *)&addr->Reserved);
19196d789b61SKonstantin Belousov 		break;
19206d789b61SKonstantin Belousov 	case ACPI_IVRS_TYPE_MEMORY3:
19216d789b61SKonstantin Belousov 		printf("Id=%#06x-%#06x PCISeg=%#x", addr->Header.DeviceId,
19226d789b61SKonstantin Belousov 		    addr->AuxData, *(UINT16 *)&addr->Reserved);
19236d789b61SKonstantin Belousov 		break;
19246d789b61SKonstantin Belousov 	}
19256d789b61SKonstantin Belousov 	printf("Start=%#18jx Length=%#jx Flags=",
19266d789b61SKonstantin Belousov 	    (uintmax_t)addr->StartAddress, (uintmax_t)addr->MemoryLength);
19276d789b61SKonstantin Belousov #define PRINTFLAG(flag, name) printflag(addr->Header.Flags, flag, #name)
19286d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVMD_EXCLUSION_RANGE, ExclusionRange);
19296d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVMD_WRITE, IW);
19306d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVMD_READ, IR);
19316d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVMD_UNITY, Unity);
19326d789b61SKonstantin Belousov #undef PRINTFLAG
19336d789b61SKonstantin Belousov 	PRINTFLAG_END();
19346d789b61SKonstantin Belousov }
19356d789b61SKonstantin Belousov 
19366d789b61SKonstantin Belousov static int
19376d789b61SKonstantin Belousov acpi_handle_ivrs_blocks(void *addr, int remaining, bool efrsup)
19386d789b61SKonstantin Belousov {
19396d789b61SKonstantin Belousov 	ACPI_IVRS_HEADER *hdr = addr;
19406d789b61SKonstantin Belousov 
19416d789b61SKonstantin Belousov 	if (remaining < (int)sizeof(ACPI_IVRS_HEADER))
19426d789b61SKonstantin Belousov 		return (-1);
19436d789b61SKonstantin Belousov 
19446d789b61SKonstantin Belousov 	if (remaining < hdr->Length)
19456d789b61SKonstantin Belousov 		return (-1);
19466d789b61SKonstantin Belousov 
19476d789b61SKonstantin Belousov 	switch (hdr->Type) {
19486d789b61SKonstantin Belousov 	case ACPI_IVRS_TYPE_HARDWARE1:
19496d789b61SKonstantin Belousov 		acpi_handle_ivrs_ivhd_10(addr, efrsup);
19506d789b61SKonstantin Belousov 		break;
19516d789b61SKonstantin Belousov 	case ACPI_IVRS_TYPE_HARDWARE2:
19526d789b61SKonstantin Belousov 		if (!efrsup)
19536d789b61SKonstantin Belousov 			printf("\t!! Found IVHD block 0x11 but !EFRsup\n");
19546d789b61SKonstantin Belousov 		acpi_handle_ivrs_ivhd_11(addr);
19556d789b61SKonstantin Belousov 		break;
19566d789b61SKonstantin Belousov 	case ACPI_IVRS_TYPE_HARDWARE3:
19576d789b61SKonstantin Belousov 		if (!efrsup)
19586d789b61SKonstantin Belousov 			printf("\t!! Found IVHD block 0x40 but !EFRsup\n");
19596d789b61SKonstantin Belousov 		acpi_handle_ivrs_ivhd_40(addr);
19606d789b61SKonstantin Belousov 		break;
19616d789b61SKonstantin Belousov 	case ACPI_IVRS_TYPE_MEMORY1:
19626d789b61SKonstantin Belousov 	case ACPI_IVRS_TYPE_MEMORY2:
19636d789b61SKonstantin Belousov 	case ACPI_IVRS_TYPE_MEMORY3:
19646d789b61SKonstantin Belousov 		acpi_handle_ivrs_ivmd(addr);
19656d789b61SKonstantin Belousov 		break;
19666d789b61SKonstantin Belousov 	default:
19676d789b61SKonstantin Belousov 		printf("\n");
19686d789b61SKonstantin Belousov 		printf("\tType=%d\n", hdr->Type);
19696d789b61SKonstantin Belousov 		printf("\tLength=%d\n", hdr->Length);
19706d789b61SKonstantin Belousov 		break;
19716d789b61SKonstantin Belousov 	}
19726d789b61SKonstantin Belousov 	return (hdr->Length);
19736d789b61SKonstantin Belousov }
19746d789b61SKonstantin Belousov 
19756d789b61SKonstantin Belousov #define	ACPI_IVRS_DMAREMAP	0x00000002
19766d789b61SKonstantin Belousov #define	ACPI_IVRS_EFRSUP	0x00000001
19776d789b61SKonstantin Belousov #define	ACPI_IVRS_GVA_SIZE	0x000000e0
19786d789b61SKonstantin Belousov 
19796d789b61SKonstantin Belousov static void
19806d789b61SKonstantin Belousov acpi_handle_ivrs(ACPI_TABLE_HEADER *sdp)
19816d789b61SKonstantin Belousov {
19826d789b61SKonstantin Belousov 	ACPI_TABLE_IVRS *ivrs;
19836d789b61SKonstantin Belousov 	char *cp;
19846d789b61SKonstantin Belousov 	int remaining, consumed;
19856d789b61SKonstantin Belousov 	bool efrsup;
19866d789b61SKonstantin Belousov 
19876d789b61SKonstantin Belousov 	printf(BEGIN_COMMENT);
19886d789b61SKonstantin Belousov 	acpi_print_sdt(sdp);
19896d789b61SKonstantin Belousov 	ivrs = (ACPI_TABLE_IVRS *)sdp;
19906d789b61SKonstantin Belousov 	efrsup = (ivrs->Info & ACPI_IVRS_EFRSUP) != 0;
19916d789b61SKonstantin Belousov 	printf("\tVAsize=%d PAsize=%d GVAsize=%d\n",
19926d789b61SKonstantin Belousov 	    (ivrs->Info & ACPI_IVRS_VIRTUAL_SIZE) >> 15,
19936d789b61SKonstantin Belousov 	    (ivrs->Info & ACPI_IVRS_PHYSICAL_SIZE) >> 8,
19946d789b61SKonstantin Belousov 	    (ivrs->Info & ACPI_IVRS_GVA_SIZE) >> 5);
19956d789b61SKonstantin Belousov 	printf("\tATS_resp_res=%d DMA_preboot_remap=%d EFRsup=%d\n",
19966d789b61SKonstantin Belousov 	    (ivrs->Info & ACPI_IVRS_ATS_RESERVED) != 0,
19976d789b61SKonstantin Belousov 	    (ivrs->Info & ACPI_IVRS_DMAREMAP) != 0, efrsup);
19986d789b61SKonstantin Belousov 
19996d789b61SKonstantin Belousov 	remaining = sdp->Length - sizeof(ACPI_TABLE_IVRS);
20006d789b61SKonstantin Belousov 	while (remaining > 0) {
20016d789b61SKonstantin Belousov 		cp = (char *)sdp + sdp->Length - remaining;
20026d789b61SKonstantin Belousov 		consumed = acpi_handle_ivrs_blocks(cp, remaining, efrsup);
20036d789b61SKonstantin Belousov 		if (consumed <= 0)
20046d789b61SKonstantin Belousov 			break;
20056d789b61SKonstantin Belousov 		else
20066d789b61SKonstantin Belousov 			remaining -= consumed;
20076d789b61SKonstantin Belousov 	}
20086d789b61SKonstantin Belousov 
20096d789b61SKonstantin Belousov 	printf(END_COMMENT);
20106d789b61SKonstantin Belousov }
20116d789b61SKonstantin Belousov 
20126d789b61SKonstantin Belousov static void
2013986dffafSJohn Baldwin acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp)
2014a0333ad1SJohn Baldwin {
2015a0333ad1SJohn Baldwin 
2016a0333ad1SJohn Baldwin 	printf("\tFlags={");
2017986dffafSJohn Baldwin 	if (mp->Flags & ACPI_SRAT_MEM_ENABLED)
2018a0333ad1SJohn Baldwin 		printf("ENABLED");
2019a0333ad1SJohn Baldwin 	else
2020a0333ad1SJohn Baldwin 		printf("DISABLED");
2021986dffafSJohn Baldwin 	if (mp->Flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)
2022a0333ad1SJohn Baldwin 		printf(",HOT_PLUGGABLE");
2023986dffafSJohn Baldwin 	if (mp->Flags & ACPI_SRAT_MEM_NON_VOLATILE)
2024a0333ad1SJohn Baldwin 		printf(",NON_VOLATILE");
2025a0333ad1SJohn Baldwin 	printf("}\n");
2026986dffafSJohn Baldwin 	printf("\tBase Address=0x%016jx\n", (uintmax_t)mp->BaseAddress);
2027986dffafSJohn Baldwin 	printf("\tLength=0x%016jx\n", (uintmax_t)mp->Length);
2028986dffafSJohn Baldwin 	printf("\tProximity Domain=%d\n", mp->ProximityDomain);
2029a0333ad1SJohn Baldwin }
2030a0333ad1SJohn Baldwin 
203127941afaSEd Maste static const char *srat_types[] = {
203227941afaSEd Maste     [ACPI_SRAT_TYPE_CPU_AFFINITY] = "CPU",
203327941afaSEd Maste     [ACPI_SRAT_TYPE_MEMORY_AFFINITY] = "Memory",
203427941afaSEd Maste     [ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY] = "X2APIC",
2035cebb7b19SEd Maste     [ACPI_SRAT_TYPE_GICC_AFFINITY] = "GICC",
2036cebb7b19SEd Maste     [ACPI_SRAT_TYPE_GIC_ITS_AFFINITY] = "GIC ITS",
203727941afaSEd Maste };
2038a0333ad1SJohn Baldwin 
2039a0333ad1SJohn Baldwin static void
2040986dffafSJohn Baldwin acpi_print_srat(ACPI_SUBTABLE_HEADER *srat)
2041a0333ad1SJohn Baldwin {
2042986dffafSJohn Baldwin 	ACPI_SRAT_CPU_AFFINITY *cpu;
2043986dffafSJohn Baldwin 	ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic;
20442b2b1f42SAndrew Turner 	ACPI_SRAT_GICC_AFFINITY *gic;
2045a0333ad1SJohn Baldwin 
2046c86932b6SMarcelo Araujo 	if (srat->Type < nitems(srat_types))
2047986dffafSJohn Baldwin 		printf("\tType=%s\n", srat_types[srat->Type]);
2048a0333ad1SJohn Baldwin 	else
2049986dffafSJohn Baldwin 		printf("\tType=%d (unknown)\n", srat->Type);
2050986dffafSJohn Baldwin 	switch (srat->Type) {
2051a0333ad1SJohn Baldwin 	case ACPI_SRAT_TYPE_CPU_AFFINITY:
2052986dffafSJohn Baldwin 		cpu = (ACPI_SRAT_CPU_AFFINITY *)srat;
2053986dffafSJohn Baldwin 		acpi_print_srat_cpu(cpu->ApicId,
2054986dffafSJohn Baldwin 		    cpu->ProximityDomainHi[2] << 24 |
2055986dffafSJohn Baldwin 		    cpu->ProximityDomainHi[1] << 16 |
2056986dffafSJohn Baldwin 		    cpu->ProximityDomainHi[0] << 0 |
2057986dffafSJohn Baldwin 		    cpu->ProximityDomainLo, cpu->Flags);
2058a0333ad1SJohn Baldwin 		break;
2059a0333ad1SJohn Baldwin 	case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
2060986dffafSJohn Baldwin 		acpi_print_srat_memory((ACPI_SRAT_MEM_AFFINITY *)srat);
2061a0333ad1SJohn Baldwin 		break;
2062a0333ad1SJohn Baldwin 	case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
2063986dffafSJohn Baldwin 		x2apic = (ACPI_SRAT_X2APIC_CPU_AFFINITY *)srat;
2064986dffafSJohn Baldwin 		acpi_print_srat_cpu(x2apic->ApicId, x2apic->ProximityDomain,
2065986dffafSJohn Baldwin 		    x2apic->Flags);
2066a0333ad1SJohn Baldwin 		break;
20672b2b1f42SAndrew Turner 	case ACPI_SRAT_TYPE_GICC_AFFINITY:
20682b2b1f42SAndrew Turner 		gic = (ACPI_SRAT_GICC_AFFINITY *)srat;
20692b2b1f42SAndrew Turner 		acpi_print_srat_cpu(gic->AcpiProcessorUid, gic->ProximityDomain,
20702b2b1f42SAndrew Turner 		    gic->Flags);
20712b2b1f42SAndrew Turner 		break;
2072a0333ad1SJohn Baldwin 	}
2073a0333ad1SJohn Baldwin }
2074a0333ad1SJohn Baldwin 
2075a0333ad1SJohn Baldwin static void
2076986dffafSJohn Baldwin acpi_handle_srat(ACPI_TABLE_HEADER *sdp)
2077a0333ad1SJohn Baldwin {
2078986dffafSJohn Baldwin 	ACPI_TABLE_SRAT *srat;
2079a0333ad1SJohn Baldwin 
2080a0333ad1SJohn Baldwin 	printf(BEGIN_COMMENT);
2081a0333ad1SJohn Baldwin 	acpi_print_sdt(sdp);
2082986dffafSJohn Baldwin 	srat = (ACPI_TABLE_SRAT *)sdp;
2083986dffafSJohn Baldwin 	printf("\tTable Revision=%d\n", srat->TableRevision);
2084986dffafSJohn Baldwin 	acpi_walk_subtables(sdp, (srat + 1), acpi_print_srat);
2085a0333ad1SJohn Baldwin 	printf(END_COMMENT);
2086a0333ad1SJohn Baldwin }
2087a0333ad1SJohn Baldwin 
2088340c0022SEd Maste static const char *nfit_types[] = {
2089340c0022SEd Maste     [ACPI_NFIT_TYPE_SYSTEM_ADDRESS] = "System Address",
2090340c0022SEd Maste     [ACPI_NFIT_TYPE_MEMORY_MAP] = "Memory Map",
2091340c0022SEd Maste     [ACPI_NFIT_TYPE_INTERLEAVE] = "Interleave",
2092340c0022SEd Maste     [ACPI_NFIT_TYPE_SMBIOS] = "SMBIOS",
2093340c0022SEd Maste     [ACPI_NFIT_TYPE_CONTROL_REGION] = "Control Region",
2094340c0022SEd Maste     [ACPI_NFIT_TYPE_DATA_REGION] = "Data Region",
20951b109c69SAlexander Motin     [ACPI_NFIT_TYPE_FLUSH_ADDRESS] = "Flush Address",
20961b109c69SAlexander Motin     [ACPI_NFIT_TYPE_CAPABILITIES] = "Platform Capabilities"
2097340c0022SEd Maste };
2098340c0022SEd Maste 
2099340c0022SEd Maste 
2100340c0022SEd Maste static void
2101340c0022SEd Maste acpi_print_nfit(ACPI_NFIT_HEADER *nfit)
2102340c0022SEd Maste {
2103340c0022SEd Maste 	char *uuidstr;
21043b7935f3SAlexander Motin 	uint32_t m, status;
2105340c0022SEd Maste 
2106340c0022SEd Maste 	ACPI_NFIT_SYSTEM_ADDRESS *sysaddr;
2107340c0022SEd Maste 	ACPI_NFIT_MEMORY_MAP *mmap;
2108340c0022SEd Maste 	ACPI_NFIT_INTERLEAVE *ileave;
2109340c0022SEd Maste 	ACPI_NFIT_CONTROL_REGION *ctlreg;
2110340c0022SEd Maste 	ACPI_NFIT_DATA_REGION *datareg;
2111340c0022SEd Maste 	ACPI_NFIT_FLUSH_ADDRESS *fladdr;
21121b109c69SAlexander Motin 	ACPI_NFIT_CAPABILITIES *caps;
2113340c0022SEd Maste 
2114340c0022SEd Maste 	if (nfit->Type < nitems(nfit_types))
2115340c0022SEd Maste 		printf("\tType=%s\n", nfit_types[nfit->Type]);
2116340c0022SEd Maste 	else
2117340c0022SEd Maste 		printf("\tType=%u (unknown)\n", nfit->Type);
2118340c0022SEd Maste 	switch (nfit->Type) {
2119340c0022SEd Maste 	case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
2120340c0022SEd Maste 		sysaddr = (ACPI_NFIT_SYSTEM_ADDRESS *)nfit;
2121340c0022SEd Maste 		printf("\tRangeIndex=%u\n", (u_int)sysaddr->RangeIndex);
2122340c0022SEd Maste 		printf("\tProximityDomain=%u\n",
2123340c0022SEd Maste 		    (u_int)sysaddr->ProximityDomain);
2124de937ecbSKonstantin Belousov 		uuid_to_string((uuid_t *)(uintptr_t)(sysaddr->RangeGuid),
2125340c0022SEd Maste 		    &uuidstr, &status);
2126340c0022SEd Maste 		if (status != uuid_s_ok)
2127340c0022SEd Maste 			errx(1, "uuid_to_string: status=%u", status);
2128340c0022SEd Maste 		printf("\tRangeGuid=%s\n", uuidstr);
2129340c0022SEd Maste 		free(uuidstr);
2130340c0022SEd Maste 		printf("\tAddress=0x%016jx\n", (uintmax_t)sysaddr->Address);
2131340c0022SEd Maste 		printf("\tLength=0x%016jx\n", (uintmax_t)sysaddr->Length);
2132340c0022SEd Maste 		printf("\tMemoryMapping=0x%016jx\n",
2133340c0022SEd Maste 		    (uintmax_t)sysaddr->MemoryMapping);
2134340c0022SEd Maste 
2135340c0022SEd Maste #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_## flag, #flag)
2136340c0022SEd Maste 
2137340c0022SEd Maste 		printf("\tFlags=");
2138340c0022SEd Maste 		PRINTFLAG(sysaddr->Flags, ADD_ONLINE_ONLY);
2139340c0022SEd Maste 		PRINTFLAG(sysaddr->Flags, PROXIMITY_VALID);
2140340c0022SEd Maste 		PRINTFLAG_END();
2141340c0022SEd Maste 
2142340c0022SEd Maste #undef PRINTFLAG
2143340c0022SEd Maste 
2144340c0022SEd Maste 		break;
2145340c0022SEd Maste 	case ACPI_NFIT_TYPE_MEMORY_MAP:
2146340c0022SEd Maste 		mmap = (ACPI_NFIT_MEMORY_MAP *)nfit;
214792d0d6bbSAlexander Motin 		printf("\tDeviceHandle=0x%x\n", (u_int)mmap->DeviceHandle);
214892d0d6bbSAlexander Motin 		printf("\tPhysicalId=0x%04x\n", (u_int)mmap->PhysicalId);
2149340c0022SEd Maste 		printf("\tRegionId=%u\n", (u_int)mmap->RegionId);
2150340c0022SEd Maste 		printf("\tRangeIndex=%u\n", (u_int)mmap->RangeIndex);
2151340c0022SEd Maste 		printf("\tRegionIndex=%u\n", (u_int)mmap->RegionIndex);
2152340c0022SEd Maste 		printf("\tRegionSize=0x%016jx\n", (uintmax_t)mmap->RegionSize);
2153340c0022SEd Maste 		printf("\tRegionOffset=0x%016jx\n",
2154340c0022SEd Maste 		    (uintmax_t)mmap->RegionOffset);
2155340c0022SEd Maste 		printf("\tAddress=0x%016jx\n", (uintmax_t)mmap->Address);
2156340c0022SEd Maste 		printf("\tInterleaveIndex=%u\n", (u_int)mmap->InterleaveIndex);
2157fb1cf2a9SAlexander Motin 		printf("\tInterleaveWays=%u\n", (u_int)mmap->InterleaveWays);
2158340c0022SEd Maste 
2159340c0022SEd Maste #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_MEM_## flag, #flag)
2160340c0022SEd Maste 
2161340c0022SEd Maste 		printf("\tFlags=");
2162340c0022SEd Maste 		PRINTFLAG(mmap->Flags, SAVE_FAILED);
2163340c0022SEd Maste 		PRINTFLAG(mmap->Flags, RESTORE_FAILED);
2164340c0022SEd Maste 		PRINTFLAG(mmap->Flags, FLUSH_FAILED);
2165340c0022SEd Maste 		PRINTFLAG(mmap->Flags, NOT_ARMED);
2166340c0022SEd Maste 		PRINTFLAG(mmap->Flags, HEALTH_OBSERVED);
2167340c0022SEd Maste 		PRINTFLAG(mmap->Flags, HEALTH_ENABLED);
2168340c0022SEd Maste 		PRINTFLAG(mmap->Flags, MAP_FAILED);
2169340c0022SEd Maste 		PRINTFLAG_END();
2170340c0022SEd Maste 
2171340c0022SEd Maste #undef PRINTFLAG
2172340c0022SEd Maste 
2173340c0022SEd Maste 		break;
2174340c0022SEd Maste 	case ACPI_NFIT_TYPE_INTERLEAVE:
2175340c0022SEd Maste 		ileave = (ACPI_NFIT_INTERLEAVE *)nfit;
2176340c0022SEd Maste 		printf("\tInterleaveIndex=%u\n",
2177340c0022SEd Maste 		    (u_int)ileave->InterleaveIndex);
2178340c0022SEd Maste 		printf("\tLineCount=%u\n", (u_int)ileave->LineCount);
2179340c0022SEd Maste 		printf("\tLineSize=%u\n", (u_int)ileave->LineSize);
21803b7935f3SAlexander Motin 		for (m = 0; m < ileave->LineCount; m++) {
21813b7935f3SAlexander Motin 			printf("\tLine%uOffset=0x%08x\n", (u_int)m + 1,
21823b7935f3SAlexander Motin 			    (u_int)ileave->LineOffset[m]);
21833b7935f3SAlexander Motin 		}
2184340c0022SEd Maste 		break;
2185340c0022SEd Maste 	case ACPI_NFIT_TYPE_SMBIOS:
2186340c0022SEd Maste 		/* XXX smbios->Data[x] output is not supported */
2187340c0022SEd Maste 		break;
2188340c0022SEd Maste 	case ACPI_NFIT_TYPE_CONTROL_REGION:
2189340c0022SEd Maste 		ctlreg = (ACPI_NFIT_CONTROL_REGION *)nfit;
2190340c0022SEd Maste 		printf("\tRegionIndex=%u\n", (u_int)ctlreg->RegionIndex);
2191340c0022SEd Maste 		printf("\tVendorId=0x%04x\n", (u_int)ctlreg->VendorId);
2192340c0022SEd Maste 		printf("\tDeviceId=0x%04x\n", (u_int)ctlreg->DeviceId);
219335e39fd9SAlexander Motin 		printf("\tRevisionId=0x%02x\n", (u_int)ctlreg->RevisionId);
2194340c0022SEd Maste 		printf("\tSubsystemVendorId=0x%04x\n",
2195340c0022SEd Maste 		    (u_int)ctlreg->SubsystemVendorId);
2196340c0022SEd Maste 		printf("\tSubsystemDeviceId=0x%04x\n",
2197340c0022SEd Maste 		    (u_int)ctlreg->SubsystemDeviceId);
219835e39fd9SAlexander Motin 		printf("\tSubsystemRevisionId=0x%02x\n",
2199340c0022SEd Maste 		    (u_int)ctlreg->SubsystemRevisionId);
2200d4c2de2eSAlexander Motin 		printf("\tValidFields=0x%02x\n", (u_int)ctlreg->ValidFields);
220135e39fd9SAlexander Motin 		printf("\tManufacturingLocation=0x%02x\n",
2202340c0022SEd Maste 		    (u_int)ctlreg->ManufacturingLocation);
220335e39fd9SAlexander Motin 		printf("\tManufacturingDate=%04x\n",
220435e39fd9SAlexander Motin 		    (u_int)be16toh(ctlreg->ManufacturingDate));
220535e39fd9SAlexander Motin 		printf("\tSerialNumber=%08X\n",
220635e39fd9SAlexander Motin 		    (u_int)be32toh(ctlreg->SerialNumber));
2207fb1cf2a9SAlexander Motin 		printf("\tCode=0x%04x\n", (u_int)ctlreg->Code);
2208340c0022SEd Maste 		printf("\tWindows=%u\n", (u_int)ctlreg->Windows);
2209340c0022SEd Maste 		printf("\tWindowSize=0x%016jx\n",
2210340c0022SEd Maste 		    (uintmax_t)ctlreg->WindowSize);
2211340c0022SEd Maste 		printf("\tCommandOffset=0x%016jx\n",
2212340c0022SEd Maste 		    (uintmax_t)ctlreg->CommandOffset);
2213340c0022SEd Maste 		printf("\tCommandSize=0x%016jx\n",
2214340c0022SEd Maste 		    (uintmax_t)ctlreg->CommandSize);
2215340c0022SEd Maste 		printf("\tStatusOffset=0x%016jx\n",
2216340c0022SEd Maste 		    (uintmax_t)ctlreg->StatusOffset);
2217340c0022SEd Maste 		printf("\tStatusSize=0x%016jx\n",
2218340c0022SEd Maste 		    (uintmax_t)ctlreg->StatusSize);
2219340c0022SEd Maste 
2220340c0022SEd Maste #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_## flag, #flag)
2221340c0022SEd Maste 
2222340c0022SEd Maste 		printf("\tFlags=");
2223d4c2de2eSAlexander Motin 		PRINTFLAG(ctlreg->Flags, CONTROL_BUFFERED);
2224340c0022SEd Maste 		PRINTFLAG_END();
2225340c0022SEd Maste 
2226340c0022SEd Maste #undef PRINTFLAG
2227340c0022SEd Maste 
2228340c0022SEd Maste 		break;
2229340c0022SEd Maste 	case ACPI_NFIT_TYPE_DATA_REGION:
2230340c0022SEd Maste 		datareg = (ACPI_NFIT_DATA_REGION *)nfit;
2231340c0022SEd Maste 		printf("\tRegionIndex=%u\n", (u_int)datareg->RegionIndex);
2232340c0022SEd Maste 		printf("\tWindows=%u\n", (u_int)datareg->Windows);
2233340c0022SEd Maste 		printf("\tOffset=0x%016jx\n", (uintmax_t)datareg->Offset);
2234340c0022SEd Maste 		printf("\tSize=0x%016jx\n", (uintmax_t)datareg->Size);
2235340c0022SEd Maste 		printf("\tCapacity=0x%016jx\n", (uintmax_t)datareg->Capacity);
2236340c0022SEd Maste 		printf("\tStartAddress=0x%016jx\n",
2237340c0022SEd Maste 		    (uintmax_t)datareg->StartAddress);
2238340c0022SEd Maste 		break;
2239340c0022SEd Maste 	case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
2240340c0022SEd Maste 		fladdr = (ACPI_NFIT_FLUSH_ADDRESS *)nfit;
2241340c0022SEd Maste 		printf("\tDeviceHandle=%u\n", (u_int)fladdr->DeviceHandle);
2242340c0022SEd Maste 		printf("\tHintCount=%u\n", (u_int)fladdr->HintCount);
22433b7935f3SAlexander Motin 		for (m = 0; m < fladdr->HintCount; m++) {
22443b7935f3SAlexander Motin 			printf("\tHintAddress%u=0x%016jx\n", (u_int)m + 1,
22453b7935f3SAlexander Motin 			    (uintmax_t)fladdr->HintAddress[m]);
22463b7935f3SAlexander Motin 		}
2247340c0022SEd Maste 		break;
22481b109c69SAlexander Motin 	case ACPI_NFIT_TYPE_CAPABILITIES:
22491b109c69SAlexander Motin 		caps = (ACPI_NFIT_CAPABILITIES *)nfit;
22501b109c69SAlexander Motin 		printf("\tHighestCapability=%u\n", (u_int)caps->HighestCapability);
22511b109c69SAlexander Motin 
22521b109c69SAlexander Motin #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_CAPABILITY_## flag, #flag)
22531b109c69SAlexander Motin 
22541b109c69SAlexander Motin 		printf("\tCapabilities=");
22551b109c69SAlexander Motin 		PRINTFLAG(caps->Capabilities, CACHE_FLUSH);
22561b109c69SAlexander Motin 		PRINTFLAG(caps->Capabilities, MEM_FLUSH);
22571b109c69SAlexander Motin 		PRINTFLAG(caps->Capabilities, MEM_MIRRORING);
22581b109c69SAlexander Motin 		PRINTFLAG_END();
22591b109c69SAlexander Motin 
22601b109c69SAlexander Motin #undef PRINTFLAG
22611b109c69SAlexander Motin 		break;
2262340c0022SEd Maste 	}
2263340c0022SEd Maste }
2264340c0022SEd Maste 
2265340c0022SEd Maste static void
2266340c0022SEd Maste acpi_handle_nfit(ACPI_TABLE_HEADER *sdp)
2267340c0022SEd Maste {
2268340c0022SEd Maste 	ACPI_TABLE_NFIT *nfit;
2269340c0022SEd Maste 
2270340c0022SEd Maste 	printf(BEGIN_COMMENT);
2271340c0022SEd Maste 	acpi_print_sdt(sdp);
2272340c0022SEd Maste 	nfit = (ACPI_TABLE_NFIT *)sdp;
2273340c0022SEd Maste 	acpi_walk_nfit(sdp, (nfit + 1), acpi_print_nfit);
2274340c0022SEd Maste 	printf(END_COMMENT);
2275340c0022SEd Maste }
2276340c0022SEd Maste 
2277a0333ad1SJohn Baldwin static void
2278986dffafSJohn Baldwin acpi_print_sdt(ACPI_TABLE_HEADER *sdp)
2279c62f1cccSMitsuru IWASAKI {
2280773b6454SNate Lawson 	printf("  ");
2281278f0de6SJung-uk Kim 	acpi_print_string(sdp->Signature, ACPI_NAMESEG_SIZE);
2282c62f1cccSMitsuru IWASAKI 	printf(": Length=%d, Revision=%d, Checksum=%d,\n",
2283986dffafSJohn Baldwin 	       sdp->Length, sdp->Revision, sdp->Checksum);
2284e1e9a4bfSMitsuru IWASAKI 	printf("\tOEMID=");
2285986dffafSJohn Baldwin 	acpi_print_string(sdp->OemId, ACPI_OEM_ID_SIZE);
2286e1e9a4bfSMitsuru IWASAKI 	printf(", OEM Table ID=");
2287986dffafSJohn Baldwin 	acpi_print_string(sdp->OemTableId, ACPI_OEM_TABLE_ID_SIZE);
2288986dffafSJohn Baldwin 	printf(", OEM Revision=0x%x,\n", sdp->OemRevision);
2289e1e9a4bfSMitsuru IWASAKI 	printf("\tCreator ID=");
2290278f0de6SJung-uk Kim 	acpi_print_string(sdp->AslCompilerId, ACPI_NAMESEG_SIZE);
2291986dffafSJohn Baldwin 	printf(", Creator Revision=0x%x\n", sdp->AslCompilerRevision);
2292e1e9a4bfSMitsuru IWASAKI }
2293e1e9a4bfSMitsuru IWASAKI 
2294945137d9SNate Lawson static void
2295986dffafSJohn Baldwin acpi_print_rsdt(ACPI_TABLE_HEADER *rsdp)
2296e1e9a4bfSMitsuru IWASAKI {
2297986dffafSJohn Baldwin 	ACPI_TABLE_RSDT *rsdt;
2298986dffafSJohn Baldwin 	ACPI_TABLE_XSDT *xsdt;
2299e1e9a4bfSMitsuru IWASAKI 	int	i, entries;
2300e1e9a4bfSMitsuru IWASAKI 
2301986dffafSJohn Baldwin 	rsdt = (ACPI_TABLE_RSDT *)rsdp;
2302986dffafSJohn Baldwin 	xsdt = (ACPI_TABLE_XSDT *)rsdp;
2303773b6454SNate Lawson 	printf(BEGIN_COMMENT);
2304773b6454SNate Lawson 	acpi_print_sdt(rsdp);
2305986dffafSJohn Baldwin 	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
2306e1e9a4bfSMitsuru IWASAKI 	printf("\tEntries={ ");
2307e1e9a4bfSMitsuru IWASAKI 	for (i = 0; i < entries; i++) {
2308e1e9a4bfSMitsuru IWASAKI 		if (i > 0)
2309e1e9a4bfSMitsuru IWASAKI 			printf(", ");
2310fe1d0c2dSJung-uk Kim 		if (addr_size == 4)
23117d369c6eSJung-uk Kim 			printf("0x%08x", le32toh(rsdt->TableOffsetEntry[i]));
2312fe1d0c2dSJung-uk Kim 		else
23137d369c6eSJung-uk Kim 			printf("0x%016jx",
23147d369c6eSJung-uk Kim 			    (uintmax_t)le64toh(xsdt->TableOffsetEntry[i]));
2315e1e9a4bfSMitsuru IWASAKI 	}
2316e1e9a4bfSMitsuru IWASAKI 	printf(" }\n");
2317c62f1cccSMitsuru IWASAKI 	printf(END_COMMENT);
2318e1e9a4bfSMitsuru IWASAKI }
2319e1e9a4bfSMitsuru IWASAKI 
23208e6a8737SNate Lawson static const char *acpi_pm_profiles[] = {
23218e6a8737SNate Lawson 	"Unspecified", "Desktop", "Mobile", "Workstation",
23228e6a8737SNate Lawson 	"Enterprise Server", "SOHO Server", "Appliance PC"
23238e6a8737SNate Lawson };
23248e6a8737SNate Lawson 
2325945137d9SNate Lawson static void
2326986dffafSJohn Baldwin acpi_print_fadt(ACPI_TABLE_HEADER *sdp)
2327e1e9a4bfSMitsuru IWASAKI {
2328986dffafSJohn Baldwin 	ACPI_TABLE_FADT *fadt;
23298e6a8737SNate Lawson 	const char *pm;
2330e1e9a4bfSMitsuru IWASAKI 
2331986dffafSJohn Baldwin 	fadt = (ACPI_TABLE_FADT *)sdp;
2332c62f1cccSMitsuru IWASAKI 	printf(BEGIN_COMMENT);
23332177d4e6SNate Lawson 	acpi_print_sdt(sdp);
2334986dffafSJohn Baldwin 	printf(" \tFACS=0x%x, DSDT=0x%x\n", fadt->Facs,
2335986dffafSJohn Baldwin 	       fadt->Dsdt);
2336986dffafSJohn Baldwin 	printf("\tINT_MODEL=%s\n", fadt->Model ? "APIC" : "PIC");
2337986dffafSJohn Baldwin 	if (fadt->PreferredProfile >= sizeof(acpi_pm_profiles) / sizeof(char *))
23388e6a8737SNate Lawson 		pm = "Reserved";
23398e6a8737SNate Lawson 	else
2340986dffafSJohn Baldwin 		pm = acpi_pm_profiles[fadt->PreferredProfile];
2341986dffafSJohn Baldwin 	printf("\tPreferred_PM_Profile=%s (%d)\n", pm, fadt->PreferredProfile);
2342986dffafSJohn Baldwin 	printf("\tSCI_INT=%d\n", fadt->SciInterrupt);
2343986dffafSJohn Baldwin 	printf("\tSMI_CMD=0x%x, ", fadt->SmiCommand);
2344986dffafSJohn Baldwin 	printf("ACPI_ENABLE=0x%x, ", fadt->AcpiEnable);
2345986dffafSJohn Baldwin 	printf("ACPI_DISABLE=0x%x, ", fadt->AcpiDisable);
2346986dffafSJohn Baldwin 	printf("S4BIOS_REQ=0x%x\n", fadt->S4BiosRequest);
2347986dffafSJohn Baldwin 	printf("\tPSTATE_CNT=0x%x\n", fadt->PstateControl);
2348e1e9a4bfSMitsuru IWASAKI 	printf("\tPM1a_EVT_BLK=0x%x-0x%x\n",
2349986dffafSJohn Baldwin 	       fadt->Pm1aEventBlock,
2350986dffafSJohn Baldwin 	       fadt->Pm1aEventBlock + fadt->Pm1EventLength - 1);
2351986dffafSJohn Baldwin 	if (fadt->Pm1bEventBlock != 0)
2352e1e9a4bfSMitsuru IWASAKI 		printf("\tPM1b_EVT_BLK=0x%x-0x%x\n",
2353986dffafSJohn Baldwin 		       fadt->Pm1bEventBlock,
2354986dffafSJohn Baldwin 		       fadt->Pm1bEventBlock + fadt->Pm1EventLength - 1);
2355e1e9a4bfSMitsuru IWASAKI 	printf("\tPM1a_CNT_BLK=0x%x-0x%x\n",
2356986dffafSJohn Baldwin 	       fadt->Pm1aControlBlock,
2357986dffafSJohn Baldwin 	       fadt->Pm1aControlBlock + fadt->Pm1ControlLength - 1);
2358986dffafSJohn Baldwin 	if (fadt->Pm1bControlBlock != 0)
2359e1e9a4bfSMitsuru IWASAKI 		printf("\tPM1b_CNT_BLK=0x%x-0x%x\n",
2360986dffafSJohn Baldwin 		       fadt->Pm1bControlBlock,
2361986dffafSJohn Baldwin 		       fadt->Pm1bControlBlock + fadt->Pm1ControlLength - 1);
2362986dffafSJohn Baldwin 	if (fadt->Pm2ControlBlock != 0)
2363e1e9a4bfSMitsuru IWASAKI 		printf("\tPM2_CNT_BLK=0x%x-0x%x\n",
2364986dffafSJohn Baldwin 		       fadt->Pm2ControlBlock,
2365986dffafSJohn Baldwin 		       fadt->Pm2ControlBlock + fadt->Pm2ControlLength - 1);
2366c08c4e81SNate Lawson 	printf("\tPM_TMR_BLK=0x%x-0x%x\n",
2367986dffafSJohn Baldwin 	       fadt->PmTimerBlock,
2368986dffafSJohn Baldwin 	       fadt->PmTimerBlock + fadt->PmTimerLength - 1);
2369986dffafSJohn Baldwin 	if (fadt->Gpe0Block != 0)
23708e6a8737SNate Lawson 		printf("\tGPE0_BLK=0x%x-0x%x\n",
2371986dffafSJohn Baldwin 		       fadt->Gpe0Block,
2372986dffafSJohn Baldwin 		       fadt->Gpe0Block + fadt->Gpe0BlockLength - 1);
2373986dffafSJohn Baldwin 	if (fadt->Gpe1Block != 0)
23748e6a8737SNate Lawson 		printf("\tGPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n",
2375986dffafSJohn Baldwin 		       fadt->Gpe1Block,
2376986dffafSJohn Baldwin 		       fadt->Gpe1Block + fadt->Gpe1BlockLength - 1,
2377986dffafSJohn Baldwin 		       fadt->Gpe1Base);
2378986dffafSJohn Baldwin 	if (fadt->CstControl != 0)
2379986dffafSJohn Baldwin 		printf("\tCST_CNT=0x%x\n", fadt->CstControl);
238051c1824fSNate Lawson 	printf("\tP_LVL2_LAT=%d us, P_LVL3_LAT=%d us\n",
2381986dffafSJohn Baldwin 	       fadt->C2Latency, fadt->C3Latency);
2382e1e9a4bfSMitsuru IWASAKI 	printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n",
2383986dffafSJohn Baldwin 	       fadt->FlushSize, fadt->FlushStride);
2384e1e9a4bfSMitsuru IWASAKI 	printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n",
2385986dffafSJohn Baldwin 	       fadt->DutyOffset, fadt->DutyWidth);
2386e1e9a4bfSMitsuru IWASAKI 	printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n",
2387986dffafSJohn Baldwin 	       fadt->DayAlarm, fadt->MonthAlarm, fadt->Century);
2388e1e9a4bfSMitsuru IWASAKI 
2389ec650989SNeel Natu #define PRINTFLAG(var, flag)	printflag((var), ACPI_FADT_## flag, #flag)
2390e1e9a4bfSMitsuru IWASAKI 
23918e6a8737SNate Lawson 	printf("\tIAPC_BOOT_ARCH=");
2392986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, LEGACY_DEVICES);
2393986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, 8042);
2394986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, NO_VGA);
2395986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, NO_MSI);
2396986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, NO_ASPM);
2397f6469ce1SAndrew Turner 	PRINTFLAG(fadt->BootFlags, NO_CMOS_RTC);
2398ec650989SNeel Natu 	PRINTFLAG_END();
23998e6a8737SNate Lawson 
24008e6a8737SNate Lawson 	printf("\tFlags=");
2401986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, WBINVD);
2402986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, WBINVD_FLUSH);
2403986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, C1_SUPPORTED);
2404986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, C2_MP_SUPPORTED);
2405986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, POWER_BUTTON);
2406986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, SLEEP_BUTTON);
2407986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, FIXED_RTC);
2408986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, S4_RTC_WAKE);
2409986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, 32BIT_TIMER);
2410986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, DOCKING_SUPPORTED);
2411986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, RESET_REGISTER);
2412986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, SEALED_CASE);
2413986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, HEADLESS);
2414986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, SLEEP_TYPE);
2415986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, PCI_EXPRESS_WAKE);
2416986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, PLATFORM_CLOCK);
2417986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, S4_RTC_VALID);
2418986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, REMOTE_POWER_ON);
2419986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, APIC_CLUSTER);
2420986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, APIC_PHYSICAL);
2421f6469ce1SAndrew Turner 	PRINTFLAG(fadt->Flags, HW_REDUCED);
2422f6469ce1SAndrew Turner 	PRINTFLAG(fadt->Flags, LOW_POWER_S0);
2423ec650989SNeel Natu 	PRINTFLAG_END();
2424e1e9a4bfSMitsuru IWASAKI 
2425e1e9a4bfSMitsuru IWASAKI #undef PRINTFLAG
2426e1e9a4bfSMitsuru IWASAKI 
2427986dffafSJohn Baldwin 	if (fadt->Flags & ACPI_FADT_RESET_REGISTER) {
24288e6a8737SNate Lawson 		printf("\tRESET_REG=");
2429986dffafSJohn Baldwin 		acpi_print_gas(&fadt->ResetRegister);
2430986dffafSJohn Baldwin 		printf(", RESET_VALUE=%#x\n", fadt->ResetValue);
24318e6a8737SNate Lawson 	}
2432c2962974SNate Lawson 	if (acpi_get_fadt_revision(fadt) > 1) {
24337d369c6eSJung-uk Kim 		printf("\tX_FACS=0x%016jx, ", (uintmax_t)fadt->XFacs);
24347d369c6eSJung-uk Kim 		printf("X_DSDT=0x%016jx\n", (uintmax_t)fadt->XDsdt);
2435c08c4e81SNate Lawson 		printf("\tX_PM1a_EVT_BLK=");
2436986dffafSJohn Baldwin 		acpi_print_gas(&fadt->XPm1aEventBlock);
2437986dffafSJohn Baldwin 		if (fadt->XPm1bEventBlock.Address != 0) {
2438c08c4e81SNate Lawson 			printf("\n\tX_PM1b_EVT_BLK=");
2439986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XPm1bEventBlock);
2440c08c4e81SNate Lawson 		}
2441c08c4e81SNate Lawson 		printf("\n\tX_PM1a_CNT_BLK=");
2442986dffafSJohn Baldwin 		acpi_print_gas(&fadt->XPm1aControlBlock);
2443986dffafSJohn Baldwin 		if (fadt->XPm1bControlBlock.Address != 0) {
2444c08c4e81SNate Lawson 			printf("\n\tX_PM1b_CNT_BLK=");
2445986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XPm1bControlBlock);
2446c08c4e81SNate Lawson 		}
2447986dffafSJohn Baldwin 		if (fadt->XPm2ControlBlock.Address != 0) {
2448773b6454SNate Lawson 			printf("\n\tX_PM2_CNT_BLK=");
2449986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XPm2ControlBlock);
2450c08c4e81SNate Lawson 		}
2451773b6454SNate Lawson 		printf("\n\tX_PM_TMR_BLK=");
2452986dffafSJohn Baldwin 		acpi_print_gas(&fadt->XPmTimerBlock);
2453986dffafSJohn Baldwin 		if (fadt->XGpe0Block.Address != 0) {
2454773b6454SNate Lawson 			printf("\n\tX_GPE0_BLK=");
2455986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XGpe0Block);
2456c08c4e81SNate Lawson 		}
2457986dffafSJohn Baldwin 		if (fadt->XGpe1Block.Address != 0) {
2458773b6454SNate Lawson 			printf("\n\tX_GPE1_BLK=");
2459986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XGpe1Block);
2460c08c4e81SNate Lawson 		}
2461773b6454SNate Lawson 		printf("\n");
2462773b6454SNate Lawson 	}
24638e6a8737SNate Lawson 
24648e6a8737SNate Lawson 	printf(END_COMMENT);
24658e6a8737SNate Lawson }
24668e6a8737SNate Lawson 
24678e6a8737SNate Lawson static void
2468986dffafSJohn Baldwin acpi_print_facs(ACPI_TABLE_FACS *facs)
24698e6a8737SNate Lawson {
24708e6a8737SNate Lawson 	printf(BEGIN_COMMENT);
2471986dffafSJohn Baldwin 	printf("  FACS:\tLength=%u, ", facs->Length);
2472986dffafSJohn Baldwin 	printf("HwSig=0x%08x, ", facs->HardwareSignature);
2473986dffafSJohn Baldwin 	printf("Firm_Wake_Vec=0x%08x\n", facs->FirmwareWakingVector);
24748e6a8737SNate Lawson 
2475773b6454SNate Lawson 	printf("\tGlobal_Lock=");
2476986dffafSJohn Baldwin 	if (facs->GlobalLock != 0) {
2477986dffafSJohn Baldwin 		if (facs->GlobalLock & ACPI_GLOCK_PENDING)
24788e6a8737SNate Lawson 			printf("PENDING,");
2479986dffafSJohn Baldwin 		if (facs->GlobalLock & ACPI_GLOCK_OWNED)
24808e6a8737SNate Lawson 			printf("OWNED");
24818e6a8737SNate Lawson 	}
2482773b6454SNate Lawson 	printf("\n");
24838e6a8737SNate Lawson 
2484773b6454SNate Lawson 	printf("\tFlags=");
2485986dffafSJohn Baldwin 	if (facs->Flags & ACPI_FACS_S4_BIOS_PRESENT)
24868e6a8737SNate Lawson 		printf("S4BIOS");
2487773b6454SNate Lawson 	printf("\n");
24888e6a8737SNate Lawson 
24897d369c6eSJung-uk Kim 	if (facs->XFirmwareWakingVector != 0)
24907d369c6eSJung-uk Kim 		printf("\tX_Firm_Wake_Vec=%016jx\n",
24917d369c6eSJung-uk Kim 		    (uintmax_t)facs->XFirmwareWakingVector);
2492986dffafSJohn Baldwin 	printf("\tVersion=%u\n", facs->Version);
24938e6a8737SNate Lawson 
2494c62f1cccSMitsuru IWASAKI 	printf(END_COMMENT);
2495e1e9a4bfSMitsuru IWASAKI }
2496e1e9a4bfSMitsuru IWASAKI 
2497945137d9SNate Lawson static void
2498986dffafSJohn Baldwin acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp)
2499e1e9a4bfSMitsuru IWASAKI {
2500773b6454SNate Lawson 	printf(BEGIN_COMMENT);
2501773b6454SNate Lawson 	acpi_print_sdt(dsdp);
2502773b6454SNate Lawson 	printf(END_COMMENT);
2503e1e9a4bfSMitsuru IWASAKI }
2504e1e9a4bfSMitsuru IWASAKI 
2505e1e9a4bfSMitsuru IWASAKI int
2506e1e9a4bfSMitsuru IWASAKI acpi_checksum(void *p, size_t length)
2507e1e9a4bfSMitsuru IWASAKI {
2508986dffafSJohn Baldwin 	uint8_t *bp;
2509986dffafSJohn Baldwin 	uint8_t sum;
2510e1e9a4bfSMitsuru IWASAKI 
2511e1e9a4bfSMitsuru IWASAKI 	bp = p;
2512e1e9a4bfSMitsuru IWASAKI 	sum = 0;
2513e1e9a4bfSMitsuru IWASAKI 	while (length--)
2514e1e9a4bfSMitsuru IWASAKI 		sum += *bp++;
2515e1e9a4bfSMitsuru IWASAKI 
2516e1e9a4bfSMitsuru IWASAKI 	return (sum);
2517e1e9a4bfSMitsuru IWASAKI }
2518e1e9a4bfSMitsuru IWASAKI 
2519986dffafSJohn Baldwin static ACPI_TABLE_HEADER *
2520e1e9a4bfSMitsuru IWASAKI acpi_map_sdt(vm_offset_t pa)
2521e1e9a4bfSMitsuru IWASAKI {
2522986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *sp;
2523e1e9a4bfSMitsuru IWASAKI 
2524986dffafSJohn Baldwin 	sp = acpi_map_physical(pa, sizeof(ACPI_TABLE_HEADER));
2525986dffafSJohn Baldwin 	sp = acpi_map_physical(pa, sp->Length);
2526e1e9a4bfSMitsuru IWASAKI 	return (sp);
2527e1e9a4bfSMitsuru IWASAKI }
2528e1e9a4bfSMitsuru IWASAKI 
2529945137d9SNate Lawson static void
2530986dffafSJohn Baldwin acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp)
2531e1e9a4bfSMitsuru IWASAKI {
2532c62f1cccSMitsuru IWASAKI 	printf(BEGIN_COMMENT);
2533a74172abSNate Lawson 	printf("  RSD PTR: OEM=");
2534986dffafSJohn Baldwin 	acpi_print_string(rp->OemId, ACPI_OEM_ID_SIZE);
2535986dffafSJohn Baldwin 	printf(", ACPI_Rev=%s (%d)\n", rp->Revision < 2 ? "1.0x" : "2.0x",
2536986dffafSJohn Baldwin 	       rp->Revision);
2537986dffafSJohn Baldwin 	if (rp->Revision < 2) {
2538986dffafSJohn Baldwin 		printf("\tRSDT=0x%08x, cksum=%u\n", rp->RsdtPhysicalAddress,
2539986dffafSJohn Baldwin 		    rp->Checksum);
2540a74172abSNate Lawson 	} else {
25417d369c6eSJung-uk Kim 		printf("\tXSDT=0x%016jx, length=%u, cksum=%u\n",
25427d369c6eSJung-uk Kim 		    (uintmax_t)rp->XsdtPhysicalAddress, rp->Length,
2543986dffafSJohn Baldwin 		    rp->ExtendedChecksum);
2544a74172abSNate Lawson 	}
2545c62f1cccSMitsuru IWASAKI 	printf(END_COMMENT);
2546e1e9a4bfSMitsuru IWASAKI }
2547e1e9a4bfSMitsuru IWASAKI 
2548945137d9SNate Lawson static void
2549986dffafSJohn Baldwin acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp)
2550e1e9a4bfSMitsuru IWASAKI {
2551986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *sdp;
2552986dffafSJohn Baldwin 	ACPI_TABLE_RSDT *rsdt;
2553986dffafSJohn Baldwin 	ACPI_TABLE_XSDT *xsdt;
2554a74172abSNate Lawson 	vm_offset_t addr;
2555a74172abSNate Lawson 	int entries, i;
2556e1e9a4bfSMitsuru IWASAKI 
2557e1e9a4bfSMitsuru IWASAKI 	acpi_print_rsdt(rsdp);
2558986dffafSJohn Baldwin 	rsdt = (ACPI_TABLE_RSDT *)rsdp;
2559986dffafSJohn Baldwin 	xsdt = (ACPI_TABLE_XSDT *)rsdp;
2560986dffafSJohn Baldwin 	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
2561e1e9a4bfSMitsuru IWASAKI 	for (i = 0; i < entries; i++) {
2562fe1d0c2dSJung-uk Kim 		if (addr_size == 4)
2563986dffafSJohn Baldwin 			addr = le32toh(rsdt->TableOffsetEntry[i]);
2564fe1d0c2dSJung-uk Kim 		else
2565986dffafSJohn Baldwin 			addr = le64toh(xsdt->TableOffsetEntry[i]);
2566fe1d0c2dSJung-uk Kim 		if (addr == 0)
2567fe1d0c2dSJung-uk Kim 			continue;
2568986dffafSJohn Baldwin 		sdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
2569986dffafSJohn Baldwin 		if (acpi_checksum(sdp, sdp->Length)) {
25705cf6d493SNate Lawson 			warnx("RSDT entry %d (sig %.4s) is corrupt", i,
2571986dffafSJohn Baldwin 			    sdp->Signature);
25725cf6d493SNate Lawson 			continue;
25735cf6d493SNate Lawson 		}
2574ebc22d04SAlexander Motin 		if (!memcmp(sdp->Signature, ACPI_SIG_BERT, 4))
2575ebc22d04SAlexander Motin 			acpi_handle_bert(sdp);
2576ebc22d04SAlexander Motin 		else if (!memcmp(sdp->Signature, ACPI_SIG_EINJ, 4))
2577ebc22d04SAlexander Motin 			acpi_handle_einj(sdp);
2578ebc22d04SAlexander Motin 		else if (!memcmp(sdp->Signature, ACPI_SIG_ERST, 4))
2579ebc22d04SAlexander Motin 			acpi_handle_erst(sdp);
2580ebc22d04SAlexander Motin 		else if (!memcmp(sdp->Signature, ACPI_SIG_FADT, 4))
25812177d4e6SNate Lawson 			acpi_handle_fadt(sdp);
2582986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_MADT, 4))
2583986dffafSJohn Baldwin 			acpi_handle_madt(sdp);
2584ebc22d04SAlexander Motin 		else if (!memcmp(sdp->Signature, ACPI_SIG_HEST, 4))
2585ebc22d04SAlexander Motin 			acpi_handle_hest(sdp);
2586986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_HPET, 4))
258779d7565cSPeter Wemm 			acpi_handle_hpet(sdp);
2588986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_ECDT, 4))
258955d7ff9eSNate Lawson 			acpi_handle_ecdt(sdp);
2590986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_MCFG, 4))
2591a47e681bSScott Long 			acpi_handle_mcfg(sdp);
259233866658SJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_SLIT, 4))
259333866658SJohn Baldwin 			acpi_handle_slit(sdp);
2594986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_SRAT, 4))
2595a0333ad1SJohn Baldwin 			acpi_handle_srat(sdp);
2596c031c93bSTakanori Watanabe 		else if (!memcmp(sdp->Signature, ACPI_SIG_TCPA, 4))
2597c031c93bSTakanori Watanabe 			acpi_handle_tcpa(sdp);
2598ec650989SNeel Natu 		else if (!memcmp(sdp->Signature, ACPI_SIG_DMAR, 4))
2599ec650989SNeel Natu 			acpi_handle_dmar(sdp);
26006d789b61SKonstantin Belousov 		else if (!memcmp(sdp->Signature, ACPI_SIG_IVRS, 4))
26016d789b61SKonstantin Belousov 			acpi_handle_ivrs(sdp);
2602340c0022SEd Maste 		else if (!memcmp(sdp->Signature, ACPI_SIG_NFIT, 4))
2603340c0022SEd Maste 			acpi_handle_nfit(sdp);
2604ed26c389SScott Long 		else if (!memcmp(sdp->Signature, ACPI_SIG_WDDT, 4))
2605ed26c389SScott Long 			acpi_handle_wddt(sdp);
26065857fba5SBen Widawsky 		else if (!memcmp(sdp->Signature, ACPI_SIG_LPIT, 4))
26075857fba5SBen Widawsky 			acpi_handle_lpit(sdp);
2608877fc2e3STakanori Watanabe 		else if (!memcmp(sdp->Signature, ACPI_SIG_TPM2, 4))
2609877fc2e3STakanori Watanabe 			acpi_handle_tpm2(sdp);
2610*5d57fad8SWarner Losh 		else if (!memcmp(sdp->Signature, ACPI_SIG_SPCR, 4))
2611*5d57fad8SWarner Losh 			acpi_handle_spcr(sdp);
2612773b6454SNate Lawson 		else {
2613773b6454SNate Lawson 			printf(BEGIN_COMMENT);
2614773b6454SNate Lawson 			acpi_print_sdt(sdp);
2615773b6454SNate Lawson 			printf(END_COMMENT);
2616773b6454SNate Lawson 		}
2617e1e9a4bfSMitsuru IWASAKI 	}
2618e1e9a4bfSMitsuru IWASAKI }
2619c62f1cccSMitsuru IWASAKI 
2620986dffafSJohn Baldwin ACPI_TABLE_HEADER *
2621476daaecSDag-Erling Smørgrav sdt_load_devmem(void)
2622945137d9SNate Lawson {
2623986dffafSJohn Baldwin 	ACPI_TABLE_RSDP *rp;
2624986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *rsdp;
2625945137d9SNate Lawson 
2626945137d9SNate Lawson 	rp = acpi_find_rsd_ptr();
2627945137d9SNate Lawson 	if (!rp)
2628945137d9SNate Lawson 		errx(1, "Can't find ACPI information");
2629945137d9SNate Lawson 
2630945137d9SNate Lawson 	if (tflag)
2631945137d9SNate Lawson 		acpi_print_rsd_ptr(rp);
2632986dffafSJohn Baldwin 	if (rp->Revision < 2) {
2633986dffafSJohn Baldwin 		rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->RsdtPhysicalAddress);
2634986dffafSJohn Baldwin 		if (memcmp(rsdp->Signature, "RSDT", 4) != 0 ||
2635986dffafSJohn Baldwin 		    acpi_checksum(rsdp, rsdp->Length) != 0)
2636945137d9SNate Lawson 			errx(1, "RSDT is corrupted");
2637a74172abSNate Lawson 		addr_size = sizeof(uint32_t);
2638a74172abSNate Lawson 	} else {
2639986dffafSJohn Baldwin 		rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->XsdtPhysicalAddress);
2640986dffafSJohn Baldwin 		if (memcmp(rsdp->Signature, "XSDT", 4) != 0 ||
2641986dffafSJohn Baldwin 		    acpi_checksum(rsdp, rsdp->Length) != 0)
2642a74172abSNate Lawson 			errx(1, "XSDT is corrupted");
2643a74172abSNate Lawson 		addr_size = sizeof(uint64_t);
2644a74172abSNate Lawson 	}
2645945137d9SNate Lawson 	return (rsdp);
2646945137d9SNate Lawson }
2647c62f1cccSMitsuru IWASAKI 
264862c7bde1SNate Lawson /* Write the DSDT to a file, concatenating any SSDTs (if present). */
2649bfa3f012SMarcel Moolenaar static int
2650986dffafSJohn Baldwin write_dsdt(int fd, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdt)
2651bfa3f012SMarcel Moolenaar {
2652986dffafSJohn Baldwin 	ACPI_TABLE_HEADER sdt;
2653986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *ssdt;
2654bfa3f012SMarcel Moolenaar 	uint8_t sum;
2655bfa3f012SMarcel Moolenaar 
265662c7bde1SNate Lawson 	/* Create a new checksum to account for the DSDT and any SSDTs. */
2657bfa3f012SMarcel Moolenaar 	sdt = *dsdt;
2658bfa3f012SMarcel Moolenaar 	if (rsdt != NULL) {
2659986dffafSJohn Baldwin 		sdt.Checksum = 0;
2660986dffafSJohn Baldwin 		sum = acpi_checksum(dsdt + 1, dsdt->Length -
2661986dffafSJohn Baldwin 		    sizeof(ACPI_TABLE_HEADER));
2662986dffafSJohn Baldwin 		ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, NULL);
2663f7675a56SNate Lawson 		while (ssdt != NULL) {
2664986dffafSJohn Baldwin 			sdt.Length += ssdt->Length - sizeof(ACPI_TABLE_HEADER);
2665986dffafSJohn Baldwin 			sum += acpi_checksum(ssdt + 1,
2666986dffafSJohn Baldwin 			    ssdt->Length - sizeof(ACPI_TABLE_HEADER));
2667986dffafSJohn Baldwin 			ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, ssdt);
2668bfa3f012SMarcel Moolenaar 		}
2669986dffafSJohn Baldwin 		sum += acpi_checksum(&sdt, sizeof(ACPI_TABLE_HEADER));
2670986dffafSJohn Baldwin 		sdt.Checksum -= sum;
2671bfa3f012SMarcel Moolenaar 	}
267262c7bde1SNate Lawson 
267362c7bde1SNate Lawson 	/* Write out the DSDT header and body. */
2674986dffafSJohn Baldwin 	write(fd, &sdt, sizeof(ACPI_TABLE_HEADER));
2675986dffafSJohn Baldwin 	write(fd, dsdt + 1, dsdt->Length - sizeof(ACPI_TABLE_HEADER));
267662c7bde1SNate Lawson 
2677b64e1b67SNate Lawson 	/* Write out any SSDTs (if present.) */
2678f7675a56SNate Lawson 	if (rsdt != NULL) {
2679bfa3f012SMarcel Moolenaar 		ssdt = sdt_from_rsdt(rsdt, "SSDT", NULL);
2680bfa3f012SMarcel Moolenaar 		while (ssdt != NULL) {
2681986dffafSJohn Baldwin 			write(fd, ssdt + 1, ssdt->Length -
2682986dffafSJohn Baldwin 			    sizeof(ACPI_TABLE_HEADER));
2683bfa3f012SMarcel Moolenaar 			ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt);
2684bfa3f012SMarcel Moolenaar 		}
2685bfa3f012SMarcel Moolenaar 	}
2686bfa3f012SMarcel Moolenaar 	return (0);
2687bfa3f012SMarcel Moolenaar }
2688bfa3f012SMarcel Moolenaar 
2689c62f1cccSMitsuru IWASAKI void
2690986dffafSJohn Baldwin dsdt_save_file(char *outfile, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
2691c62f1cccSMitsuru IWASAKI {
2692945137d9SNate Lawson 	int	fd;
2693945137d9SNate Lawson 	mode_t	mode;
2694945137d9SNate Lawson 
2695945137d9SNate Lawson 	assert(outfile != NULL);
2696945137d9SNate Lawson 	mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
2697945137d9SNate Lawson 	fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, mode);
2698945137d9SNate Lawson 	if (fd == -1) {
2699945137d9SNate Lawson 		perror("dsdt_save_file");
2700945137d9SNate Lawson 		return;
2701945137d9SNate Lawson 	}
2702bfa3f012SMarcel Moolenaar 	write_dsdt(fd, rsdt, dsdp);
2703945137d9SNate Lawson 	close(fd);
2704c62f1cccSMitsuru IWASAKI }
2705c62f1cccSMitsuru IWASAKI 
2706945137d9SNate Lawson void
2707986dffafSJohn Baldwin aml_disassemble(ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
2708c62f1cccSMitsuru IWASAKI {
27097e2cc014SDon Lewis 	char buf[PATH_MAX], tmpstr[PATH_MAX], wrkdir[PATH_MAX];
27107e2cc014SDon Lewis 	const char *iname = "/acpdump.din";
27117e2cc014SDon Lewis 	const char *oname = "/acpdump.dsl";
271299065116SJung-uk Kim 	const char *tmpdir;
2713945137d9SNate Lawson 	FILE *fp;
271499065116SJung-uk Kim 	size_t len;
27157e2cc014SDon Lewis 	int fd, status;
27167e2cc014SDon Lewis 	pid_t pid;
2717945137d9SNate Lawson 
271899065116SJung-uk Kim 	tmpdir = getenv("TMPDIR");
271999065116SJung-uk Kim 	if (tmpdir == NULL)
272099065116SJung-uk Kim 		tmpdir = _PATH_TMP;
27217e2cc014SDon Lewis 	if (realpath(tmpdir, buf) == NULL) {
2722d6a6e590SJung-uk Kim 		perror("realpath tmp dir");
272399065116SJung-uk Kim 		return;
272499065116SJung-uk Kim 	}
27257e2cc014SDon Lewis 	len = sizeof(wrkdir) - strlen(iname);
27267e2cc014SDon Lewis 	if ((size_t)snprintf(wrkdir, len, "%s/acpidump.XXXXXX", buf) > len-1 ) {
27277e2cc014SDon Lewis 		fprintf(stderr, "$TMPDIR too long\n");
27287e2cc014SDon Lewis 		return;
27297e2cc014SDon Lewis 	}
27307e2cc014SDon Lewis 	if  (mkdtemp(wrkdir) == NULL) {
27317e2cc014SDon Lewis 		perror("mkdtemp tmp working dir");
27327e2cc014SDon Lewis 		return;
27337e2cc014SDon Lewis 	}
273430bebccaSMaxim Konovalov 	len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, iname);
273530bebccaSMaxim Konovalov 	assert(len <= sizeof(tmpstr) - 1);
27367e2cc014SDon Lewis 	fd = open(tmpstr, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
2737945137d9SNate Lawson 	if (fd < 0) {
2738945137d9SNate Lawson 		perror("iasl tmp file");
2739945137d9SNate Lawson 		return;
2740c62f1cccSMitsuru IWASAKI 	}
2741bfa3f012SMarcel Moolenaar 	write_dsdt(fd, rsdt, dsdp);
2742945137d9SNate Lawson 	close(fd);
2743945137d9SNate Lawson 
2744945137d9SNate Lawson 	/* Run iasl -d on the temp file */
27457e2cc014SDon Lewis 	if ((pid = fork()) == 0) {
2746945137d9SNate Lawson 		close(STDOUT_FILENO);
2747945137d9SNate Lawson 		if (vflag == 0)
2748945137d9SNate Lawson 			close(STDERR_FILENO);
274999065116SJung-uk Kim 		execl("/usr/sbin/iasl", "iasl", "-d", tmpstr, NULL);
2750945137d9SNate Lawson 		err(1, "exec");
2751c62f1cccSMitsuru IWASAKI 	}
27527e2cc014SDon Lewis 	if (pid > 0)
27537e2cc014SDon Lewis 		wait(&status);
27547e2cc014SDon Lewis 	if (unlink(tmpstr) < 0) {
27557e2cc014SDon Lewis 		perror("unlink");
27567e2cc014SDon Lewis 		goto out;
27577e2cc014SDon Lewis 	}
27587e2cc014SDon Lewis 	if (pid < 0) {
27597e2cc014SDon Lewis 		perror("fork");
27607e2cc014SDon Lewis 		goto out;
27617e2cc014SDon Lewis 	}
27627e2cc014SDon Lewis 	if (status != 0) {
2763861f5b95SSHENG-YI HONG 		fprintf(stderr, "iasl exit status = %d\n", status);
27647e2cc014SDon Lewis 	}
2765945137d9SNate Lawson 
2766945137d9SNate Lawson 	/* Dump iasl's output to stdout */
276730bebccaSMaxim Konovalov 	len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, oname);
276830bebccaSMaxim Konovalov 	assert(len <= sizeof(tmpstr) - 1);
276999065116SJung-uk Kim 	fp = fopen(tmpstr, "r");
27707e2cc014SDon Lewis 	if (unlink(tmpstr) < 0) {
27717e2cc014SDon Lewis 		perror("unlink");
27727e2cc014SDon Lewis 		goto out;
27737e2cc014SDon Lewis 	}
2774945137d9SNate Lawson 	if (fp == NULL) {
2775945137d9SNate Lawson 		perror("iasl tmp file (read)");
27767e2cc014SDon Lewis 		goto out;
2777945137d9SNate Lawson 	}
2778945137d9SNate Lawson 	while ((len = fread(buf, 1, sizeof(buf), fp)) > 0)
2779945137d9SNate Lawson 		fwrite(buf, 1, len, stdout);
2780945137d9SNate Lawson 	fclose(fp);
27817e2cc014SDon Lewis 
27827e2cc014SDon Lewis     out:
27837e2cc014SDon Lewis 	if (rmdir(wrkdir) < 0)
27847e2cc014SDon Lewis 		perror("rmdir");
2785c62f1cccSMitsuru IWASAKI }
2786c62f1cccSMitsuru IWASAKI 
2787945137d9SNate Lawson void
2788f5a04b16STakanori Watanabe aml_disassemble_separate(ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
2789f5a04b16STakanori Watanabe {
2790f5a04b16STakanori Watanabe 	ACPI_TABLE_HEADER *ssdt = NULL;
2791f5a04b16STakanori Watanabe 
2792f5a04b16STakanori Watanabe 	aml_disassemble(NULL, dsdp);
2793f5a04b16STakanori Watanabe 	if (rsdt != NULL) {
2794f5a04b16STakanori Watanabe 		for (;;) {
2795f5a04b16STakanori Watanabe 			ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt);
2796f5a04b16STakanori Watanabe 			if (ssdt == NULL)
2797f5a04b16STakanori Watanabe 				break;
2798f5a04b16STakanori Watanabe 			aml_disassemble(NULL, ssdt);
2799f5a04b16STakanori Watanabe 		}
2800f5a04b16STakanori Watanabe 	}
2801f5a04b16STakanori Watanabe }
2802f5a04b16STakanori Watanabe 
2803f5a04b16STakanori Watanabe void
2804986dffafSJohn Baldwin sdt_print_all(ACPI_TABLE_HEADER *rsdp)
2805c62f1cccSMitsuru IWASAKI {
2806945137d9SNate Lawson 	acpi_handle_rsdt(rsdp);
2807c62f1cccSMitsuru IWASAKI }
2808c62f1cccSMitsuru IWASAKI 
2809bfa3f012SMarcel Moolenaar /* Fetch a table matching the given signature via the RSDT. */
2810986dffafSJohn Baldwin ACPI_TABLE_HEADER *
2811986dffafSJohn Baldwin sdt_from_rsdt(ACPI_TABLE_HEADER *rsdp, const char *sig, ACPI_TABLE_HEADER *last)
2812c62f1cccSMitsuru IWASAKI {
2813986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *sdt;
2814986dffafSJohn Baldwin 	ACPI_TABLE_RSDT *rsdt;
2815986dffafSJohn Baldwin 	ACPI_TABLE_XSDT *xsdt;
2816a74172abSNate Lawson 	vm_offset_t addr;
2817a74172abSNate Lawson 	int entries, i;
2818945137d9SNate Lawson 
2819986dffafSJohn Baldwin 	rsdt = (ACPI_TABLE_RSDT *)rsdp;
2820986dffafSJohn Baldwin 	xsdt = (ACPI_TABLE_XSDT *)rsdp;
2821986dffafSJohn Baldwin 	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
2822945137d9SNate Lawson 	for (i = 0; i < entries; i++) {
2823fe1d0c2dSJung-uk Kim 		if (addr_size == 4)
2824986dffafSJohn Baldwin 			addr = le32toh(rsdt->TableOffsetEntry[i]);
2825fe1d0c2dSJung-uk Kim 		else
2826986dffafSJohn Baldwin 			addr = le64toh(xsdt->TableOffsetEntry[i]);
2827fe1d0c2dSJung-uk Kim 		if (addr == 0)
2828fe1d0c2dSJung-uk Kim 			continue;
2829986dffafSJohn Baldwin 		sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
2830bfa3f012SMarcel Moolenaar 		if (last != NULL) {
2831bfa3f012SMarcel Moolenaar 			if (sdt == last)
2832bfa3f012SMarcel Moolenaar 				last = NULL;
2833bfa3f012SMarcel Moolenaar 			continue;
2834bfa3f012SMarcel Moolenaar 		}
2835986dffafSJohn Baldwin 		if (memcmp(sdt->Signature, sig, strlen(sig)))
2836a74172abSNate Lawson 			continue;
2837986dffafSJohn Baldwin 		if (acpi_checksum(sdt, sdt->Length))
2838945137d9SNate Lawson 			errx(1, "RSDT entry %d is corrupt", i);
2839945137d9SNate Lawson 		return (sdt);
2840c62f1cccSMitsuru IWASAKI 	}
2841c62f1cccSMitsuru IWASAKI 
2842945137d9SNate Lawson 	return (NULL);
2843c62f1cccSMitsuru IWASAKI }
2844c62f1cccSMitsuru IWASAKI 
2845986dffafSJohn Baldwin ACPI_TABLE_HEADER *
2846986dffafSJohn Baldwin dsdt_from_fadt(ACPI_TABLE_FADT *fadt)
2847c62f1cccSMitsuru IWASAKI {
2848986dffafSJohn Baldwin 	ACPI_TABLE_HEADER	*sdt;
2849c62f1cccSMitsuru IWASAKI 
2850986dffafSJohn Baldwin 	/* Use the DSDT address if it is version 1, otherwise use XDSDT. */
2851c2962974SNate Lawson 	if (acpi_get_fadt_revision(fadt) == 1)
2852986dffafSJohn Baldwin 		sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt);
28532e71eb12SNate Lawson 	else
2854986dffafSJohn Baldwin 		sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt);
2855986dffafSJohn Baldwin 	if (acpi_checksum(sdt, sdt->Length))
2856945137d9SNate Lawson 		errx(1, "DSDT is corrupt\n");
2857945137d9SNate Lawson 	return (sdt);
2858c62f1cccSMitsuru IWASAKI }
2859