xref: /freebsd/usr.sbin/acpi/acpidump/acpi.c (revision 6d789b6126afe1c23b65eef2c5cf4c6bd258c26f)
1e1e9a4bfSMitsuru IWASAKI /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
31de7b4b8SPedro F. Giffuni  *
4e1e9a4bfSMitsuru IWASAKI  * Copyright (c) 1998 Doug Rabson
5e1e9a4bfSMitsuru IWASAKI  * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
6ebc22d04SAlexander Motin  * Copyright (c) 2020 Alexander Motin <mav@FreeBSD.org>
7e1e9a4bfSMitsuru IWASAKI  * All rights reserved.
8e1e9a4bfSMitsuru IWASAKI  *
9e1e9a4bfSMitsuru IWASAKI  * Redistribution and use in source and binary forms, with or without
10e1e9a4bfSMitsuru IWASAKI  * modification, are permitted provided that the following conditions
11e1e9a4bfSMitsuru IWASAKI  * are met:
12e1e9a4bfSMitsuru IWASAKI  * 1. Redistributions of source code must retain the above copyright
13e1e9a4bfSMitsuru IWASAKI  *    notice, this list of conditions and the following disclaimer.
14e1e9a4bfSMitsuru IWASAKI  * 2. Redistributions in binary form must reproduce the above copyright
15e1e9a4bfSMitsuru IWASAKI  *    notice, this list of conditions and the following disclaimer in the
16e1e9a4bfSMitsuru IWASAKI  *    documentation and/or other materials provided with the distribution.
17e1e9a4bfSMitsuru IWASAKI  *
18e1e9a4bfSMitsuru IWASAKI  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19e1e9a4bfSMitsuru IWASAKI  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20e1e9a4bfSMitsuru IWASAKI  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21e1e9a4bfSMitsuru IWASAKI  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22e1e9a4bfSMitsuru IWASAKI  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23e1e9a4bfSMitsuru IWASAKI  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24e1e9a4bfSMitsuru IWASAKI  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25e1e9a4bfSMitsuru IWASAKI  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26e1e9a4bfSMitsuru IWASAKI  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27e1e9a4bfSMitsuru IWASAKI  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28e1e9a4bfSMitsuru IWASAKI  * SUCH DAMAGE.
29e1e9a4bfSMitsuru IWASAKI  */
30e1e9a4bfSMitsuru IWASAKI 
31e1e9a4bfSMitsuru IWASAKI #include <sys/param.h>
32a74172abSNate Lawson #include <sys/endian.h>
33e1e9a4bfSMitsuru IWASAKI #include <sys/stat.h>
34945137d9SNate Lawson #include <sys/wait.h>
35e1e9a4bfSMitsuru IWASAKI #include <assert.h>
36e1e9a4bfSMitsuru IWASAKI #include <err.h>
37e1e9a4bfSMitsuru IWASAKI #include <fcntl.h>
3899065116SJung-uk Kim #include <paths.h>
39*6d789b61SKonstantin Belousov #include <stdbool.h>
40e1e9a4bfSMitsuru IWASAKI #include <stdio.h>
41a0333ad1SJohn Baldwin #include <stdint.h>
4299065116SJung-uk Kim #include <stdlib.h>
43945137d9SNate Lawson #include <string.h>
44e1e9a4bfSMitsuru IWASAKI #include <unistd.h>
45340c0022SEd Maste #include <uuid.h>
46e1e9a4bfSMitsuru IWASAKI 
47e1e9a4bfSMitsuru IWASAKI #include "acpidump.h"
48e1e9a4bfSMitsuru IWASAKI 
49c62f1cccSMitsuru IWASAKI #define BEGIN_COMMENT	"/*\n"
50c62f1cccSMitsuru IWASAKI #define END_COMMENT	" */\n"
51c62f1cccSMitsuru IWASAKI 
52945137d9SNate Lawson static void	acpi_print_string(char *s, size_t length);
53986dffafSJohn Baldwin static void	acpi_print_gas(ACPI_GENERIC_ADDRESS *gas);
54986dffafSJohn Baldwin static int	acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt);
55986dffafSJohn Baldwin static void	acpi_handle_fadt(ACPI_TABLE_HEADER *fadt);
56945137d9SNate Lawson static void	acpi_print_cpu(u_char cpu_id);
57986dffafSJohn Baldwin static void	acpi_print_cpu_uid(uint32_t uid, char *uid_string);
58986dffafSJohn Baldwin static void	acpi_print_local_apic(uint32_t apic_id, uint32_t flags);
59986dffafSJohn Baldwin static void	acpi_print_io_apic(uint32_t apic_id, uint32_t int_base,
60986dffafSJohn Baldwin 		    uint64_t apic_addr);
61986dffafSJohn Baldwin static void	acpi_print_mps_flags(uint16_t flags);
62986dffafSJohn Baldwin static void	acpi_print_intr(uint32_t intr, uint16_t mps_flags);
63986dffafSJohn Baldwin static void	acpi_print_local_nmi(u_int lint, uint16_t mps_flags);
64986dffafSJohn Baldwin static void	acpi_print_madt(ACPI_SUBTABLE_HEADER *mp);
65986dffafSJohn Baldwin static void	acpi_handle_madt(ACPI_TABLE_HEADER *sdp);
66986dffafSJohn Baldwin static void	acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp);
67986dffafSJohn Baldwin static void	acpi_handle_hpet(ACPI_TABLE_HEADER *sdp);
68986dffafSJohn Baldwin static void	acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp);
6933866658SJohn Baldwin static void	acpi_handle_slit(ACPI_TABLE_HEADER *sdp);
70ed26c389SScott Long static void	acpi_handle_wddt(ACPI_TABLE_HEADER *sdp);
715857fba5SBen Widawsky static void	acpi_handle_lpit(ACPI_TABLE_HEADER *sdp);
72a0333ad1SJohn Baldwin static void	acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain,
73a0333ad1SJohn Baldwin 		    uint32_t flags);
74986dffafSJohn Baldwin static void	acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp);
75986dffafSJohn Baldwin static void	acpi_print_srat(ACPI_SUBTABLE_HEADER *srat);
76986dffafSJohn Baldwin static void	acpi_handle_srat(ACPI_TABLE_HEADER *sdp);
77c031c93bSTakanori Watanabe static void	acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp);
78340c0022SEd Maste static void	acpi_print_nfit(ACPI_NFIT_HEADER *nfit);
79340c0022SEd Maste static void	acpi_handle_nfit(ACPI_TABLE_HEADER *sdp);
80986dffafSJohn Baldwin static void	acpi_print_sdt(ACPI_TABLE_HEADER *sdp);
81986dffafSJohn Baldwin static void	acpi_print_fadt(ACPI_TABLE_HEADER *sdp);
82986dffafSJohn Baldwin static void	acpi_print_facs(ACPI_TABLE_FACS *facs);
83986dffafSJohn Baldwin static void	acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp);
84986dffafSJohn Baldwin static ACPI_TABLE_HEADER *acpi_map_sdt(vm_offset_t pa);
85986dffafSJohn Baldwin static void	acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp);
86986dffafSJohn Baldwin static void	acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp);
87986dffafSJohn Baldwin static void	acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
88986dffafSJohn Baldwin 		    void (*action)(ACPI_SUBTABLE_HEADER *));
89340c0022SEd Maste static void	acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first,
90340c0022SEd Maste 		    void (*action)(ACPI_NFIT_HEADER *));
91c62f1cccSMitsuru IWASAKI 
92773b6454SNate Lawson /* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up. */
93a74172abSNate Lawson static int addr_size;
94a74172abSNate Lawson 
95c031c93bSTakanori Watanabe /* Strings used in the TCPA table */
96c031c93bSTakanori Watanabe static const char *tcpa_event_type_strings[] = {
97c031c93bSTakanori Watanabe 	"PREBOOT Certificate",
98c031c93bSTakanori Watanabe 	"POST Code",
99c031c93bSTakanori Watanabe 	"Unused",
100c031c93bSTakanori Watanabe 	"No Action",
101c031c93bSTakanori Watanabe 	"Separator",
102c031c93bSTakanori Watanabe 	"Action",
103c031c93bSTakanori Watanabe 	"Event Tag",
104c031c93bSTakanori Watanabe 	"S-CRTM Contents",
105c031c93bSTakanori Watanabe 	"S-CRTM Version",
106c031c93bSTakanori Watanabe 	"CPU Microcode",
107c031c93bSTakanori Watanabe 	"Platform Config Flags",
108c031c93bSTakanori Watanabe 	"Table of Devices",
109c031c93bSTakanori Watanabe 	"Compact Hash",
110c031c93bSTakanori Watanabe 	"IPL",
111c031c93bSTakanori Watanabe 	"IPL Partition Data",
112c031c93bSTakanori Watanabe 	"Non-Host Code",
113c031c93bSTakanori Watanabe 	"Non-Host Config",
114c031c93bSTakanori Watanabe 	"Non-Host Info"
115c031c93bSTakanori Watanabe };
116c031c93bSTakanori Watanabe 
117c031c93bSTakanori Watanabe static const char *TCPA_pcclient_strings[] = {
118c031c93bSTakanori Watanabe 	"<undefined>",
119c031c93bSTakanori Watanabe 	"SMBIOS",
120c031c93bSTakanori Watanabe 	"BIS Certificate",
121c031c93bSTakanori Watanabe 	"POST BIOS ROM Strings",
122c031c93bSTakanori Watanabe 	"ESCD",
123c031c93bSTakanori Watanabe 	"CMOS",
124c031c93bSTakanori Watanabe 	"NVRAM",
125c031c93bSTakanori Watanabe 	"Option ROM Execute",
126c031c93bSTakanori Watanabe 	"Option ROM Configurateion",
127c031c93bSTakanori Watanabe 	"<undefined>",
128c031c93bSTakanori Watanabe 	"Option ROM Microcode Update ",
129c031c93bSTakanori Watanabe 	"S-CRTM Version String",
130c031c93bSTakanori Watanabe 	"S-CRTM Contents",
131c031c93bSTakanori Watanabe 	"POST Contents",
132c031c93bSTakanori Watanabe 	"Table of Devices",
133c031c93bSTakanori Watanabe };
134c031c93bSTakanori Watanabe 
135ec650989SNeel Natu #define	PRINTFLAG_END()		printflag_end()
136ec650989SNeel Natu 
137ec650989SNeel Natu static char pf_sep = '{';
138ec650989SNeel Natu 
139ec650989SNeel Natu static void
140ec650989SNeel Natu printflag_end(void)
141ec650989SNeel Natu {
142ec650989SNeel Natu 
143ec650989SNeel Natu 	if (pf_sep != '{') {
144ec650989SNeel Natu 		printf("}");
145ec650989SNeel Natu 		pf_sep = '{';
146ec650989SNeel Natu 	}
147ec650989SNeel Natu 	printf("\n");
148ec650989SNeel Natu }
149ec650989SNeel Natu 
150ec650989SNeel Natu static void
151ec650989SNeel Natu printflag(uint64_t var, uint64_t mask, const char *name)
152ec650989SNeel Natu {
153ec650989SNeel Natu 
154ec650989SNeel Natu 	if (var & mask) {
155ec650989SNeel Natu 		printf("%c%s", pf_sep, name);
156ec650989SNeel Natu 		pf_sep = ',';
157ec650989SNeel Natu 	}
158ec650989SNeel Natu }
159ec650989SNeel Natu 
160e1e9a4bfSMitsuru IWASAKI static void
161969a4b8bSKonstantin Belousov printfield(uint64_t var, int lbit, int hbit, const char *name)
162969a4b8bSKonstantin Belousov {
163969a4b8bSKonstantin Belousov 	uint64_t mask;
164969a4b8bSKonstantin Belousov 	int len;
165969a4b8bSKonstantin Belousov 
166969a4b8bSKonstantin Belousov 	len = hbit - lbit + 1;
167969a4b8bSKonstantin Belousov 	mask = ((1 << (len + 1)) - 1) << lbit;
168969a4b8bSKonstantin Belousov 	printf("%c%s=%#jx", pf_sep, name, (uintmax_t)((var & mask) >> lbit));
169969a4b8bSKonstantin Belousov 	pf_sep = ',';
170969a4b8bSKonstantin Belousov }
171969a4b8bSKonstantin Belousov 
172969a4b8bSKonstantin Belousov static void
173e1e9a4bfSMitsuru IWASAKI acpi_print_string(char *s, size_t length)
174e1e9a4bfSMitsuru IWASAKI {
175e1e9a4bfSMitsuru IWASAKI 	int	c;
176e1e9a4bfSMitsuru IWASAKI 
177e1e9a4bfSMitsuru IWASAKI 	/* Trim trailing spaces and NULLs */
178e1e9a4bfSMitsuru IWASAKI 	while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0'))
179e1e9a4bfSMitsuru IWASAKI 		length--;
180e1e9a4bfSMitsuru IWASAKI 
181e1e9a4bfSMitsuru IWASAKI 	while (length--) {
182e1e9a4bfSMitsuru IWASAKI 		c = *s++;
183e1e9a4bfSMitsuru IWASAKI 		putchar(c);
184e1e9a4bfSMitsuru IWASAKI 	}
185e1e9a4bfSMitsuru IWASAKI }
186e1e9a4bfSMitsuru IWASAKI 
187e1e9a4bfSMitsuru IWASAKI static void
188986dffafSJohn Baldwin acpi_print_gas(ACPI_GENERIC_ADDRESS *gas)
1898e6a8737SNate Lawson {
190986dffafSJohn Baldwin 	switch(gas->SpaceId) {
1918e6a8737SNate Lawson 	case ACPI_GAS_MEMORY:
192ebc22d04SAlexander Motin 		printf("0x%016jx:%u[%u] (Memory)", (uintmax_t)gas->Address,
193ebc22d04SAlexander Motin 		    gas->BitOffset, gas->BitWidth);
1948e6a8737SNate Lawson 		break;
1958e6a8737SNate Lawson 	case ACPI_GAS_IO:
196ebc22d04SAlexander Motin 		printf("0x%02jx:%u[%u] (IO)", (uintmax_t)gas->Address,
197986dffafSJohn Baldwin 		    gas->BitOffset, gas->BitWidth);
1988e6a8737SNate Lawson 		break;
1998e6a8737SNate Lawson 	case ACPI_GAS_PCI:
200ebc22d04SAlexander Motin 		printf("%x:%x+0x%x:%u[%u] (PCI)", (uint16_t)(gas->Address >> 32),
201986dffafSJohn Baldwin 		       (uint16_t)((gas->Address >> 16) & 0xffff),
202ebc22d04SAlexander Motin 		       (uint16_t)gas->Address, gas->BitOffset, gas->BitWidth);
2038e6a8737SNate Lawson 		break;
2048e6a8737SNate Lawson 	/* XXX How to handle these below? */
2058e6a8737SNate Lawson 	case ACPI_GAS_EMBEDDED:
206986dffafSJohn Baldwin 		printf("0x%x:%u[%u] (EC)", (uint16_t)gas->Address,
207986dffafSJohn Baldwin 		       gas->BitOffset, gas->BitWidth);
2088e6a8737SNate Lawson 		break;
2098e6a8737SNate Lawson 	case ACPI_GAS_SMBUS:
210986dffafSJohn Baldwin 		printf("0x%x:%u[%u] (SMBus)", (uint16_t)gas->Address,
211986dffafSJohn Baldwin 		       gas->BitOffset, gas->BitWidth);
2128e6a8737SNate Lawson 		break;
213986dffafSJohn Baldwin 	case ACPI_GAS_CMOS:
214986dffafSJohn Baldwin 	case ACPI_GAS_PCIBAR:
215986dffafSJohn Baldwin 	case ACPI_GAS_DATATABLE:
2168e6a8737SNate Lawson 	case ACPI_GAS_FIXED:
2178e6a8737SNate Lawson 	default:
2187d369c6eSJung-uk Kim 		printf("0x%016jx (?)", (uintmax_t)gas->Address);
2198e6a8737SNate Lawson 		break;
2208e6a8737SNate Lawson 	}
2218e6a8737SNate Lawson }
2228e6a8737SNate Lawson 
223c2962974SNate Lawson /* The FADT revision indicates whether we use the DSDT or X_DSDT addresses. */
224c2962974SNate Lawson static int
2254262ad56SKonstantin Belousov acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt __unused)
226e1e9a4bfSMitsuru IWASAKI {
227c2962974SNate Lawson 	int fadt_revision;
228e1e9a4bfSMitsuru IWASAKI 
229c83f0f99SNate Lawson 	/* Set the FADT revision separately from the RSDP version. */
230c83f0f99SNate Lawson 	if (addr_size == 8) {
231c83f0f99SNate Lawson 		fadt_revision = 2;
2328e6a8737SNate Lawson 
23301593a0fSAndrew Turner #if defined(__i386__)
234773b6454SNate Lawson 		/*
235c83f0f99SNate Lawson 		 * A few systems (e.g., IBM T23) have an RSDP that claims
236c83f0f99SNate Lawson 		 * revision 2 but the 64 bit addresses are invalid.  If
237c83f0f99SNate Lawson 		 * revision 2 and the 32 bit address is non-zero but the
238c83f0f99SNate Lawson 		 * 32 and 64 bit versions don't match, prefer the 32 bit
239c83f0f99SNate Lawson 		 * version for all subsequent tables.
24001593a0fSAndrew Turner 		 *
24101593a0fSAndrew Turner 		 * The only known ACPI systems this affects are early
24201593a0fSAndrew Turner 		 * implementations on 32-bit x86. Because of this limit the
24301593a0fSAndrew Turner 		 * workaround to i386.
244773b6454SNate Lawson 		 */
245986dffafSJohn Baldwin 		if (fadt->Facs != 0 &&
246986dffafSJohn Baldwin 		    (fadt->XFacs & 0xffffffff) != fadt->Facs)
247c83f0f99SNate Lawson 			fadt_revision = 1;
24801593a0fSAndrew Turner #endif
249c2962974SNate Lawson 	} else
250c83f0f99SNate Lawson 		fadt_revision = 1;
251c2962974SNate Lawson 	return (fadt_revision);
252c83f0f99SNate Lawson }
253c2962974SNate Lawson 
254c2962974SNate Lawson static void
255986dffafSJohn Baldwin acpi_handle_fadt(ACPI_TABLE_HEADER *sdp)
256c2962974SNate Lawson {
257986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *dsdp;
258986dffafSJohn Baldwin 	ACPI_TABLE_FACS	*facs;
259986dffafSJohn Baldwin 	ACPI_TABLE_FADT *fadt;
260bc711181SAndrew Turner 	vm_offset_t	addr;
261c2962974SNate Lawson 	int		fadt_revision;
262c2962974SNate Lawson 
263986dffafSJohn Baldwin 	fadt = (ACPI_TABLE_FADT *)sdp;
2642177d4e6SNate Lawson 	acpi_print_fadt(sdp);
265c83f0f99SNate Lawson 
266c2962974SNate Lawson 	fadt_revision = acpi_get_fadt_revision(fadt);
267c83f0f99SNate Lawson 	if (fadt_revision == 1)
268bc711181SAndrew Turner 		addr = fadt->Facs;
269773b6454SNate Lawson 	else
270bc711181SAndrew Turner 		addr = fadt->XFacs;
271bc711181SAndrew Turner 	if (addr != 0) {
272bc711181SAndrew Turner 		facs = (ACPI_TABLE_FACS *)acpi_map_sdt(addr);
273bc711181SAndrew Turner 
274bc711181SAndrew Turner 		if (memcmp(facs->Signature, ACPI_SIG_FACS, 4) != 0 ||
275bc711181SAndrew Turner 		    facs->Length < 64)
2768e6a8737SNate Lawson 			errx(1, "FACS is corrupt");
2778e6a8737SNate Lawson 		acpi_print_facs(facs);
278bc711181SAndrew Turner 	}
2798e6a8737SNate Lawson 
280c83f0f99SNate Lawson 	if (fadt_revision == 1)
281986dffafSJohn Baldwin 		dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt);
282773b6454SNate Lawson 	else
283986dffafSJohn Baldwin 		dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt);
284986dffafSJohn Baldwin 	if (acpi_checksum(dsdp, dsdp->Length))
285945137d9SNate Lawson 		errx(1, "DSDT is corrupt");
286945137d9SNate Lawson 	acpi_print_dsdt(dsdp);
287c62f1cccSMitsuru IWASAKI }
288c62f1cccSMitsuru IWASAKI 
289c62f1cccSMitsuru IWASAKI static void
290986dffafSJohn Baldwin acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
291986dffafSJohn Baldwin     void (*action)(ACPI_SUBTABLE_HEADER *))
292986dffafSJohn Baldwin {
293986dffafSJohn Baldwin 	ACPI_SUBTABLE_HEADER *subtable;
294986dffafSJohn Baldwin 	char *end;
295986dffafSJohn Baldwin 
296986dffafSJohn Baldwin 	subtable = first;
297986dffafSJohn Baldwin 	end = (char *)table + table->Length;
298986dffafSJohn Baldwin 	while ((char *)subtable < end) {
299986dffafSJohn Baldwin 		printf("\n");
300f5d0a8f7SEd Maste 		if (subtable->Length < sizeof(ACPI_SUBTABLE_HEADER)) {
301f5d0a8f7SEd Maste 			warnx("invalid subtable length %u", subtable->Length);
302f5d0a8f7SEd Maste 			return;
303f5d0a8f7SEd Maste 		}
304986dffafSJohn Baldwin 		action(subtable);
305986dffafSJohn Baldwin 		subtable = (ACPI_SUBTABLE_HEADER *)((char *)subtable +
306986dffafSJohn Baldwin 		    subtable->Length);
307986dffafSJohn Baldwin 	}
308986dffafSJohn Baldwin }
309986dffafSJohn Baldwin 
310986dffafSJohn Baldwin static void
311340c0022SEd Maste acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first,
312340c0022SEd Maste     void (*action)(ACPI_NFIT_HEADER *))
313340c0022SEd Maste {
314340c0022SEd Maste 	ACPI_NFIT_HEADER *subtable;
315340c0022SEd Maste 	char *end;
316340c0022SEd Maste 
317340c0022SEd Maste 	subtable = first;
318340c0022SEd Maste 	end = (char *)table + table->Length;
319340c0022SEd Maste 	while ((char *)subtable < end) {
320340c0022SEd Maste 		printf("\n");
321340c0022SEd Maste 		if (subtable->Length < sizeof(ACPI_NFIT_HEADER)) {
322340c0022SEd Maste 			warnx("invalid subtable length %u", subtable->Length);
323340c0022SEd Maste 			return;
324340c0022SEd Maste 		}
325340c0022SEd Maste 		action(subtable);
326340c0022SEd Maste 		subtable = (ACPI_NFIT_HEADER *)((char *)subtable +
327340c0022SEd Maste 		    subtable->Length);
328340c0022SEd Maste 	}
329340c0022SEd Maste }
330340c0022SEd Maste 
331340c0022SEd Maste static void
3320a473124SJohn Baldwin acpi_print_cpu(u_char cpu_id)
3330a473124SJohn Baldwin {
3340a473124SJohn Baldwin 
3350a473124SJohn Baldwin 	printf("\tACPI CPU=");
3360a473124SJohn Baldwin 	if (cpu_id == 0xff)
3370a473124SJohn Baldwin 		printf("ALL\n");
3380a473124SJohn Baldwin 	else
3390a473124SJohn Baldwin 		printf("%d\n", (u_int)cpu_id);
3400a473124SJohn Baldwin }
3410a473124SJohn Baldwin 
3420a473124SJohn Baldwin static void
343986dffafSJohn Baldwin acpi_print_cpu_uid(uint32_t uid, char *uid_string)
3440a473124SJohn Baldwin {
345986dffafSJohn Baldwin 
346986dffafSJohn Baldwin 	printf("\tUID=%d", uid);
347986dffafSJohn Baldwin 	if (uid_string != NULL)
348986dffafSJohn Baldwin 		printf(" (%s)", uid_string);
349986dffafSJohn Baldwin 	printf("\n");
350986dffafSJohn Baldwin }
351986dffafSJohn Baldwin 
352986dffafSJohn Baldwin static void
353986dffafSJohn Baldwin acpi_print_local_apic(uint32_t apic_id, uint32_t flags)
354986dffafSJohn Baldwin {
355986dffafSJohn Baldwin 
3560a473124SJohn Baldwin 	printf("\tFlags={");
357986dffafSJohn Baldwin 	if (flags & ACPI_MADT_ENABLED)
3580a473124SJohn Baldwin 		printf("ENABLED");
3590a473124SJohn Baldwin 	else
3600a473124SJohn Baldwin 		printf("DISABLED");
3610a473124SJohn Baldwin 	printf("}\n");
362986dffafSJohn Baldwin 	printf("\tAPIC ID=%d\n", apic_id);
3630a473124SJohn Baldwin }
3640a473124SJohn Baldwin 
3650a473124SJohn Baldwin static void
366986dffafSJohn Baldwin acpi_print_io_apic(uint32_t apic_id, uint32_t int_base, uint64_t apic_addr)
3670a473124SJohn Baldwin {
368986dffafSJohn Baldwin 
369986dffafSJohn Baldwin 	printf("\tAPIC ID=%d\n", apic_id);
3700a473124SJohn Baldwin 	printf("\tINT BASE=%d\n", int_base);
371986dffafSJohn Baldwin 	printf("\tADDR=0x%016jx\n", (uintmax_t)apic_addr);
3720a473124SJohn Baldwin }
3730a473124SJohn Baldwin 
3740a473124SJohn Baldwin static void
375986dffafSJohn Baldwin acpi_print_mps_flags(uint16_t flags)
3760a473124SJohn Baldwin {
3770a473124SJohn Baldwin 
3780a473124SJohn Baldwin 	printf("\tFlags={Polarity=");
379986dffafSJohn Baldwin 	switch (flags & ACPI_MADT_POLARITY_MASK) {
380986dffafSJohn Baldwin 	case ACPI_MADT_POLARITY_CONFORMS:
3810a473124SJohn Baldwin 		printf("conforming");
3820a473124SJohn Baldwin 		break;
383986dffafSJohn Baldwin 	case ACPI_MADT_POLARITY_ACTIVE_HIGH:
3840a473124SJohn Baldwin 		printf("active-hi");
3850a473124SJohn Baldwin 		break;
386986dffafSJohn Baldwin 	case ACPI_MADT_POLARITY_ACTIVE_LOW:
3870a473124SJohn Baldwin 		printf("active-lo");
3880a473124SJohn Baldwin 		break;
3890a473124SJohn Baldwin 	default:
390986dffafSJohn Baldwin 		printf("0x%x", flags & ACPI_MADT_POLARITY_MASK);
3910a473124SJohn Baldwin 		break;
3920a473124SJohn Baldwin 	}
3930a473124SJohn Baldwin 	printf(", Trigger=");
394986dffafSJohn Baldwin 	switch (flags & ACPI_MADT_TRIGGER_MASK) {
395986dffafSJohn Baldwin 	case ACPI_MADT_TRIGGER_CONFORMS:
3960a473124SJohn Baldwin 		printf("conforming");
3970a473124SJohn Baldwin 		break;
398986dffafSJohn Baldwin 	case ACPI_MADT_TRIGGER_EDGE:
3990a473124SJohn Baldwin 		printf("edge");
4000a473124SJohn Baldwin 		break;
401986dffafSJohn Baldwin 	case ACPI_MADT_TRIGGER_LEVEL:
4020a473124SJohn Baldwin 		printf("level");
4030a473124SJohn Baldwin 		break;
4040a473124SJohn Baldwin 	default:
405986dffafSJohn Baldwin 		printf("0x%x", (flags & ACPI_MADT_TRIGGER_MASK) >> 2);
4060a473124SJohn Baldwin 	}
4070a473124SJohn Baldwin 	printf("}\n");
4080a473124SJohn Baldwin }
4090a473124SJohn Baldwin 
4100a473124SJohn Baldwin static void
4112b2b1f42SAndrew Turner acpi_print_gicc_flags(uint32_t flags)
4122b2b1f42SAndrew Turner {
4132b2b1f42SAndrew Turner 
4142b2b1f42SAndrew Turner 	printf("\tFlags={Performance intr=");
4152b2b1f42SAndrew Turner 	if (flags & ACPI_MADT_PERFORMANCE_IRQ_MODE)
4162b2b1f42SAndrew Turner 		printf("edge");
4172b2b1f42SAndrew Turner 	else
4182b2b1f42SAndrew Turner 		printf("level");
4192b2b1f42SAndrew Turner 	printf(", VGIC intr=");
4202b2b1f42SAndrew Turner 	if (flags & ACPI_MADT_VGIC_IRQ_MODE)
4212b2b1f42SAndrew Turner 		printf("edge");
4222b2b1f42SAndrew Turner 	else
4232b2b1f42SAndrew Turner 		printf("level");
4242b2b1f42SAndrew Turner 	printf("}\n");
4252b2b1f42SAndrew Turner }
4262b2b1f42SAndrew Turner 
4272b2b1f42SAndrew Turner static void
428986dffafSJohn Baldwin acpi_print_intr(uint32_t intr, uint16_t mps_flags)
4290a473124SJohn Baldwin {
4300a473124SJohn Baldwin 
431986dffafSJohn Baldwin 	printf("\tINTR=%d\n", intr);
432986dffafSJohn Baldwin 	acpi_print_mps_flags(mps_flags);
433986dffafSJohn Baldwin }
434986dffafSJohn Baldwin 
435986dffafSJohn Baldwin static void
436986dffafSJohn Baldwin acpi_print_local_nmi(u_int lint, uint16_t mps_flags)
437986dffafSJohn Baldwin {
438986dffafSJohn Baldwin 
439986dffafSJohn Baldwin 	printf("\tLINT Pin=%d\n", lint);
4400a473124SJohn Baldwin 	acpi_print_mps_flags(mps_flags);
4410a473124SJohn Baldwin }
4420a473124SJohn Baldwin 
44327941afaSEd Maste static const char *apic_types[] = {
44427941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_APIC] = "Local APIC",
44527941afaSEd Maste     [ACPI_MADT_TYPE_IO_APIC] = "IO APIC",
44627941afaSEd Maste     [ACPI_MADT_TYPE_INTERRUPT_OVERRIDE] = "INT Override",
44727941afaSEd Maste     [ACPI_MADT_TYPE_NMI_SOURCE] = "NMI",
44827941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_APIC_NMI] = "Local APIC NMI",
44927941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE] = "Local APIC Override",
45027941afaSEd Maste     [ACPI_MADT_TYPE_IO_SAPIC] = "IO SAPIC",
45127941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_SAPIC] = "Local SAPIC",
45227941afaSEd Maste     [ACPI_MADT_TYPE_INTERRUPT_SOURCE] = "Platform Interrupt",
45327941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_X2APIC] = "Local X2APIC",
45427941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_X2APIC_NMI] = "Local X2APIC NMI",
45527941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_INTERRUPT] = "GIC CPU Interface Structure",
45627941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR] = "GIC Distributor Structure",
45727941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_MSI_FRAME] = "GICv2m MSI Frame",
45827941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR] = "GIC Redistributor Structure",
45927941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_TRANSLATOR] = "GIC ITS Structure"
46027941afaSEd Maste };
46127941afaSEd Maste 
462bf70beceSEd Schouten static const char *platform_int_types[] = { "0 (unknown)", "PMI", "INIT",
4630a473124SJohn Baldwin 					    "Corrected Platform Error" };
4640a473124SJohn Baldwin 
4650a473124SJohn Baldwin static void
466986dffafSJohn Baldwin acpi_print_madt(ACPI_SUBTABLE_HEADER *mp)
4670a473124SJohn Baldwin {
468986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_APIC *lapic;
469986dffafSJohn Baldwin 	ACPI_MADT_IO_APIC *ioapic;
470986dffafSJohn Baldwin 	ACPI_MADT_INTERRUPT_OVERRIDE *over;
471986dffafSJohn Baldwin 	ACPI_MADT_NMI_SOURCE *nmi;
472986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_APIC_NMI *lapic_nmi;
473986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic_over;
474986dffafSJohn Baldwin 	ACPI_MADT_IO_SAPIC *iosapic;
475986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_SAPIC *lsapic;
476986dffafSJohn Baldwin 	ACPI_MADT_INTERRUPT_SOURCE *isrc;
477986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_X2APIC *x2apic;
478986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_X2APIC_NMI *x2apic_nmi;
4792b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_INTERRUPT *gicc;
4802b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_DISTRIBUTOR *gicd;
4812b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_REDISTRIBUTOR *gicr;
4822b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_TRANSLATOR *gict;
4830a473124SJohn Baldwin 
484c86932b6SMarcelo Araujo 	if (mp->Type < nitems(apic_types))
485986dffafSJohn Baldwin 		printf("\tType=%s\n", apic_types[mp->Type]);
486a0333ad1SJohn Baldwin 	else
487986dffafSJohn Baldwin 		printf("\tType=%d (unknown)\n", mp->Type);
488986dffafSJohn Baldwin 	switch (mp->Type) {
489986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_APIC:
490986dffafSJohn Baldwin 		lapic = (ACPI_MADT_LOCAL_APIC *)mp;
491986dffafSJohn Baldwin 		acpi_print_cpu(lapic->ProcessorId);
492986dffafSJohn Baldwin 		acpi_print_local_apic(lapic->Id, lapic->LapicFlags);
4930a473124SJohn Baldwin 		break;
494986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_IO_APIC:
495986dffafSJohn Baldwin 		ioapic = (ACPI_MADT_IO_APIC *)mp;
496986dffafSJohn Baldwin 		acpi_print_io_apic(ioapic->Id, ioapic->GlobalIrqBase,
497986dffafSJohn Baldwin 		    ioapic->Address);
4980a473124SJohn Baldwin 		break;
499986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
500986dffafSJohn Baldwin 		over = (ACPI_MADT_INTERRUPT_OVERRIDE *)mp;
501986dffafSJohn Baldwin 		printf("\tBUS=%d\n", (u_int)over->Bus);
502986dffafSJohn Baldwin 		printf("\tIRQ=%d\n", (u_int)over->SourceIrq);
503986dffafSJohn Baldwin 		acpi_print_intr(over->GlobalIrq, over->IntiFlags);
5040a473124SJohn Baldwin 		break;
505986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_NMI_SOURCE:
506986dffafSJohn Baldwin 		nmi = (ACPI_MADT_NMI_SOURCE *)mp;
507986dffafSJohn Baldwin 		acpi_print_intr(nmi->GlobalIrq, nmi->IntiFlags);
5080a473124SJohn Baldwin 		break;
509986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
510986dffafSJohn Baldwin 		lapic_nmi = (ACPI_MADT_LOCAL_APIC_NMI *)mp;
511986dffafSJohn Baldwin 		acpi_print_cpu(lapic_nmi->ProcessorId);
512986dffafSJohn Baldwin 		acpi_print_local_nmi(lapic_nmi->Lint, lapic_nmi->IntiFlags);
5130a473124SJohn Baldwin 		break;
514986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
515986dffafSJohn Baldwin 		lapic_over = (ACPI_MADT_LOCAL_APIC_OVERRIDE *)mp;
516945137d9SNate Lawson 		printf("\tLocal APIC ADDR=0x%016jx\n",
517986dffafSJohn Baldwin 		    (uintmax_t)lapic_over->Address);
5180a473124SJohn Baldwin 		break;
519986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_IO_SAPIC:
520986dffafSJohn Baldwin 		iosapic = (ACPI_MADT_IO_SAPIC *)mp;
521986dffafSJohn Baldwin 		acpi_print_io_apic(iosapic->Id, iosapic->GlobalIrqBase,
522986dffafSJohn Baldwin 		    iosapic->Address);
5230a473124SJohn Baldwin 		break;
524986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_SAPIC:
525986dffafSJohn Baldwin 		lsapic = (ACPI_MADT_LOCAL_SAPIC *)mp;
526986dffafSJohn Baldwin 		acpi_print_cpu(lsapic->ProcessorId);
527986dffafSJohn Baldwin 		acpi_print_local_apic(lsapic->Id, lsapic->LapicFlags);
528986dffafSJohn Baldwin 		printf("\tAPIC EID=%d\n", (u_int)lsapic->Eid);
529986dffafSJohn Baldwin 		if (mp->Length > __offsetof(ACPI_MADT_LOCAL_SAPIC, Uid))
530986dffafSJohn Baldwin 			acpi_print_cpu_uid(lsapic->Uid, lsapic->UidString);
5310a473124SJohn Baldwin 		break;
532986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
533986dffafSJohn Baldwin 		isrc = (ACPI_MADT_INTERRUPT_SOURCE *)mp;
534c86932b6SMarcelo Araujo 		if (isrc->Type < nitems(platform_int_types))
535986dffafSJohn Baldwin 			printf("\tType=%s\n", platform_int_types[isrc->Type]);
536986dffafSJohn Baldwin 		else
537986dffafSJohn Baldwin 			printf("\tType=%d (unknown)\n", isrc->Type);
538986dffafSJohn Baldwin 		printf("\tAPIC ID=%d\n", (u_int)isrc->Id);
539986dffafSJohn Baldwin 		printf("\tAPIC EID=%d\n", (u_int)isrc->Eid);
540986dffafSJohn Baldwin 		printf("\tSAPIC Vector=%d\n", (u_int)isrc->IoSapicVector);
541986dffafSJohn Baldwin 		acpi_print_intr(isrc->GlobalIrq, isrc->IntiFlags);
542986dffafSJohn Baldwin 		break;
543986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_X2APIC:
544986dffafSJohn Baldwin 		x2apic = (ACPI_MADT_LOCAL_X2APIC *)mp;
545986dffafSJohn Baldwin 		acpi_print_cpu_uid(x2apic->Uid, NULL);
546986dffafSJohn Baldwin 		acpi_print_local_apic(x2apic->LocalApicId, x2apic->LapicFlags);
547986dffafSJohn Baldwin 		break;
548986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
549986dffafSJohn Baldwin 		x2apic_nmi = (ACPI_MADT_LOCAL_X2APIC_NMI *)mp;
550986dffafSJohn Baldwin 		acpi_print_cpu_uid(x2apic_nmi->Uid, NULL);
551986dffafSJohn Baldwin 		acpi_print_local_nmi(x2apic_nmi->Lint, x2apic_nmi->IntiFlags);
5520a473124SJohn Baldwin 		break;
5532b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
5542b2b1f42SAndrew Turner 		gicc = (ACPI_MADT_GENERIC_INTERRUPT *)mp;
5552b2b1f42SAndrew Turner 		acpi_print_cpu_uid(gicc->Uid, NULL);
5562b2b1f42SAndrew Turner 		printf("\tCPU INTERFACE=%x\n", gicc->CpuInterfaceNumber);
5572b2b1f42SAndrew Turner 		acpi_print_gicc_flags(gicc->Flags);
5582b2b1f42SAndrew Turner 		printf("\tParking Protocol Version=%x\n", gicc->ParkingVersion);
5592b2b1f42SAndrew Turner 		printf("\tPERF INTR=%d\n", gicc->PerformanceInterrupt);
5602b2b1f42SAndrew Turner 		printf("\tParked ADDR=%016jx\n",
5612b2b1f42SAndrew Turner 		    (uintmax_t)gicc->ParkedAddress);
5622b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicc->BaseAddress);
5632b2b1f42SAndrew Turner 		printf("\tGICV=%016jx\n", (uintmax_t)gicc->GicvBaseAddress);
5642b2b1f42SAndrew Turner 		printf("\tGICH=%016jx\n", (uintmax_t)gicc->GichBaseAddress);
5652b2b1f42SAndrew Turner 		printf("\tVGIC INTR=%d\n", gicc->VgicInterrupt);
5662b2b1f42SAndrew Turner 		printf("\tGICR ADDR=%016jx\n",
5672b2b1f42SAndrew Turner 		    (uintmax_t)gicc->GicrBaseAddress);
5682b2b1f42SAndrew Turner 		printf("\tMPIDR=%jx\n", (uintmax_t)gicc->ArmMpidr);
5690b4302aaSGordon Bergling 		printf("\tEfficiency Class=%d\n", (u_int)gicc->EfficiencyClass);
570c363da4aSAndrew Turner 		printf("\tSPE INTR=%d\n", gicc->SpeInterrupt);
5712b2b1f42SAndrew Turner 		break;
5722b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
5732b2b1f42SAndrew Turner 		gicd = (ACPI_MADT_GENERIC_DISTRIBUTOR *)mp;
5742b2b1f42SAndrew Turner 		printf("\tGIC ID=%d\n", (u_int)gicd->GicId);
5752b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicd->BaseAddress);
5762b2b1f42SAndrew Turner 		printf("\tVector Base=%d\n", gicd->GlobalIrqBase);
5772b2b1f42SAndrew Turner 		printf("\tGIC VERSION=%d\n", (u_int)gicd->Version);
5782b2b1f42SAndrew Turner 		break;
5792b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
5802b2b1f42SAndrew Turner 		gicr = (ACPI_MADT_GENERIC_REDISTRIBUTOR *)mp;
5812b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicr->BaseAddress);
5822b2b1f42SAndrew Turner 		printf("\tLength=%08x\n", gicr->Length);
5832b2b1f42SAndrew Turner 		break;
5842b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
5852b2b1f42SAndrew Turner 		gict = (ACPI_MADT_GENERIC_TRANSLATOR *)mp;
5862b2b1f42SAndrew Turner 		printf("\tGIC ITS ID=%d\n", gict->TranslationId);
5872b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gict->BaseAddress);
5882b2b1f42SAndrew Turner 		break;
5890a473124SJohn Baldwin 	}
5900a473124SJohn Baldwin }
5910a473124SJohn Baldwin 
5920a473124SJohn Baldwin static void
593986dffafSJohn Baldwin acpi_handle_madt(ACPI_TABLE_HEADER *sdp)
5940a473124SJohn Baldwin {
595986dffafSJohn Baldwin 	ACPI_TABLE_MADT *madt;
5960a473124SJohn Baldwin 
597773b6454SNate Lawson 	printf(BEGIN_COMMENT);
598773b6454SNate Lawson 	acpi_print_sdt(sdp);
599986dffafSJohn Baldwin 	madt = (ACPI_TABLE_MADT *)sdp;
600986dffafSJohn Baldwin 	printf("\tLocal APIC ADDR=0x%08x\n", madt->Address);
6010a473124SJohn Baldwin 	printf("\tFlags={");
602986dffafSJohn Baldwin 	if (madt->Flags & ACPI_MADT_PCAT_COMPAT)
6030a473124SJohn Baldwin 		printf("PC-AT");
6040a473124SJohn Baldwin 	printf("}\n");
605986dffafSJohn Baldwin 	acpi_walk_subtables(sdp, (madt + 1), acpi_print_madt);
6060a473124SJohn Baldwin 	printf(END_COMMENT);
6070a473124SJohn Baldwin }
6080a473124SJohn Baldwin 
6090a473124SJohn Baldwin static void
610ebc22d04SAlexander Motin acpi_handle_bert(ACPI_TABLE_HEADER *sdp)
611ebc22d04SAlexander Motin {
612ebc22d04SAlexander Motin 	ACPI_TABLE_BERT *bert;
613ebc22d04SAlexander Motin 
614ebc22d04SAlexander Motin 	printf(BEGIN_COMMENT);
615ebc22d04SAlexander Motin 	acpi_print_sdt(sdp);
616ebc22d04SAlexander Motin 	bert = (ACPI_TABLE_BERT *)sdp;
617ebc22d04SAlexander Motin 	printf("\tRegionLength=%d\n", bert->RegionLength);
618ebc22d04SAlexander Motin 	printf("\tAddress=0x%016jx\n", bert->Address);
619ebc22d04SAlexander Motin 	printf(END_COMMENT);
620ebc22d04SAlexander Motin }
621ebc22d04SAlexander Motin 
622ebc22d04SAlexander Motin static void
623ebc22d04SAlexander Motin acpi_print_whea(ACPI_WHEA_HEADER *w)
624ebc22d04SAlexander Motin {
625ebc22d04SAlexander Motin 
626ebc22d04SAlexander Motin 	printf("\n\tAction=%d\n", w->Action);
627ebc22d04SAlexander Motin 	printf("\tInstruction=%d\n", w->Instruction);
628ebc22d04SAlexander Motin 	printf("\tFlags=%02x\n", w->Flags);
629ebc22d04SAlexander Motin 	printf("\tRegisterRegion=");
630ebc22d04SAlexander Motin 	acpi_print_gas(&w->RegisterRegion);
631ebc22d04SAlexander Motin 	printf("\n\tValue=0x%016jx\n", w->Value);
632ebc22d04SAlexander Motin 	printf("\tMask=0x%016jx\n", w->Mask);
633ebc22d04SAlexander Motin }
634ebc22d04SAlexander Motin 
635ebc22d04SAlexander Motin static void
636ebc22d04SAlexander Motin acpi_handle_einj(ACPI_TABLE_HEADER *sdp)
637ebc22d04SAlexander Motin {
638ebc22d04SAlexander Motin 	ACPI_TABLE_EINJ *einj;
639ebc22d04SAlexander Motin 	ACPI_WHEA_HEADER *w;
640ebc22d04SAlexander Motin 	u_int i;
641ebc22d04SAlexander Motin 
642ebc22d04SAlexander Motin 	printf(BEGIN_COMMENT);
643ebc22d04SAlexander Motin 	acpi_print_sdt(sdp);
644ebc22d04SAlexander Motin 	einj = (ACPI_TABLE_EINJ *)sdp;
645ebc22d04SAlexander Motin 	printf("\tHeaderLength=%d\n", einj->HeaderLength);
646ebc22d04SAlexander Motin 	printf("\tFlags=0x%02x\n", einj->Flags);
647ebc22d04SAlexander Motin 	printf("\tEntries=%d\n", einj->Entries);
648ebc22d04SAlexander Motin 	w = (ACPI_WHEA_HEADER *)(einj + 1);
649ebc22d04SAlexander Motin 	for (i = 0; i < MIN(einj->Entries, (sdp->Length -
650ebc22d04SAlexander Motin 	    sizeof(ACPI_TABLE_EINJ)) / sizeof(ACPI_WHEA_HEADER)); i++)
651ebc22d04SAlexander Motin 		acpi_print_whea(w + i);
652ebc22d04SAlexander Motin 	printf(END_COMMENT);
653ebc22d04SAlexander Motin }
654ebc22d04SAlexander Motin 
655ebc22d04SAlexander Motin static void
656ebc22d04SAlexander Motin acpi_handle_erst(ACPI_TABLE_HEADER *sdp)
657ebc22d04SAlexander Motin {
658ebc22d04SAlexander Motin 	ACPI_TABLE_ERST *erst;
659ebc22d04SAlexander Motin 	ACPI_WHEA_HEADER *w;
660ebc22d04SAlexander Motin 	u_int i;
661ebc22d04SAlexander Motin 
662ebc22d04SAlexander Motin 	printf(BEGIN_COMMENT);
663ebc22d04SAlexander Motin 	acpi_print_sdt(sdp);
664ebc22d04SAlexander Motin 	erst = (ACPI_TABLE_ERST *)sdp;
665ebc22d04SAlexander Motin 	printf("\tHeaderLength=%d\n", erst->HeaderLength);
666ebc22d04SAlexander Motin 	printf("\tEntries=%d\n", erst->Entries);
667ebc22d04SAlexander Motin 	w = (ACPI_WHEA_HEADER *)(erst + 1);
668ebc22d04SAlexander Motin 	for (i = 0; i < MIN(erst->Entries, (sdp->Length -
669ebc22d04SAlexander Motin 	    sizeof(ACPI_TABLE_ERST)) / sizeof(ACPI_WHEA_HEADER)); i++)
670ebc22d04SAlexander Motin 		acpi_print_whea(w + i);
671ebc22d04SAlexander Motin 	printf(END_COMMENT);
672ebc22d04SAlexander Motin }
673ebc22d04SAlexander Motin 
674ebc22d04SAlexander Motin static void
675ebc22d04SAlexander Motin acpi_print_hest_bank(ACPI_HEST_IA_ERROR_BANK *b)
676ebc22d04SAlexander Motin {
677ebc22d04SAlexander Motin 
678ebc22d04SAlexander Motin 	printf("\tBank:\n");
679ebc22d04SAlexander Motin 	printf("\t\tBankNumber=%d\n", b->BankNumber);
680ebc22d04SAlexander Motin 	printf("\t\tClearStatusOnInit=%d\n", b->ClearStatusOnInit);
681ebc22d04SAlexander Motin 	printf("\t\tStatusFormat=%d\n", b->StatusFormat);
682ebc22d04SAlexander Motin 	printf("\t\tControlRegister=%x\n", b->ControlRegister);
683ebc22d04SAlexander Motin 	printf("\t\tControlData=%jx\n", b->ControlData);
684ebc22d04SAlexander Motin 	printf("\t\tStatusRegister=%x\n", b->StatusRegister);
685ebc22d04SAlexander Motin 	printf("\t\tAddressRegister=%x\n", b->AddressRegister);
686ebc22d04SAlexander Motin 	printf("\t\tMiscRegister=%x\n", b->MiscRegister);
687ebc22d04SAlexander Motin }
688ebc22d04SAlexander Motin 
689ebc22d04SAlexander Motin static void
690ebc22d04SAlexander Motin acpi_print_hest_notify(ACPI_HEST_NOTIFY *n)
691ebc22d04SAlexander Motin {
692ebc22d04SAlexander Motin 
693ebc22d04SAlexander Motin 	printf("\t\tType=%d\n", n->Type);
694ebc22d04SAlexander Motin 	printf("\t\tLength=%d\n", n->Length);
695ebc22d04SAlexander Motin 	printf("\t\tConfigWriteEnable=%04x\n", n->ConfigWriteEnable);
696ebc22d04SAlexander Motin 	printf("\t\tPollInterval=%d\n", n->PollInterval);
697ebc22d04SAlexander Motin 	printf("\t\tVector=%d\n", n->Vector);
698ebc22d04SAlexander Motin 	printf("\t\tPollingThresholdValue=%d\n", n->PollingThresholdValue);
699ebc22d04SAlexander Motin 	printf("\t\tPollingThresholdWindow=%d\n", n->PollingThresholdWindow);
700ebc22d04SAlexander Motin 	printf("\t\tErrorThresholdValue=%d\n", n->ErrorThresholdValue);
701ebc22d04SAlexander Motin 	printf("\t\tErrorThresholdWindow=%d\n", n->ErrorThresholdWindow);
702ebc22d04SAlexander Motin }
703ebc22d04SAlexander Motin 
704ebc22d04SAlexander Motin static void
705ebc22d04SAlexander Motin acpi_print_hest_aer(ACPI_HEST_AER_COMMON *a)
706ebc22d04SAlexander Motin {
707ebc22d04SAlexander Motin 
708ebc22d04SAlexander Motin 	printf("\tFlags=%02x\n", a->Flags);
709ebc22d04SAlexander Motin 	printf("\tEnabled=%d\n", a->Enabled);
710ebc22d04SAlexander Motin 	printf("\tRecordsToPreallocate=%d\n", a->RecordsToPreallocate);
711ebc22d04SAlexander Motin 	printf("\tMaxSectionsPerRecord=%d\n", a->MaxSectionsPerRecord);
712ebc22d04SAlexander Motin 	printf("\tBus=%d\n", a->Bus);
713ebc22d04SAlexander Motin 	printf("\tDevice=%d\n", a->Device);
714ebc22d04SAlexander Motin 	printf("\tFunction=%d\n", a->Function);
715ebc22d04SAlexander Motin 	printf("\tDeviceControl=%d\n", a->DeviceControl);
716ebc22d04SAlexander Motin 	printf("\tUncorrectableMask=%d\n", a->UncorrectableMask);
717ebc22d04SAlexander Motin 	printf("\tUncorrectableSeverity=%d\n", a->UncorrectableSeverity);
718ebc22d04SAlexander Motin 	printf("\tCorrectableMask=%d\n", a->CorrectableMask);
719ebc22d04SAlexander Motin 	printf("\tAdvancedCapabilities=%d\n", a->AdvancedCapabilities);
720ebc22d04SAlexander Motin }
721ebc22d04SAlexander Motin 
722ebc22d04SAlexander Motin static int
723ebc22d04SAlexander Motin acpi_handle_hest_structure(void *addr, int remaining)
724ebc22d04SAlexander Motin {
725ebc22d04SAlexander Motin 	ACPI_HEST_HEADER *hdr = addr;
726ebc22d04SAlexander Motin 	int i;
727ebc22d04SAlexander Motin 
728ebc22d04SAlexander Motin 	if (remaining < (int)sizeof(ACPI_HEST_HEADER))
729ebc22d04SAlexander Motin 		return (-1);
730ebc22d04SAlexander Motin 
731ebc22d04SAlexander Motin 	printf("\n\tType=%d\n", hdr->Type);
732ebc22d04SAlexander Motin 	printf("\tSourceId=%d\n", hdr->SourceId);
733ebc22d04SAlexander Motin 	switch (hdr->Type) {
734ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_IA32_CHECK: {
735ebc22d04SAlexander Motin 		ACPI_HEST_IA_MACHINE_CHECK *s = addr;
736ebc22d04SAlexander Motin 		printf("\tFlags=%02x\n", s->Flags);
737ebc22d04SAlexander Motin 		printf("\tEnabled=%d\n", s->Enabled);
738ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
739ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
740ebc22d04SAlexander Motin 		printf("\tGlobalCapabilityData=%jd\n", s->GlobalCapabilityData);
741ebc22d04SAlexander Motin 		printf("\tGlobalControlData=%jd\n", s->GlobalControlData);
742ebc22d04SAlexander Motin 		printf("\tNumHardwareBanks=%d\n", s->NumHardwareBanks);
743ebc22d04SAlexander Motin 		for (i = 0; i < s->NumHardwareBanks; i++) {
744ebc22d04SAlexander Motin 			acpi_print_hest_bank((ACPI_HEST_IA_ERROR_BANK *)
745ebc22d04SAlexander Motin 			    (s + 1) + i);
746ebc22d04SAlexander Motin 		}
747ebc22d04SAlexander Motin 		return (sizeof(*s) + s->NumHardwareBanks *
748ebc22d04SAlexander Motin 		    sizeof(ACPI_HEST_IA_ERROR_BANK));
749ebc22d04SAlexander Motin 	}
750ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: {
751ebc22d04SAlexander Motin 		ACPI_HEST_IA_CORRECTED *s = addr;
752ebc22d04SAlexander Motin 		printf("\tFlags=%02x\n", s->Flags);
753ebc22d04SAlexander Motin 		printf("\tEnabled=%d\n", s->Enabled);
754ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
755ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
756ebc22d04SAlexander Motin 		printf("\tNotify:\n");
757ebc22d04SAlexander Motin 		acpi_print_hest_notify(&s->Notify);
758ebc22d04SAlexander Motin 		printf("\tNumHardwareBanks=%d\n", s->NumHardwareBanks);
759ebc22d04SAlexander Motin 		for (i = 0; i < s->NumHardwareBanks; i++) {
760ebc22d04SAlexander Motin 			acpi_print_hest_bank((ACPI_HEST_IA_ERROR_BANK *)
761ebc22d04SAlexander Motin 			    (s + 1) + i);
762ebc22d04SAlexander Motin 		}
763ebc22d04SAlexander Motin 		return (sizeof(*s) + s->NumHardwareBanks *
764ebc22d04SAlexander Motin 		    sizeof(ACPI_HEST_IA_ERROR_BANK));
765ebc22d04SAlexander Motin 	}
766ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_IA32_NMI: {
767ebc22d04SAlexander Motin 		ACPI_HEST_IA_NMI *s = addr;
768ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
769ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
770ebc22d04SAlexander Motin 		printf("\tMaxRawDataLength=%d\n", s->MaxRawDataLength);
771ebc22d04SAlexander Motin 		return (sizeof(*s));
772ebc22d04SAlexander Motin 	}
773ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_AER_ROOT_PORT: {
774ebc22d04SAlexander Motin 		ACPI_HEST_AER_ROOT *s = addr;
775ebc22d04SAlexander Motin 		acpi_print_hest_aer(&s->Aer);
776ebc22d04SAlexander Motin 		printf("\tRootErrorCommand=%d\n", s->RootErrorCommand);
777ebc22d04SAlexander Motin 		return (sizeof(*s));
778ebc22d04SAlexander Motin 	}
779ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_AER_ENDPOINT: {
780ebc22d04SAlexander Motin 		ACPI_HEST_AER *s = addr;
781ebc22d04SAlexander Motin 		acpi_print_hest_aer(&s->Aer);
782ebc22d04SAlexander Motin 		return (sizeof(*s));
783ebc22d04SAlexander Motin 	}
784ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_AER_BRIDGE: {
785ebc22d04SAlexander Motin 		ACPI_HEST_AER_BRIDGE *s = addr;
786ebc22d04SAlexander Motin 		acpi_print_hest_aer(&s->Aer);
787ebc22d04SAlexander Motin 		printf("\tUncorrectableMask2=%d\n", s->UncorrectableMask2);
788ebc22d04SAlexander Motin 		printf("\tUncorrectableSeverity2=%d\n", s->UncorrectableSeverity2);
789ebc22d04SAlexander Motin 		printf("\tAdvancedCapabilities2=%d\n", s->AdvancedCapabilities2);
790ebc22d04SAlexander Motin 		return (sizeof(*s));
791ebc22d04SAlexander Motin 	}
792ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_GENERIC_ERROR: {
793ebc22d04SAlexander Motin 		ACPI_HEST_GENERIC *s = addr;
794ebc22d04SAlexander Motin 		printf("\tRelatedSourceId=%d\n", s->RelatedSourceId);
795ebc22d04SAlexander Motin 		printf("\tEnabled=%d\n", s->Enabled);
796ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
797ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
798ebc22d04SAlexander Motin 		printf("\tMaxRawDataLength=%d\n", s->MaxRawDataLength);
799ebc22d04SAlexander Motin 		printf("\tErrorStatusAddress=");
800ebc22d04SAlexander Motin 		acpi_print_gas(&s->ErrorStatusAddress);
801ebc22d04SAlexander Motin 		printf("\n");
802ebc22d04SAlexander Motin 		printf("\tNotify:\n");
803ebc22d04SAlexander Motin 		acpi_print_hest_notify(&s->Notify);
804ebc22d04SAlexander Motin 		printf("\tErrorBlockLength=%d\n", s->ErrorBlockLength);
805ebc22d04SAlexander Motin 		return (sizeof(*s));
806ebc22d04SAlexander Motin 	}
807ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_GENERIC_ERROR_V2: {
808ebc22d04SAlexander Motin 		ACPI_HEST_GENERIC_V2 *s = addr;
809ebc22d04SAlexander Motin 		printf("\tRelatedSourceId=%d\n", s->RelatedSourceId);
810ebc22d04SAlexander Motin 		printf("\tEnabled=%d\n", s->Enabled);
811ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
812ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
813ebc22d04SAlexander Motin 		printf("\tMaxRawDataLength=%d\n", s->MaxRawDataLength);
814ebc22d04SAlexander Motin 		printf("\tErrorStatusAddress=");
815ebc22d04SAlexander Motin 		acpi_print_gas(&s->ErrorStatusAddress);
816ebc22d04SAlexander Motin 		printf("\n");
817ebc22d04SAlexander Motin 		printf("\tNotify:\n");
818ebc22d04SAlexander Motin 		acpi_print_hest_notify(&s->Notify);
819ebc22d04SAlexander Motin 		printf("\tErrorBlockLength=%d\n", s->ErrorBlockLength);
820ebc22d04SAlexander Motin 		printf("\tReadAckRegister=");
821ebc22d04SAlexander Motin 		acpi_print_gas(&s->ReadAckRegister);
822ebc22d04SAlexander Motin 		printf("\n");
823ebc22d04SAlexander Motin 		printf("\tReadAckPreserve=%jd\n", s->ReadAckPreserve);
824ebc22d04SAlexander Motin 		printf("\tReadAckWrite=%jd\n", s->ReadAckWrite);
825ebc22d04SAlexander Motin 		return (sizeof(*s));
826ebc22d04SAlexander Motin 	}
827ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: {
828ebc22d04SAlexander Motin 		ACPI_HEST_IA_DEFERRED_CHECK *s = addr;
829ebc22d04SAlexander Motin 		printf("\tFlags=%02x\n", s->Flags);
830ebc22d04SAlexander Motin 		printf("\tEnabled=%d\n", s->Enabled);
831ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
832ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
833ebc22d04SAlexander Motin 		printf("\tNotify:\n");
834ebc22d04SAlexander Motin 		acpi_print_hest_notify(&s->Notify);
835ebc22d04SAlexander Motin 		printf("\tNumHardwareBanks=%d\n", s->NumHardwareBanks);
836ebc22d04SAlexander Motin 		for (i = 0; i < s->NumHardwareBanks; i++) {
837ebc22d04SAlexander Motin 			acpi_print_hest_bank((ACPI_HEST_IA_ERROR_BANK *)
838ebc22d04SAlexander Motin 			    (s + 1) + i);
839ebc22d04SAlexander Motin 		}
840ebc22d04SAlexander Motin 		return (sizeof(*s) + s->NumHardwareBanks *
841ebc22d04SAlexander Motin 		    sizeof(ACPI_HEST_IA_ERROR_BANK));
842ebc22d04SAlexander Motin 	}
843ebc22d04SAlexander Motin 	default:
844ebc22d04SAlexander Motin 		return (-1);
845ebc22d04SAlexander Motin 	}
846ebc22d04SAlexander Motin }
847ebc22d04SAlexander Motin 
848ebc22d04SAlexander Motin static void
849ebc22d04SAlexander Motin acpi_handle_hest(ACPI_TABLE_HEADER *sdp)
850ebc22d04SAlexander Motin {
851ebc22d04SAlexander Motin 	char *cp;
852ebc22d04SAlexander Motin 	int remaining, consumed;
853ebc22d04SAlexander Motin 	ACPI_TABLE_HEST *hest;
854ebc22d04SAlexander Motin 
855ebc22d04SAlexander Motin 	printf(BEGIN_COMMENT);
856ebc22d04SAlexander Motin 	acpi_print_sdt(sdp);
857ebc22d04SAlexander Motin 	hest = (ACPI_TABLE_HEST *)sdp;
858ebc22d04SAlexander Motin 	printf("\tErrorSourceCount=%d\n", hest->ErrorSourceCount);
859ebc22d04SAlexander Motin 
860ebc22d04SAlexander Motin 	remaining = sdp->Length - sizeof(ACPI_TABLE_HEST);
861ebc22d04SAlexander Motin 	while (remaining > 0) {
862ebc22d04SAlexander Motin 		cp = (char *)sdp + sdp->Length - remaining;
863ebc22d04SAlexander Motin 		consumed = acpi_handle_hest_structure(cp, remaining);
864ebc22d04SAlexander Motin 		if (consumed <= 0)
865ebc22d04SAlexander Motin 			break;
866ebc22d04SAlexander Motin 		else
867ebc22d04SAlexander Motin 			remaining -= consumed;
868ebc22d04SAlexander Motin 	}
869ebc22d04SAlexander Motin 	printf(END_COMMENT);
870ebc22d04SAlexander Motin }
871ebc22d04SAlexander Motin 
872ebc22d04SAlexander Motin static void
873986dffafSJohn Baldwin acpi_handle_hpet(ACPI_TABLE_HEADER *sdp)
87479d7565cSPeter Wemm {
875986dffafSJohn Baldwin 	ACPI_TABLE_HPET *hpet;
87679d7565cSPeter Wemm 
877773b6454SNate Lawson 	printf(BEGIN_COMMENT);
878773b6454SNate Lawson 	acpi_print_sdt(sdp);
879986dffafSJohn Baldwin 	hpet = (ACPI_TABLE_HPET *)sdp;
880986dffafSJohn Baldwin 	printf("\tHPET Number=%d\n", hpet->Sequence);
88187f9f09aSTakanori Watanabe 	printf("\tADDR=");
882986dffafSJohn Baldwin 	acpi_print_gas(&hpet->Address);
883ebc22d04SAlexander Motin 	printf("\n\tHW Rev=0x%x\n", hpet->Id & ACPI_HPET_ID_HARDWARE_REV_ID);
884986dffafSJohn Baldwin 	printf("\tComparators=%d\n", (hpet->Id & ACPI_HPET_ID_COMPARATORS) >>
885986dffafSJohn Baldwin 	    8);
886986dffafSJohn Baldwin 	printf("\tCounter Size=%d\n", hpet->Id & ACPI_HPET_ID_COUNT_SIZE_CAP ?
887986dffafSJohn Baldwin 	    1 : 0);
88879d7565cSPeter Wemm 	printf("\tLegacy IRQ routing capable={");
889986dffafSJohn Baldwin 	if (hpet->Id & ACPI_HPET_ID_LEGACY_CAPABLE)
89079d7565cSPeter Wemm 		printf("TRUE}\n");
89179d7565cSPeter Wemm 	else
89279d7565cSPeter Wemm 		printf("FALSE}\n");
893986dffafSJohn Baldwin 	printf("\tPCI Vendor ID=0x%04x\n", hpet->Id >> 16);
894986dffafSJohn Baldwin 	printf("\tMinimal Tick=%d\n", hpet->MinimumTick);
8959785e979SNeel Natu 	printf("\tFlags=0x%02x\n", hpet->Flags);
89679d7565cSPeter Wemm 	printf(END_COMMENT);
89779d7565cSPeter Wemm }
89879d7565cSPeter Wemm 
89979d7565cSPeter Wemm static void
900986dffafSJohn Baldwin acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp)
90155d7ff9eSNate Lawson {
902986dffafSJohn Baldwin 	ACPI_TABLE_ECDT *ecdt;
90355d7ff9eSNate Lawson 
90455d7ff9eSNate Lawson 	printf(BEGIN_COMMENT);
90555d7ff9eSNate Lawson 	acpi_print_sdt(sdp);
906986dffafSJohn Baldwin 	ecdt = (ACPI_TABLE_ECDT *)sdp;
90755d7ff9eSNate Lawson 	printf("\tEC_CONTROL=");
908986dffafSJohn Baldwin 	acpi_print_gas(&ecdt->Control);
90955d7ff9eSNate Lawson 	printf("\n\tEC_DATA=");
910986dffafSJohn Baldwin 	acpi_print_gas(&ecdt->Data);
911986dffafSJohn Baldwin 	printf("\n\tUID=%#x, ", ecdt->Uid);
912986dffafSJohn Baldwin 	printf("GPE_BIT=%#x\n", ecdt->Gpe);
913986dffafSJohn Baldwin 	printf("\tEC_ID=%s\n", ecdt->Id);
91455d7ff9eSNate Lawson 	printf(END_COMMENT);
91555d7ff9eSNate Lawson }
91655d7ff9eSNate Lawson 
91755d7ff9eSNate Lawson static void
918986dffafSJohn Baldwin acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp)
919a47e681bSScott Long {
920986dffafSJohn Baldwin 	ACPI_TABLE_MCFG *mcfg;
921986dffafSJohn Baldwin 	ACPI_MCFG_ALLOCATION *alloc;
922986dffafSJohn Baldwin 	u_int i, entries;
923a47e681bSScott Long 
924a47e681bSScott Long 	printf(BEGIN_COMMENT);
925a47e681bSScott Long 	acpi_print_sdt(sdp);
926986dffafSJohn Baldwin 	mcfg = (ACPI_TABLE_MCFG *)sdp;
927986dffafSJohn Baldwin 	entries = (sdp->Length - sizeof(ACPI_TABLE_MCFG)) /
928986dffafSJohn Baldwin 	    sizeof(ACPI_MCFG_ALLOCATION);
929986dffafSJohn Baldwin 	alloc = (ACPI_MCFG_ALLOCATION *)(mcfg + 1);
930986dffafSJohn Baldwin 	for (i = 0; i < entries; i++, alloc++) {
931a47e681bSScott Long 		printf("\n");
9320c10b85aSJung-uk Kim 		printf("\tBase Address=0x%016jx\n", (uintmax_t)alloc->Address);
933986dffafSJohn Baldwin 		printf("\tSegment Group=0x%04x\n", alloc->PciSegment);
934986dffafSJohn Baldwin 		printf("\tStart Bus=%d\n", alloc->StartBusNumber);
935986dffafSJohn Baldwin 		printf("\tEnd Bus=%d\n", alloc->EndBusNumber);
936a47e681bSScott Long 	}
937a47e681bSScott Long 	printf(END_COMMENT);
938a47e681bSScott Long }
939a47e681bSScott Long 
940a47e681bSScott Long static void
94133866658SJohn Baldwin acpi_handle_slit(ACPI_TABLE_HEADER *sdp)
94233866658SJohn Baldwin {
94333866658SJohn Baldwin 	ACPI_TABLE_SLIT *slit;
94433866658SJohn Baldwin 	UINT64 i, j;
94533866658SJohn Baldwin 
94633866658SJohn Baldwin 	printf(BEGIN_COMMENT);
94733866658SJohn Baldwin 	acpi_print_sdt(sdp);
94833866658SJohn Baldwin 	slit = (ACPI_TABLE_SLIT *)sdp;
9490c10b85aSJung-uk Kim 	printf("\tLocality Count=%ju\n", (uintmax_t)slit->LocalityCount);
95033866658SJohn Baldwin 	printf("\n\t      ");
95133866658SJohn Baldwin 	for (i = 0; i < slit->LocalityCount; i++)
9520c10b85aSJung-uk Kim 		printf(" %3ju", (uintmax_t)i);
95333866658SJohn Baldwin 	printf("\n\t     +");
95433866658SJohn Baldwin 	for (i = 0; i < slit->LocalityCount; i++)
95533866658SJohn Baldwin 		printf("----");
95633866658SJohn Baldwin 	printf("\n");
95733866658SJohn Baldwin 	for (i = 0; i < slit->LocalityCount; i++) {
9580c10b85aSJung-uk Kim 		printf("\t %3ju |", (uintmax_t)i);
95933866658SJohn Baldwin 		for (j = 0; j < slit->LocalityCount; j++)
96033866658SJohn Baldwin 			printf(" %3d",
96133866658SJohn Baldwin 			    slit->Entry[i * slit->LocalityCount + j]);
96233866658SJohn Baldwin 		printf("\n");
96333866658SJohn Baldwin 	}
96433866658SJohn Baldwin 	printf(END_COMMENT);
96533866658SJohn Baldwin }
96633866658SJohn Baldwin 
96733866658SJohn Baldwin static void
968ed26c389SScott Long acpi_handle_wddt(ACPI_TABLE_HEADER *sdp)
969ed26c389SScott Long {
970ed26c389SScott Long 	ACPI_TABLE_WDDT *wddt;
971ed26c389SScott Long 
972ed26c389SScott Long 	printf(BEGIN_COMMENT);
973ed26c389SScott Long 	acpi_print_sdt(sdp);
974ed26c389SScott Long 	wddt = (ACPI_TABLE_WDDT *)sdp;
975ed26c389SScott Long 	printf("\tSpecVersion=0x%04x, TableVersion=0x%04x\n",
976ed26c389SScott Long 	    wddt->SpecVersion, wddt->TableVersion);
977ed26c389SScott Long 	printf("\tPciVendorId=0x%04x, Address=", wddt->PciVendorId);
978ed26c389SScott Long 	acpi_print_gas(&wddt->Address);
979ed26c389SScott Long 	printf("\n\tMaxCount=%u, MinCount=%u, Period=%ums\n",
980ed26c389SScott Long 	    wddt->MaxCount, wddt->MinCount, wddt->Period);
981ed26c389SScott Long 
982ed26c389SScott Long #define	PRINTFLAG(var, flag)	printflag((var), ACPI_WDDT_## flag, #flag)
983ed26c389SScott Long 	printf("\tStatus=");
984ed26c389SScott Long 	PRINTFLAG(wddt->Status, AVAILABLE);
985ed26c389SScott Long 	PRINTFLAG(wddt->Status, ACTIVE);
986ed26c389SScott Long 	PRINTFLAG(wddt->Status, TCO_OS_OWNED);
987ed26c389SScott Long 	PRINTFLAG(wddt->Status, USER_RESET);
988ed26c389SScott Long 	PRINTFLAG(wddt->Status, WDT_RESET);
989ed26c389SScott Long 	PRINTFLAG(wddt->Status, POWER_FAIL);
990ed26c389SScott Long 	PRINTFLAG(wddt->Status, UNKNOWN_RESET);
991ed26c389SScott Long 	PRINTFLAG_END();
992ed26c389SScott Long 	printf("\tCapability=");
993ed26c389SScott Long 	PRINTFLAG(wddt->Capability, AUTO_RESET);
994ed26c389SScott Long 	PRINTFLAG(wddt->Capability, ALERT_SUPPORT);
995ed26c389SScott Long 	PRINTFLAG_END();
996ed26c389SScott Long #undef PRINTFLAG
997ed26c389SScott Long 
998ed26c389SScott Long 	printf(END_COMMENT);
999ed26c389SScott Long }
1000ed26c389SScott Long 
1001ed26c389SScott Long static void
10025857fba5SBen Widawsky acpi_print_native_lpit(ACPI_LPIT_NATIVE *nl)
10035857fba5SBen Widawsky {
10045857fba5SBen Widawsky 	printf("\tEntryTrigger=");
10055857fba5SBen Widawsky 	acpi_print_gas(&nl->EntryTrigger);
1006ebc22d04SAlexander Motin 	printf("\n\tResidency=%u\n", nl->Residency);
10075857fba5SBen Widawsky 	printf("\tLatency=%u\n", nl->Latency);
10085857fba5SBen Widawsky 	if (nl->Header.Flags & ACPI_LPIT_NO_COUNTER)
10095857fba5SBen Widawsky 		printf("\tResidencyCounter=Not Present");
10105857fba5SBen Widawsky 	else {
10115857fba5SBen Widawsky 		printf("\tResidencyCounter=");
10125857fba5SBen Widawsky 		acpi_print_gas(&nl->ResidencyCounter);
1013ebc22d04SAlexander Motin 		printf("\n");
10145857fba5SBen Widawsky 	}
10155857fba5SBen Widawsky 	if (nl->CounterFrequency)
10165857fba5SBen Widawsky 		printf("\tCounterFrequency=%ju\n", nl->CounterFrequency);
10175857fba5SBen Widawsky 	else
10185857fba5SBen Widawsky 		printf("\tCounterFrequency=TSC\n");
10195857fba5SBen Widawsky }
10205857fba5SBen Widawsky 
10215857fba5SBen Widawsky static void
10225857fba5SBen Widawsky acpi_print_lpit(ACPI_LPIT_HEADER *lpit)
10235857fba5SBen Widawsky {
10245857fba5SBen Widawsky 	if (lpit->Type == ACPI_LPIT_TYPE_NATIVE_CSTATE)
10255857fba5SBen Widawsky 		printf("\tType=ACPI_LPIT_TYPE_NATIVE_CSTATE\n");
10265857fba5SBen Widawsky 	else
10275857fba5SBen Widawsky 		warnx("unknown LPIT type %u", lpit->Type);
10285857fba5SBen Widawsky 
10295857fba5SBen Widawsky 	printf("\tLength=%u\n", lpit->Length);
10305857fba5SBen Widawsky 	printf("\tUniqueId=0x%04x\n", lpit->UniqueId);
10315857fba5SBen Widawsky #define	PRINTFLAG(var, flag)	printflag((var), ACPI_LPIT_## flag, #flag)
10325857fba5SBen Widawsky 	printf("\tFlags=");
10335857fba5SBen Widawsky 	PRINTFLAG(lpit->Flags, STATE_DISABLED);
10345857fba5SBen Widawsky 	PRINTFLAG_END();
10355857fba5SBen Widawsky #undef PRINTFLAG
10365857fba5SBen Widawsky 
10375857fba5SBen Widawsky 	if (lpit->Type == ACPI_LPIT_TYPE_NATIVE_CSTATE)
10385857fba5SBen Widawsky 		return acpi_print_native_lpit((ACPI_LPIT_NATIVE *)lpit);
10395857fba5SBen Widawsky }
10405857fba5SBen Widawsky 
10415857fba5SBen Widawsky static void
10425857fba5SBen Widawsky acpi_walk_lpit(ACPI_TABLE_HEADER *table, void *first,
10435857fba5SBen Widawsky     void (*action)(ACPI_LPIT_HEADER *))
10445857fba5SBen Widawsky {
10455857fba5SBen Widawsky 	ACPI_LPIT_HEADER *subtable;
10465857fba5SBen Widawsky 	char *end;
10475857fba5SBen Widawsky 
10485857fba5SBen Widawsky 	subtable = first;
10495857fba5SBen Widawsky 	end = (char *)table + table->Length;
10505857fba5SBen Widawsky 	while ((char *)subtable < end) {
10515857fba5SBen Widawsky 		printf("\n");
10525857fba5SBen Widawsky 		if (subtable->Length < sizeof(ACPI_LPIT_HEADER)) {
10535857fba5SBen Widawsky 			warnx("invalid subtable length %u", subtable->Length);
10545857fba5SBen Widawsky 			return;
10555857fba5SBen Widawsky 		}
10565857fba5SBen Widawsky 		action(subtable);
10575857fba5SBen Widawsky 		subtable = (ACPI_LPIT_HEADER *)((char *)subtable +
10585857fba5SBen Widawsky 		    subtable->Length);
10595857fba5SBen Widawsky 	}
10605857fba5SBen Widawsky }
10615857fba5SBen Widawsky 
10625857fba5SBen Widawsky static void
10635857fba5SBen Widawsky acpi_handle_lpit(ACPI_TABLE_HEADER *sdp)
10645857fba5SBen Widawsky {
10655857fba5SBen Widawsky 	ACPI_TABLE_LPIT *lpit;
10665857fba5SBen Widawsky 
10675857fba5SBen Widawsky 	printf(BEGIN_COMMENT);
10685857fba5SBen Widawsky 	acpi_print_sdt(sdp);
10695857fba5SBen Widawsky 	lpit = (ACPI_TABLE_LPIT *)sdp;
10705857fba5SBen Widawsky 	acpi_walk_lpit(sdp, (lpit + 1), acpi_print_lpit);
10715857fba5SBen Widawsky 
10725857fba5SBen Widawsky 	printf(END_COMMENT);
10735857fba5SBen Widawsky }
10745857fba5SBen Widawsky 
10755857fba5SBen Widawsky static void
1076a0333ad1SJohn Baldwin acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain,
1077a0333ad1SJohn Baldwin     uint32_t flags)
1078a0333ad1SJohn Baldwin {
1079a0333ad1SJohn Baldwin 
1080a0333ad1SJohn Baldwin 	printf("\tFlags={");
1081a0333ad1SJohn Baldwin 	if (flags & ACPI_SRAT_CPU_ENABLED)
1082a0333ad1SJohn Baldwin 		printf("ENABLED");
1083a0333ad1SJohn Baldwin 	else
1084a0333ad1SJohn Baldwin 		printf("DISABLED");
1085a0333ad1SJohn Baldwin 	printf("}\n");
1086a0333ad1SJohn Baldwin 	printf("\tAPIC ID=%d\n", apic_id);
1087a0333ad1SJohn Baldwin 	printf("\tProximity Domain=%d\n", proximity_domain);
1088a0333ad1SJohn Baldwin }
1089a0333ad1SJohn Baldwin 
1090c031c93bSTakanori Watanabe static char *
1091c031c93bSTakanori Watanabe acpi_tcpa_evname(struct TCPAevent *event)
1092c031c93bSTakanori Watanabe {
1093c031c93bSTakanori Watanabe 	struct TCPApc_event *pc_event;
1094c031c93bSTakanori Watanabe 	char *eventname = NULL;
1095c031c93bSTakanori Watanabe 
1096c031c93bSTakanori Watanabe 	pc_event = (struct TCPApc_event *)(event + 1);
1097c031c93bSTakanori Watanabe 
1098c031c93bSTakanori Watanabe 	switch(event->event_type) {
1099c031c93bSTakanori Watanabe 	case PREBOOT:
1100c031c93bSTakanori Watanabe 	case POST_CODE:
1101c031c93bSTakanori Watanabe 	case UNUSED:
1102c031c93bSTakanori Watanabe 	case NO_ACTION:
1103c031c93bSTakanori Watanabe 	case SEPARATOR:
1104c031c93bSTakanori Watanabe 	case SCRTM_CONTENTS:
1105c031c93bSTakanori Watanabe 	case SCRTM_VERSION:
1106c031c93bSTakanori Watanabe 	case CPU_MICROCODE:
1107c031c93bSTakanori Watanabe 	case PLATFORM_CONFIG_FLAGS:
1108c031c93bSTakanori Watanabe 	case TABLE_OF_DEVICES:
1109c031c93bSTakanori Watanabe 	case COMPACT_HASH:
1110c031c93bSTakanori Watanabe 	case IPL:
1111c031c93bSTakanori Watanabe 	case IPL_PARTITION_DATA:
1112c031c93bSTakanori Watanabe 	case NONHOST_CODE:
1113c031c93bSTakanori Watanabe 	case NONHOST_CONFIG:
1114c031c93bSTakanori Watanabe 	case NONHOST_INFO:
1115c031c93bSTakanori Watanabe 		asprintf(&eventname, "%s",
1116c031c93bSTakanori Watanabe 		    tcpa_event_type_strings[event->event_type]);
1117c031c93bSTakanori Watanabe 		break;
1118c031c93bSTakanori Watanabe 
1119c031c93bSTakanori Watanabe 	case ACTION:
1120c031c93bSTakanori Watanabe 		eventname = calloc(event->event_size + 1, sizeof(char));
1121c031c93bSTakanori Watanabe 		memcpy(eventname, pc_event, event->event_size);
1122c031c93bSTakanori Watanabe 		break;
1123c031c93bSTakanori Watanabe 
1124c031c93bSTakanori Watanabe 	case EVENT_TAG:
1125c031c93bSTakanori Watanabe 		switch (pc_event->event_id) {
1126c031c93bSTakanori Watanabe 		case SMBIOS:
1127c031c93bSTakanori Watanabe 		case BIS_CERT:
1128c031c93bSTakanori Watanabe 		case CMOS:
1129c031c93bSTakanori Watanabe 		case NVRAM:
1130c031c93bSTakanori Watanabe 		case OPTION_ROM_EXEC:
1131c031c93bSTakanori Watanabe 		case OPTION_ROM_CONFIG:
1132c031c93bSTakanori Watanabe 		case S_CRTM_VERSION:
1133c031c93bSTakanori Watanabe 		case POST_BIOS_ROM:
1134c031c93bSTakanori Watanabe 		case ESCD:
1135c031c93bSTakanori Watanabe 		case OPTION_ROM_MICROCODE:
1136c031c93bSTakanori Watanabe 		case S_CRTM_CONTENTS:
1137c031c93bSTakanori Watanabe 		case POST_CONTENTS:
1138c031c93bSTakanori Watanabe 			asprintf(&eventname, "%s",
1139c031c93bSTakanori Watanabe 			    TCPA_pcclient_strings[pc_event->event_id]);
1140c031c93bSTakanori Watanabe 			break;
1141c031c93bSTakanori Watanabe 
1142c031c93bSTakanori Watanabe 		default:
1143c031c93bSTakanori Watanabe 			asprintf(&eventname, "<unknown tag 0x%02x>",
1144c031c93bSTakanori Watanabe 			    pc_event->event_id);
1145c031c93bSTakanori Watanabe 			break;
1146c031c93bSTakanori Watanabe 		}
1147c031c93bSTakanori Watanabe 		break;
1148c031c93bSTakanori Watanabe 
1149c031c93bSTakanori Watanabe 	default:
1150c031c93bSTakanori Watanabe 		asprintf(&eventname, "<unknown 0x%02x>", event->event_type);
1151c031c93bSTakanori Watanabe 		break;
1152c031c93bSTakanori Watanabe 	}
1153c031c93bSTakanori Watanabe 
1154c031c93bSTakanori Watanabe 	return eventname;
1155c031c93bSTakanori Watanabe }
1156c031c93bSTakanori Watanabe 
1157c031c93bSTakanori Watanabe static void
1158c031c93bSTakanori Watanabe acpi_print_tcpa(struct TCPAevent *event)
1159c031c93bSTakanori Watanabe {
1160c031c93bSTakanori Watanabe 	int i;
1161c031c93bSTakanori Watanabe 	char *eventname;
1162c031c93bSTakanori Watanabe 
1163c031c93bSTakanori Watanabe 	eventname = acpi_tcpa_evname(event);
1164c031c93bSTakanori Watanabe 
1165c031c93bSTakanori Watanabe 	printf("\t%d", event->pcr_index);
1166c031c93bSTakanori Watanabe 	printf(" 0x");
1167c031c93bSTakanori Watanabe 	for (i = 0; i < 20; i++)
1168c031c93bSTakanori Watanabe 		printf("%02x", event->pcr_value[i]);
1169c031c93bSTakanori Watanabe 	printf(" [%s]\n", eventname ? eventname : "<unknown>");
1170c031c93bSTakanori Watanabe 
1171c031c93bSTakanori Watanabe 	free(eventname);
1172c031c93bSTakanori Watanabe }
1173c031c93bSTakanori Watanabe 
1174c031c93bSTakanori Watanabe static void
1175c031c93bSTakanori Watanabe acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp)
1176c031c93bSTakanori Watanabe {
1177c031c93bSTakanori Watanabe 	struct TCPAbody *tcpa;
1178c031c93bSTakanori Watanabe 	struct TCPAevent *event;
1179977fd9daSTakanori Watanabe 	uintmax_t len, paddr;
1180c031c93bSTakanori Watanabe 	unsigned char *vaddr = NULL;
1181c031c93bSTakanori Watanabe 	unsigned char *vend = NULL;
1182c031c93bSTakanori Watanabe 
1183c031c93bSTakanori Watanabe 	printf(BEGIN_COMMENT);
1184c031c93bSTakanori Watanabe 	acpi_print_sdt(sdp);
1185c031c93bSTakanori Watanabe 	tcpa = (struct TCPAbody *) sdp;
1186c031c93bSTakanori Watanabe 
1187c031c93bSTakanori Watanabe 	switch (tcpa->platform_class) {
1188c031c93bSTakanori Watanabe 	case ACPI_TCPA_BIOS_CLIENT:
1189c031c93bSTakanori Watanabe 		len = tcpa->client.log_max_len;
1190c031c93bSTakanori Watanabe 		paddr = tcpa->client.log_start_addr;
1191c031c93bSTakanori Watanabe 		break;
1192c031c93bSTakanori Watanabe 
1193c031c93bSTakanori Watanabe 	case ACPI_TCPA_BIOS_SERVER:
1194c031c93bSTakanori Watanabe 		len = tcpa->server.log_max_len;
1195c031c93bSTakanori Watanabe 		paddr = tcpa->server.log_start_addr;
1196c031c93bSTakanori Watanabe 		break;
1197c031c93bSTakanori Watanabe 
1198c031c93bSTakanori Watanabe 	default:
1199c031c93bSTakanori Watanabe 		printf("XXX");
1200c031c93bSTakanori Watanabe 		printf(END_COMMENT);
1201c031c93bSTakanori Watanabe 		return;
1202c031c93bSTakanori Watanabe 	}
12030e1982f4STakanori Watanabe 	printf("\tClass %u Base Address 0x%jx Length %ju\n\n",
1204c031c93bSTakanori Watanabe 	    tcpa->platform_class, paddr, len);
1205c031c93bSTakanori Watanabe 
1206c031c93bSTakanori Watanabe 	if (len == 0) {
1207c031c93bSTakanori Watanabe 		printf("\tEmpty TCPA table\n");
1208c031c93bSTakanori Watanabe 		printf(END_COMMENT);
1209c031c93bSTakanori Watanabe 		return;
1210c031c93bSTakanori Watanabe 	}
12112ef23c6dSTakanori Watanabe 	if(sdp->Revision == 1){
12122ef23c6dSTakanori Watanabe 		printf("\tOLD TCPA spec log found. Dumping not supported.\n");
12132ef23c6dSTakanori Watanabe 		printf(END_COMMENT);
12142ef23c6dSTakanori Watanabe 		return;
12152ef23c6dSTakanori Watanabe 	}
1216c031c93bSTakanori Watanabe 
1217c031c93bSTakanori Watanabe 	vaddr = (unsigned char *)acpi_map_physical(paddr, len);
1218c031c93bSTakanori Watanabe 	vend = vaddr + len;
1219c031c93bSTakanori Watanabe 
1220c031c93bSTakanori Watanabe 	while (vaddr != NULL) {
12212ef23c6dSTakanori Watanabe 		if ((vaddr + sizeof(struct TCPAevent) >= vend)||
12222ef23c6dSTakanori Watanabe 		    (vaddr + sizeof(struct TCPAevent) < vaddr))
1223c031c93bSTakanori Watanabe 			break;
12240e1982f4STakanori Watanabe 		event = (struct TCPAevent *)(void *)vaddr;
1225c031c93bSTakanori Watanabe 		if (vaddr + event->event_size >= vend)
1226c031c93bSTakanori Watanabe 			break;
12272ef23c6dSTakanori Watanabe 		if (vaddr + event->event_size < vaddr)
12282ef23c6dSTakanori Watanabe 			break;
1229c031c93bSTakanori Watanabe 		if (event->event_type == 0 && event->event_size == 0)
1230c031c93bSTakanori Watanabe 			break;
1231c031c93bSTakanori Watanabe #if 0
1232c031c93bSTakanori Watanabe 		{
1233c031c93bSTakanori Watanabe 		unsigned int i, j, k;
1234c031c93bSTakanori Watanabe 
1235c031c93bSTakanori Watanabe 		printf("\n\tsize %d\n\t\t%p ", event->event_size, vaddr);
1236c031c93bSTakanori Watanabe 		for (j = 0, i = 0; i <
1237c031c93bSTakanori Watanabe 		    sizeof(struct TCPAevent) + event->event_size; i++) {
1238c031c93bSTakanori Watanabe 			printf("%02x ", vaddr[i]);
1239c031c93bSTakanori Watanabe 			if ((i+1) % 8 == 0) {
1240c031c93bSTakanori Watanabe 				for (k = 0; k < 8; k++)
1241c031c93bSTakanori Watanabe 					printf("%c", isprint(vaddr[j+k]) ?
1242c031c93bSTakanori Watanabe 					    vaddr[j+k] : '.');
1243c031c93bSTakanori Watanabe 				printf("\n\t\t%p ", &vaddr[i + 1]);
1244c031c93bSTakanori Watanabe 				j = i + 1;
1245c031c93bSTakanori Watanabe 			}
1246c031c93bSTakanori Watanabe 		}
1247c031c93bSTakanori Watanabe 		printf("\n"); }
1248c031c93bSTakanori Watanabe #endif
1249c031c93bSTakanori Watanabe 		acpi_print_tcpa(event);
1250c031c93bSTakanori Watanabe 
1251c031c93bSTakanori Watanabe 		vaddr += sizeof(struct TCPAevent) + event->event_size;
1252c031c93bSTakanori Watanabe 	}
1253c031c93bSTakanori Watanabe 
1254c031c93bSTakanori Watanabe 	printf(END_COMMENT);
1255c031c93bSTakanori Watanabe }
1256877fc2e3STakanori Watanabe static void acpi_handle_tpm2(ACPI_TABLE_HEADER *sdp)
1257877fc2e3STakanori Watanabe {
1258877fc2e3STakanori Watanabe 	ACPI_TABLE_TPM2 *tpm2;
1259877fc2e3STakanori Watanabe 
1260877fc2e3STakanori Watanabe 	printf (BEGIN_COMMENT);
1261877fc2e3STakanori Watanabe 	acpi_print_sdt(sdp);
1262877fc2e3STakanori Watanabe 	tpm2 = (ACPI_TABLE_TPM2 *) sdp;
12637aef7138SCy Schubert 	printf ("\t\tControlArea=%jx\n", tpm2->ControlAddress);
1264877fc2e3STakanori Watanabe 	printf ("\t\tStartMethod=%x\n", tpm2->StartMethod);
1265877fc2e3STakanori Watanabe 	printf (END_COMMENT);
1266877fc2e3STakanori Watanabe }
1267c031c93bSTakanori Watanabe 
1268ec650989SNeel Natu static const char *
1269ec650989SNeel Natu devscope_type2str(int type)
1270ec650989SNeel Natu {
1271ec650989SNeel Natu 	static char typebuf[16];
1272ec650989SNeel Natu 
1273ec650989SNeel Natu 	switch (type) {
1274ec650989SNeel Natu 	case 1:
1275ec650989SNeel Natu 		return ("PCI Endpoint Device");
1276ec650989SNeel Natu 	case 2:
1277ec650989SNeel Natu 		return ("PCI Sub-Hierarchy");
1278ec650989SNeel Natu 	case 3:
1279ec650989SNeel Natu 		return ("IOAPIC");
1280ec650989SNeel Natu 	case 4:
1281ec650989SNeel Natu 		return ("HPET");
1282ec650989SNeel Natu 	default:
1283ec650989SNeel Natu 		snprintf(typebuf, sizeof(typebuf), "%d", type);
1284ec650989SNeel Natu 		return (typebuf);
1285ec650989SNeel Natu 	}
1286ec650989SNeel Natu }
1287ec650989SNeel Natu 
1288ec650989SNeel Natu static int
1289ec650989SNeel Natu acpi_handle_dmar_devscope(void *addr, int remaining)
1290ec650989SNeel Natu {
1291ec650989SNeel Natu 	char sep;
1292ec650989SNeel Natu 	int pathlen;
1293ec650989SNeel Natu 	ACPI_DMAR_PCI_PATH *path, *pathend;
1294ec650989SNeel Natu 	ACPI_DMAR_DEVICE_SCOPE *devscope = addr;
1295ec650989SNeel Natu 
1296ec650989SNeel Natu 	if (remaining < (int)sizeof(ACPI_DMAR_DEVICE_SCOPE))
1297ec650989SNeel Natu 		return (-1);
1298ec650989SNeel Natu 
1299ec650989SNeel Natu 	if (remaining < devscope->Length)
1300ec650989SNeel Natu 		return (-1);
1301ec650989SNeel Natu 
1302ec650989SNeel Natu 	printf("\n");
1303ec650989SNeel Natu 	printf("\t\tType=%s\n", devscope_type2str(devscope->EntryType));
1304ec650989SNeel Natu 	printf("\t\tLength=%d\n", devscope->Length);
1305ec650989SNeel Natu 	printf("\t\tEnumerationId=%d\n", devscope->EnumerationId);
1306ec650989SNeel Natu 	printf("\t\tStartBusNumber=%d\n", devscope->Bus);
1307ec650989SNeel Natu 
1308ec650989SNeel Natu 	path = (ACPI_DMAR_PCI_PATH *)(devscope + 1);
1309ec650989SNeel Natu 	pathlen = devscope->Length - sizeof(ACPI_DMAR_DEVICE_SCOPE);
1310ec650989SNeel Natu 	pathend = path + pathlen / sizeof(ACPI_DMAR_PCI_PATH);
1311ec650989SNeel Natu 	if (path < pathend) {
1312ec650989SNeel Natu 		sep = '{';
1313ec650989SNeel Natu 		printf("\t\tPath=");
1314ec650989SNeel Natu 		do {
1315ec650989SNeel Natu 			printf("%c%d:%d", sep, path->Device, path->Function);
1316ec650989SNeel Natu 			sep=',';
1317ec650989SNeel Natu 			path++;
1318ec650989SNeel Natu 		} while (path < pathend);
1319ec650989SNeel Natu 		printf("}\n");
1320ec650989SNeel Natu 	}
1321ec650989SNeel Natu 
1322ec650989SNeel Natu 	return (devscope->Length);
1323ec650989SNeel Natu }
1324ec650989SNeel Natu 
1325ec650989SNeel Natu static void
1326ec650989SNeel Natu acpi_handle_dmar_drhd(ACPI_DMAR_HARDWARE_UNIT *drhd)
1327ec650989SNeel Natu {
1328ec650989SNeel Natu 	char *cp;
1329ec650989SNeel Natu 	int remaining, consumed;
1330ec650989SNeel Natu 
1331ec650989SNeel Natu 	printf("\n");
1332ec650989SNeel Natu 	printf("\tType=DRHD\n");
1333ec650989SNeel Natu 	printf("\tLength=%d\n", drhd->Header.Length);
1334ec650989SNeel Natu 
1335ec650989SNeel Natu #define	PRINTFLAG(var, flag)	printflag((var), ACPI_DMAR_## flag, #flag)
1336ec650989SNeel Natu 
1337ec650989SNeel Natu 	printf("\tFlags=");
1338ec650989SNeel Natu 	PRINTFLAG(drhd->Flags, INCLUDE_ALL);
1339ec650989SNeel Natu 	PRINTFLAG_END();
1340ec650989SNeel Natu 
1341ec650989SNeel Natu #undef PRINTFLAG
1342ec650989SNeel Natu 
1343ec650989SNeel Natu 	printf("\tSegment=%d\n", drhd->Segment);
13447d369c6eSJung-uk Kim 	printf("\tAddress=0x%016jx\n", (uintmax_t)drhd->Address);
1345ec650989SNeel Natu 
1346ec650989SNeel Natu 	remaining = drhd->Header.Length - sizeof(ACPI_DMAR_HARDWARE_UNIT);
1347ec650989SNeel Natu 	if (remaining > 0)
1348ec650989SNeel Natu 		printf("\tDevice Scope:");
1349ec650989SNeel Natu 	while (remaining > 0) {
1350ec650989SNeel Natu 		cp = (char *)drhd + drhd->Header.Length - remaining;
1351ec650989SNeel Natu 		consumed = acpi_handle_dmar_devscope(cp, remaining);
1352ec650989SNeel Natu 		if (consumed <= 0)
1353ec650989SNeel Natu 			break;
1354ec650989SNeel Natu 		else
1355ec650989SNeel Natu 			remaining -= consumed;
1356ec650989SNeel Natu 	}
1357ec650989SNeel Natu }
1358ec650989SNeel Natu 
1359ec650989SNeel Natu static void
1360ec650989SNeel Natu acpi_handle_dmar_rmrr(ACPI_DMAR_RESERVED_MEMORY *rmrr)
1361ec650989SNeel Natu {
1362ec650989SNeel Natu 	char *cp;
1363ec650989SNeel Natu 	int remaining, consumed;
1364ec650989SNeel Natu 
1365ec650989SNeel Natu 	printf("\n");
1366ec650989SNeel Natu 	printf("\tType=RMRR\n");
1367ec650989SNeel Natu 	printf("\tLength=%d\n", rmrr->Header.Length);
1368ec650989SNeel Natu 	printf("\tSegment=%d\n", rmrr->Segment);
13697d369c6eSJung-uk Kim 	printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rmrr->BaseAddress);
13707d369c6eSJung-uk Kim 	printf("\tLimitAddress=0x%016jx\n", (uintmax_t)rmrr->EndAddress);
1371ec650989SNeel Natu 
1372ec650989SNeel Natu 	remaining = rmrr->Header.Length - sizeof(ACPI_DMAR_RESERVED_MEMORY);
1373ec650989SNeel Natu 	if (remaining > 0)
1374ec650989SNeel Natu 		printf("\tDevice Scope:");
1375ec650989SNeel Natu 	while (remaining > 0) {
1376ec650989SNeel Natu 		cp = (char *)rmrr + rmrr->Header.Length - remaining;
1377ec650989SNeel Natu 		consumed = acpi_handle_dmar_devscope(cp, remaining);
1378ec650989SNeel Natu 		if (consumed <= 0)
1379ec650989SNeel Natu 			break;
1380ec650989SNeel Natu 		else
1381ec650989SNeel Natu 			remaining -= consumed;
1382ec650989SNeel Natu 	}
1383ec650989SNeel Natu }
1384ec650989SNeel Natu 
1385ec650989SNeel Natu static void
1386ec650989SNeel Natu acpi_handle_dmar_atsr(ACPI_DMAR_ATSR *atsr)
1387ec650989SNeel Natu {
1388ec650989SNeel Natu 	char *cp;
1389ec650989SNeel Natu 	int remaining, consumed;
1390ec650989SNeel Natu 
1391ec650989SNeel Natu 	printf("\n");
1392ec650989SNeel Natu 	printf("\tType=ATSR\n");
1393ec650989SNeel Natu 	printf("\tLength=%d\n", atsr->Header.Length);
1394ec650989SNeel Natu 
1395ec650989SNeel Natu #define	PRINTFLAG(var, flag)	printflag((var), ACPI_DMAR_## flag, #flag)
1396ec650989SNeel Natu 
1397ec650989SNeel Natu 	printf("\tFlags=");
1398ec650989SNeel Natu 	PRINTFLAG(atsr->Flags, ALL_PORTS);
1399ec650989SNeel Natu 	PRINTFLAG_END();
1400ec650989SNeel Natu 
1401ec650989SNeel Natu #undef PRINTFLAG
1402ec650989SNeel Natu 
1403ec650989SNeel Natu 	printf("\tSegment=%d\n", atsr->Segment);
1404ec650989SNeel Natu 
1405ec650989SNeel Natu 	remaining = atsr->Header.Length - sizeof(ACPI_DMAR_ATSR);
1406ec650989SNeel Natu 	if (remaining > 0)
1407ec650989SNeel Natu 		printf("\tDevice Scope:");
1408ec650989SNeel Natu 	while (remaining > 0) {
1409ec650989SNeel Natu 		cp = (char *)atsr + atsr->Header.Length - remaining;
1410ec650989SNeel Natu 		consumed = acpi_handle_dmar_devscope(cp, remaining);
1411ec650989SNeel Natu 		if (consumed <= 0)
1412ec650989SNeel Natu 			break;
1413ec650989SNeel Natu 		else
1414ec650989SNeel Natu 			remaining -= consumed;
1415ec650989SNeel Natu 	}
1416ec650989SNeel Natu }
1417ec650989SNeel Natu 
1418ec650989SNeel Natu static void
1419ec650989SNeel Natu acpi_handle_dmar_rhsa(ACPI_DMAR_RHSA *rhsa)
1420ec650989SNeel Natu {
1421ec650989SNeel Natu 
1422ec650989SNeel Natu 	printf("\n");
1423ec650989SNeel Natu 	printf("\tType=RHSA\n");
1424ec650989SNeel Natu 	printf("\tLength=%d\n", rhsa->Header.Length);
14257d369c6eSJung-uk Kim 	printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rhsa->BaseAddress);
1426ec650989SNeel Natu 	printf("\tProximityDomain=0x%08x\n", rhsa->ProximityDomain);
1427ec650989SNeel Natu }
1428ec650989SNeel Natu 
1429ec650989SNeel Natu static int
1430ec650989SNeel Natu acpi_handle_dmar_remapping_structure(void *addr, int remaining)
1431ec650989SNeel Natu {
1432ec650989SNeel Natu 	ACPI_DMAR_HEADER *hdr = addr;
1433ec650989SNeel Natu 
1434ec650989SNeel Natu 	if (remaining < (int)sizeof(ACPI_DMAR_HEADER))
1435ec650989SNeel Natu 		return (-1);
1436ec650989SNeel Natu 
1437ec650989SNeel Natu 	if (remaining < hdr->Length)
1438ec650989SNeel Natu 		return (-1);
1439ec650989SNeel Natu 
1440ec650989SNeel Natu 	switch (hdr->Type) {
1441ec650989SNeel Natu 	case ACPI_DMAR_TYPE_HARDWARE_UNIT:
1442ec650989SNeel Natu 		acpi_handle_dmar_drhd(addr);
1443ec650989SNeel Natu 		break;
1444ec650989SNeel Natu 	case ACPI_DMAR_TYPE_RESERVED_MEMORY:
1445ec650989SNeel Natu 		acpi_handle_dmar_rmrr(addr);
1446ec650989SNeel Natu 		break;
1447313a0c13SJung-uk Kim 	case ACPI_DMAR_TYPE_ROOT_ATS:
1448ec650989SNeel Natu 		acpi_handle_dmar_atsr(addr);
1449ec650989SNeel Natu 		break;
1450313a0c13SJung-uk Kim 	case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
1451ec650989SNeel Natu 		acpi_handle_dmar_rhsa(addr);
1452ec650989SNeel Natu 		break;
1453ec650989SNeel Natu 	default:
1454ec650989SNeel Natu 		printf("\n");
1455ec650989SNeel Natu 		printf("\tType=%d\n", hdr->Type);
1456ec650989SNeel Natu 		printf("\tLength=%d\n", hdr->Length);
1457ec650989SNeel Natu 		break;
1458ec650989SNeel Natu 	}
1459ec650989SNeel Natu 	return (hdr->Length);
1460ec650989SNeel Natu }
1461ec650989SNeel Natu 
1462ec650989SNeel Natu #ifndef ACPI_DMAR_X2APIC_OPT_OUT
1463ec650989SNeel Natu #define	ACPI_DMAR_X2APIC_OPT_OUT	(0x2)
1464ec650989SNeel Natu #endif
1465ec650989SNeel Natu 
1466ec650989SNeel Natu static void
1467ec650989SNeel Natu acpi_handle_dmar(ACPI_TABLE_HEADER *sdp)
1468ec650989SNeel Natu {
1469ec650989SNeel Natu 	char *cp;
1470ec650989SNeel Natu 	int remaining, consumed;
1471ec650989SNeel Natu 	ACPI_TABLE_DMAR *dmar;
1472ec650989SNeel Natu 
1473ec650989SNeel Natu 	printf(BEGIN_COMMENT);
1474ec650989SNeel Natu 	acpi_print_sdt(sdp);
1475ec650989SNeel Natu 	dmar = (ACPI_TABLE_DMAR *)sdp;
1476ec650989SNeel Natu 	printf("\tHost Address Width=%d\n", dmar->Width + 1);
1477ec650989SNeel Natu 
1478ec650989SNeel Natu #define PRINTFLAG(var, flag)	printflag((var), ACPI_DMAR_## flag, #flag)
1479ec650989SNeel Natu 
1480ec650989SNeel Natu 	printf("\tFlags=");
1481ec650989SNeel Natu 	PRINTFLAG(dmar->Flags, INTR_REMAP);
1482ec650989SNeel Natu 	PRINTFLAG(dmar->Flags, X2APIC_OPT_OUT);
1483ec650989SNeel Natu 	PRINTFLAG_END();
1484ec650989SNeel Natu 
1485ec650989SNeel Natu #undef PRINTFLAG
1486ec650989SNeel Natu 
1487ec650989SNeel Natu 	remaining = sdp->Length - sizeof(ACPI_TABLE_DMAR);
1488ec650989SNeel Natu 	while (remaining > 0) {
1489ec650989SNeel Natu 		cp = (char *)sdp + sdp->Length - remaining;
1490ec650989SNeel Natu 		consumed = acpi_handle_dmar_remapping_structure(cp, remaining);
1491ec650989SNeel Natu 		if (consumed <= 0)
1492ec650989SNeel Natu 			break;
1493ec650989SNeel Natu 		else
1494ec650989SNeel Natu 			remaining -= consumed;
1495ec650989SNeel Natu 	}
1496ec650989SNeel Natu 
1497ec650989SNeel Natu 	printf(END_COMMENT);
1498ec650989SNeel Natu }
1499ec650989SNeel Natu 
1500a0333ad1SJohn Baldwin static void
1501*6d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_header(ACPI_IVRS_HEADER *addr)
1502*6d789b61SKonstantin Belousov {
1503*6d789b61SKonstantin Belousov 	printf("\n\tIVHD Type=%#x IOMMUId=%x\n\tFlags=",
1504*6d789b61SKonstantin Belousov 	    addr->Type, addr->DeviceId);
1505*6d789b61SKonstantin Belousov #define PRINTFLAG(flag, name) printflag(addr->Flags, flag, #name)
1506*6d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVHD_TT_ENABLE, HtTunEn);
1507*6d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVHD_ISOC, PassPW);
1508*6d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVHD_RES_PASS_PW, ResPassPW);
1509*6d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVHD_ISOC, Isoc);
1510*6d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVHD_TT_ENABLE, IotlbSup);
1511*6d789b61SKonstantin Belousov 	PRINTFLAG((1 << 5), Coherent);
1512*6d789b61SKonstantin Belousov 	PRINTFLAG((1 << 6), PreFSup);
1513*6d789b61SKonstantin Belousov 	PRINTFLAG((1 << 7), PPRSup);
1514*6d789b61SKonstantin Belousov #undef PRINTFLAG
1515*6d789b61SKonstantin Belousov 	PRINTFLAG_END();
1516*6d789b61SKonstantin Belousov }
1517*6d789b61SKonstantin Belousov 
1518*6d789b61SKonstantin Belousov static void
1519*6d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_dte(UINT8 dte)
1520*6d789b61SKonstantin Belousov {
1521*6d789b61SKonstantin Belousov 	if (dte == 0) {
1522*6d789b61SKonstantin Belousov 		printf("\n");
1523*6d789b61SKonstantin Belousov 		return;
1524*6d789b61SKonstantin Belousov 	}
1525*6d789b61SKonstantin Belousov 	printf(" DTE=");
1526*6d789b61SKonstantin Belousov #define PRINTFLAG(flag, name) printflag(dte, flag, #name)
1527*6d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVHD_INIT_PASS, INITPass);
1528*6d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVHD_EINT_PASS, EIntPass);
1529*6d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVHD_NMI_PASS, NMIPass);
1530*6d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVHD_SYSTEM_MGMT, SysMgtPass);
1531*6d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVHD_LINT0_PASS, Lint0Pass);
1532*6d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVHD_LINT1_PASS, Lint1Pass);
1533*6d789b61SKonstantin Belousov #undef PRINTFLAG
1534*6d789b61SKonstantin Belousov 	PRINTFLAG_END();
1535*6d789b61SKonstantin Belousov }
1536*6d789b61SKonstantin Belousov 
1537*6d789b61SKonstantin Belousov static void
1538*6d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_edte(UINT32 edte)
1539*6d789b61SKonstantin Belousov {
1540*6d789b61SKonstantin Belousov 	if (edte == 0)
1541*6d789b61SKonstantin Belousov 		return;
1542*6d789b61SKonstantin Belousov 	printf("\t\t ExtDTE=");
1543*6d789b61SKonstantin Belousov #define PRINTFLAG(flag, name) printflag(edte, flag, #name)
1544*6d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVHD_ATS_DISABLED, AtsDisabled);
1545*6d789b61SKonstantin Belousov #undef PRINTFLAG
1546*6d789b61SKonstantin Belousov 	PRINTFLAG_END();
1547*6d789b61SKonstantin Belousov }
1548*6d789b61SKonstantin Belousov 
1549*6d789b61SKonstantin Belousov static const char *
1550*6d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_variety(UINT8 v)
1551*6d789b61SKonstantin Belousov {
1552*6d789b61SKonstantin Belousov 	switch (v) {
1553*6d789b61SKonstantin Belousov 	case ACPI_IVHD_IOAPIC:
1554*6d789b61SKonstantin Belousov 		return ("IOAPIC");
1555*6d789b61SKonstantin Belousov 	case ACPI_IVHD_HPET:
1556*6d789b61SKonstantin Belousov 		return ("HPET");
1557*6d789b61SKonstantin Belousov 	default:
1558*6d789b61SKonstantin Belousov 		return ("UNKNOWN");
1559*6d789b61SKonstantin Belousov 	}
1560*6d789b61SKonstantin Belousov }
1561*6d789b61SKonstantin Belousov 
1562*6d789b61SKonstantin Belousov static void
1563*6d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_devs(ACPI_IVRS_DE_HEADER *d, char *de)
1564*6d789b61SKonstantin Belousov {
1565*6d789b61SKonstantin Belousov 	char *db;
1566*6d789b61SKonstantin Belousov 	ACPI_IVRS_DEVICE4 *d4;
1567*6d789b61SKonstantin Belousov 	ACPI_IVRS_DEVICE8A *d8a;
1568*6d789b61SKonstantin Belousov 	ACPI_IVRS_DEVICE8B *d8b;
1569*6d789b61SKonstantin Belousov 	ACPI_IVRS_DEVICE8C *d8c;
1570*6d789b61SKonstantin Belousov 	ACPI_IVRS_DEVICE_HID *dh;
1571*6d789b61SKonstantin Belousov 	size_t len;
1572*6d789b61SKonstantin Belousov 	UINT32 x32;
1573*6d789b61SKonstantin Belousov 
1574*6d789b61SKonstantin Belousov 	for (; (char *)d < de; d = (ACPI_IVRS_DE_HEADER *)(db + len)) {
1575*6d789b61SKonstantin Belousov 		db = (char *)d;
1576*6d789b61SKonstantin Belousov 		if (d->Type == ACPI_IVRS_TYPE_PAD4) {
1577*6d789b61SKonstantin Belousov 			len = sizeof(*d4);
1578*6d789b61SKonstantin Belousov 		} else if (d->Type == ACPI_IVRS_TYPE_ALL) {
1579*6d789b61SKonstantin Belousov 			d4 = (ACPI_IVRS_DEVICE4 *)db;
1580*6d789b61SKonstantin Belousov 			len = sizeof(*d4);
1581*6d789b61SKonstantin Belousov 			printf("\t\tDev Type=%#x Id=ALL", d4->Header.Type);
1582*6d789b61SKonstantin Belousov 			acpi_handle_ivrs_ivhd_dte(d4->Header.DataSetting);
1583*6d789b61SKonstantin Belousov 		} else if (d->Type == ACPI_IVRS_TYPE_SELECT) {
1584*6d789b61SKonstantin Belousov 			d4 = (ACPI_IVRS_DEVICE4 *)db;
1585*6d789b61SKonstantin Belousov 			len = sizeof(*d4);
1586*6d789b61SKonstantin Belousov 			printf("\t\tDev Type=%#x Id=%#06x", d4->Header.Type,
1587*6d789b61SKonstantin Belousov 			    d4->Header.Id);
1588*6d789b61SKonstantin Belousov 			acpi_handle_ivrs_ivhd_dte(d4->Header.DataSetting);
1589*6d789b61SKonstantin Belousov 		} else if (d->Type == ACPI_IVRS_TYPE_START) {
1590*6d789b61SKonstantin Belousov 			d4 = (ACPI_IVRS_DEVICE4 *)db;
1591*6d789b61SKonstantin Belousov 			len = 2 * sizeof(*d4);
1592*6d789b61SKonstantin Belousov 			printf("\t\tDev Type=%#x Id=%#06x-%#06x",
1593*6d789b61SKonstantin Belousov 			    d4->Header.Type,
1594*6d789b61SKonstantin Belousov 			    d4->Header.Id, (d4 + 1)->Header.Id);
1595*6d789b61SKonstantin Belousov 			acpi_handle_ivrs_ivhd_dte(d4->Header.DataSetting);
1596*6d789b61SKonstantin Belousov 		} else if (d->Type == ACPI_IVRS_TYPE_END) {
1597*6d789b61SKonstantin Belousov 			d4 = (ACPI_IVRS_DEVICE4 *)db;
1598*6d789b61SKonstantin Belousov 			len = 2 * sizeof(*d4);
1599*6d789b61SKonstantin Belousov 			printf("\t\tDev Type=%#x Id=%#06x BIOS BUG\n",
1600*6d789b61SKonstantin Belousov 			    d4->Header.Type, d4->Header.Id);
1601*6d789b61SKonstantin Belousov 		} else if (d->Type == ACPI_IVRS_TYPE_PAD8) {
1602*6d789b61SKonstantin Belousov 			len = sizeof(*d8a);
1603*6d789b61SKonstantin Belousov 		} else if (d->Type == ACPI_IVRS_TYPE_ALIAS_SELECT) {
1604*6d789b61SKonstantin Belousov 			d8a = (ACPI_IVRS_DEVICE8A *)db;
1605*6d789b61SKonstantin Belousov 			len = sizeof(*d8a);
1606*6d789b61SKonstantin Belousov 			printf("\t\tDev Type=%#x Id=%#06x AliasId=%#06x",
1607*6d789b61SKonstantin Belousov 			    d8a->Header.Type, d8a->Header.Id, d8a->UsedId);
1608*6d789b61SKonstantin Belousov 			acpi_handle_ivrs_ivhd_dte(d8a->Header.DataSetting);
1609*6d789b61SKonstantin Belousov 		} else if (d->Type == ACPI_IVRS_TYPE_ALIAS_START) {
1610*6d789b61SKonstantin Belousov 			d8a = (ACPI_IVRS_DEVICE8A *)db;
1611*6d789b61SKonstantin Belousov 			d4 = (ACPI_IVRS_DEVICE4 *)(db + sizeof(*d8a));
1612*6d789b61SKonstantin Belousov 			len = sizeof(*d8a) + sizeof(*d4);
1613*6d789b61SKonstantin Belousov 			printf("\t\tDev Type=%#x Id=%#06x-%#06x AliasId=%#06x",
1614*6d789b61SKonstantin Belousov 			    d8a->Header.Type, d8a->Header.Id, d4->Header.Id,
1615*6d789b61SKonstantin Belousov 			    d8a->UsedId);
1616*6d789b61SKonstantin Belousov 			acpi_handle_ivrs_ivhd_dte(d8a->Header.DataSetting);
1617*6d789b61SKonstantin Belousov 		} else if (d->Type == ACPI_IVRS_TYPE_EXT_SELECT) {
1618*6d789b61SKonstantin Belousov 			d8b = (ACPI_IVRS_DEVICE8B *)db;
1619*6d789b61SKonstantin Belousov 			len = sizeof(*d8b);
1620*6d789b61SKonstantin Belousov 			printf("\t\tDev Type=%#x Id=%#06x",
1621*6d789b61SKonstantin Belousov 			    d8a->Header.Type, d8a->Header.Id);
1622*6d789b61SKonstantin Belousov 			acpi_handle_ivrs_ivhd_dte(d8b->Header.DataSetting);
1623*6d789b61SKonstantin Belousov 			printf("\t\t");
1624*6d789b61SKonstantin Belousov 			acpi_handle_ivrs_ivhd_edte(d8b->ExtendedData);
1625*6d789b61SKonstantin Belousov 		} else if (d->Type == ACPI_IVRS_TYPE_EXT_START) {
1626*6d789b61SKonstantin Belousov 			d8b = (ACPI_IVRS_DEVICE8B *)db;
1627*6d789b61SKonstantin Belousov 			len = sizeof(*d8b);
1628*6d789b61SKonstantin Belousov 			d4 = (ACPI_IVRS_DEVICE4 *)(db + sizeof(*d8a));
1629*6d789b61SKonstantin Belousov 			len = sizeof(*d8a) + sizeof(*d4);
1630*6d789b61SKonstantin Belousov 			printf("\t\tDev Type=%#x Id=%#06x-%#06x",
1631*6d789b61SKonstantin Belousov 			    d8a->Header.Type, d8a->Header.Id, d4->Header.Id);
1632*6d789b61SKonstantin Belousov 			acpi_handle_ivrs_ivhd_dte(d8b->Header.DataSetting);
1633*6d789b61SKonstantin Belousov 			acpi_handle_ivrs_ivhd_edte(d8b->ExtendedData);
1634*6d789b61SKonstantin Belousov 		} else if (d->Type == ACPI_IVRS_TYPE_SPECIAL) {
1635*6d789b61SKonstantin Belousov 			d8c = (ACPI_IVRS_DEVICE8C *)db;
1636*6d789b61SKonstantin Belousov 			len = sizeof(*d8c);
1637*6d789b61SKonstantin Belousov 			printf("\t\tDev Type=%#x Id=%#06x Handle=%#x "
1638*6d789b61SKonstantin Belousov 			    "Variety=%d(%s)",
1639*6d789b61SKonstantin Belousov 			    d8c->Header.Type, d8c->UsedId, d8c->Handle,
1640*6d789b61SKonstantin Belousov 			    d8c->Variety,
1641*6d789b61SKonstantin Belousov 			    acpi_handle_ivrs_ivhd_variety(d8c->Variety));
1642*6d789b61SKonstantin Belousov 			acpi_handle_ivrs_ivhd_dte(d8c->Header.DataSetting);
1643*6d789b61SKonstantin Belousov 		} else if (d->Type == ACPI_IVRS_TYPE_HID) {
1644*6d789b61SKonstantin Belousov 			dh = (ACPI_IVRS_DEVICE_HID *)db;
1645*6d789b61SKonstantin Belousov 			len = sizeof(*dh) + dh->UidLength;
1646*6d789b61SKonstantin Belousov 			printf("\t\tDev Type=%#x Id=%#06x HID=",
1647*6d789b61SKonstantin Belousov 			    dh->Header.Type, dh->Header.Id);
1648*6d789b61SKonstantin Belousov 			acpi_print_string((char *)&dh->AcpiHid,
1649*6d789b61SKonstantin Belousov 			    sizeof(dh->AcpiHid));
1650*6d789b61SKonstantin Belousov 			printf(" CID=");
1651*6d789b61SKonstantin Belousov 			acpi_print_string((char *)&dh->AcpiCid,
1652*6d789b61SKonstantin Belousov 			    sizeof(dh->AcpiCid));
1653*6d789b61SKonstantin Belousov 			printf(" UID=");
1654*6d789b61SKonstantin Belousov 			switch (dh->UidType) {
1655*6d789b61SKonstantin Belousov 			case ACPI_IVRS_UID_NOT_PRESENT:
1656*6d789b61SKonstantin Belousov 			default:
1657*6d789b61SKonstantin Belousov 				printf("none");
1658*6d789b61SKonstantin Belousov 				break;
1659*6d789b61SKonstantin Belousov 			case ACPI_IVRS_UID_IS_INTEGER:
1660*6d789b61SKonstantin Belousov 				memcpy(&x32, dh + 1, sizeof(x32));
1661*6d789b61SKonstantin Belousov 				printf("%#x", x32);
1662*6d789b61SKonstantin Belousov 				break;
1663*6d789b61SKonstantin Belousov 			case ACPI_IVRS_UID_IS_STRING:
1664*6d789b61SKonstantin Belousov 				acpi_print_string((char *)(dh + 1),
1665*6d789b61SKonstantin Belousov 				    dh->UidLength);
1666*6d789b61SKonstantin Belousov 				break;
1667*6d789b61SKonstantin Belousov 			}
1668*6d789b61SKonstantin Belousov 			acpi_handle_ivrs_ivhd_dte(dh->Header.DataSetting);
1669*6d789b61SKonstantin Belousov 		} else {
1670*6d789b61SKonstantin Belousov 			printf("\t\tDev Type=%#x Unknown\n", d->Type);
1671*6d789b61SKonstantin Belousov 			if (d->Type <= 63)
1672*6d789b61SKonstantin Belousov 				len = sizeof(*d4);
1673*6d789b61SKonstantin Belousov 			else if (d->Type <= 127)
1674*6d789b61SKonstantin Belousov 				len = sizeof(*d8a);
1675*6d789b61SKonstantin Belousov 			else {
1676*6d789b61SKonstantin Belousov 				printf("Abort, cannot advance iterator.\n");
1677*6d789b61SKonstantin Belousov 				return;
1678*6d789b61SKonstantin Belousov 			}
1679*6d789b61SKonstantin Belousov 		}
1680*6d789b61SKonstantin Belousov 	}
1681*6d789b61SKonstantin Belousov }
1682*6d789b61SKonstantin Belousov 
1683*6d789b61SKonstantin Belousov static void
1684*6d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_10(ACPI_IVRS_HARDWARE1 *addr, bool efrsup)
1685*6d789b61SKonstantin Belousov {
1686*6d789b61SKonstantin Belousov 	acpi_handle_ivrs_ivhd_header(&addr->Header);
1687*6d789b61SKonstantin Belousov 	printf("\tCapOffset=%#x Base=%#jx PCISeg=%#x Unit=%#x MSIlog=%d\n",
1688*6d789b61SKonstantin Belousov 	    addr->CapabilityOffset, (uintmax_t)addr->BaseAddress,
1689*6d789b61SKonstantin Belousov 	    addr->PciSegmentGroup, (addr->Info & ACPI_IVHD_UNIT_ID_MASK) >> 8,
1690*6d789b61SKonstantin Belousov 	    addr->Info & ACPI_IVHD_MSI_NUMBER_MASK);
1691*6d789b61SKonstantin Belousov 	if (efrsup) {
1692*6d789b61SKonstantin Belousov #define PRINTFLAG(flag, name) printflag(addr->FeatureReporting, flag, #name)
1693*6d789b61SKonstantin Belousov #define PRINTFIELD(lbit, hbit, name) \
1694*6d789b61SKonstantin Belousov     printfield(addr->FeatureReporting, lbit, hbit, #name)
1695*6d789b61SKonstantin Belousov 		PRINTFIELD(30, 31, HATS);
1696*6d789b61SKonstantin Belousov 		PRINTFIELD(28, 29, GATS);
1697*6d789b61SKonstantin Belousov 		PRINTFIELD(23, 27, MsiNumPPR);
1698*6d789b61SKonstantin Belousov 		PRINTFIELD(17, 22, PNBanks);
1699*6d789b61SKonstantin Belousov 		PRINTFIELD(13, 16, PNCounters);
1700*6d789b61SKonstantin Belousov 		PRINTFIELD(8, 12, PASmax);
1701*6d789b61SKonstantin Belousov 		PRINTFLAG(1 << 7, HESup);
1702*6d789b61SKonstantin Belousov 		PRINTFLAG(1 << 6, GASup);
1703*6d789b61SKonstantin Belousov 		PRINTFLAG(1 << 5, UASup);
1704*6d789b61SKonstantin Belousov 		PRINTFIELD(3, 2, GLXSup);
1705*6d789b61SKonstantin Belousov 		PRINTFLAG(1 << 1, NXSup);
1706*6d789b61SKonstantin Belousov 		PRINTFLAG(1 << 0, XTSup);
1707*6d789b61SKonstantin Belousov #undef PRINTFLAG
1708*6d789b61SKonstantin Belousov #undef PRINTFIELD
1709*6d789b61SKonstantin Belousov 		PRINTFLAG_END();
1710*6d789b61SKonstantin Belousov 	}
1711*6d789b61SKonstantin Belousov 	acpi_handle_ivrs_ivhd_devs((ACPI_IVRS_DE_HEADER *)(addr + 1),
1712*6d789b61SKonstantin Belousov 	    (char *)addr + addr->Header.Length);
1713*6d789b61SKonstantin Belousov }
1714*6d789b61SKonstantin Belousov 
1715*6d789b61SKonstantin Belousov static void
1716*6d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_info_11(ACPI_IVRS_HARDWARE2 *addr)
1717*6d789b61SKonstantin Belousov {
1718*6d789b61SKonstantin Belousov 	acpi_handle_ivrs_ivhd_header(&addr->Header);
1719*6d789b61SKonstantin Belousov 	printf("\tCapOffset=%#x Base=%#jx PCISeg=%#x Unit=%#x MSIlog=%d\n",
1720*6d789b61SKonstantin Belousov 	    addr->CapabilityOffset, (uintmax_t)addr->BaseAddress,
1721*6d789b61SKonstantin Belousov 	    addr->PciSegmentGroup, (addr->Info >> 8) & 0x1f,
1722*6d789b61SKonstantin Belousov 	    addr->Info & 0x5);
1723*6d789b61SKonstantin Belousov 	printf("\tAttr=");
1724*6d789b61SKonstantin Belousov #define PRINTFIELD(lbit, hbit, name) \
1725*6d789b61SKonstantin Belousov     printfield(addr->Attributes, lbit, hbit, #name)
1726*6d789b61SKonstantin Belousov 	PRINTFIELD(23, 27, MsiNumPPR);
1727*6d789b61SKonstantin Belousov 	PRINTFIELD(17, 22, PNBanks);
1728*6d789b61SKonstantin Belousov 	PRINTFIELD(13, 16, PNCounters);
1729*6d789b61SKonstantin Belousov #undef PRINTFIELD
1730*6d789b61SKonstantin Belousov 	PRINTFLAG_END();
1731*6d789b61SKonstantin Belousov }
1732*6d789b61SKonstantin Belousov 
1733*6d789b61SKonstantin Belousov static void
1734*6d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_11(ACPI_IVRS_HARDWARE2 *addr)
1735*6d789b61SKonstantin Belousov {
1736*6d789b61SKonstantin Belousov 	acpi_handle_ivrs_ivhd_info_11(addr);
1737*6d789b61SKonstantin Belousov 	printf("\tEFRreg=%#018jx\n", (uintmax_t)addr->EfrRegisterImage);
1738*6d789b61SKonstantin Belousov 	acpi_handle_ivrs_ivhd_devs((ACPI_IVRS_DE_HEADER *)(addr + 1),
1739*6d789b61SKonstantin Belousov 	    (char *)addr + addr->Header.Length);
1740*6d789b61SKonstantin Belousov }
1741*6d789b61SKonstantin Belousov 
1742*6d789b61SKonstantin Belousov static void
1743*6d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_40(ACPI_IVRS_HARDWARE2 *addr)
1744*6d789b61SKonstantin Belousov {
1745*6d789b61SKonstantin Belousov 	acpi_handle_ivrs_ivhd_info_11(addr);
1746*6d789b61SKonstantin Belousov 	printf("\tEFRreg=%#018jx EFR2reg=%#018jx\n",
1747*6d789b61SKonstantin Belousov 	    (uintmax_t)addr->EfrRegisterImage, (uintmax_t)addr->Reserved);
1748*6d789b61SKonstantin Belousov 	acpi_handle_ivrs_ivhd_devs((ACPI_IVRS_DE_HEADER *)(addr + 1),
1749*6d789b61SKonstantin Belousov 	    (char *)addr + addr->Header.Length);
1750*6d789b61SKonstantin Belousov }
1751*6d789b61SKonstantin Belousov 
1752*6d789b61SKonstantin Belousov static const char *
1753*6d789b61SKonstantin Belousov acpi_handle_ivrs_ivmd_type(ACPI_IVRS_MEMORY *addr)
1754*6d789b61SKonstantin Belousov {
1755*6d789b61SKonstantin Belousov 	switch (addr->Header.Type) {
1756*6d789b61SKonstantin Belousov 	case ACPI_IVRS_TYPE_MEMORY1:
1757*6d789b61SKonstantin Belousov 		return ("ALL");
1758*6d789b61SKonstantin Belousov 	case ACPI_IVRS_TYPE_MEMORY2:
1759*6d789b61SKonstantin Belousov 		return ("specified");
1760*6d789b61SKonstantin Belousov 	case ACPI_IVRS_TYPE_MEMORY3:
1761*6d789b61SKonstantin Belousov 		return ("range");
1762*6d789b61SKonstantin Belousov 	default:
1763*6d789b61SKonstantin Belousov 		return ("unknown");
1764*6d789b61SKonstantin Belousov 	}
1765*6d789b61SKonstantin Belousov }
1766*6d789b61SKonstantin Belousov 
1767*6d789b61SKonstantin Belousov static void
1768*6d789b61SKonstantin Belousov acpi_handle_ivrs_ivmd(ACPI_IVRS_MEMORY *addr)
1769*6d789b61SKonstantin Belousov {
1770*6d789b61SKonstantin Belousov 	printf("\tMem Type=%#x(%s) ",
1771*6d789b61SKonstantin Belousov 	    addr->Header.Type, acpi_handle_ivrs_ivmd_type(addr));
1772*6d789b61SKonstantin Belousov 	switch (addr->Header.Type) {
1773*6d789b61SKonstantin Belousov 	case ACPI_IVRS_TYPE_MEMORY2:
1774*6d789b61SKonstantin Belousov 		printf("Id=%#06x PCISeg=%#x ", addr->Header.DeviceId,
1775*6d789b61SKonstantin Belousov 		    *(UINT16 *)&addr->Reserved);
1776*6d789b61SKonstantin Belousov 		break;
1777*6d789b61SKonstantin Belousov 	case ACPI_IVRS_TYPE_MEMORY3:
1778*6d789b61SKonstantin Belousov 		printf("Id=%#06x-%#06x PCISeg=%#x", addr->Header.DeviceId,
1779*6d789b61SKonstantin Belousov 		    addr->AuxData, *(UINT16 *)&addr->Reserved);
1780*6d789b61SKonstantin Belousov 		break;
1781*6d789b61SKonstantin Belousov 	}
1782*6d789b61SKonstantin Belousov 	printf("Start=%#18jx Length=%#jx Flags=",
1783*6d789b61SKonstantin Belousov 	    (uintmax_t)addr->StartAddress, (uintmax_t)addr->MemoryLength);
1784*6d789b61SKonstantin Belousov #define PRINTFLAG(flag, name) printflag(addr->Header.Flags, flag, #name)
1785*6d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVMD_EXCLUSION_RANGE, ExclusionRange);
1786*6d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVMD_WRITE, IW);
1787*6d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVMD_READ, IR);
1788*6d789b61SKonstantin Belousov 	PRINTFLAG(ACPI_IVMD_UNITY, Unity);
1789*6d789b61SKonstantin Belousov #undef PRINTFLAG
1790*6d789b61SKonstantin Belousov 	PRINTFLAG_END();
1791*6d789b61SKonstantin Belousov }
1792*6d789b61SKonstantin Belousov 
1793*6d789b61SKonstantin Belousov static int
1794*6d789b61SKonstantin Belousov acpi_handle_ivrs_blocks(void *addr, int remaining, bool efrsup)
1795*6d789b61SKonstantin Belousov {
1796*6d789b61SKonstantin Belousov 	ACPI_IVRS_HEADER *hdr = addr;
1797*6d789b61SKonstantin Belousov 
1798*6d789b61SKonstantin Belousov 	if (remaining < (int)sizeof(ACPI_IVRS_HEADER))
1799*6d789b61SKonstantin Belousov 		return (-1);
1800*6d789b61SKonstantin Belousov 
1801*6d789b61SKonstantin Belousov 	if (remaining < hdr->Length)
1802*6d789b61SKonstantin Belousov 		return (-1);
1803*6d789b61SKonstantin Belousov 
1804*6d789b61SKonstantin Belousov 	switch (hdr->Type) {
1805*6d789b61SKonstantin Belousov 	case ACPI_IVRS_TYPE_HARDWARE1:
1806*6d789b61SKonstantin Belousov 		acpi_handle_ivrs_ivhd_10(addr, efrsup);
1807*6d789b61SKonstantin Belousov 		break;
1808*6d789b61SKonstantin Belousov 	case ACPI_IVRS_TYPE_HARDWARE2:
1809*6d789b61SKonstantin Belousov 		if (!efrsup)
1810*6d789b61SKonstantin Belousov 			printf("\t!! Found IVHD block 0x11 but !EFRsup\n");
1811*6d789b61SKonstantin Belousov 		acpi_handle_ivrs_ivhd_11(addr);
1812*6d789b61SKonstantin Belousov 		break;
1813*6d789b61SKonstantin Belousov 	case ACPI_IVRS_TYPE_HARDWARE3:
1814*6d789b61SKonstantin Belousov 		if (!efrsup)
1815*6d789b61SKonstantin Belousov 			printf("\t!! Found IVHD block 0x40 but !EFRsup\n");
1816*6d789b61SKonstantin Belousov 		acpi_handle_ivrs_ivhd_40(addr);
1817*6d789b61SKonstantin Belousov 		break;
1818*6d789b61SKonstantin Belousov 	case ACPI_IVRS_TYPE_MEMORY1:
1819*6d789b61SKonstantin Belousov 	case ACPI_IVRS_TYPE_MEMORY2:
1820*6d789b61SKonstantin Belousov 	case ACPI_IVRS_TYPE_MEMORY3:
1821*6d789b61SKonstantin Belousov 		acpi_handle_ivrs_ivmd(addr);
1822*6d789b61SKonstantin Belousov 		break;
1823*6d789b61SKonstantin Belousov 	default:
1824*6d789b61SKonstantin Belousov 		printf("\n");
1825*6d789b61SKonstantin Belousov 		printf("\tType=%d\n", hdr->Type);
1826*6d789b61SKonstantin Belousov 		printf("\tLength=%d\n", hdr->Length);
1827*6d789b61SKonstantin Belousov 		break;
1828*6d789b61SKonstantin Belousov 	}
1829*6d789b61SKonstantin Belousov 	return (hdr->Length);
1830*6d789b61SKonstantin Belousov }
1831*6d789b61SKonstantin Belousov 
1832*6d789b61SKonstantin Belousov #define	ACPI_IVRS_DMAREMAP	0x00000002
1833*6d789b61SKonstantin Belousov #define	ACPI_IVRS_EFRSUP	0x00000001
1834*6d789b61SKonstantin Belousov #define	ACPI_IVRS_GVA_SIZE	0x000000e0
1835*6d789b61SKonstantin Belousov 
1836*6d789b61SKonstantin Belousov static void
1837*6d789b61SKonstantin Belousov acpi_handle_ivrs(ACPI_TABLE_HEADER *sdp)
1838*6d789b61SKonstantin Belousov {
1839*6d789b61SKonstantin Belousov 	ACPI_TABLE_IVRS *ivrs;
1840*6d789b61SKonstantin Belousov 	char *cp;
1841*6d789b61SKonstantin Belousov 	int remaining, consumed;
1842*6d789b61SKonstantin Belousov 	bool efrsup;
1843*6d789b61SKonstantin Belousov 
1844*6d789b61SKonstantin Belousov 	printf(BEGIN_COMMENT);
1845*6d789b61SKonstantin Belousov 	acpi_print_sdt(sdp);
1846*6d789b61SKonstantin Belousov 	ivrs = (ACPI_TABLE_IVRS *)sdp;
1847*6d789b61SKonstantin Belousov 	efrsup = (ivrs->Info & ACPI_IVRS_EFRSUP) != 0;
1848*6d789b61SKonstantin Belousov 	printf("\tVAsize=%d PAsize=%d GVAsize=%d\n",
1849*6d789b61SKonstantin Belousov 	    (ivrs->Info & ACPI_IVRS_VIRTUAL_SIZE) >> 15,
1850*6d789b61SKonstantin Belousov 	    (ivrs->Info & ACPI_IVRS_PHYSICAL_SIZE) >> 8,
1851*6d789b61SKonstantin Belousov 	    (ivrs->Info & ACPI_IVRS_GVA_SIZE) >> 5);
1852*6d789b61SKonstantin Belousov 	printf("\tATS_resp_res=%d DMA_preboot_remap=%d EFRsup=%d\n",
1853*6d789b61SKonstantin Belousov 	    (ivrs->Info & ACPI_IVRS_ATS_RESERVED) != 0,
1854*6d789b61SKonstantin Belousov 	    (ivrs->Info & ACPI_IVRS_DMAREMAP) != 0, efrsup);
1855*6d789b61SKonstantin Belousov 
1856*6d789b61SKonstantin Belousov 	remaining = sdp->Length - sizeof(ACPI_TABLE_IVRS);
1857*6d789b61SKonstantin Belousov 	while (remaining > 0) {
1858*6d789b61SKonstantin Belousov 		cp = (char *)sdp + sdp->Length - remaining;
1859*6d789b61SKonstantin Belousov 		consumed = acpi_handle_ivrs_blocks(cp, remaining, efrsup);
1860*6d789b61SKonstantin Belousov 		if (consumed <= 0)
1861*6d789b61SKonstantin Belousov 			break;
1862*6d789b61SKonstantin Belousov 		else
1863*6d789b61SKonstantin Belousov 			remaining -= consumed;
1864*6d789b61SKonstantin Belousov 	}
1865*6d789b61SKonstantin Belousov 
1866*6d789b61SKonstantin Belousov 	printf(END_COMMENT);
1867*6d789b61SKonstantin Belousov }
1868*6d789b61SKonstantin Belousov 
1869*6d789b61SKonstantin Belousov static void
1870986dffafSJohn Baldwin acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp)
1871a0333ad1SJohn Baldwin {
1872a0333ad1SJohn Baldwin 
1873a0333ad1SJohn Baldwin 	printf("\tFlags={");
1874986dffafSJohn Baldwin 	if (mp->Flags & ACPI_SRAT_MEM_ENABLED)
1875a0333ad1SJohn Baldwin 		printf("ENABLED");
1876a0333ad1SJohn Baldwin 	else
1877a0333ad1SJohn Baldwin 		printf("DISABLED");
1878986dffafSJohn Baldwin 	if (mp->Flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)
1879a0333ad1SJohn Baldwin 		printf(",HOT_PLUGGABLE");
1880986dffafSJohn Baldwin 	if (mp->Flags & ACPI_SRAT_MEM_NON_VOLATILE)
1881a0333ad1SJohn Baldwin 		printf(",NON_VOLATILE");
1882a0333ad1SJohn Baldwin 	printf("}\n");
1883986dffafSJohn Baldwin 	printf("\tBase Address=0x%016jx\n", (uintmax_t)mp->BaseAddress);
1884986dffafSJohn Baldwin 	printf("\tLength=0x%016jx\n", (uintmax_t)mp->Length);
1885986dffafSJohn Baldwin 	printf("\tProximity Domain=%d\n", mp->ProximityDomain);
1886a0333ad1SJohn Baldwin }
1887a0333ad1SJohn Baldwin 
188827941afaSEd Maste static const char *srat_types[] = {
188927941afaSEd Maste     [ACPI_SRAT_TYPE_CPU_AFFINITY] = "CPU",
189027941afaSEd Maste     [ACPI_SRAT_TYPE_MEMORY_AFFINITY] = "Memory",
189127941afaSEd Maste     [ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY] = "X2APIC",
1892cebb7b19SEd Maste     [ACPI_SRAT_TYPE_GICC_AFFINITY] = "GICC",
1893cebb7b19SEd Maste     [ACPI_SRAT_TYPE_GIC_ITS_AFFINITY] = "GIC ITS",
189427941afaSEd Maste };
1895a0333ad1SJohn Baldwin 
1896a0333ad1SJohn Baldwin static void
1897986dffafSJohn Baldwin acpi_print_srat(ACPI_SUBTABLE_HEADER *srat)
1898a0333ad1SJohn Baldwin {
1899986dffafSJohn Baldwin 	ACPI_SRAT_CPU_AFFINITY *cpu;
1900986dffafSJohn Baldwin 	ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic;
19012b2b1f42SAndrew Turner 	ACPI_SRAT_GICC_AFFINITY *gic;
1902a0333ad1SJohn Baldwin 
1903c86932b6SMarcelo Araujo 	if (srat->Type < nitems(srat_types))
1904986dffafSJohn Baldwin 		printf("\tType=%s\n", srat_types[srat->Type]);
1905a0333ad1SJohn Baldwin 	else
1906986dffafSJohn Baldwin 		printf("\tType=%d (unknown)\n", srat->Type);
1907986dffafSJohn Baldwin 	switch (srat->Type) {
1908a0333ad1SJohn Baldwin 	case ACPI_SRAT_TYPE_CPU_AFFINITY:
1909986dffafSJohn Baldwin 		cpu = (ACPI_SRAT_CPU_AFFINITY *)srat;
1910986dffafSJohn Baldwin 		acpi_print_srat_cpu(cpu->ApicId,
1911986dffafSJohn Baldwin 		    cpu->ProximityDomainHi[2] << 24 |
1912986dffafSJohn Baldwin 		    cpu->ProximityDomainHi[1] << 16 |
1913986dffafSJohn Baldwin 		    cpu->ProximityDomainHi[0] << 0 |
1914986dffafSJohn Baldwin 		    cpu->ProximityDomainLo, cpu->Flags);
1915a0333ad1SJohn Baldwin 		break;
1916a0333ad1SJohn Baldwin 	case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
1917986dffafSJohn Baldwin 		acpi_print_srat_memory((ACPI_SRAT_MEM_AFFINITY *)srat);
1918a0333ad1SJohn Baldwin 		break;
1919a0333ad1SJohn Baldwin 	case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
1920986dffafSJohn Baldwin 		x2apic = (ACPI_SRAT_X2APIC_CPU_AFFINITY *)srat;
1921986dffafSJohn Baldwin 		acpi_print_srat_cpu(x2apic->ApicId, x2apic->ProximityDomain,
1922986dffafSJohn Baldwin 		    x2apic->Flags);
1923a0333ad1SJohn Baldwin 		break;
19242b2b1f42SAndrew Turner 	case ACPI_SRAT_TYPE_GICC_AFFINITY:
19252b2b1f42SAndrew Turner 		gic = (ACPI_SRAT_GICC_AFFINITY *)srat;
19262b2b1f42SAndrew Turner 		acpi_print_srat_cpu(gic->AcpiProcessorUid, gic->ProximityDomain,
19272b2b1f42SAndrew Turner 		    gic->Flags);
19282b2b1f42SAndrew Turner 		break;
1929a0333ad1SJohn Baldwin 	}
1930a0333ad1SJohn Baldwin }
1931a0333ad1SJohn Baldwin 
1932a0333ad1SJohn Baldwin static void
1933986dffafSJohn Baldwin acpi_handle_srat(ACPI_TABLE_HEADER *sdp)
1934a0333ad1SJohn Baldwin {
1935986dffafSJohn Baldwin 	ACPI_TABLE_SRAT *srat;
1936a0333ad1SJohn Baldwin 
1937a0333ad1SJohn Baldwin 	printf(BEGIN_COMMENT);
1938a0333ad1SJohn Baldwin 	acpi_print_sdt(sdp);
1939986dffafSJohn Baldwin 	srat = (ACPI_TABLE_SRAT *)sdp;
1940986dffafSJohn Baldwin 	printf("\tTable Revision=%d\n", srat->TableRevision);
1941986dffafSJohn Baldwin 	acpi_walk_subtables(sdp, (srat + 1), acpi_print_srat);
1942a0333ad1SJohn Baldwin 	printf(END_COMMENT);
1943a0333ad1SJohn Baldwin }
1944a0333ad1SJohn Baldwin 
1945340c0022SEd Maste static const char *nfit_types[] = {
1946340c0022SEd Maste     [ACPI_NFIT_TYPE_SYSTEM_ADDRESS] = "System Address",
1947340c0022SEd Maste     [ACPI_NFIT_TYPE_MEMORY_MAP] = "Memory Map",
1948340c0022SEd Maste     [ACPI_NFIT_TYPE_INTERLEAVE] = "Interleave",
1949340c0022SEd Maste     [ACPI_NFIT_TYPE_SMBIOS] = "SMBIOS",
1950340c0022SEd Maste     [ACPI_NFIT_TYPE_CONTROL_REGION] = "Control Region",
1951340c0022SEd Maste     [ACPI_NFIT_TYPE_DATA_REGION] = "Data Region",
19521b109c69SAlexander Motin     [ACPI_NFIT_TYPE_FLUSH_ADDRESS] = "Flush Address",
19531b109c69SAlexander Motin     [ACPI_NFIT_TYPE_CAPABILITIES] = "Platform Capabilities"
1954340c0022SEd Maste };
1955340c0022SEd Maste 
1956340c0022SEd Maste 
1957340c0022SEd Maste static void
1958340c0022SEd Maste acpi_print_nfit(ACPI_NFIT_HEADER *nfit)
1959340c0022SEd Maste {
1960340c0022SEd Maste 	char *uuidstr;
19613b7935f3SAlexander Motin 	uint32_t m, status;
1962340c0022SEd Maste 
1963340c0022SEd Maste 	ACPI_NFIT_SYSTEM_ADDRESS *sysaddr;
1964340c0022SEd Maste 	ACPI_NFIT_MEMORY_MAP *mmap;
1965340c0022SEd Maste 	ACPI_NFIT_INTERLEAVE *ileave;
1966340c0022SEd Maste 	ACPI_NFIT_CONTROL_REGION *ctlreg;
1967340c0022SEd Maste 	ACPI_NFIT_DATA_REGION *datareg;
1968340c0022SEd Maste 	ACPI_NFIT_FLUSH_ADDRESS *fladdr;
19691b109c69SAlexander Motin 	ACPI_NFIT_CAPABILITIES *caps;
1970340c0022SEd Maste 
1971340c0022SEd Maste 	if (nfit->Type < nitems(nfit_types))
1972340c0022SEd Maste 		printf("\tType=%s\n", nfit_types[nfit->Type]);
1973340c0022SEd Maste 	else
1974340c0022SEd Maste 		printf("\tType=%u (unknown)\n", nfit->Type);
1975340c0022SEd Maste 	switch (nfit->Type) {
1976340c0022SEd Maste 	case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
1977340c0022SEd Maste 		sysaddr = (ACPI_NFIT_SYSTEM_ADDRESS *)nfit;
1978340c0022SEd Maste 		printf("\tRangeIndex=%u\n", (u_int)sysaddr->RangeIndex);
1979340c0022SEd Maste 		printf("\tProximityDomain=%u\n",
1980340c0022SEd Maste 		    (u_int)sysaddr->ProximityDomain);
1981de937ecbSKonstantin Belousov 		uuid_to_string((uuid_t *)(uintptr_t)(sysaddr->RangeGuid),
1982340c0022SEd Maste 		    &uuidstr, &status);
1983340c0022SEd Maste 		if (status != uuid_s_ok)
1984340c0022SEd Maste 			errx(1, "uuid_to_string: status=%u", status);
1985340c0022SEd Maste 		printf("\tRangeGuid=%s\n", uuidstr);
1986340c0022SEd Maste 		free(uuidstr);
1987340c0022SEd Maste 		printf("\tAddress=0x%016jx\n", (uintmax_t)sysaddr->Address);
1988340c0022SEd Maste 		printf("\tLength=0x%016jx\n", (uintmax_t)sysaddr->Length);
1989340c0022SEd Maste 		printf("\tMemoryMapping=0x%016jx\n",
1990340c0022SEd Maste 		    (uintmax_t)sysaddr->MemoryMapping);
1991340c0022SEd Maste 
1992340c0022SEd Maste #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_## flag, #flag)
1993340c0022SEd Maste 
1994340c0022SEd Maste 		printf("\tFlags=");
1995340c0022SEd Maste 		PRINTFLAG(sysaddr->Flags, ADD_ONLINE_ONLY);
1996340c0022SEd Maste 		PRINTFLAG(sysaddr->Flags, PROXIMITY_VALID);
1997340c0022SEd Maste 		PRINTFLAG_END();
1998340c0022SEd Maste 
1999340c0022SEd Maste #undef PRINTFLAG
2000340c0022SEd Maste 
2001340c0022SEd Maste 		break;
2002340c0022SEd Maste 	case ACPI_NFIT_TYPE_MEMORY_MAP:
2003340c0022SEd Maste 		mmap = (ACPI_NFIT_MEMORY_MAP *)nfit;
200492d0d6bbSAlexander Motin 		printf("\tDeviceHandle=0x%x\n", (u_int)mmap->DeviceHandle);
200592d0d6bbSAlexander Motin 		printf("\tPhysicalId=0x%04x\n", (u_int)mmap->PhysicalId);
2006340c0022SEd Maste 		printf("\tRegionId=%u\n", (u_int)mmap->RegionId);
2007340c0022SEd Maste 		printf("\tRangeIndex=%u\n", (u_int)mmap->RangeIndex);
2008340c0022SEd Maste 		printf("\tRegionIndex=%u\n", (u_int)mmap->RegionIndex);
2009340c0022SEd Maste 		printf("\tRegionSize=0x%016jx\n", (uintmax_t)mmap->RegionSize);
2010340c0022SEd Maste 		printf("\tRegionOffset=0x%016jx\n",
2011340c0022SEd Maste 		    (uintmax_t)mmap->RegionOffset);
2012340c0022SEd Maste 		printf("\tAddress=0x%016jx\n", (uintmax_t)mmap->Address);
2013340c0022SEd Maste 		printf("\tInterleaveIndex=%u\n", (u_int)mmap->InterleaveIndex);
2014fb1cf2a9SAlexander Motin 		printf("\tInterleaveWays=%u\n", (u_int)mmap->InterleaveWays);
2015340c0022SEd Maste 
2016340c0022SEd Maste #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_MEM_## flag, #flag)
2017340c0022SEd Maste 
2018340c0022SEd Maste 		printf("\tFlags=");
2019340c0022SEd Maste 		PRINTFLAG(mmap->Flags, SAVE_FAILED);
2020340c0022SEd Maste 		PRINTFLAG(mmap->Flags, RESTORE_FAILED);
2021340c0022SEd Maste 		PRINTFLAG(mmap->Flags, FLUSH_FAILED);
2022340c0022SEd Maste 		PRINTFLAG(mmap->Flags, NOT_ARMED);
2023340c0022SEd Maste 		PRINTFLAG(mmap->Flags, HEALTH_OBSERVED);
2024340c0022SEd Maste 		PRINTFLAG(mmap->Flags, HEALTH_ENABLED);
2025340c0022SEd Maste 		PRINTFLAG(mmap->Flags, MAP_FAILED);
2026340c0022SEd Maste 		PRINTFLAG_END();
2027340c0022SEd Maste 
2028340c0022SEd Maste #undef PRINTFLAG
2029340c0022SEd Maste 
2030340c0022SEd Maste 		break;
2031340c0022SEd Maste 	case ACPI_NFIT_TYPE_INTERLEAVE:
2032340c0022SEd Maste 		ileave = (ACPI_NFIT_INTERLEAVE *)nfit;
2033340c0022SEd Maste 		printf("\tInterleaveIndex=%u\n",
2034340c0022SEd Maste 		    (u_int)ileave->InterleaveIndex);
2035340c0022SEd Maste 		printf("\tLineCount=%u\n", (u_int)ileave->LineCount);
2036340c0022SEd Maste 		printf("\tLineSize=%u\n", (u_int)ileave->LineSize);
20373b7935f3SAlexander Motin 		for (m = 0; m < ileave->LineCount; m++) {
20383b7935f3SAlexander Motin 			printf("\tLine%uOffset=0x%08x\n", (u_int)m + 1,
20393b7935f3SAlexander Motin 			    (u_int)ileave->LineOffset[m]);
20403b7935f3SAlexander Motin 		}
2041340c0022SEd Maste 		break;
2042340c0022SEd Maste 	case ACPI_NFIT_TYPE_SMBIOS:
2043340c0022SEd Maste 		/* XXX smbios->Data[x] output is not supported */
2044340c0022SEd Maste 		break;
2045340c0022SEd Maste 	case ACPI_NFIT_TYPE_CONTROL_REGION:
2046340c0022SEd Maste 		ctlreg = (ACPI_NFIT_CONTROL_REGION *)nfit;
2047340c0022SEd Maste 		printf("\tRegionIndex=%u\n", (u_int)ctlreg->RegionIndex);
2048340c0022SEd Maste 		printf("\tVendorId=0x%04x\n", (u_int)ctlreg->VendorId);
2049340c0022SEd Maste 		printf("\tDeviceId=0x%04x\n", (u_int)ctlreg->DeviceId);
205035e39fd9SAlexander Motin 		printf("\tRevisionId=0x%02x\n", (u_int)ctlreg->RevisionId);
2051340c0022SEd Maste 		printf("\tSubsystemVendorId=0x%04x\n",
2052340c0022SEd Maste 		    (u_int)ctlreg->SubsystemVendorId);
2053340c0022SEd Maste 		printf("\tSubsystemDeviceId=0x%04x\n",
2054340c0022SEd Maste 		    (u_int)ctlreg->SubsystemDeviceId);
205535e39fd9SAlexander Motin 		printf("\tSubsystemRevisionId=0x%02x\n",
2056340c0022SEd Maste 		    (u_int)ctlreg->SubsystemRevisionId);
2057d4c2de2eSAlexander Motin 		printf("\tValidFields=0x%02x\n", (u_int)ctlreg->ValidFields);
205835e39fd9SAlexander Motin 		printf("\tManufacturingLocation=0x%02x\n",
2059340c0022SEd Maste 		    (u_int)ctlreg->ManufacturingLocation);
206035e39fd9SAlexander Motin 		printf("\tManufacturingDate=%04x\n",
206135e39fd9SAlexander Motin 		    (u_int)be16toh(ctlreg->ManufacturingDate));
206235e39fd9SAlexander Motin 		printf("\tSerialNumber=%08X\n",
206335e39fd9SAlexander Motin 		    (u_int)be32toh(ctlreg->SerialNumber));
2064fb1cf2a9SAlexander Motin 		printf("\tCode=0x%04x\n", (u_int)ctlreg->Code);
2065340c0022SEd Maste 		printf("\tWindows=%u\n", (u_int)ctlreg->Windows);
2066340c0022SEd Maste 		printf("\tWindowSize=0x%016jx\n",
2067340c0022SEd Maste 		    (uintmax_t)ctlreg->WindowSize);
2068340c0022SEd Maste 		printf("\tCommandOffset=0x%016jx\n",
2069340c0022SEd Maste 		    (uintmax_t)ctlreg->CommandOffset);
2070340c0022SEd Maste 		printf("\tCommandSize=0x%016jx\n",
2071340c0022SEd Maste 		    (uintmax_t)ctlreg->CommandSize);
2072340c0022SEd Maste 		printf("\tStatusOffset=0x%016jx\n",
2073340c0022SEd Maste 		    (uintmax_t)ctlreg->StatusOffset);
2074340c0022SEd Maste 		printf("\tStatusSize=0x%016jx\n",
2075340c0022SEd Maste 		    (uintmax_t)ctlreg->StatusSize);
2076340c0022SEd Maste 
2077340c0022SEd Maste #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_## flag, #flag)
2078340c0022SEd Maste 
2079340c0022SEd Maste 		printf("\tFlags=");
2080d4c2de2eSAlexander Motin 		PRINTFLAG(ctlreg->Flags, CONTROL_BUFFERED);
2081340c0022SEd Maste 		PRINTFLAG_END();
2082340c0022SEd Maste 
2083340c0022SEd Maste #undef PRINTFLAG
2084340c0022SEd Maste 
2085340c0022SEd Maste 		break;
2086340c0022SEd Maste 	case ACPI_NFIT_TYPE_DATA_REGION:
2087340c0022SEd Maste 		datareg = (ACPI_NFIT_DATA_REGION *)nfit;
2088340c0022SEd Maste 		printf("\tRegionIndex=%u\n", (u_int)datareg->RegionIndex);
2089340c0022SEd Maste 		printf("\tWindows=%u\n", (u_int)datareg->Windows);
2090340c0022SEd Maste 		printf("\tOffset=0x%016jx\n", (uintmax_t)datareg->Offset);
2091340c0022SEd Maste 		printf("\tSize=0x%016jx\n", (uintmax_t)datareg->Size);
2092340c0022SEd Maste 		printf("\tCapacity=0x%016jx\n", (uintmax_t)datareg->Capacity);
2093340c0022SEd Maste 		printf("\tStartAddress=0x%016jx\n",
2094340c0022SEd Maste 		    (uintmax_t)datareg->StartAddress);
2095340c0022SEd Maste 		break;
2096340c0022SEd Maste 	case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
2097340c0022SEd Maste 		fladdr = (ACPI_NFIT_FLUSH_ADDRESS *)nfit;
2098340c0022SEd Maste 		printf("\tDeviceHandle=%u\n", (u_int)fladdr->DeviceHandle);
2099340c0022SEd Maste 		printf("\tHintCount=%u\n", (u_int)fladdr->HintCount);
21003b7935f3SAlexander Motin 		for (m = 0; m < fladdr->HintCount; m++) {
21013b7935f3SAlexander Motin 			printf("\tHintAddress%u=0x%016jx\n", (u_int)m + 1,
21023b7935f3SAlexander Motin 			    (uintmax_t)fladdr->HintAddress[m]);
21033b7935f3SAlexander Motin 		}
2104340c0022SEd Maste 		break;
21051b109c69SAlexander Motin 	case ACPI_NFIT_TYPE_CAPABILITIES:
21061b109c69SAlexander Motin 		caps = (ACPI_NFIT_CAPABILITIES *)nfit;
21071b109c69SAlexander Motin 		printf("\tHighestCapability=%u\n", (u_int)caps->HighestCapability);
21081b109c69SAlexander Motin 
21091b109c69SAlexander Motin #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_CAPABILITY_## flag, #flag)
21101b109c69SAlexander Motin 
21111b109c69SAlexander Motin 		printf("\tCapabilities=");
21121b109c69SAlexander Motin 		PRINTFLAG(caps->Capabilities, CACHE_FLUSH);
21131b109c69SAlexander Motin 		PRINTFLAG(caps->Capabilities, MEM_FLUSH);
21141b109c69SAlexander Motin 		PRINTFLAG(caps->Capabilities, MEM_MIRRORING);
21151b109c69SAlexander Motin 		PRINTFLAG_END();
21161b109c69SAlexander Motin 
21171b109c69SAlexander Motin #undef PRINTFLAG
21181b109c69SAlexander Motin 		break;
2119340c0022SEd Maste 	}
2120340c0022SEd Maste }
2121340c0022SEd Maste 
2122340c0022SEd Maste static void
2123340c0022SEd Maste acpi_handle_nfit(ACPI_TABLE_HEADER *sdp)
2124340c0022SEd Maste {
2125340c0022SEd Maste 	ACPI_TABLE_NFIT *nfit;
2126340c0022SEd Maste 
2127340c0022SEd Maste 	printf(BEGIN_COMMENT);
2128340c0022SEd Maste 	acpi_print_sdt(sdp);
2129340c0022SEd Maste 	nfit = (ACPI_TABLE_NFIT *)sdp;
2130340c0022SEd Maste 	acpi_walk_nfit(sdp, (nfit + 1), acpi_print_nfit);
2131340c0022SEd Maste 	printf(END_COMMENT);
2132340c0022SEd Maste }
2133340c0022SEd Maste 
2134a0333ad1SJohn Baldwin static void
2135986dffafSJohn Baldwin acpi_print_sdt(ACPI_TABLE_HEADER *sdp)
2136c62f1cccSMitsuru IWASAKI {
2137773b6454SNate Lawson 	printf("  ");
2138278f0de6SJung-uk Kim 	acpi_print_string(sdp->Signature, ACPI_NAMESEG_SIZE);
2139c62f1cccSMitsuru IWASAKI 	printf(": Length=%d, Revision=%d, Checksum=%d,\n",
2140986dffafSJohn Baldwin 	       sdp->Length, sdp->Revision, sdp->Checksum);
2141e1e9a4bfSMitsuru IWASAKI 	printf("\tOEMID=");
2142986dffafSJohn Baldwin 	acpi_print_string(sdp->OemId, ACPI_OEM_ID_SIZE);
2143e1e9a4bfSMitsuru IWASAKI 	printf(", OEM Table ID=");
2144986dffafSJohn Baldwin 	acpi_print_string(sdp->OemTableId, ACPI_OEM_TABLE_ID_SIZE);
2145986dffafSJohn Baldwin 	printf(", OEM Revision=0x%x,\n", sdp->OemRevision);
2146e1e9a4bfSMitsuru IWASAKI 	printf("\tCreator ID=");
2147278f0de6SJung-uk Kim 	acpi_print_string(sdp->AslCompilerId, ACPI_NAMESEG_SIZE);
2148986dffafSJohn Baldwin 	printf(", Creator Revision=0x%x\n", sdp->AslCompilerRevision);
2149e1e9a4bfSMitsuru IWASAKI }
2150e1e9a4bfSMitsuru IWASAKI 
2151945137d9SNate Lawson static void
2152986dffafSJohn Baldwin acpi_print_rsdt(ACPI_TABLE_HEADER *rsdp)
2153e1e9a4bfSMitsuru IWASAKI {
2154986dffafSJohn Baldwin 	ACPI_TABLE_RSDT *rsdt;
2155986dffafSJohn Baldwin 	ACPI_TABLE_XSDT *xsdt;
2156e1e9a4bfSMitsuru IWASAKI 	int	i, entries;
2157e1e9a4bfSMitsuru IWASAKI 
2158986dffafSJohn Baldwin 	rsdt = (ACPI_TABLE_RSDT *)rsdp;
2159986dffafSJohn Baldwin 	xsdt = (ACPI_TABLE_XSDT *)rsdp;
2160773b6454SNate Lawson 	printf(BEGIN_COMMENT);
2161773b6454SNate Lawson 	acpi_print_sdt(rsdp);
2162986dffafSJohn Baldwin 	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
2163e1e9a4bfSMitsuru IWASAKI 	printf("\tEntries={ ");
2164e1e9a4bfSMitsuru IWASAKI 	for (i = 0; i < entries; i++) {
2165e1e9a4bfSMitsuru IWASAKI 		if (i > 0)
2166e1e9a4bfSMitsuru IWASAKI 			printf(", ");
2167fe1d0c2dSJung-uk Kim 		if (addr_size == 4)
21687d369c6eSJung-uk Kim 			printf("0x%08x", le32toh(rsdt->TableOffsetEntry[i]));
2169fe1d0c2dSJung-uk Kim 		else
21707d369c6eSJung-uk Kim 			printf("0x%016jx",
21717d369c6eSJung-uk Kim 			    (uintmax_t)le64toh(xsdt->TableOffsetEntry[i]));
2172e1e9a4bfSMitsuru IWASAKI 	}
2173e1e9a4bfSMitsuru IWASAKI 	printf(" }\n");
2174c62f1cccSMitsuru IWASAKI 	printf(END_COMMENT);
2175e1e9a4bfSMitsuru IWASAKI }
2176e1e9a4bfSMitsuru IWASAKI 
21778e6a8737SNate Lawson static const char *acpi_pm_profiles[] = {
21788e6a8737SNate Lawson 	"Unspecified", "Desktop", "Mobile", "Workstation",
21798e6a8737SNate Lawson 	"Enterprise Server", "SOHO Server", "Appliance PC"
21808e6a8737SNate Lawson };
21818e6a8737SNate Lawson 
2182945137d9SNate Lawson static void
2183986dffafSJohn Baldwin acpi_print_fadt(ACPI_TABLE_HEADER *sdp)
2184e1e9a4bfSMitsuru IWASAKI {
2185986dffafSJohn Baldwin 	ACPI_TABLE_FADT *fadt;
21868e6a8737SNate Lawson 	const char *pm;
2187e1e9a4bfSMitsuru IWASAKI 
2188986dffafSJohn Baldwin 	fadt = (ACPI_TABLE_FADT *)sdp;
2189c62f1cccSMitsuru IWASAKI 	printf(BEGIN_COMMENT);
21902177d4e6SNate Lawson 	acpi_print_sdt(sdp);
2191986dffafSJohn Baldwin 	printf(" \tFACS=0x%x, DSDT=0x%x\n", fadt->Facs,
2192986dffafSJohn Baldwin 	       fadt->Dsdt);
2193986dffafSJohn Baldwin 	printf("\tINT_MODEL=%s\n", fadt->Model ? "APIC" : "PIC");
2194986dffafSJohn Baldwin 	if (fadt->PreferredProfile >= sizeof(acpi_pm_profiles) / sizeof(char *))
21958e6a8737SNate Lawson 		pm = "Reserved";
21968e6a8737SNate Lawson 	else
2197986dffafSJohn Baldwin 		pm = acpi_pm_profiles[fadt->PreferredProfile];
2198986dffafSJohn Baldwin 	printf("\tPreferred_PM_Profile=%s (%d)\n", pm, fadt->PreferredProfile);
2199986dffafSJohn Baldwin 	printf("\tSCI_INT=%d\n", fadt->SciInterrupt);
2200986dffafSJohn Baldwin 	printf("\tSMI_CMD=0x%x, ", fadt->SmiCommand);
2201986dffafSJohn Baldwin 	printf("ACPI_ENABLE=0x%x, ", fadt->AcpiEnable);
2202986dffafSJohn Baldwin 	printf("ACPI_DISABLE=0x%x, ", fadt->AcpiDisable);
2203986dffafSJohn Baldwin 	printf("S4BIOS_REQ=0x%x\n", fadt->S4BiosRequest);
2204986dffafSJohn Baldwin 	printf("\tPSTATE_CNT=0x%x\n", fadt->PstateControl);
2205e1e9a4bfSMitsuru IWASAKI 	printf("\tPM1a_EVT_BLK=0x%x-0x%x\n",
2206986dffafSJohn Baldwin 	       fadt->Pm1aEventBlock,
2207986dffafSJohn Baldwin 	       fadt->Pm1aEventBlock + fadt->Pm1EventLength - 1);
2208986dffafSJohn Baldwin 	if (fadt->Pm1bEventBlock != 0)
2209e1e9a4bfSMitsuru IWASAKI 		printf("\tPM1b_EVT_BLK=0x%x-0x%x\n",
2210986dffafSJohn Baldwin 		       fadt->Pm1bEventBlock,
2211986dffafSJohn Baldwin 		       fadt->Pm1bEventBlock + fadt->Pm1EventLength - 1);
2212e1e9a4bfSMitsuru IWASAKI 	printf("\tPM1a_CNT_BLK=0x%x-0x%x\n",
2213986dffafSJohn Baldwin 	       fadt->Pm1aControlBlock,
2214986dffafSJohn Baldwin 	       fadt->Pm1aControlBlock + fadt->Pm1ControlLength - 1);
2215986dffafSJohn Baldwin 	if (fadt->Pm1bControlBlock != 0)
2216e1e9a4bfSMitsuru IWASAKI 		printf("\tPM1b_CNT_BLK=0x%x-0x%x\n",
2217986dffafSJohn Baldwin 		       fadt->Pm1bControlBlock,
2218986dffafSJohn Baldwin 		       fadt->Pm1bControlBlock + fadt->Pm1ControlLength - 1);
2219986dffafSJohn Baldwin 	if (fadt->Pm2ControlBlock != 0)
2220e1e9a4bfSMitsuru IWASAKI 		printf("\tPM2_CNT_BLK=0x%x-0x%x\n",
2221986dffafSJohn Baldwin 		       fadt->Pm2ControlBlock,
2222986dffafSJohn Baldwin 		       fadt->Pm2ControlBlock + fadt->Pm2ControlLength - 1);
2223c08c4e81SNate Lawson 	printf("\tPM_TMR_BLK=0x%x-0x%x\n",
2224986dffafSJohn Baldwin 	       fadt->PmTimerBlock,
2225986dffafSJohn Baldwin 	       fadt->PmTimerBlock + fadt->PmTimerLength - 1);
2226986dffafSJohn Baldwin 	if (fadt->Gpe0Block != 0)
22278e6a8737SNate Lawson 		printf("\tGPE0_BLK=0x%x-0x%x\n",
2228986dffafSJohn Baldwin 		       fadt->Gpe0Block,
2229986dffafSJohn Baldwin 		       fadt->Gpe0Block + fadt->Gpe0BlockLength - 1);
2230986dffafSJohn Baldwin 	if (fadt->Gpe1Block != 0)
22318e6a8737SNate Lawson 		printf("\tGPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n",
2232986dffafSJohn Baldwin 		       fadt->Gpe1Block,
2233986dffafSJohn Baldwin 		       fadt->Gpe1Block + fadt->Gpe1BlockLength - 1,
2234986dffafSJohn Baldwin 		       fadt->Gpe1Base);
2235986dffafSJohn Baldwin 	if (fadt->CstControl != 0)
2236986dffafSJohn Baldwin 		printf("\tCST_CNT=0x%x\n", fadt->CstControl);
223751c1824fSNate Lawson 	printf("\tP_LVL2_LAT=%d us, P_LVL3_LAT=%d us\n",
2238986dffafSJohn Baldwin 	       fadt->C2Latency, fadt->C3Latency);
2239e1e9a4bfSMitsuru IWASAKI 	printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n",
2240986dffafSJohn Baldwin 	       fadt->FlushSize, fadt->FlushStride);
2241e1e9a4bfSMitsuru IWASAKI 	printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n",
2242986dffafSJohn Baldwin 	       fadt->DutyOffset, fadt->DutyWidth);
2243e1e9a4bfSMitsuru IWASAKI 	printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n",
2244986dffafSJohn Baldwin 	       fadt->DayAlarm, fadt->MonthAlarm, fadt->Century);
2245e1e9a4bfSMitsuru IWASAKI 
2246ec650989SNeel Natu #define PRINTFLAG(var, flag)	printflag((var), ACPI_FADT_## flag, #flag)
2247e1e9a4bfSMitsuru IWASAKI 
22488e6a8737SNate Lawson 	printf("\tIAPC_BOOT_ARCH=");
2249986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, LEGACY_DEVICES);
2250986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, 8042);
2251986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, NO_VGA);
2252986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, NO_MSI);
2253986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, NO_ASPM);
2254f6469ce1SAndrew Turner 	PRINTFLAG(fadt->BootFlags, NO_CMOS_RTC);
2255ec650989SNeel Natu 	PRINTFLAG_END();
22568e6a8737SNate Lawson 
22578e6a8737SNate Lawson 	printf("\tFlags=");
2258986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, WBINVD);
2259986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, WBINVD_FLUSH);
2260986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, C1_SUPPORTED);
2261986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, C2_MP_SUPPORTED);
2262986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, POWER_BUTTON);
2263986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, SLEEP_BUTTON);
2264986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, FIXED_RTC);
2265986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, S4_RTC_WAKE);
2266986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, 32BIT_TIMER);
2267986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, DOCKING_SUPPORTED);
2268986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, RESET_REGISTER);
2269986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, SEALED_CASE);
2270986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, HEADLESS);
2271986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, SLEEP_TYPE);
2272986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, PCI_EXPRESS_WAKE);
2273986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, PLATFORM_CLOCK);
2274986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, S4_RTC_VALID);
2275986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, REMOTE_POWER_ON);
2276986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, APIC_CLUSTER);
2277986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, APIC_PHYSICAL);
2278f6469ce1SAndrew Turner 	PRINTFLAG(fadt->Flags, HW_REDUCED);
2279f6469ce1SAndrew Turner 	PRINTFLAG(fadt->Flags, LOW_POWER_S0);
2280ec650989SNeel Natu 	PRINTFLAG_END();
2281e1e9a4bfSMitsuru IWASAKI 
2282e1e9a4bfSMitsuru IWASAKI #undef PRINTFLAG
2283e1e9a4bfSMitsuru IWASAKI 
2284986dffafSJohn Baldwin 	if (fadt->Flags & ACPI_FADT_RESET_REGISTER) {
22858e6a8737SNate Lawson 		printf("\tRESET_REG=");
2286986dffafSJohn Baldwin 		acpi_print_gas(&fadt->ResetRegister);
2287986dffafSJohn Baldwin 		printf(", RESET_VALUE=%#x\n", fadt->ResetValue);
22888e6a8737SNate Lawson 	}
2289c2962974SNate Lawson 	if (acpi_get_fadt_revision(fadt) > 1) {
22907d369c6eSJung-uk Kim 		printf("\tX_FACS=0x%016jx, ", (uintmax_t)fadt->XFacs);
22917d369c6eSJung-uk Kim 		printf("X_DSDT=0x%016jx\n", (uintmax_t)fadt->XDsdt);
2292c08c4e81SNate Lawson 		printf("\tX_PM1a_EVT_BLK=");
2293986dffafSJohn Baldwin 		acpi_print_gas(&fadt->XPm1aEventBlock);
2294986dffafSJohn Baldwin 		if (fadt->XPm1bEventBlock.Address != 0) {
2295c08c4e81SNate Lawson 			printf("\n\tX_PM1b_EVT_BLK=");
2296986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XPm1bEventBlock);
2297c08c4e81SNate Lawson 		}
2298c08c4e81SNate Lawson 		printf("\n\tX_PM1a_CNT_BLK=");
2299986dffafSJohn Baldwin 		acpi_print_gas(&fadt->XPm1aControlBlock);
2300986dffafSJohn Baldwin 		if (fadt->XPm1bControlBlock.Address != 0) {
2301c08c4e81SNate Lawson 			printf("\n\tX_PM1b_CNT_BLK=");
2302986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XPm1bControlBlock);
2303c08c4e81SNate Lawson 		}
2304986dffafSJohn Baldwin 		if (fadt->XPm2ControlBlock.Address != 0) {
2305773b6454SNate Lawson 			printf("\n\tX_PM2_CNT_BLK=");
2306986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XPm2ControlBlock);
2307c08c4e81SNate Lawson 		}
2308773b6454SNate Lawson 		printf("\n\tX_PM_TMR_BLK=");
2309986dffafSJohn Baldwin 		acpi_print_gas(&fadt->XPmTimerBlock);
2310986dffafSJohn Baldwin 		if (fadt->XGpe0Block.Address != 0) {
2311773b6454SNate Lawson 			printf("\n\tX_GPE0_BLK=");
2312986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XGpe0Block);
2313c08c4e81SNate Lawson 		}
2314986dffafSJohn Baldwin 		if (fadt->XGpe1Block.Address != 0) {
2315773b6454SNate Lawson 			printf("\n\tX_GPE1_BLK=");
2316986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XGpe1Block);
2317c08c4e81SNate Lawson 		}
2318773b6454SNate Lawson 		printf("\n");
2319773b6454SNate Lawson 	}
23208e6a8737SNate Lawson 
23218e6a8737SNate Lawson 	printf(END_COMMENT);
23228e6a8737SNate Lawson }
23238e6a8737SNate Lawson 
23248e6a8737SNate Lawson static void
2325986dffafSJohn Baldwin acpi_print_facs(ACPI_TABLE_FACS *facs)
23268e6a8737SNate Lawson {
23278e6a8737SNate Lawson 	printf(BEGIN_COMMENT);
2328986dffafSJohn Baldwin 	printf("  FACS:\tLength=%u, ", facs->Length);
2329986dffafSJohn Baldwin 	printf("HwSig=0x%08x, ", facs->HardwareSignature);
2330986dffafSJohn Baldwin 	printf("Firm_Wake_Vec=0x%08x\n", facs->FirmwareWakingVector);
23318e6a8737SNate Lawson 
2332773b6454SNate Lawson 	printf("\tGlobal_Lock=");
2333986dffafSJohn Baldwin 	if (facs->GlobalLock != 0) {
2334986dffafSJohn Baldwin 		if (facs->GlobalLock & ACPI_GLOCK_PENDING)
23358e6a8737SNate Lawson 			printf("PENDING,");
2336986dffafSJohn Baldwin 		if (facs->GlobalLock & ACPI_GLOCK_OWNED)
23378e6a8737SNate Lawson 			printf("OWNED");
23388e6a8737SNate Lawson 	}
2339773b6454SNate Lawson 	printf("\n");
23408e6a8737SNate Lawson 
2341773b6454SNate Lawson 	printf("\tFlags=");
2342986dffafSJohn Baldwin 	if (facs->Flags & ACPI_FACS_S4_BIOS_PRESENT)
23438e6a8737SNate Lawson 		printf("S4BIOS");
2344773b6454SNate Lawson 	printf("\n");
23458e6a8737SNate Lawson 
23467d369c6eSJung-uk Kim 	if (facs->XFirmwareWakingVector != 0)
23477d369c6eSJung-uk Kim 		printf("\tX_Firm_Wake_Vec=%016jx\n",
23487d369c6eSJung-uk Kim 		    (uintmax_t)facs->XFirmwareWakingVector);
2349986dffafSJohn Baldwin 	printf("\tVersion=%u\n", facs->Version);
23508e6a8737SNate Lawson 
2351c62f1cccSMitsuru IWASAKI 	printf(END_COMMENT);
2352e1e9a4bfSMitsuru IWASAKI }
2353e1e9a4bfSMitsuru IWASAKI 
2354945137d9SNate Lawson static void
2355986dffafSJohn Baldwin acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp)
2356e1e9a4bfSMitsuru IWASAKI {
2357773b6454SNate Lawson 	printf(BEGIN_COMMENT);
2358773b6454SNate Lawson 	acpi_print_sdt(dsdp);
2359773b6454SNate Lawson 	printf(END_COMMENT);
2360e1e9a4bfSMitsuru IWASAKI }
2361e1e9a4bfSMitsuru IWASAKI 
2362e1e9a4bfSMitsuru IWASAKI int
2363e1e9a4bfSMitsuru IWASAKI acpi_checksum(void *p, size_t length)
2364e1e9a4bfSMitsuru IWASAKI {
2365986dffafSJohn Baldwin 	uint8_t *bp;
2366986dffafSJohn Baldwin 	uint8_t sum;
2367e1e9a4bfSMitsuru IWASAKI 
2368e1e9a4bfSMitsuru IWASAKI 	bp = p;
2369e1e9a4bfSMitsuru IWASAKI 	sum = 0;
2370e1e9a4bfSMitsuru IWASAKI 	while (length--)
2371e1e9a4bfSMitsuru IWASAKI 		sum += *bp++;
2372e1e9a4bfSMitsuru IWASAKI 
2373e1e9a4bfSMitsuru IWASAKI 	return (sum);
2374e1e9a4bfSMitsuru IWASAKI }
2375e1e9a4bfSMitsuru IWASAKI 
2376986dffafSJohn Baldwin static ACPI_TABLE_HEADER *
2377e1e9a4bfSMitsuru IWASAKI acpi_map_sdt(vm_offset_t pa)
2378e1e9a4bfSMitsuru IWASAKI {
2379986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *sp;
2380e1e9a4bfSMitsuru IWASAKI 
2381986dffafSJohn Baldwin 	sp = acpi_map_physical(pa, sizeof(ACPI_TABLE_HEADER));
2382986dffafSJohn Baldwin 	sp = acpi_map_physical(pa, sp->Length);
2383e1e9a4bfSMitsuru IWASAKI 	return (sp);
2384e1e9a4bfSMitsuru IWASAKI }
2385e1e9a4bfSMitsuru IWASAKI 
2386945137d9SNate Lawson static void
2387986dffafSJohn Baldwin acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp)
2388e1e9a4bfSMitsuru IWASAKI {
2389c62f1cccSMitsuru IWASAKI 	printf(BEGIN_COMMENT);
2390a74172abSNate Lawson 	printf("  RSD PTR: OEM=");
2391986dffafSJohn Baldwin 	acpi_print_string(rp->OemId, ACPI_OEM_ID_SIZE);
2392986dffafSJohn Baldwin 	printf(", ACPI_Rev=%s (%d)\n", rp->Revision < 2 ? "1.0x" : "2.0x",
2393986dffafSJohn Baldwin 	       rp->Revision);
2394986dffafSJohn Baldwin 	if (rp->Revision < 2) {
2395986dffafSJohn Baldwin 		printf("\tRSDT=0x%08x, cksum=%u\n", rp->RsdtPhysicalAddress,
2396986dffafSJohn Baldwin 		    rp->Checksum);
2397a74172abSNate Lawson 	} else {
23987d369c6eSJung-uk Kim 		printf("\tXSDT=0x%016jx, length=%u, cksum=%u\n",
23997d369c6eSJung-uk Kim 		    (uintmax_t)rp->XsdtPhysicalAddress, rp->Length,
2400986dffafSJohn Baldwin 		    rp->ExtendedChecksum);
2401a74172abSNate Lawson 	}
2402c62f1cccSMitsuru IWASAKI 	printf(END_COMMENT);
2403e1e9a4bfSMitsuru IWASAKI }
2404e1e9a4bfSMitsuru IWASAKI 
2405945137d9SNate Lawson static void
2406986dffafSJohn Baldwin acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp)
2407e1e9a4bfSMitsuru IWASAKI {
2408986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *sdp;
2409986dffafSJohn Baldwin 	ACPI_TABLE_RSDT *rsdt;
2410986dffafSJohn Baldwin 	ACPI_TABLE_XSDT *xsdt;
2411a74172abSNate Lawson 	vm_offset_t addr;
2412a74172abSNate Lawson 	int entries, i;
2413e1e9a4bfSMitsuru IWASAKI 
2414e1e9a4bfSMitsuru IWASAKI 	acpi_print_rsdt(rsdp);
2415986dffafSJohn Baldwin 	rsdt = (ACPI_TABLE_RSDT *)rsdp;
2416986dffafSJohn Baldwin 	xsdt = (ACPI_TABLE_XSDT *)rsdp;
2417986dffafSJohn Baldwin 	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
2418e1e9a4bfSMitsuru IWASAKI 	for (i = 0; i < entries; i++) {
2419fe1d0c2dSJung-uk Kim 		if (addr_size == 4)
2420986dffafSJohn Baldwin 			addr = le32toh(rsdt->TableOffsetEntry[i]);
2421fe1d0c2dSJung-uk Kim 		else
2422986dffafSJohn Baldwin 			addr = le64toh(xsdt->TableOffsetEntry[i]);
2423fe1d0c2dSJung-uk Kim 		if (addr == 0)
2424fe1d0c2dSJung-uk Kim 			continue;
2425986dffafSJohn Baldwin 		sdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
2426986dffafSJohn Baldwin 		if (acpi_checksum(sdp, sdp->Length)) {
24275cf6d493SNate Lawson 			warnx("RSDT entry %d (sig %.4s) is corrupt", i,
2428986dffafSJohn Baldwin 			    sdp->Signature);
24295cf6d493SNate Lawson 			continue;
24305cf6d493SNate Lawson 		}
2431ebc22d04SAlexander Motin 		if (!memcmp(sdp->Signature, ACPI_SIG_BERT, 4))
2432ebc22d04SAlexander Motin 			acpi_handle_bert(sdp);
2433ebc22d04SAlexander Motin 		else if (!memcmp(sdp->Signature, ACPI_SIG_EINJ, 4))
2434ebc22d04SAlexander Motin 			acpi_handle_einj(sdp);
2435ebc22d04SAlexander Motin 		else if (!memcmp(sdp->Signature, ACPI_SIG_ERST, 4))
2436ebc22d04SAlexander Motin 			acpi_handle_erst(sdp);
2437ebc22d04SAlexander Motin 		else if (!memcmp(sdp->Signature, ACPI_SIG_FADT, 4))
24382177d4e6SNate Lawson 			acpi_handle_fadt(sdp);
2439986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_MADT, 4))
2440986dffafSJohn Baldwin 			acpi_handle_madt(sdp);
2441ebc22d04SAlexander Motin 		else if (!memcmp(sdp->Signature, ACPI_SIG_HEST, 4))
2442ebc22d04SAlexander Motin 			acpi_handle_hest(sdp);
2443986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_HPET, 4))
244479d7565cSPeter Wemm 			acpi_handle_hpet(sdp);
2445986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_ECDT, 4))
244655d7ff9eSNate Lawson 			acpi_handle_ecdt(sdp);
2447986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_MCFG, 4))
2448a47e681bSScott Long 			acpi_handle_mcfg(sdp);
244933866658SJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_SLIT, 4))
245033866658SJohn Baldwin 			acpi_handle_slit(sdp);
2451986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_SRAT, 4))
2452a0333ad1SJohn Baldwin 			acpi_handle_srat(sdp);
2453c031c93bSTakanori Watanabe 		else if (!memcmp(sdp->Signature, ACPI_SIG_TCPA, 4))
2454c031c93bSTakanori Watanabe 			acpi_handle_tcpa(sdp);
2455ec650989SNeel Natu 		else if (!memcmp(sdp->Signature, ACPI_SIG_DMAR, 4))
2456ec650989SNeel Natu 			acpi_handle_dmar(sdp);
2457*6d789b61SKonstantin Belousov 		else if (!memcmp(sdp->Signature, ACPI_SIG_IVRS, 4))
2458*6d789b61SKonstantin Belousov 			acpi_handle_ivrs(sdp);
2459340c0022SEd Maste 		else if (!memcmp(sdp->Signature, ACPI_SIG_NFIT, 4))
2460340c0022SEd Maste 			acpi_handle_nfit(sdp);
2461ed26c389SScott Long 		else if (!memcmp(sdp->Signature, ACPI_SIG_WDDT, 4))
2462ed26c389SScott Long 			acpi_handle_wddt(sdp);
24635857fba5SBen Widawsky 		else if (!memcmp(sdp->Signature, ACPI_SIG_LPIT, 4))
24645857fba5SBen Widawsky 			acpi_handle_lpit(sdp);
2465877fc2e3STakanori Watanabe 		else if (!memcmp(sdp->Signature, ACPI_SIG_TPM2, 4))
2466877fc2e3STakanori Watanabe 			acpi_handle_tpm2(sdp);
2467773b6454SNate Lawson 		else {
2468773b6454SNate Lawson 			printf(BEGIN_COMMENT);
2469773b6454SNate Lawson 			acpi_print_sdt(sdp);
2470773b6454SNate Lawson 			printf(END_COMMENT);
2471773b6454SNate Lawson 		}
2472e1e9a4bfSMitsuru IWASAKI 	}
2473e1e9a4bfSMitsuru IWASAKI }
2474c62f1cccSMitsuru IWASAKI 
2475986dffafSJohn Baldwin ACPI_TABLE_HEADER *
2476476daaecSDag-Erling Smørgrav sdt_load_devmem(void)
2477945137d9SNate Lawson {
2478986dffafSJohn Baldwin 	ACPI_TABLE_RSDP *rp;
2479986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *rsdp;
2480945137d9SNate Lawson 
2481945137d9SNate Lawson 	rp = acpi_find_rsd_ptr();
2482945137d9SNate Lawson 	if (!rp)
2483945137d9SNate Lawson 		errx(1, "Can't find ACPI information");
2484945137d9SNate Lawson 
2485945137d9SNate Lawson 	if (tflag)
2486945137d9SNate Lawson 		acpi_print_rsd_ptr(rp);
2487986dffafSJohn Baldwin 	if (rp->Revision < 2) {
2488986dffafSJohn Baldwin 		rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->RsdtPhysicalAddress);
2489986dffafSJohn Baldwin 		if (memcmp(rsdp->Signature, "RSDT", 4) != 0 ||
2490986dffafSJohn Baldwin 		    acpi_checksum(rsdp, rsdp->Length) != 0)
2491945137d9SNate Lawson 			errx(1, "RSDT is corrupted");
2492a74172abSNate Lawson 		addr_size = sizeof(uint32_t);
2493a74172abSNate Lawson 	} else {
2494986dffafSJohn Baldwin 		rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->XsdtPhysicalAddress);
2495986dffafSJohn Baldwin 		if (memcmp(rsdp->Signature, "XSDT", 4) != 0 ||
2496986dffafSJohn Baldwin 		    acpi_checksum(rsdp, rsdp->Length) != 0)
2497a74172abSNate Lawson 			errx(1, "XSDT is corrupted");
2498a74172abSNate Lawson 		addr_size = sizeof(uint64_t);
2499a74172abSNate Lawson 	}
2500945137d9SNate Lawson 	return (rsdp);
2501945137d9SNate Lawson }
2502c62f1cccSMitsuru IWASAKI 
250362c7bde1SNate Lawson /* Write the DSDT to a file, concatenating any SSDTs (if present). */
2504bfa3f012SMarcel Moolenaar static int
2505986dffafSJohn Baldwin write_dsdt(int fd, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdt)
2506bfa3f012SMarcel Moolenaar {
2507986dffafSJohn Baldwin 	ACPI_TABLE_HEADER sdt;
2508986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *ssdt;
2509bfa3f012SMarcel Moolenaar 	uint8_t sum;
2510bfa3f012SMarcel Moolenaar 
251162c7bde1SNate Lawson 	/* Create a new checksum to account for the DSDT and any SSDTs. */
2512bfa3f012SMarcel Moolenaar 	sdt = *dsdt;
2513bfa3f012SMarcel Moolenaar 	if (rsdt != NULL) {
2514986dffafSJohn Baldwin 		sdt.Checksum = 0;
2515986dffafSJohn Baldwin 		sum = acpi_checksum(dsdt + 1, dsdt->Length -
2516986dffafSJohn Baldwin 		    sizeof(ACPI_TABLE_HEADER));
2517986dffafSJohn Baldwin 		ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, NULL);
2518f7675a56SNate Lawson 		while (ssdt != NULL) {
2519986dffafSJohn Baldwin 			sdt.Length += ssdt->Length - sizeof(ACPI_TABLE_HEADER);
2520986dffafSJohn Baldwin 			sum += acpi_checksum(ssdt + 1,
2521986dffafSJohn Baldwin 			    ssdt->Length - sizeof(ACPI_TABLE_HEADER));
2522986dffafSJohn Baldwin 			ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, ssdt);
2523bfa3f012SMarcel Moolenaar 		}
2524986dffafSJohn Baldwin 		sum += acpi_checksum(&sdt, sizeof(ACPI_TABLE_HEADER));
2525986dffafSJohn Baldwin 		sdt.Checksum -= sum;
2526bfa3f012SMarcel Moolenaar 	}
252762c7bde1SNate Lawson 
252862c7bde1SNate Lawson 	/* Write out the DSDT header and body. */
2529986dffafSJohn Baldwin 	write(fd, &sdt, sizeof(ACPI_TABLE_HEADER));
2530986dffafSJohn Baldwin 	write(fd, dsdt + 1, dsdt->Length - sizeof(ACPI_TABLE_HEADER));
253162c7bde1SNate Lawson 
2532b64e1b67SNate Lawson 	/* Write out any SSDTs (if present.) */
2533f7675a56SNate Lawson 	if (rsdt != NULL) {
2534bfa3f012SMarcel Moolenaar 		ssdt = sdt_from_rsdt(rsdt, "SSDT", NULL);
2535bfa3f012SMarcel Moolenaar 		while (ssdt != NULL) {
2536986dffafSJohn Baldwin 			write(fd, ssdt + 1, ssdt->Length -
2537986dffafSJohn Baldwin 			    sizeof(ACPI_TABLE_HEADER));
2538bfa3f012SMarcel Moolenaar 			ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt);
2539bfa3f012SMarcel Moolenaar 		}
2540bfa3f012SMarcel Moolenaar 	}
2541bfa3f012SMarcel Moolenaar 	return (0);
2542bfa3f012SMarcel Moolenaar }
2543bfa3f012SMarcel Moolenaar 
2544c62f1cccSMitsuru IWASAKI void
2545986dffafSJohn Baldwin dsdt_save_file(char *outfile, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
2546c62f1cccSMitsuru IWASAKI {
2547945137d9SNate Lawson 	int	fd;
2548945137d9SNate Lawson 	mode_t	mode;
2549945137d9SNate Lawson 
2550945137d9SNate Lawson 	assert(outfile != NULL);
2551945137d9SNate Lawson 	mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
2552945137d9SNate Lawson 	fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, mode);
2553945137d9SNate Lawson 	if (fd == -1) {
2554945137d9SNate Lawson 		perror("dsdt_save_file");
2555945137d9SNate Lawson 		return;
2556945137d9SNate Lawson 	}
2557bfa3f012SMarcel Moolenaar 	write_dsdt(fd, rsdt, dsdp);
2558945137d9SNate Lawson 	close(fd);
2559c62f1cccSMitsuru IWASAKI }
2560c62f1cccSMitsuru IWASAKI 
2561945137d9SNate Lawson void
2562986dffafSJohn Baldwin aml_disassemble(ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
2563c62f1cccSMitsuru IWASAKI {
25647e2cc014SDon Lewis 	char buf[PATH_MAX], tmpstr[PATH_MAX], wrkdir[PATH_MAX];
25657e2cc014SDon Lewis 	const char *iname = "/acpdump.din";
25667e2cc014SDon Lewis 	const char *oname = "/acpdump.dsl";
256799065116SJung-uk Kim 	const char *tmpdir;
2568945137d9SNate Lawson 	FILE *fp;
256999065116SJung-uk Kim 	size_t len;
25707e2cc014SDon Lewis 	int fd, status;
25717e2cc014SDon Lewis 	pid_t pid;
2572945137d9SNate Lawson 
257399065116SJung-uk Kim 	tmpdir = getenv("TMPDIR");
257499065116SJung-uk Kim 	if (tmpdir == NULL)
257599065116SJung-uk Kim 		tmpdir = _PATH_TMP;
25767e2cc014SDon Lewis 	if (realpath(tmpdir, buf) == NULL) {
2577d6a6e590SJung-uk Kim 		perror("realpath tmp dir");
257899065116SJung-uk Kim 		return;
257999065116SJung-uk Kim 	}
25807e2cc014SDon Lewis 	len = sizeof(wrkdir) - strlen(iname);
25817e2cc014SDon Lewis 	if ((size_t)snprintf(wrkdir, len, "%s/acpidump.XXXXXX", buf) > len-1 ) {
25827e2cc014SDon Lewis 		fprintf(stderr, "$TMPDIR too long\n");
25837e2cc014SDon Lewis 		return;
25847e2cc014SDon Lewis 	}
25857e2cc014SDon Lewis 	if  (mkdtemp(wrkdir) == NULL) {
25867e2cc014SDon Lewis 		perror("mkdtemp tmp working dir");
25877e2cc014SDon Lewis 		return;
25887e2cc014SDon Lewis 	}
258930bebccaSMaxim Konovalov 	len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, iname);
259030bebccaSMaxim Konovalov 	assert(len <= sizeof(tmpstr) - 1);
25917e2cc014SDon Lewis 	fd = open(tmpstr, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
2592945137d9SNate Lawson 	if (fd < 0) {
2593945137d9SNate Lawson 		perror("iasl tmp file");
2594945137d9SNate Lawson 		return;
2595c62f1cccSMitsuru IWASAKI 	}
2596bfa3f012SMarcel Moolenaar 	write_dsdt(fd, rsdt, dsdp);
2597945137d9SNate Lawson 	close(fd);
2598945137d9SNate Lawson 
2599945137d9SNate Lawson 	/* Run iasl -d on the temp file */
26007e2cc014SDon Lewis 	if ((pid = fork()) == 0) {
2601945137d9SNate Lawson 		close(STDOUT_FILENO);
2602945137d9SNate Lawson 		if (vflag == 0)
2603945137d9SNate Lawson 			close(STDERR_FILENO);
260499065116SJung-uk Kim 		execl("/usr/sbin/iasl", "iasl", "-d", tmpstr, NULL);
2605945137d9SNate Lawson 		err(1, "exec");
2606c62f1cccSMitsuru IWASAKI 	}
26077e2cc014SDon Lewis 	if (pid > 0)
26087e2cc014SDon Lewis 		wait(&status);
26097e2cc014SDon Lewis 	if (unlink(tmpstr) < 0) {
26107e2cc014SDon Lewis 		perror("unlink");
26117e2cc014SDon Lewis 		goto out;
26127e2cc014SDon Lewis 	}
26137e2cc014SDon Lewis 	if (pid < 0) {
26147e2cc014SDon Lewis 		perror("fork");
26157e2cc014SDon Lewis 		goto out;
26167e2cc014SDon Lewis 	}
26177e2cc014SDon Lewis 	if (status != 0) {
2618861f5b95SSHENG-YI HONG 		fprintf(stderr, "iasl exit status = %d\n", status);
26197e2cc014SDon Lewis 	}
2620945137d9SNate Lawson 
2621945137d9SNate Lawson 	/* Dump iasl's output to stdout */
262230bebccaSMaxim Konovalov 	len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, oname);
262330bebccaSMaxim Konovalov 	assert(len <= sizeof(tmpstr) - 1);
262499065116SJung-uk Kim 	fp = fopen(tmpstr, "r");
26257e2cc014SDon Lewis 	if (unlink(tmpstr) < 0) {
26267e2cc014SDon Lewis 		perror("unlink");
26277e2cc014SDon Lewis 		goto out;
26287e2cc014SDon Lewis 	}
2629945137d9SNate Lawson 	if (fp == NULL) {
2630945137d9SNate Lawson 		perror("iasl tmp file (read)");
26317e2cc014SDon Lewis 		goto out;
2632945137d9SNate Lawson 	}
2633945137d9SNate Lawson 	while ((len = fread(buf, 1, sizeof(buf), fp)) > 0)
2634945137d9SNate Lawson 		fwrite(buf, 1, len, stdout);
2635945137d9SNate Lawson 	fclose(fp);
26367e2cc014SDon Lewis 
26377e2cc014SDon Lewis     out:
26387e2cc014SDon Lewis 	if (rmdir(wrkdir) < 0)
26397e2cc014SDon Lewis 		perror("rmdir");
2640c62f1cccSMitsuru IWASAKI }
2641c62f1cccSMitsuru IWASAKI 
2642945137d9SNate Lawson void
2643986dffafSJohn Baldwin sdt_print_all(ACPI_TABLE_HEADER *rsdp)
2644c62f1cccSMitsuru IWASAKI {
2645945137d9SNate Lawson 	acpi_handle_rsdt(rsdp);
2646c62f1cccSMitsuru IWASAKI }
2647c62f1cccSMitsuru IWASAKI 
2648bfa3f012SMarcel Moolenaar /* Fetch a table matching the given signature via the RSDT. */
2649986dffafSJohn Baldwin ACPI_TABLE_HEADER *
2650986dffafSJohn Baldwin sdt_from_rsdt(ACPI_TABLE_HEADER *rsdp, const char *sig, ACPI_TABLE_HEADER *last)
2651c62f1cccSMitsuru IWASAKI {
2652986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *sdt;
2653986dffafSJohn Baldwin 	ACPI_TABLE_RSDT *rsdt;
2654986dffafSJohn Baldwin 	ACPI_TABLE_XSDT *xsdt;
2655a74172abSNate Lawson 	vm_offset_t addr;
2656a74172abSNate Lawson 	int entries, i;
2657945137d9SNate Lawson 
2658986dffafSJohn Baldwin 	rsdt = (ACPI_TABLE_RSDT *)rsdp;
2659986dffafSJohn Baldwin 	xsdt = (ACPI_TABLE_XSDT *)rsdp;
2660986dffafSJohn Baldwin 	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
2661945137d9SNate Lawson 	for (i = 0; i < entries; i++) {
2662fe1d0c2dSJung-uk Kim 		if (addr_size == 4)
2663986dffafSJohn Baldwin 			addr = le32toh(rsdt->TableOffsetEntry[i]);
2664fe1d0c2dSJung-uk Kim 		else
2665986dffafSJohn Baldwin 			addr = le64toh(xsdt->TableOffsetEntry[i]);
2666fe1d0c2dSJung-uk Kim 		if (addr == 0)
2667fe1d0c2dSJung-uk Kim 			continue;
2668986dffafSJohn Baldwin 		sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
2669bfa3f012SMarcel Moolenaar 		if (last != NULL) {
2670bfa3f012SMarcel Moolenaar 			if (sdt == last)
2671bfa3f012SMarcel Moolenaar 				last = NULL;
2672bfa3f012SMarcel Moolenaar 			continue;
2673bfa3f012SMarcel Moolenaar 		}
2674986dffafSJohn Baldwin 		if (memcmp(sdt->Signature, sig, strlen(sig)))
2675a74172abSNate Lawson 			continue;
2676986dffafSJohn Baldwin 		if (acpi_checksum(sdt, sdt->Length))
2677945137d9SNate Lawson 			errx(1, "RSDT entry %d is corrupt", i);
2678945137d9SNate Lawson 		return (sdt);
2679c62f1cccSMitsuru IWASAKI 	}
2680c62f1cccSMitsuru IWASAKI 
2681945137d9SNate Lawson 	return (NULL);
2682c62f1cccSMitsuru IWASAKI }
2683c62f1cccSMitsuru IWASAKI 
2684986dffafSJohn Baldwin ACPI_TABLE_HEADER *
2685986dffafSJohn Baldwin dsdt_from_fadt(ACPI_TABLE_FADT *fadt)
2686c62f1cccSMitsuru IWASAKI {
2687986dffafSJohn Baldwin 	ACPI_TABLE_HEADER	*sdt;
2688c62f1cccSMitsuru IWASAKI 
2689986dffafSJohn Baldwin 	/* Use the DSDT address if it is version 1, otherwise use XDSDT. */
2690c2962974SNate Lawson 	if (acpi_get_fadt_revision(fadt) == 1)
2691986dffafSJohn Baldwin 		sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt);
26922e71eb12SNate Lawson 	else
2693986dffafSJohn Baldwin 		sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt);
2694986dffafSJohn Baldwin 	if (acpi_checksum(sdt, sdt->Length))
2695945137d9SNate Lawson 		errx(1, "DSDT is corrupt\n");
2696945137d9SNate Lawson 	return (sdt);
2697c62f1cccSMitsuru IWASAKI }
2698