xref: /freebsd/usr.sbin/acpi/acpidump/acpi.c (revision 3b7935f33b50aa69637e722c3d3fd275c0efd3cd)
1e1e9a4bfSMitsuru IWASAKI /*-
21de7b4b8SPedro F. Giffuni  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
31de7b4b8SPedro F. Giffuni  *
4e1e9a4bfSMitsuru IWASAKI  * Copyright (c) 1998 Doug Rabson
5e1e9a4bfSMitsuru IWASAKI  * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
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  *	$FreeBSD$
31e1e9a4bfSMitsuru IWASAKI  */
32e1e9a4bfSMitsuru IWASAKI 
33e1e9a4bfSMitsuru IWASAKI #include <sys/param.h>
34a74172abSNate Lawson #include <sys/endian.h>
35e1e9a4bfSMitsuru IWASAKI #include <sys/stat.h>
36945137d9SNate Lawson #include <sys/wait.h>
37e1e9a4bfSMitsuru IWASAKI #include <assert.h>
38e1e9a4bfSMitsuru IWASAKI #include <err.h>
39e1e9a4bfSMitsuru IWASAKI #include <fcntl.h>
4099065116SJung-uk Kim #include <paths.h>
41e1e9a4bfSMitsuru IWASAKI #include <stdio.h>
42a0333ad1SJohn Baldwin #include <stdint.h>
4399065116SJung-uk Kim #include <stdlib.h>
44945137d9SNate Lawson #include <string.h>
45e1e9a4bfSMitsuru IWASAKI #include <unistd.h>
46340c0022SEd Maste #include <uuid.h>
47e1e9a4bfSMitsuru IWASAKI 
48e1e9a4bfSMitsuru IWASAKI #include "acpidump.h"
49e1e9a4bfSMitsuru IWASAKI 
50c62f1cccSMitsuru IWASAKI #define BEGIN_COMMENT	"/*\n"
51c62f1cccSMitsuru IWASAKI #define END_COMMENT	" */\n"
52c62f1cccSMitsuru IWASAKI 
53945137d9SNate Lawson static void	acpi_print_string(char *s, size_t length);
54986dffafSJohn Baldwin static void	acpi_print_gas(ACPI_GENERIC_ADDRESS *gas);
55986dffafSJohn Baldwin static int	acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt);
56986dffafSJohn Baldwin static void	acpi_handle_fadt(ACPI_TABLE_HEADER *fadt);
57945137d9SNate Lawson static void	acpi_print_cpu(u_char cpu_id);
58986dffafSJohn Baldwin static void	acpi_print_cpu_uid(uint32_t uid, char *uid_string);
59986dffafSJohn Baldwin static void	acpi_print_local_apic(uint32_t apic_id, uint32_t flags);
60986dffafSJohn Baldwin static void	acpi_print_io_apic(uint32_t apic_id, uint32_t int_base,
61986dffafSJohn Baldwin 		    uint64_t apic_addr);
62986dffafSJohn Baldwin static void	acpi_print_mps_flags(uint16_t flags);
63986dffafSJohn Baldwin static void	acpi_print_intr(uint32_t intr, uint16_t mps_flags);
64986dffafSJohn Baldwin static void	acpi_print_local_nmi(u_int lint, uint16_t mps_flags);
65986dffafSJohn Baldwin static void	acpi_print_madt(ACPI_SUBTABLE_HEADER *mp);
66986dffafSJohn Baldwin static void	acpi_handle_madt(ACPI_TABLE_HEADER *sdp);
67986dffafSJohn Baldwin static void	acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp);
68986dffafSJohn Baldwin static void	acpi_handle_hpet(ACPI_TABLE_HEADER *sdp);
69986dffafSJohn Baldwin static void	acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp);
7033866658SJohn Baldwin static void	acpi_handle_slit(ACPI_TABLE_HEADER *sdp);
71ed26c389SScott Long static void	acpi_handle_wddt(ACPI_TABLE_HEADER *sdp);
725857fba5SBen Widawsky static void	acpi_handle_lpit(ACPI_TABLE_HEADER *sdp);
73a0333ad1SJohn Baldwin static void	acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain,
74a0333ad1SJohn Baldwin 		    uint32_t flags);
75986dffafSJohn Baldwin static void	acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp);
76986dffafSJohn Baldwin static void	acpi_print_srat(ACPI_SUBTABLE_HEADER *srat);
77986dffafSJohn Baldwin static void	acpi_handle_srat(ACPI_TABLE_HEADER *sdp);
78c031c93bSTakanori Watanabe static void	acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp);
79340c0022SEd Maste static void	acpi_print_nfit(ACPI_NFIT_HEADER *nfit);
80340c0022SEd Maste static void	acpi_handle_nfit(ACPI_TABLE_HEADER *sdp);
81986dffafSJohn Baldwin static void	acpi_print_sdt(ACPI_TABLE_HEADER *sdp);
82986dffafSJohn Baldwin static void	acpi_print_fadt(ACPI_TABLE_HEADER *sdp);
83986dffafSJohn Baldwin static void	acpi_print_facs(ACPI_TABLE_FACS *facs);
84986dffafSJohn Baldwin static void	acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp);
85986dffafSJohn Baldwin static ACPI_TABLE_HEADER *acpi_map_sdt(vm_offset_t pa);
86986dffafSJohn Baldwin static void	acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp);
87986dffafSJohn Baldwin static void	acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp);
88986dffafSJohn Baldwin static void	acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
89986dffafSJohn Baldwin 		    void (*action)(ACPI_SUBTABLE_HEADER *));
90340c0022SEd Maste static void	acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first,
91340c0022SEd Maste 		    void (*action)(ACPI_NFIT_HEADER *));
92c62f1cccSMitsuru IWASAKI 
93773b6454SNate Lawson /* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up. */
94a74172abSNate Lawson static int addr_size;
95a74172abSNate Lawson 
96c031c93bSTakanori Watanabe /* Strings used in the TCPA table */
97c031c93bSTakanori Watanabe static const char *tcpa_event_type_strings[] = {
98c031c93bSTakanori Watanabe 	"PREBOOT Certificate",
99c031c93bSTakanori Watanabe 	"POST Code",
100c031c93bSTakanori Watanabe 	"Unused",
101c031c93bSTakanori Watanabe 	"No Action",
102c031c93bSTakanori Watanabe 	"Separator",
103c031c93bSTakanori Watanabe 	"Action",
104c031c93bSTakanori Watanabe 	"Event Tag",
105c031c93bSTakanori Watanabe 	"S-CRTM Contents",
106c031c93bSTakanori Watanabe 	"S-CRTM Version",
107c031c93bSTakanori Watanabe 	"CPU Microcode",
108c031c93bSTakanori Watanabe 	"Platform Config Flags",
109c031c93bSTakanori Watanabe 	"Table of Devices",
110c031c93bSTakanori Watanabe 	"Compact Hash",
111c031c93bSTakanori Watanabe 	"IPL",
112c031c93bSTakanori Watanabe 	"IPL Partition Data",
113c031c93bSTakanori Watanabe 	"Non-Host Code",
114c031c93bSTakanori Watanabe 	"Non-Host Config",
115c031c93bSTakanori Watanabe 	"Non-Host Info"
116c031c93bSTakanori Watanabe };
117c031c93bSTakanori Watanabe 
118c031c93bSTakanori Watanabe static const char *TCPA_pcclient_strings[] = {
119c031c93bSTakanori Watanabe 	"<undefined>",
120c031c93bSTakanori Watanabe 	"SMBIOS",
121c031c93bSTakanori Watanabe 	"BIS Certificate",
122c031c93bSTakanori Watanabe 	"POST BIOS ROM Strings",
123c031c93bSTakanori Watanabe 	"ESCD",
124c031c93bSTakanori Watanabe 	"CMOS",
125c031c93bSTakanori Watanabe 	"NVRAM",
126c031c93bSTakanori Watanabe 	"Option ROM Execute",
127c031c93bSTakanori Watanabe 	"Option ROM Configurateion",
128c031c93bSTakanori Watanabe 	"<undefined>",
129c031c93bSTakanori Watanabe 	"Option ROM Microcode Update ",
130c031c93bSTakanori Watanabe 	"S-CRTM Version String",
131c031c93bSTakanori Watanabe 	"S-CRTM Contents",
132c031c93bSTakanori Watanabe 	"POST Contents",
133c031c93bSTakanori Watanabe 	"Table of Devices",
134c031c93bSTakanori Watanabe };
135c031c93bSTakanori Watanabe 
136ec650989SNeel Natu #define	PRINTFLAG_END()		printflag_end()
137ec650989SNeel Natu 
138ec650989SNeel Natu static char pf_sep = '{';
139ec650989SNeel Natu 
140ec650989SNeel Natu static void
141ec650989SNeel Natu printflag_end(void)
142ec650989SNeel Natu {
143ec650989SNeel Natu 
144ec650989SNeel Natu 	if (pf_sep != '{') {
145ec650989SNeel Natu 		printf("}");
146ec650989SNeel Natu 		pf_sep = '{';
147ec650989SNeel Natu 	}
148ec650989SNeel Natu 	printf("\n");
149ec650989SNeel Natu }
150ec650989SNeel Natu 
151ec650989SNeel Natu static void
152ec650989SNeel Natu printflag(uint64_t var, uint64_t mask, const char *name)
153ec650989SNeel Natu {
154ec650989SNeel Natu 
155ec650989SNeel Natu 	if (var & mask) {
156ec650989SNeel Natu 		printf("%c%s", pf_sep, name);
157ec650989SNeel Natu 		pf_sep = ',';
158ec650989SNeel Natu 	}
159ec650989SNeel Natu }
160ec650989SNeel Natu 
161e1e9a4bfSMitsuru IWASAKI static void
162e1e9a4bfSMitsuru IWASAKI acpi_print_string(char *s, size_t length)
163e1e9a4bfSMitsuru IWASAKI {
164e1e9a4bfSMitsuru IWASAKI 	int	c;
165e1e9a4bfSMitsuru IWASAKI 
166e1e9a4bfSMitsuru IWASAKI 	/* Trim trailing spaces and NULLs */
167e1e9a4bfSMitsuru IWASAKI 	while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0'))
168e1e9a4bfSMitsuru IWASAKI 		length--;
169e1e9a4bfSMitsuru IWASAKI 
170e1e9a4bfSMitsuru IWASAKI 	while (length--) {
171e1e9a4bfSMitsuru IWASAKI 		c = *s++;
172e1e9a4bfSMitsuru IWASAKI 		putchar(c);
173e1e9a4bfSMitsuru IWASAKI 	}
174e1e9a4bfSMitsuru IWASAKI }
175e1e9a4bfSMitsuru IWASAKI 
176e1e9a4bfSMitsuru IWASAKI static void
177986dffafSJohn Baldwin acpi_print_gas(ACPI_GENERIC_ADDRESS *gas)
1788e6a8737SNate Lawson {
179986dffafSJohn Baldwin 	switch(gas->SpaceId) {
1808e6a8737SNate Lawson 	case ACPI_GAS_MEMORY:
181ebc22d04SAlexander Motin 		printf("0x%016jx:%u[%u] (Memory)", (uintmax_t)gas->Address,
182ebc22d04SAlexander Motin 		    gas->BitOffset, gas->BitWidth);
1838e6a8737SNate Lawson 		break;
1848e6a8737SNate Lawson 	case ACPI_GAS_IO:
185ebc22d04SAlexander Motin 		printf("0x%02jx:%u[%u] (IO)", (uintmax_t)gas->Address,
186986dffafSJohn Baldwin 		    gas->BitOffset, gas->BitWidth);
1878e6a8737SNate Lawson 		break;
1888e6a8737SNate Lawson 	case ACPI_GAS_PCI:
189ebc22d04SAlexander Motin 		printf("%x:%x+0x%x:%u[%u] (PCI)", (uint16_t)(gas->Address >> 32),
190986dffafSJohn Baldwin 		       (uint16_t)((gas->Address >> 16) & 0xffff),
191ebc22d04SAlexander Motin 		       (uint16_t)gas->Address, gas->BitOffset, gas->BitWidth);
1928e6a8737SNate Lawson 		break;
1938e6a8737SNate Lawson 	/* XXX How to handle these below? */
1948e6a8737SNate Lawson 	case ACPI_GAS_EMBEDDED:
195986dffafSJohn Baldwin 		printf("0x%x:%u[%u] (EC)", (uint16_t)gas->Address,
196986dffafSJohn Baldwin 		       gas->BitOffset, gas->BitWidth);
1978e6a8737SNate Lawson 		break;
1988e6a8737SNate Lawson 	case ACPI_GAS_SMBUS:
199986dffafSJohn Baldwin 		printf("0x%x:%u[%u] (SMBus)", (uint16_t)gas->Address,
200986dffafSJohn Baldwin 		       gas->BitOffset, gas->BitWidth);
2018e6a8737SNate Lawson 		break;
202986dffafSJohn Baldwin 	case ACPI_GAS_CMOS:
203986dffafSJohn Baldwin 	case ACPI_GAS_PCIBAR:
204986dffafSJohn Baldwin 	case ACPI_GAS_DATATABLE:
2058e6a8737SNate Lawson 	case ACPI_GAS_FIXED:
2068e6a8737SNate Lawson 	default:
2077d369c6eSJung-uk Kim 		printf("0x%016jx (?)", (uintmax_t)gas->Address);
2088e6a8737SNate Lawson 		break;
2098e6a8737SNate Lawson 	}
2108e6a8737SNate Lawson }
2118e6a8737SNate Lawson 
212c2962974SNate Lawson /* The FADT revision indicates whether we use the DSDT or X_DSDT addresses. */
213c2962974SNate Lawson static int
214986dffafSJohn Baldwin acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt)
215e1e9a4bfSMitsuru IWASAKI {
216c2962974SNate Lawson 	int fadt_revision;
217e1e9a4bfSMitsuru IWASAKI 
218c83f0f99SNate Lawson 	/* Set the FADT revision separately from the RSDP version. */
219c83f0f99SNate Lawson 	if (addr_size == 8) {
220c83f0f99SNate Lawson 		fadt_revision = 2;
2218e6a8737SNate Lawson 
22201593a0fSAndrew Turner #if defined(__i386__)
223773b6454SNate Lawson 		/*
224c83f0f99SNate Lawson 		 * A few systems (e.g., IBM T23) have an RSDP that claims
225c83f0f99SNate Lawson 		 * revision 2 but the 64 bit addresses are invalid.  If
226c83f0f99SNate Lawson 		 * revision 2 and the 32 bit address is non-zero but the
227c83f0f99SNate Lawson 		 * 32 and 64 bit versions don't match, prefer the 32 bit
228c83f0f99SNate Lawson 		 * version for all subsequent tables.
22901593a0fSAndrew Turner 		 *
23001593a0fSAndrew Turner 		 * The only known ACPI systems this affects are early
23101593a0fSAndrew Turner 		 * implementations on 32-bit x86. Because of this limit the
23201593a0fSAndrew Turner 		 * workaround to i386.
233773b6454SNate Lawson 		 */
234986dffafSJohn Baldwin 		if (fadt->Facs != 0 &&
235986dffafSJohn Baldwin 		    (fadt->XFacs & 0xffffffff) != fadt->Facs)
236c83f0f99SNate Lawson 			fadt_revision = 1;
23701593a0fSAndrew Turner #endif
238c2962974SNate Lawson 	} else
239c83f0f99SNate Lawson 		fadt_revision = 1;
240c2962974SNate Lawson 	return (fadt_revision);
241c83f0f99SNate Lawson }
242c2962974SNate Lawson 
243c2962974SNate Lawson static void
244986dffafSJohn Baldwin acpi_handle_fadt(ACPI_TABLE_HEADER *sdp)
245c2962974SNate Lawson {
246986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *dsdp;
247986dffafSJohn Baldwin 	ACPI_TABLE_FACS	*facs;
248986dffafSJohn Baldwin 	ACPI_TABLE_FADT *fadt;
249bc711181SAndrew Turner 	vm_offset_t	addr;
250c2962974SNate Lawson 	int		fadt_revision;
251c2962974SNate Lawson 
252986dffafSJohn Baldwin 	fadt = (ACPI_TABLE_FADT *)sdp;
2532177d4e6SNate Lawson 	acpi_print_fadt(sdp);
254c83f0f99SNate Lawson 
255c2962974SNate Lawson 	fadt_revision = acpi_get_fadt_revision(fadt);
256c83f0f99SNate Lawson 	if (fadt_revision == 1)
257bc711181SAndrew Turner 		addr = fadt->Facs;
258773b6454SNate Lawson 	else
259bc711181SAndrew Turner 		addr = fadt->XFacs;
260bc711181SAndrew Turner 	if (addr != 0) {
261bc711181SAndrew Turner 		facs = (ACPI_TABLE_FACS *)acpi_map_sdt(addr);
262bc711181SAndrew Turner 
263bc711181SAndrew Turner 		if (memcmp(facs->Signature, ACPI_SIG_FACS, 4) != 0 ||
264bc711181SAndrew Turner 		    facs->Length < 64)
2658e6a8737SNate Lawson 			errx(1, "FACS is corrupt");
2668e6a8737SNate Lawson 		acpi_print_facs(facs);
267bc711181SAndrew Turner 	}
2688e6a8737SNate Lawson 
269c83f0f99SNate Lawson 	if (fadt_revision == 1)
270986dffafSJohn Baldwin 		dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt);
271773b6454SNate Lawson 	else
272986dffafSJohn Baldwin 		dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt);
273986dffafSJohn Baldwin 	if (acpi_checksum(dsdp, dsdp->Length))
274945137d9SNate Lawson 		errx(1, "DSDT is corrupt");
275945137d9SNate Lawson 	acpi_print_dsdt(dsdp);
276c62f1cccSMitsuru IWASAKI }
277c62f1cccSMitsuru IWASAKI 
278c62f1cccSMitsuru IWASAKI static void
279986dffafSJohn Baldwin acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
280986dffafSJohn Baldwin     void (*action)(ACPI_SUBTABLE_HEADER *))
281986dffafSJohn Baldwin {
282986dffafSJohn Baldwin 	ACPI_SUBTABLE_HEADER *subtable;
283986dffafSJohn Baldwin 	char *end;
284986dffafSJohn Baldwin 
285986dffafSJohn Baldwin 	subtable = first;
286986dffafSJohn Baldwin 	end = (char *)table + table->Length;
287986dffafSJohn Baldwin 	while ((char *)subtable < end) {
288986dffafSJohn Baldwin 		printf("\n");
289f5d0a8f7SEd Maste 		if (subtable->Length < sizeof(ACPI_SUBTABLE_HEADER)) {
290f5d0a8f7SEd Maste 			warnx("invalid subtable length %u", subtable->Length);
291f5d0a8f7SEd Maste 			return;
292f5d0a8f7SEd Maste 		}
293986dffafSJohn Baldwin 		action(subtable);
294986dffafSJohn Baldwin 		subtable = (ACPI_SUBTABLE_HEADER *)((char *)subtable +
295986dffafSJohn Baldwin 		    subtable->Length);
296986dffafSJohn Baldwin 	}
297986dffafSJohn Baldwin }
298986dffafSJohn Baldwin 
299986dffafSJohn Baldwin static void
300340c0022SEd Maste acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first,
301340c0022SEd Maste     void (*action)(ACPI_NFIT_HEADER *))
302340c0022SEd Maste {
303340c0022SEd Maste 	ACPI_NFIT_HEADER *subtable;
304340c0022SEd Maste 	char *end;
305340c0022SEd Maste 
306340c0022SEd Maste 	subtable = first;
307340c0022SEd Maste 	end = (char *)table + table->Length;
308340c0022SEd Maste 	while ((char *)subtable < end) {
309340c0022SEd Maste 		printf("\n");
310340c0022SEd Maste 		if (subtable->Length < sizeof(ACPI_NFIT_HEADER)) {
311340c0022SEd Maste 			warnx("invalid subtable length %u", subtable->Length);
312340c0022SEd Maste 			return;
313340c0022SEd Maste 		}
314340c0022SEd Maste 		action(subtable);
315340c0022SEd Maste 		subtable = (ACPI_NFIT_HEADER *)((char *)subtable +
316340c0022SEd Maste 		    subtable->Length);
317340c0022SEd Maste 	}
318340c0022SEd Maste }
319340c0022SEd Maste 
320340c0022SEd Maste static void
3210a473124SJohn Baldwin acpi_print_cpu(u_char cpu_id)
3220a473124SJohn Baldwin {
3230a473124SJohn Baldwin 
3240a473124SJohn Baldwin 	printf("\tACPI CPU=");
3250a473124SJohn Baldwin 	if (cpu_id == 0xff)
3260a473124SJohn Baldwin 		printf("ALL\n");
3270a473124SJohn Baldwin 	else
3280a473124SJohn Baldwin 		printf("%d\n", (u_int)cpu_id);
3290a473124SJohn Baldwin }
3300a473124SJohn Baldwin 
3310a473124SJohn Baldwin static void
332986dffafSJohn Baldwin acpi_print_cpu_uid(uint32_t uid, char *uid_string)
3330a473124SJohn Baldwin {
334986dffafSJohn Baldwin 
335986dffafSJohn Baldwin 	printf("\tUID=%d", uid);
336986dffafSJohn Baldwin 	if (uid_string != NULL)
337986dffafSJohn Baldwin 		printf(" (%s)", uid_string);
338986dffafSJohn Baldwin 	printf("\n");
339986dffafSJohn Baldwin }
340986dffafSJohn Baldwin 
341986dffafSJohn Baldwin static void
342986dffafSJohn Baldwin acpi_print_local_apic(uint32_t apic_id, uint32_t flags)
343986dffafSJohn Baldwin {
344986dffafSJohn Baldwin 
3450a473124SJohn Baldwin 	printf("\tFlags={");
346986dffafSJohn Baldwin 	if (flags & ACPI_MADT_ENABLED)
3470a473124SJohn Baldwin 		printf("ENABLED");
3480a473124SJohn Baldwin 	else
3490a473124SJohn Baldwin 		printf("DISABLED");
3500a473124SJohn Baldwin 	printf("}\n");
351986dffafSJohn Baldwin 	printf("\tAPIC ID=%d\n", apic_id);
3520a473124SJohn Baldwin }
3530a473124SJohn Baldwin 
3540a473124SJohn Baldwin static void
355986dffafSJohn Baldwin acpi_print_io_apic(uint32_t apic_id, uint32_t int_base, uint64_t apic_addr)
3560a473124SJohn Baldwin {
357986dffafSJohn Baldwin 
358986dffafSJohn Baldwin 	printf("\tAPIC ID=%d\n", apic_id);
3590a473124SJohn Baldwin 	printf("\tINT BASE=%d\n", int_base);
360986dffafSJohn Baldwin 	printf("\tADDR=0x%016jx\n", (uintmax_t)apic_addr);
3610a473124SJohn Baldwin }
3620a473124SJohn Baldwin 
3630a473124SJohn Baldwin static void
364986dffafSJohn Baldwin acpi_print_mps_flags(uint16_t flags)
3650a473124SJohn Baldwin {
3660a473124SJohn Baldwin 
3670a473124SJohn Baldwin 	printf("\tFlags={Polarity=");
368986dffafSJohn Baldwin 	switch (flags & ACPI_MADT_POLARITY_MASK) {
369986dffafSJohn Baldwin 	case ACPI_MADT_POLARITY_CONFORMS:
3700a473124SJohn Baldwin 		printf("conforming");
3710a473124SJohn Baldwin 		break;
372986dffafSJohn Baldwin 	case ACPI_MADT_POLARITY_ACTIVE_HIGH:
3730a473124SJohn Baldwin 		printf("active-hi");
3740a473124SJohn Baldwin 		break;
375986dffafSJohn Baldwin 	case ACPI_MADT_POLARITY_ACTIVE_LOW:
3760a473124SJohn Baldwin 		printf("active-lo");
3770a473124SJohn Baldwin 		break;
3780a473124SJohn Baldwin 	default:
379986dffafSJohn Baldwin 		printf("0x%x", flags & ACPI_MADT_POLARITY_MASK);
3800a473124SJohn Baldwin 		break;
3810a473124SJohn Baldwin 	}
3820a473124SJohn Baldwin 	printf(", Trigger=");
383986dffafSJohn Baldwin 	switch (flags & ACPI_MADT_TRIGGER_MASK) {
384986dffafSJohn Baldwin 	case ACPI_MADT_TRIGGER_CONFORMS:
3850a473124SJohn Baldwin 		printf("conforming");
3860a473124SJohn Baldwin 		break;
387986dffafSJohn Baldwin 	case ACPI_MADT_TRIGGER_EDGE:
3880a473124SJohn Baldwin 		printf("edge");
3890a473124SJohn Baldwin 		break;
390986dffafSJohn Baldwin 	case ACPI_MADT_TRIGGER_LEVEL:
3910a473124SJohn Baldwin 		printf("level");
3920a473124SJohn Baldwin 		break;
3930a473124SJohn Baldwin 	default:
394986dffafSJohn Baldwin 		printf("0x%x", (flags & ACPI_MADT_TRIGGER_MASK) >> 2);
3950a473124SJohn Baldwin 	}
3960a473124SJohn Baldwin 	printf("}\n");
3970a473124SJohn Baldwin }
3980a473124SJohn Baldwin 
3990a473124SJohn Baldwin static void
4002b2b1f42SAndrew Turner acpi_print_gicc_flags(uint32_t flags)
4012b2b1f42SAndrew Turner {
4022b2b1f42SAndrew Turner 
4032b2b1f42SAndrew Turner 	printf("\tFlags={Performance intr=");
4042b2b1f42SAndrew Turner 	if (flags & ACPI_MADT_PERFORMANCE_IRQ_MODE)
4052b2b1f42SAndrew Turner 		printf("edge");
4062b2b1f42SAndrew Turner 	else
4072b2b1f42SAndrew Turner 		printf("level");
4082b2b1f42SAndrew Turner 	printf(", VGIC intr=");
4092b2b1f42SAndrew Turner 	if (flags & ACPI_MADT_VGIC_IRQ_MODE)
4102b2b1f42SAndrew Turner 		printf("edge");
4112b2b1f42SAndrew Turner 	else
4122b2b1f42SAndrew Turner 		printf("level");
4132b2b1f42SAndrew Turner 	printf("}\n");
4142b2b1f42SAndrew Turner }
4152b2b1f42SAndrew Turner 
4162b2b1f42SAndrew Turner static void
417986dffafSJohn Baldwin acpi_print_intr(uint32_t intr, uint16_t mps_flags)
4180a473124SJohn Baldwin {
4190a473124SJohn Baldwin 
420986dffafSJohn Baldwin 	printf("\tINTR=%d\n", intr);
421986dffafSJohn Baldwin 	acpi_print_mps_flags(mps_flags);
422986dffafSJohn Baldwin }
423986dffafSJohn Baldwin 
424986dffafSJohn Baldwin static void
425986dffafSJohn Baldwin acpi_print_local_nmi(u_int lint, uint16_t mps_flags)
426986dffafSJohn Baldwin {
427986dffafSJohn Baldwin 
428986dffafSJohn Baldwin 	printf("\tLINT Pin=%d\n", lint);
4290a473124SJohn Baldwin 	acpi_print_mps_flags(mps_flags);
4300a473124SJohn Baldwin }
4310a473124SJohn Baldwin 
43227941afaSEd Maste static const char *apic_types[] = {
43327941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_APIC] = "Local APIC",
43427941afaSEd Maste     [ACPI_MADT_TYPE_IO_APIC] = "IO APIC",
43527941afaSEd Maste     [ACPI_MADT_TYPE_INTERRUPT_OVERRIDE] = "INT Override",
43627941afaSEd Maste     [ACPI_MADT_TYPE_NMI_SOURCE] = "NMI",
43727941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_APIC_NMI] = "Local APIC NMI",
43827941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE] = "Local APIC Override",
43927941afaSEd Maste     [ACPI_MADT_TYPE_IO_SAPIC] = "IO SAPIC",
44027941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_SAPIC] = "Local SAPIC",
44127941afaSEd Maste     [ACPI_MADT_TYPE_INTERRUPT_SOURCE] = "Platform Interrupt",
44227941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_X2APIC] = "Local X2APIC",
44327941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_X2APIC_NMI] = "Local X2APIC NMI",
44427941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_INTERRUPT] = "GIC CPU Interface Structure",
44527941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR] = "GIC Distributor Structure",
44627941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_MSI_FRAME] = "GICv2m MSI Frame",
44727941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR] = "GIC Redistributor Structure",
44827941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_TRANSLATOR] = "GIC ITS Structure"
44927941afaSEd Maste };
45027941afaSEd Maste 
451bf70beceSEd Schouten static const char *platform_int_types[] = { "0 (unknown)", "PMI", "INIT",
4520a473124SJohn Baldwin 					    "Corrected Platform Error" };
4530a473124SJohn Baldwin 
4540a473124SJohn Baldwin static void
455986dffafSJohn Baldwin acpi_print_madt(ACPI_SUBTABLE_HEADER *mp)
4560a473124SJohn Baldwin {
457986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_APIC *lapic;
458986dffafSJohn Baldwin 	ACPI_MADT_IO_APIC *ioapic;
459986dffafSJohn Baldwin 	ACPI_MADT_INTERRUPT_OVERRIDE *over;
460986dffafSJohn Baldwin 	ACPI_MADT_NMI_SOURCE *nmi;
461986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_APIC_NMI *lapic_nmi;
462986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic_over;
463986dffafSJohn Baldwin 	ACPI_MADT_IO_SAPIC *iosapic;
464986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_SAPIC *lsapic;
465986dffafSJohn Baldwin 	ACPI_MADT_INTERRUPT_SOURCE *isrc;
466986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_X2APIC *x2apic;
467986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_X2APIC_NMI *x2apic_nmi;
4682b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_INTERRUPT *gicc;
4692b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_DISTRIBUTOR *gicd;
4702b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_REDISTRIBUTOR *gicr;
4712b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_TRANSLATOR *gict;
4720a473124SJohn Baldwin 
473c86932b6SMarcelo Araujo 	if (mp->Type < nitems(apic_types))
474986dffafSJohn Baldwin 		printf("\tType=%s\n", apic_types[mp->Type]);
475a0333ad1SJohn Baldwin 	else
476986dffafSJohn Baldwin 		printf("\tType=%d (unknown)\n", mp->Type);
477986dffafSJohn Baldwin 	switch (mp->Type) {
478986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_APIC:
479986dffafSJohn Baldwin 		lapic = (ACPI_MADT_LOCAL_APIC *)mp;
480986dffafSJohn Baldwin 		acpi_print_cpu(lapic->ProcessorId);
481986dffafSJohn Baldwin 		acpi_print_local_apic(lapic->Id, lapic->LapicFlags);
4820a473124SJohn Baldwin 		break;
483986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_IO_APIC:
484986dffafSJohn Baldwin 		ioapic = (ACPI_MADT_IO_APIC *)mp;
485986dffafSJohn Baldwin 		acpi_print_io_apic(ioapic->Id, ioapic->GlobalIrqBase,
486986dffafSJohn Baldwin 		    ioapic->Address);
4870a473124SJohn Baldwin 		break;
488986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
489986dffafSJohn Baldwin 		over = (ACPI_MADT_INTERRUPT_OVERRIDE *)mp;
490986dffafSJohn Baldwin 		printf("\tBUS=%d\n", (u_int)over->Bus);
491986dffafSJohn Baldwin 		printf("\tIRQ=%d\n", (u_int)over->SourceIrq);
492986dffafSJohn Baldwin 		acpi_print_intr(over->GlobalIrq, over->IntiFlags);
4930a473124SJohn Baldwin 		break;
494986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_NMI_SOURCE:
495986dffafSJohn Baldwin 		nmi = (ACPI_MADT_NMI_SOURCE *)mp;
496986dffafSJohn Baldwin 		acpi_print_intr(nmi->GlobalIrq, nmi->IntiFlags);
4970a473124SJohn Baldwin 		break;
498986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
499986dffafSJohn Baldwin 		lapic_nmi = (ACPI_MADT_LOCAL_APIC_NMI *)mp;
500986dffafSJohn Baldwin 		acpi_print_cpu(lapic_nmi->ProcessorId);
501986dffafSJohn Baldwin 		acpi_print_local_nmi(lapic_nmi->Lint, lapic_nmi->IntiFlags);
5020a473124SJohn Baldwin 		break;
503986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
504986dffafSJohn Baldwin 		lapic_over = (ACPI_MADT_LOCAL_APIC_OVERRIDE *)mp;
505945137d9SNate Lawson 		printf("\tLocal APIC ADDR=0x%016jx\n",
506986dffafSJohn Baldwin 		    (uintmax_t)lapic_over->Address);
5070a473124SJohn Baldwin 		break;
508986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_IO_SAPIC:
509986dffafSJohn Baldwin 		iosapic = (ACPI_MADT_IO_SAPIC *)mp;
510986dffafSJohn Baldwin 		acpi_print_io_apic(iosapic->Id, iosapic->GlobalIrqBase,
511986dffafSJohn Baldwin 		    iosapic->Address);
5120a473124SJohn Baldwin 		break;
513986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_SAPIC:
514986dffafSJohn Baldwin 		lsapic = (ACPI_MADT_LOCAL_SAPIC *)mp;
515986dffafSJohn Baldwin 		acpi_print_cpu(lsapic->ProcessorId);
516986dffafSJohn Baldwin 		acpi_print_local_apic(lsapic->Id, lsapic->LapicFlags);
517986dffafSJohn Baldwin 		printf("\tAPIC EID=%d\n", (u_int)lsapic->Eid);
518986dffafSJohn Baldwin 		if (mp->Length > __offsetof(ACPI_MADT_LOCAL_SAPIC, Uid))
519986dffafSJohn Baldwin 			acpi_print_cpu_uid(lsapic->Uid, lsapic->UidString);
5200a473124SJohn Baldwin 		break;
521986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
522986dffafSJohn Baldwin 		isrc = (ACPI_MADT_INTERRUPT_SOURCE *)mp;
523c86932b6SMarcelo Araujo 		if (isrc->Type < nitems(platform_int_types))
524986dffafSJohn Baldwin 			printf("\tType=%s\n", platform_int_types[isrc->Type]);
525986dffafSJohn Baldwin 		else
526986dffafSJohn Baldwin 			printf("\tType=%d (unknown)\n", isrc->Type);
527986dffafSJohn Baldwin 		printf("\tAPIC ID=%d\n", (u_int)isrc->Id);
528986dffafSJohn Baldwin 		printf("\tAPIC EID=%d\n", (u_int)isrc->Eid);
529986dffafSJohn Baldwin 		printf("\tSAPIC Vector=%d\n", (u_int)isrc->IoSapicVector);
530986dffafSJohn Baldwin 		acpi_print_intr(isrc->GlobalIrq, isrc->IntiFlags);
531986dffafSJohn Baldwin 		break;
532986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_X2APIC:
533986dffafSJohn Baldwin 		x2apic = (ACPI_MADT_LOCAL_X2APIC *)mp;
534986dffafSJohn Baldwin 		acpi_print_cpu_uid(x2apic->Uid, NULL);
535986dffafSJohn Baldwin 		acpi_print_local_apic(x2apic->LocalApicId, x2apic->LapicFlags);
536986dffafSJohn Baldwin 		break;
537986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
538986dffafSJohn Baldwin 		x2apic_nmi = (ACPI_MADT_LOCAL_X2APIC_NMI *)mp;
539986dffafSJohn Baldwin 		acpi_print_cpu_uid(x2apic_nmi->Uid, NULL);
540986dffafSJohn Baldwin 		acpi_print_local_nmi(x2apic_nmi->Lint, x2apic_nmi->IntiFlags);
5410a473124SJohn Baldwin 		break;
5422b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
5432b2b1f42SAndrew Turner 		gicc = (ACPI_MADT_GENERIC_INTERRUPT *)mp;
5442b2b1f42SAndrew Turner 		acpi_print_cpu_uid(gicc->Uid, NULL);
5452b2b1f42SAndrew Turner 		printf("\tCPU INTERFACE=%x\n", gicc->CpuInterfaceNumber);
5462b2b1f42SAndrew Turner 		acpi_print_gicc_flags(gicc->Flags);
5472b2b1f42SAndrew Turner 		printf("\tParking Protocol Version=%x\n", gicc->ParkingVersion);
5482b2b1f42SAndrew Turner 		printf("\tPERF INTR=%d\n", gicc->PerformanceInterrupt);
5492b2b1f42SAndrew Turner 		printf("\tParked ADDR=%016jx\n",
5502b2b1f42SAndrew Turner 		    (uintmax_t)gicc->ParkedAddress);
5512b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicc->BaseAddress);
5522b2b1f42SAndrew Turner 		printf("\tGICV=%016jx\n", (uintmax_t)gicc->GicvBaseAddress);
5532b2b1f42SAndrew Turner 		printf("\tGICH=%016jx\n", (uintmax_t)gicc->GichBaseAddress);
5542b2b1f42SAndrew Turner 		printf("\tVGIC INTR=%d\n", gicc->VgicInterrupt);
5552b2b1f42SAndrew Turner 		printf("\tGICR ADDR=%016jx\n",
5562b2b1f42SAndrew Turner 		    (uintmax_t)gicc->GicrBaseAddress);
5572b2b1f42SAndrew Turner 		printf("\tMPIDR=%jx\n", (uintmax_t)gicc->ArmMpidr);
5580b4302aaSGordon Bergling 		printf("\tEfficiency Class=%d\n", (u_int)gicc->EfficiencyClass);
559c363da4aSAndrew Turner 		printf("\tSPE INTR=%d\n", gicc->SpeInterrupt);
5602b2b1f42SAndrew Turner 		break;
5612b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
5622b2b1f42SAndrew Turner 		gicd = (ACPI_MADT_GENERIC_DISTRIBUTOR *)mp;
5632b2b1f42SAndrew Turner 		printf("\tGIC ID=%d\n", (u_int)gicd->GicId);
5642b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicd->BaseAddress);
5652b2b1f42SAndrew Turner 		printf("\tVector Base=%d\n", gicd->GlobalIrqBase);
5662b2b1f42SAndrew Turner 		printf("\tGIC VERSION=%d\n", (u_int)gicd->Version);
5672b2b1f42SAndrew Turner 		break;
5682b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
5692b2b1f42SAndrew Turner 		gicr = (ACPI_MADT_GENERIC_REDISTRIBUTOR *)mp;
5702b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicr->BaseAddress);
5712b2b1f42SAndrew Turner 		printf("\tLength=%08x\n", gicr->Length);
5722b2b1f42SAndrew Turner 		break;
5732b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
5742b2b1f42SAndrew Turner 		gict = (ACPI_MADT_GENERIC_TRANSLATOR *)mp;
5752b2b1f42SAndrew Turner 		printf("\tGIC ITS ID=%d\n", gict->TranslationId);
5762b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gict->BaseAddress);
5772b2b1f42SAndrew Turner 		break;
5780a473124SJohn Baldwin 	}
5790a473124SJohn Baldwin }
5800a473124SJohn Baldwin 
5810a473124SJohn Baldwin static void
582986dffafSJohn Baldwin acpi_handle_madt(ACPI_TABLE_HEADER *sdp)
5830a473124SJohn Baldwin {
584986dffafSJohn Baldwin 	ACPI_TABLE_MADT *madt;
5850a473124SJohn Baldwin 
586773b6454SNate Lawson 	printf(BEGIN_COMMENT);
587773b6454SNate Lawson 	acpi_print_sdt(sdp);
588986dffafSJohn Baldwin 	madt = (ACPI_TABLE_MADT *)sdp;
589986dffafSJohn Baldwin 	printf("\tLocal APIC ADDR=0x%08x\n", madt->Address);
5900a473124SJohn Baldwin 	printf("\tFlags={");
591986dffafSJohn Baldwin 	if (madt->Flags & ACPI_MADT_PCAT_COMPAT)
5920a473124SJohn Baldwin 		printf("PC-AT");
5930a473124SJohn Baldwin 	printf("}\n");
594986dffafSJohn Baldwin 	acpi_walk_subtables(sdp, (madt + 1), acpi_print_madt);
5950a473124SJohn Baldwin 	printf(END_COMMENT);
5960a473124SJohn Baldwin }
5970a473124SJohn Baldwin 
5980a473124SJohn Baldwin static void
599ebc22d04SAlexander Motin acpi_handle_bert(ACPI_TABLE_HEADER *sdp)
600ebc22d04SAlexander Motin {
601ebc22d04SAlexander Motin 	ACPI_TABLE_BERT *bert;
602ebc22d04SAlexander Motin 
603ebc22d04SAlexander Motin 	printf(BEGIN_COMMENT);
604ebc22d04SAlexander Motin 	acpi_print_sdt(sdp);
605ebc22d04SAlexander Motin 	bert = (ACPI_TABLE_BERT *)sdp;
606ebc22d04SAlexander Motin 	printf("\tRegionLength=%d\n", bert->RegionLength);
607ebc22d04SAlexander Motin 	printf("\tAddress=0x%016jx\n", bert->Address);
608ebc22d04SAlexander Motin 	printf(END_COMMENT);
609ebc22d04SAlexander Motin }
610ebc22d04SAlexander Motin 
611ebc22d04SAlexander Motin static void
612ebc22d04SAlexander Motin acpi_print_whea(ACPI_WHEA_HEADER *w)
613ebc22d04SAlexander Motin {
614ebc22d04SAlexander Motin 
615ebc22d04SAlexander Motin 	printf("\n\tAction=%d\n", w->Action);
616ebc22d04SAlexander Motin 	printf("\tInstruction=%d\n", w->Instruction);
617ebc22d04SAlexander Motin 	printf("\tFlags=%02x\n", w->Flags);
618ebc22d04SAlexander Motin 	printf("\tRegisterRegion=");
619ebc22d04SAlexander Motin 	acpi_print_gas(&w->RegisterRegion);
620ebc22d04SAlexander Motin 	printf("\n\tValue=0x%016jx\n", w->Value);
621ebc22d04SAlexander Motin 	printf("\tMask=0x%016jx\n", w->Mask);
622ebc22d04SAlexander Motin }
623ebc22d04SAlexander Motin 
624ebc22d04SAlexander Motin static void
625ebc22d04SAlexander Motin acpi_handle_einj(ACPI_TABLE_HEADER *sdp)
626ebc22d04SAlexander Motin {
627ebc22d04SAlexander Motin 	ACPI_TABLE_EINJ *einj;
628ebc22d04SAlexander Motin 	ACPI_WHEA_HEADER *w;
629ebc22d04SAlexander Motin 	u_int i;
630ebc22d04SAlexander Motin 
631ebc22d04SAlexander Motin 	printf(BEGIN_COMMENT);
632ebc22d04SAlexander Motin 	acpi_print_sdt(sdp);
633ebc22d04SAlexander Motin 	einj = (ACPI_TABLE_EINJ *)sdp;
634ebc22d04SAlexander Motin 	printf("\tHeaderLength=%d\n", einj->HeaderLength);
635ebc22d04SAlexander Motin 	printf("\tFlags=0x%02x\n", einj->Flags);
636ebc22d04SAlexander Motin 	printf("\tEntries=%d\n", einj->Entries);
637ebc22d04SAlexander Motin 	w = (ACPI_WHEA_HEADER *)(einj + 1);
638ebc22d04SAlexander Motin 	for (i = 0; i < MIN(einj->Entries, (sdp->Length -
639ebc22d04SAlexander Motin 	    sizeof(ACPI_TABLE_EINJ)) / sizeof(ACPI_WHEA_HEADER)); i++)
640ebc22d04SAlexander Motin 		acpi_print_whea(w + i);
641ebc22d04SAlexander Motin 	printf(END_COMMENT);
642ebc22d04SAlexander Motin }
643ebc22d04SAlexander Motin 
644ebc22d04SAlexander Motin static void
645ebc22d04SAlexander Motin acpi_handle_erst(ACPI_TABLE_HEADER *sdp)
646ebc22d04SAlexander Motin {
647ebc22d04SAlexander Motin 	ACPI_TABLE_ERST *erst;
648ebc22d04SAlexander Motin 	ACPI_WHEA_HEADER *w;
649ebc22d04SAlexander Motin 	u_int i;
650ebc22d04SAlexander Motin 
651ebc22d04SAlexander Motin 	printf(BEGIN_COMMENT);
652ebc22d04SAlexander Motin 	acpi_print_sdt(sdp);
653ebc22d04SAlexander Motin 	erst = (ACPI_TABLE_ERST *)sdp;
654ebc22d04SAlexander Motin 	printf("\tHeaderLength=%d\n", erst->HeaderLength);
655ebc22d04SAlexander Motin 	printf("\tEntries=%d\n", erst->Entries);
656ebc22d04SAlexander Motin 	w = (ACPI_WHEA_HEADER *)(erst + 1);
657ebc22d04SAlexander Motin 	for (i = 0; i < MIN(erst->Entries, (sdp->Length -
658ebc22d04SAlexander Motin 	    sizeof(ACPI_TABLE_ERST)) / sizeof(ACPI_WHEA_HEADER)); i++)
659ebc22d04SAlexander Motin 		acpi_print_whea(w + i);
660ebc22d04SAlexander Motin 	printf(END_COMMENT);
661ebc22d04SAlexander Motin }
662ebc22d04SAlexander Motin 
663ebc22d04SAlexander Motin static void
664ebc22d04SAlexander Motin acpi_print_hest_bank(ACPI_HEST_IA_ERROR_BANK *b)
665ebc22d04SAlexander Motin {
666ebc22d04SAlexander Motin 
667ebc22d04SAlexander Motin 	printf("\tBank:\n");
668ebc22d04SAlexander Motin 	printf("\t\tBankNumber=%d\n", b->BankNumber);
669ebc22d04SAlexander Motin 	printf("\t\tClearStatusOnInit=%d\n", b->ClearStatusOnInit);
670ebc22d04SAlexander Motin 	printf("\t\tStatusFormat=%d\n", b->StatusFormat);
671ebc22d04SAlexander Motin 	printf("\t\tControlRegister=%x\n", b->ControlRegister);
672ebc22d04SAlexander Motin 	printf("\t\tControlData=%jx\n", b->ControlData);
673ebc22d04SAlexander Motin 	printf("\t\tStatusRegister=%x\n", b->StatusRegister);
674ebc22d04SAlexander Motin 	printf("\t\tAddressRegister=%x\n", b->AddressRegister);
675ebc22d04SAlexander Motin 	printf("\t\tMiscRegister=%x\n", b->MiscRegister);
676ebc22d04SAlexander Motin }
677ebc22d04SAlexander Motin 
678ebc22d04SAlexander Motin static void
679ebc22d04SAlexander Motin acpi_print_hest_notify(ACPI_HEST_NOTIFY *n)
680ebc22d04SAlexander Motin {
681ebc22d04SAlexander Motin 
682ebc22d04SAlexander Motin 	printf("\t\tType=%d\n", n->Type);
683ebc22d04SAlexander Motin 	printf("\t\tLength=%d\n", n->Length);
684ebc22d04SAlexander Motin 	printf("\t\tConfigWriteEnable=%04x\n", n->ConfigWriteEnable);
685ebc22d04SAlexander Motin 	printf("\t\tPollInterval=%d\n", n->PollInterval);
686ebc22d04SAlexander Motin 	printf("\t\tVector=%d\n", n->Vector);
687ebc22d04SAlexander Motin 	printf("\t\tPollingThresholdValue=%d\n", n->PollingThresholdValue);
688ebc22d04SAlexander Motin 	printf("\t\tPollingThresholdWindow=%d\n", n->PollingThresholdWindow);
689ebc22d04SAlexander Motin 	printf("\t\tErrorThresholdValue=%d\n", n->ErrorThresholdValue);
690ebc22d04SAlexander Motin 	printf("\t\tErrorThresholdWindow=%d\n", n->ErrorThresholdWindow);
691ebc22d04SAlexander Motin }
692ebc22d04SAlexander Motin 
693ebc22d04SAlexander Motin static void
694ebc22d04SAlexander Motin acpi_print_hest_aer(ACPI_HEST_AER_COMMON *a)
695ebc22d04SAlexander Motin {
696ebc22d04SAlexander Motin 
697ebc22d04SAlexander Motin 	printf("\tFlags=%02x\n", a->Flags);
698ebc22d04SAlexander Motin 	printf("\tEnabled=%d\n", a->Enabled);
699ebc22d04SAlexander Motin 	printf("\tRecordsToPreallocate=%d\n", a->RecordsToPreallocate);
700ebc22d04SAlexander Motin 	printf("\tMaxSectionsPerRecord=%d\n", a->MaxSectionsPerRecord);
701ebc22d04SAlexander Motin 	printf("\tBus=%d\n", a->Bus);
702ebc22d04SAlexander Motin 	printf("\tDevice=%d\n", a->Device);
703ebc22d04SAlexander Motin 	printf("\tFunction=%d\n", a->Function);
704ebc22d04SAlexander Motin 	printf("\tDeviceControl=%d\n", a->DeviceControl);
705ebc22d04SAlexander Motin 	printf("\tUncorrectableMask=%d\n", a->UncorrectableMask);
706ebc22d04SAlexander Motin 	printf("\tUncorrectableSeverity=%d\n", a->UncorrectableSeverity);
707ebc22d04SAlexander Motin 	printf("\tCorrectableMask=%d\n", a->CorrectableMask);
708ebc22d04SAlexander Motin 	printf("\tAdvancedCapabilities=%d\n", a->AdvancedCapabilities);
709ebc22d04SAlexander Motin }
710ebc22d04SAlexander Motin 
711ebc22d04SAlexander Motin static int
712ebc22d04SAlexander Motin acpi_handle_hest_structure(void *addr, int remaining)
713ebc22d04SAlexander Motin {
714ebc22d04SAlexander Motin 	ACPI_HEST_HEADER *hdr = addr;
715ebc22d04SAlexander Motin 	int i;
716ebc22d04SAlexander Motin 
717ebc22d04SAlexander Motin 	if (remaining < (int)sizeof(ACPI_HEST_HEADER))
718ebc22d04SAlexander Motin 		return (-1);
719ebc22d04SAlexander Motin 
720ebc22d04SAlexander Motin 	printf("\n\tType=%d\n", hdr->Type);
721ebc22d04SAlexander Motin 	printf("\tSourceId=%d\n", hdr->SourceId);
722ebc22d04SAlexander Motin 	switch (hdr->Type) {
723ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_IA32_CHECK: {
724ebc22d04SAlexander Motin 		ACPI_HEST_IA_MACHINE_CHECK *s = addr;
725ebc22d04SAlexander Motin 		printf("\tFlags=%02x\n", s->Flags);
726ebc22d04SAlexander Motin 		printf("\tEnabled=%d\n", s->Enabled);
727ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
728ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
729ebc22d04SAlexander Motin 		printf("\tGlobalCapabilityData=%jd\n", s->GlobalCapabilityData);
730ebc22d04SAlexander Motin 		printf("\tGlobalControlData=%jd\n", s->GlobalControlData);
731ebc22d04SAlexander Motin 		printf("\tNumHardwareBanks=%d\n", s->NumHardwareBanks);
732ebc22d04SAlexander Motin 		for (i = 0; i < s->NumHardwareBanks; i++) {
733ebc22d04SAlexander Motin 			acpi_print_hest_bank((ACPI_HEST_IA_ERROR_BANK *)
734ebc22d04SAlexander Motin 			    (s + 1) + i);
735ebc22d04SAlexander Motin 		}
736ebc22d04SAlexander Motin 		return (sizeof(*s) + s->NumHardwareBanks *
737ebc22d04SAlexander Motin 		    sizeof(ACPI_HEST_IA_ERROR_BANK));
738ebc22d04SAlexander Motin 	}
739ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: {
740ebc22d04SAlexander Motin 		ACPI_HEST_IA_CORRECTED *s = addr;
741ebc22d04SAlexander Motin 		printf("\tFlags=%02x\n", s->Flags);
742ebc22d04SAlexander Motin 		printf("\tEnabled=%d\n", s->Enabled);
743ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
744ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
745ebc22d04SAlexander Motin 		printf("\tNotify:\n");
746ebc22d04SAlexander Motin 		acpi_print_hest_notify(&s->Notify);
747ebc22d04SAlexander Motin 		printf("\tNumHardwareBanks=%d\n", s->NumHardwareBanks);
748ebc22d04SAlexander Motin 		for (i = 0; i < s->NumHardwareBanks; i++) {
749ebc22d04SAlexander Motin 			acpi_print_hest_bank((ACPI_HEST_IA_ERROR_BANK *)
750ebc22d04SAlexander Motin 			    (s + 1) + i);
751ebc22d04SAlexander Motin 		}
752ebc22d04SAlexander Motin 		return (sizeof(*s) + s->NumHardwareBanks *
753ebc22d04SAlexander Motin 		    sizeof(ACPI_HEST_IA_ERROR_BANK));
754ebc22d04SAlexander Motin 	}
755ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_IA32_NMI: {
756ebc22d04SAlexander Motin 		ACPI_HEST_IA_NMI *s = addr;
757ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
758ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
759ebc22d04SAlexander Motin 		printf("\tMaxRawDataLength=%d\n", s->MaxRawDataLength);
760ebc22d04SAlexander Motin 		return (sizeof(*s));
761ebc22d04SAlexander Motin 	}
762ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_AER_ROOT_PORT: {
763ebc22d04SAlexander Motin 		ACPI_HEST_AER_ROOT *s = addr;
764ebc22d04SAlexander Motin 		acpi_print_hest_aer(&s->Aer);
765ebc22d04SAlexander Motin 		printf("\tRootErrorCommand=%d\n", s->RootErrorCommand);
766ebc22d04SAlexander Motin 		return (sizeof(*s));
767ebc22d04SAlexander Motin 	}
768ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_AER_ENDPOINT: {
769ebc22d04SAlexander Motin 		ACPI_HEST_AER *s = addr;
770ebc22d04SAlexander Motin 		acpi_print_hest_aer(&s->Aer);
771ebc22d04SAlexander Motin 		return (sizeof(*s));
772ebc22d04SAlexander Motin 	}
773ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_AER_BRIDGE: {
774ebc22d04SAlexander Motin 		ACPI_HEST_AER_BRIDGE *s = addr;
775ebc22d04SAlexander Motin 		acpi_print_hest_aer(&s->Aer);
776ebc22d04SAlexander Motin 		printf("\tUncorrectableMask2=%d\n", s->UncorrectableMask2);
777ebc22d04SAlexander Motin 		printf("\tUncorrectableSeverity2=%d\n", s->UncorrectableSeverity2);
778ebc22d04SAlexander Motin 		printf("\tAdvancedCapabilities2=%d\n", s->AdvancedCapabilities2);
779ebc22d04SAlexander Motin 		return (sizeof(*s));
780ebc22d04SAlexander Motin 	}
781ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_GENERIC_ERROR: {
782ebc22d04SAlexander Motin 		ACPI_HEST_GENERIC *s = addr;
783ebc22d04SAlexander Motin 		printf("\tRelatedSourceId=%d\n", s->RelatedSourceId);
784ebc22d04SAlexander Motin 		printf("\tEnabled=%d\n", s->Enabled);
785ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
786ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
787ebc22d04SAlexander Motin 		printf("\tMaxRawDataLength=%d\n", s->MaxRawDataLength);
788ebc22d04SAlexander Motin 		printf("\tErrorStatusAddress=");
789ebc22d04SAlexander Motin 		acpi_print_gas(&s->ErrorStatusAddress);
790ebc22d04SAlexander Motin 		printf("\n");
791ebc22d04SAlexander Motin 		printf("\tNotify:\n");
792ebc22d04SAlexander Motin 		acpi_print_hest_notify(&s->Notify);
793ebc22d04SAlexander Motin 		printf("\tErrorBlockLength=%d\n", s->ErrorBlockLength);
794ebc22d04SAlexander Motin 		return (sizeof(*s));
795ebc22d04SAlexander Motin 	}
796ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_GENERIC_ERROR_V2: {
797ebc22d04SAlexander Motin 		ACPI_HEST_GENERIC_V2 *s = addr;
798ebc22d04SAlexander Motin 		printf("\tRelatedSourceId=%d\n", s->RelatedSourceId);
799ebc22d04SAlexander Motin 		printf("\tEnabled=%d\n", s->Enabled);
800ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
801ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
802ebc22d04SAlexander Motin 		printf("\tMaxRawDataLength=%d\n", s->MaxRawDataLength);
803ebc22d04SAlexander Motin 		printf("\tErrorStatusAddress=");
804ebc22d04SAlexander Motin 		acpi_print_gas(&s->ErrorStatusAddress);
805ebc22d04SAlexander Motin 		printf("\n");
806ebc22d04SAlexander Motin 		printf("\tNotify:\n");
807ebc22d04SAlexander Motin 		acpi_print_hest_notify(&s->Notify);
808ebc22d04SAlexander Motin 		printf("\tErrorBlockLength=%d\n", s->ErrorBlockLength);
809ebc22d04SAlexander Motin 		printf("\tReadAckRegister=");
810ebc22d04SAlexander Motin 		acpi_print_gas(&s->ReadAckRegister);
811ebc22d04SAlexander Motin 		printf("\n");
812ebc22d04SAlexander Motin 		printf("\tReadAckPreserve=%jd\n", s->ReadAckPreserve);
813ebc22d04SAlexander Motin 		printf("\tReadAckWrite=%jd\n", s->ReadAckWrite);
814ebc22d04SAlexander Motin 		return (sizeof(*s));
815ebc22d04SAlexander Motin 	}
816ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: {
817ebc22d04SAlexander Motin 		ACPI_HEST_IA_DEFERRED_CHECK *s = addr;
818ebc22d04SAlexander Motin 		printf("\tFlags=%02x\n", s->Flags);
819ebc22d04SAlexander Motin 		printf("\tEnabled=%d\n", s->Enabled);
820ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
821ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
822ebc22d04SAlexander Motin 		printf("\tNotify:\n");
823ebc22d04SAlexander Motin 		acpi_print_hest_notify(&s->Notify);
824ebc22d04SAlexander Motin 		printf("\tNumHardwareBanks=%d\n", s->NumHardwareBanks);
825ebc22d04SAlexander Motin 		for (i = 0; i < s->NumHardwareBanks; i++) {
826ebc22d04SAlexander Motin 			acpi_print_hest_bank((ACPI_HEST_IA_ERROR_BANK *)
827ebc22d04SAlexander Motin 			    (s + 1) + i);
828ebc22d04SAlexander Motin 		}
829ebc22d04SAlexander Motin 		return (sizeof(*s) + s->NumHardwareBanks *
830ebc22d04SAlexander Motin 		    sizeof(ACPI_HEST_IA_ERROR_BANK));
831ebc22d04SAlexander Motin 	}
832ebc22d04SAlexander Motin 	default:
833ebc22d04SAlexander Motin 		return (-1);
834ebc22d04SAlexander Motin 	}
835ebc22d04SAlexander Motin }
836ebc22d04SAlexander Motin 
837ebc22d04SAlexander Motin static void
838ebc22d04SAlexander Motin acpi_handle_hest(ACPI_TABLE_HEADER *sdp)
839ebc22d04SAlexander Motin {
840ebc22d04SAlexander Motin 	char *cp;
841ebc22d04SAlexander Motin 	int remaining, consumed;
842ebc22d04SAlexander Motin 	ACPI_TABLE_HEST *hest;
843ebc22d04SAlexander Motin 
844ebc22d04SAlexander Motin 	printf(BEGIN_COMMENT);
845ebc22d04SAlexander Motin 	acpi_print_sdt(sdp);
846ebc22d04SAlexander Motin 	hest = (ACPI_TABLE_HEST *)sdp;
847ebc22d04SAlexander Motin 	printf("\tErrorSourceCount=%d\n", hest->ErrorSourceCount);
848ebc22d04SAlexander Motin 
849ebc22d04SAlexander Motin 	remaining = sdp->Length - sizeof(ACPI_TABLE_HEST);
850ebc22d04SAlexander Motin 	while (remaining > 0) {
851ebc22d04SAlexander Motin 		cp = (char *)sdp + sdp->Length - remaining;
852ebc22d04SAlexander Motin 		consumed = acpi_handle_hest_structure(cp, remaining);
853ebc22d04SAlexander Motin 		if (consumed <= 0)
854ebc22d04SAlexander Motin 			break;
855ebc22d04SAlexander Motin 		else
856ebc22d04SAlexander Motin 			remaining -= consumed;
857ebc22d04SAlexander Motin 	}
858ebc22d04SAlexander Motin 	printf(END_COMMENT);
859ebc22d04SAlexander Motin }
860ebc22d04SAlexander Motin 
861ebc22d04SAlexander Motin static void
862986dffafSJohn Baldwin acpi_handle_hpet(ACPI_TABLE_HEADER *sdp)
86379d7565cSPeter Wemm {
864986dffafSJohn Baldwin 	ACPI_TABLE_HPET *hpet;
86579d7565cSPeter Wemm 
866773b6454SNate Lawson 	printf(BEGIN_COMMENT);
867773b6454SNate Lawson 	acpi_print_sdt(sdp);
868986dffafSJohn Baldwin 	hpet = (ACPI_TABLE_HPET *)sdp;
869986dffafSJohn Baldwin 	printf("\tHPET Number=%d\n", hpet->Sequence);
87087f9f09aSTakanori Watanabe 	printf("\tADDR=");
871986dffafSJohn Baldwin 	acpi_print_gas(&hpet->Address);
872ebc22d04SAlexander Motin 	printf("\n\tHW Rev=0x%x\n", hpet->Id & ACPI_HPET_ID_HARDWARE_REV_ID);
873986dffafSJohn Baldwin 	printf("\tComparators=%d\n", (hpet->Id & ACPI_HPET_ID_COMPARATORS) >>
874986dffafSJohn Baldwin 	    8);
875986dffafSJohn Baldwin 	printf("\tCounter Size=%d\n", hpet->Id & ACPI_HPET_ID_COUNT_SIZE_CAP ?
876986dffafSJohn Baldwin 	    1 : 0);
87779d7565cSPeter Wemm 	printf("\tLegacy IRQ routing capable={");
878986dffafSJohn Baldwin 	if (hpet->Id & ACPI_HPET_ID_LEGACY_CAPABLE)
87979d7565cSPeter Wemm 		printf("TRUE}\n");
88079d7565cSPeter Wemm 	else
88179d7565cSPeter Wemm 		printf("FALSE}\n");
882986dffafSJohn Baldwin 	printf("\tPCI Vendor ID=0x%04x\n", hpet->Id >> 16);
883986dffafSJohn Baldwin 	printf("\tMinimal Tick=%d\n", hpet->MinimumTick);
8849785e979SNeel Natu 	printf("\tFlags=0x%02x\n", hpet->Flags);
88579d7565cSPeter Wemm 	printf(END_COMMENT);
88679d7565cSPeter Wemm }
88779d7565cSPeter Wemm 
88879d7565cSPeter Wemm static void
889986dffafSJohn Baldwin acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp)
89055d7ff9eSNate Lawson {
891986dffafSJohn Baldwin 	ACPI_TABLE_ECDT *ecdt;
89255d7ff9eSNate Lawson 
89355d7ff9eSNate Lawson 	printf(BEGIN_COMMENT);
89455d7ff9eSNate Lawson 	acpi_print_sdt(sdp);
895986dffafSJohn Baldwin 	ecdt = (ACPI_TABLE_ECDT *)sdp;
89655d7ff9eSNate Lawson 	printf("\tEC_CONTROL=");
897986dffafSJohn Baldwin 	acpi_print_gas(&ecdt->Control);
89855d7ff9eSNate Lawson 	printf("\n\tEC_DATA=");
899986dffafSJohn Baldwin 	acpi_print_gas(&ecdt->Data);
900986dffafSJohn Baldwin 	printf("\n\tUID=%#x, ", ecdt->Uid);
901986dffafSJohn Baldwin 	printf("GPE_BIT=%#x\n", ecdt->Gpe);
902986dffafSJohn Baldwin 	printf("\tEC_ID=%s\n", ecdt->Id);
90355d7ff9eSNate Lawson 	printf(END_COMMENT);
90455d7ff9eSNate Lawson }
90555d7ff9eSNate Lawson 
90655d7ff9eSNate Lawson static void
907986dffafSJohn Baldwin acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp)
908a47e681bSScott Long {
909986dffafSJohn Baldwin 	ACPI_TABLE_MCFG *mcfg;
910986dffafSJohn Baldwin 	ACPI_MCFG_ALLOCATION *alloc;
911986dffafSJohn Baldwin 	u_int i, entries;
912a47e681bSScott Long 
913a47e681bSScott Long 	printf(BEGIN_COMMENT);
914a47e681bSScott Long 	acpi_print_sdt(sdp);
915986dffafSJohn Baldwin 	mcfg = (ACPI_TABLE_MCFG *)sdp;
916986dffafSJohn Baldwin 	entries = (sdp->Length - sizeof(ACPI_TABLE_MCFG)) /
917986dffafSJohn Baldwin 	    sizeof(ACPI_MCFG_ALLOCATION);
918986dffafSJohn Baldwin 	alloc = (ACPI_MCFG_ALLOCATION *)(mcfg + 1);
919986dffafSJohn Baldwin 	for (i = 0; i < entries; i++, alloc++) {
920a47e681bSScott Long 		printf("\n");
9210c10b85aSJung-uk Kim 		printf("\tBase Address=0x%016jx\n", (uintmax_t)alloc->Address);
922986dffafSJohn Baldwin 		printf("\tSegment Group=0x%04x\n", alloc->PciSegment);
923986dffafSJohn Baldwin 		printf("\tStart Bus=%d\n", alloc->StartBusNumber);
924986dffafSJohn Baldwin 		printf("\tEnd Bus=%d\n", alloc->EndBusNumber);
925a47e681bSScott Long 	}
926a47e681bSScott Long 	printf(END_COMMENT);
927a47e681bSScott Long }
928a47e681bSScott Long 
929a47e681bSScott Long static void
93033866658SJohn Baldwin acpi_handle_slit(ACPI_TABLE_HEADER *sdp)
93133866658SJohn Baldwin {
93233866658SJohn Baldwin 	ACPI_TABLE_SLIT *slit;
93333866658SJohn Baldwin 	UINT64 i, j;
93433866658SJohn Baldwin 
93533866658SJohn Baldwin 	printf(BEGIN_COMMENT);
93633866658SJohn Baldwin 	acpi_print_sdt(sdp);
93733866658SJohn Baldwin 	slit = (ACPI_TABLE_SLIT *)sdp;
9380c10b85aSJung-uk Kim 	printf("\tLocality Count=%ju\n", (uintmax_t)slit->LocalityCount);
93933866658SJohn Baldwin 	printf("\n\t      ");
94033866658SJohn Baldwin 	for (i = 0; i < slit->LocalityCount; i++)
9410c10b85aSJung-uk Kim 		printf(" %3ju", (uintmax_t)i);
94233866658SJohn Baldwin 	printf("\n\t     +");
94333866658SJohn Baldwin 	for (i = 0; i < slit->LocalityCount; i++)
94433866658SJohn Baldwin 		printf("----");
94533866658SJohn Baldwin 	printf("\n");
94633866658SJohn Baldwin 	for (i = 0; i < slit->LocalityCount; i++) {
9470c10b85aSJung-uk Kim 		printf("\t %3ju |", (uintmax_t)i);
94833866658SJohn Baldwin 		for (j = 0; j < slit->LocalityCount; j++)
94933866658SJohn Baldwin 			printf(" %3d",
95033866658SJohn Baldwin 			    slit->Entry[i * slit->LocalityCount + j]);
95133866658SJohn Baldwin 		printf("\n");
95233866658SJohn Baldwin 	}
95333866658SJohn Baldwin 	printf(END_COMMENT);
95433866658SJohn Baldwin }
95533866658SJohn Baldwin 
95633866658SJohn Baldwin static void
957ed26c389SScott Long acpi_handle_wddt(ACPI_TABLE_HEADER *sdp)
958ed26c389SScott Long {
959ed26c389SScott Long 	ACPI_TABLE_WDDT *wddt;
960ed26c389SScott Long 
961ed26c389SScott Long 	printf(BEGIN_COMMENT);
962ed26c389SScott Long 	acpi_print_sdt(sdp);
963ed26c389SScott Long 	wddt = (ACPI_TABLE_WDDT *)sdp;
964ed26c389SScott Long 	printf("\tSpecVersion=0x%04x, TableVersion=0x%04x\n",
965ed26c389SScott Long 	    wddt->SpecVersion, wddt->TableVersion);
966ed26c389SScott Long 	printf("\tPciVendorId=0x%04x, Address=", wddt->PciVendorId);
967ed26c389SScott Long 	acpi_print_gas(&wddt->Address);
968ed26c389SScott Long 	printf("\n\tMaxCount=%u, MinCount=%u, Period=%ums\n",
969ed26c389SScott Long 	    wddt->MaxCount, wddt->MinCount, wddt->Period);
970ed26c389SScott Long 
971ed26c389SScott Long #define	PRINTFLAG(var, flag)	printflag((var), ACPI_WDDT_## flag, #flag)
972ed26c389SScott Long 	printf("\tStatus=");
973ed26c389SScott Long 	PRINTFLAG(wddt->Status, AVAILABLE);
974ed26c389SScott Long 	PRINTFLAG(wddt->Status, ACTIVE);
975ed26c389SScott Long 	PRINTFLAG(wddt->Status, TCO_OS_OWNED);
976ed26c389SScott Long 	PRINTFLAG(wddt->Status, USER_RESET);
977ed26c389SScott Long 	PRINTFLAG(wddt->Status, WDT_RESET);
978ed26c389SScott Long 	PRINTFLAG(wddt->Status, POWER_FAIL);
979ed26c389SScott Long 	PRINTFLAG(wddt->Status, UNKNOWN_RESET);
980ed26c389SScott Long 	PRINTFLAG_END();
981ed26c389SScott Long 	printf("\tCapability=");
982ed26c389SScott Long 	PRINTFLAG(wddt->Capability, AUTO_RESET);
983ed26c389SScott Long 	PRINTFLAG(wddt->Capability, ALERT_SUPPORT);
984ed26c389SScott Long 	PRINTFLAG_END();
985ed26c389SScott Long #undef PRINTFLAG
986ed26c389SScott Long 
987ed26c389SScott Long 	printf(END_COMMENT);
988ed26c389SScott Long }
989ed26c389SScott Long 
990ed26c389SScott Long static void
9915857fba5SBen Widawsky acpi_print_native_lpit(ACPI_LPIT_NATIVE *nl)
9925857fba5SBen Widawsky {
9935857fba5SBen Widawsky 	printf("\tEntryTrigger=");
9945857fba5SBen Widawsky 	acpi_print_gas(&nl->EntryTrigger);
995ebc22d04SAlexander Motin 	printf("\n\tResidency=%u\n", nl->Residency);
9965857fba5SBen Widawsky 	printf("\tLatency=%u\n", nl->Latency);
9975857fba5SBen Widawsky 	if (nl->Header.Flags & ACPI_LPIT_NO_COUNTER)
9985857fba5SBen Widawsky 		printf("\tResidencyCounter=Not Present");
9995857fba5SBen Widawsky 	else {
10005857fba5SBen Widawsky 		printf("\tResidencyCounter=");
10015857fba5SBen Widawsky 		acpi_print_gas(&nl->ResidencyCounter);
1002ebc22d04SAlexander Motin 		printf("\n");
10035857fba5SBen Widawsky 	}
10045857fba5SBen Widawsky 	if (nl->CounterFrequency)
10055857fba5SBen Widawsky 		printf("\tCounterFrequency=%ju\n", nl->CounterFrequency);
10065857fba5SBen Widawsky 	else
10075857fba5SBen Widawsky 		printf("\tCounterFrequency=TSC\n");
10085857fba5SBen Widawsky }
10095857fba5SBen Widawsky 
10105857fba5SBen Widawsky static void
10115857fba5SBen Widawsky acpi_print_lpit(ACPI_LPIT_HEADER *lpit)
10125857fba5SBen Widawsky {
10135857fba5SBen Widawsky 	if (lpit->Type == ACPI_LPIT_TYPE_NATIVE_CSTATE)
10145857fba5SBen Widawsky 		printf("\tType=ACPI_LPIT_TYPE_NATIVE_CSTATE\n");
10155857fba5SBen Widawsky 	else
10165857fba5SBen Widawsky 		warnx("unknown LPIT type %u", lpit->Type);
10175857fba5SBen Widawsky 
10185857fba5SBen Widawsky 	printf("\tLength=%u\n", lpit->Length);
10195857fba5SBen Widawsky 	printf("\tUniqueId=0x%04x\n", lpit->UniqueId);
10205857fba5SBen Widawsky #define	PRINTFLAG(var, flag)	printflag((var), ACPI_LPIT_## flag, #flag)
10215857fba5SBen Widawsky 	printf("\tFlags=");
10225857fba5SBen Widawsky 	PRINTFLAG(lpit->Flags, STATE_DISABLED);
10235857fba5SBen Widawsky 	PRINTFLAG_END();
10245857fba5SBen Widawsky #undef PRINTFLAG
10255857fba5SBen Widawsky 
10265857fba5SBen Widawsky 	if (lpit->Type == ACPI_LPIT_TYPE_NATIVE_CSTATE)
10275857fba5SBen Widawsky 		return acpi_print_native_lpit((ACPI_LPIT_NATIVE *)lpit);
10285857fba5SBen Widawsky }
10295857fba5SBen Widawsky 
10305857fba5SBen Widawsky static void
10315857fba5SBen Widawsky acpi_walk_lpit(ACPI_TABLE_HEADER *table, void *first,
10325857fba5SBen Widawsky     void (*action)(ACPI_LPIT_HEADER *))
10335857fba5SBen Widawsky {
10345857fba5SBen Widawsky 	ACPI_LPIT_HEADER *subtable;
10355857fba5SBen Widawsky 	char *end;
10365857fba5SBen Widawsky 
10375857fba5SBen Widawsky 	subtable = first;
10385857fba5SBen Widawsky 	end = (char *)table + table->Length;
10395857fba5SBen Widawsky 	while ((char *)subtable < end) {
10405857fba5SBen Widawsky 		printf("\n");
10415857fba5SBen Widawsky 		if (subtable->Length < sizeof(ACPI_LPIT_HEADER)) {
10425857fba5SBen Widawsky 			warnx("invalid subtable length %u", subtable->Length);
10435857fba5SBen Widawsky 			return;
10445857fba5SBen Widawsky 		}
10455857fba5SBen Widawsky 		action(subtable);
10465857fba5SBen Widawsky 		subtable = (ACPI_LPIT_HEADER *)((char *)subtable +
10475857fba5SBen Widawsky 		    subtable->Length);
10485857fba5SBen Widawsky 	}
10495857fba5SBen Widawsky }
10505857fba5SBen Widawsky 
10515857fba5SBen Widawsky static void
10525857fba5SBen Widawsky acpi_handle_lpit(ACPI_TABLE_HEADER *sdp)
10535857fba5SBen Widawsky {
10545857fba5SBen Widawsky 	ACPI_TABLE_LPIT *lpit;
10555857fba5SBen Widawsky 
10565857fba5SBen Widawsky 	printf(BEGIN_COMMENT);
10575857fba5SBen Widawsky 	acpi_print_sdt(sdp);
10585857fba5SBen Widawsky 	lpit = (ACPI_TABLE_LPIT *)sdp;
10595857fba5SBen Widawsky 	acpi_walk_lpit(sdp, (lpit + 1), acpi_print_lpit);
10605857fba5SBen Widawsky 
10615857fba5SBen Widawsky 	printf(END_COMMENT);
10625857fba5SBen Widawsky }
10635857fba5SBen Widawsky 
10645857fba5SBen Widawsky static void
1065a0333ad1SJohn Baldwin acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain,
1066a0333ad1SJohn Baldwin     uint32_t flags)
1067a0333ad1SJohn Baldwin {
1068a0333ad1SJohn Baldwin 
1069a0333ad1SJohn Baldwin 	printf("\tFlags={");
1070a0333ad1SJohn Baldwin 	if (flags & ACPI_SRAT_CPU_ENABLED)
1071a0333ad1SJohn Baldwin 		printf("ENABLED");
1072a0333ad1SJohn Baldwin 	else
1073a0333ad1SJohn Baldwin 		printf("DISABLED");
1074a0333ad1SJohn Baldwin 	printf("}\n");
1075a0333ad1SJohn Baldwin 	printf("\tAPIC ID=%d\n", apic_id);
1076a0333ad1SJohn Baldwin 	printf("\tProximity Domain=%d\n", proximity_domain);
1077a0333ad1SJohn Baldwin }
1078a0333ad1SJohn Baldwin 
1079c031c93bSTakanori Watanabe static char *
1080c031c93bSTakanori Watanabe acpi_tcpa_evname(struct TCPAevent *event)
1081c031c93bSTakanori Watanabe {
1082c031c93bSTakanori Watanabe 	struct TCPApc_event *pc_event;
1083c031c93bSTakanori Watanabe 	char *eventname = NULL;
1084c031c93bSTakanori Watanabe 
1085c031c93bSTakanori Watanabe 	pc_event = (struct TCPApc_event *)(event + 1);
1086c031c93bSTakanori Watanabe 
1087c031c93bSTakanori Watanabe 	switch(event->event_type) {
1088c031c93bSTakanori Watanabe 	case PREBOOT:
1089c031c93bSTakanori Watanabe 	case POST_CODE:
1090c031c93bSTakanori Watanabe 	case UNUSED:
1091c031c93bSTakanori Watanabe 	case NO_ACTION:
1092c031c93bSTakanori Watanabe 	case SEPARATOR:
1093c031c93bSTakanori Watanabe 	case SCRTM_CONTENTS:
1094c031c93bSTakanori Watanabe 	case SCRTM_VERSION:
1095c031c93bSTakanori Watanabe 	case CPU_MICROCODE:
1096c031c93bSTakanori Watanabe 	case PLATFORM_CONFIG_FLAGS:
1097c031c93bSTakanori Watanabe 	case TABLE_OF_DEVICES:
1098c031c93bSTakanori Watanabe 	case COMPACT_HASH:
1099c031c93bSTakanori Watanabe 	case IPL:
1100c031c93bSTakanori Watanabe 	case IPL_PARTITION_DATA:
1101c031c93bSTakanori Watanabe 	case NONHOST_CODE:
1102c031c93bSTakanori Watanabe 	case NONHOST_CONFIG:
1103c031c93bSTakanori Watanabe 	case NONHOST_INFO:
1104c031c93bSTakanori Watanabe 		asprintf(&eventname, "%s",
1105c031c93bSTakanori Watanabe 		    tcpa_event_type_strings[event->event_type]);
1106c031c93bSTakanori Watanabe 		break;
1107c031c93bSTakanori Watanabe 
1108c031c93bSTakanori Watanabe 	case ACTION:
1109c031c93bSTakanori Watanabe 		eventname = calloc(event->event_size + 1, sizeof(char));
1110c031c93bSTakanori Watanabe 		memcpy(eventname, pc_event, event->event_size);
1111c031c93bSTakanori Watanabe 		break;
1112c031c93bSTakanori Watanabe 
1113c031c93bSTakanori Watanabe 	case EVENT_TAG:
1114c031c93bSTakanori Watanabe 		switch (pc_event->event_id) {
1115c031c93bSTakanori Watanabe 		case SMBIOS:
1116c031c93bSTakanori Watanabe 		case BIS_CERT:
1117c031c93bSTakanori Watanabe 		case CMOS:
1118c031c93bSTakanori Watanabe 		case NVRAM:
1119c031c93bSTakanori Watanabe 		case OPTION_ROM_EXEC:
1120c031c93bSTakanori Watanabe 		case OPTION_ROM_CONFIG:
1121c031c93bSTakanori Watanabe 		case S_CRTM_VERSION:
1122c031c93bSTakanori Watanabe 		case POST_BIOS_ROM:
1123c031c93bSTakanori Watanabe 		case ESCD:
1124c031c93bSTakanori Watanabe 		case OPTION_ROM_MICROCODE:
1125c031c93bSTakanori Watanabe 		case S_CRTM_CONTENTS:
1126c031c93bSTakanori Watanabe 		case POST_CONTENTS:
1127c031c93bSTakanori Watanabe 			asprintf(&eventname, "%s",
1128c031c93bSTakanori Watanabe 			    TCPA_pcclient_strings[pc_event->event_id]);
1129c031c93bSTakanori Watanabe 			break;
1130c031c93bSTakanori Watanabe 
1131c031c93bSTakanori Watanabe 		default:
1132c031c93bSTakanori Watanabe 			asprintf(&eventname, "<unknown tag 0x%02x>",
1133c031c93bSTakanori Watanabe 			    pc_event->event_id);
1134c031c93bSTakanori Watanabe 			break;
1135c031c93bSTakanori Watanabe 		}
1136c031c93bSTakanori Watanabe 		break;
1137c031c93bSTakanori Watanabe 
1138c031c93bSTakanori Watanabe 	default:
1139c031c93bSTakanori Watanabe 		asprintf(&eventname, "<unknown 0x%02x>", event->event_type);
1140c031c93bSTakanori Watanabe 		break;
1141c031c93bSTakanori Watanabe 	}
1142c031c93bSTakanori Watanabe 
1143c031c93bSTakanori Watanabe 	return eventname;
1144c031c93bSTakanori Watanabe }
1145c031c93bSTakanori Watanabe 
1146c031c93bSTakanori Watanabe static void
1147c031c93bSTakanori Watanabe acpi_print_tcpa(struct TCPAevent *event)
1148c031c93bSTakanori Watanabe {
1149c031c93bSTakanori Watanabe 	int i;
1150c031c93bSTakanori Watanabe 	char *eventname;
1151c031c93bSTakanori Watanabe 
1152c031c93bSTakanori Watanabe 	eventname = acpi_tcpa_evname(event);
1153c031c93bSTakanori Watanabe 
1154c031c93bSTakanori Watanabe 	printf("\t%d", event->pcr_index);
1155c031c93bSTakanori Watanabe 	printf(" 0x");
1156c031c93bSTakanori Watanabe 	for (i = 0; i < 20; i++)
1157c031c93bSTakanori Watanabe 		printf("%02x", event->pcr_value[i]);
1158c031c93bSTakanori Watanabe 	printf(" [%s]\n", eventname ? eventname : "<unknown>");
1159c031c93bSTakanori Watanabe 
1160c031c93bSTakanori Watanabe 	free(eventname);
1161c031c93bSTakanori Watanabe }
1162c031c93bSTakanori Watanabe 
1163c031c93bSTakanori Watanabe static void
1164c031c93bSTakanori Watanabe acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp)
1165c031c93bSTakanori Watanabe {
1166c031c93bSTakanori Watanabe 	struct TCPAbody *tcpa;
1167c031c93bSTakanori Watanabe 	struct TCPAevent *event;
1168977fd9daSTakanori Watanabe 	uintmax_t len, paddr;
1169c031c93bSTakanori Watanabe 	unsigned char *vaddr = NULL;
1170c031c93bSTakanori Watanabe 	unsigned char *vend = NULL;
1171c031c93bSTakanori Watanabe 
1172c031c93bSTakanori Watanabe 	printf(BEGIN_COMMENT);
1173c031c93bSTakanori Watanabe 	acpi_print_sdt(sdp);
1174c031c93bSTakanori Watanabe 	tcpa = (struct TCPAbody *) sdp;
1175c031c93bSTakanori Watanabe 
1176c031c93bSTakanori Watanabe 	switch (tcpa->platform_class) {
1177c031c93bSTakanori Watanabe 	case ACPI_TCPA_BIOS_CLIENT:
1178c031c93bSTakanori Watanabe 		len = tcpa->client.log_max_len;
1179c031c93bSTakanori Watanabe 		paddr = tcpa->client.log_start_addr;
1180c031c93bSTakanori Watanabe 		break;
1181c031c93bSTakanori Watanabe 
1182c031c93bSTakanori Watanabe 	case ACPI_TCPA_BIOS_SERVER:
1183c031c93bSTakanori Watanabe 		len = tcpa->server.log_max_len;
1184c031c93bSTakanori Watanabe 		paddr = tcpa->server.log_start_addr;
1185c031c93bSTakanori Watanabe 		break;
1186c031c93bSTakanori Watanabe 
1187c031c93bSTakanori Watanabe 	default:
1188c031c93bSTakanori Watanabe 		printf("XXX");
1189c031c93bSTakanori Watanabe 		printf(END_COMMENT);
1190c031c93bSTakanori Watanabe 		return;
1191c031c93bSTakanori Watanabe 	}
11920e1982f4STakanori Watanabe 	printf("\tClass %u Base Address 0x%jx Length %ju\n\n",
1193c031c93bSTakanori Watanabe 	    tcpa->platform_class, paddr, len);
1194c031c93bSTakanori Watanabe 
1195c031c93bSTakanori Watanabe 	if (len == 0) {
1196c031c93bSTakanori Watanabe 		printf("\tEmpty TCPA table\n");
1197c031c93bSTakanori Watanabe 		printf(END_COMMENT);
1198c031c93bSTakanori Watanabe 		return;
1199c031c93bSTakanori Watanabe 	}
12002ef23c6dSTakanori Watanabe 	if(sdp->Revision == 1){
12012ef23c6dSTakanori Watanabe 		printf("\tOLD TCPA spec log found. Dumping not supported.\n");
12022ef23c6dSTakanori Watanabe 		printf(END_COMMENT);
12032ef23c6dSTakanori Watanabe 		return;
12042ef23c6dSTakanori Watanabe 	}
1205c031c93bSTakanori Watanabe 
1206c031c93bSTakanori Watanabe 	vaddr = (unsigned char *)acpi_map_physical(paddr, len);
1207c031c93bSTakanori Watanabe 	vend = vaddr + len;
1208c031c93bSTakanori Watanabe 
1209c031c93bSTakanori Watanabe 	while (vaddr != NULL) {
12102ef23c6dSTakanori Watanabe 		if ((vaddr + sizeof(struct TCPAevent) >= vend)||
12112ef23c6dSTakanori Watanabe 		    (vaddr + sizeof(struct TCPAevent) < vaddr))
1212c031c93bSTakanori Watanabe 			break;
12130e1982f4STakanori Watanabe 		event = (struct TCPAevent *)(void *)vaddr;
1214c031c93bSTakanori Watanabe 		if (vaddr + event->event_size >= vend)
1215c031c93bSTakanori Watanabe 			break;
12162ef23c6dSTakanori Watanabe 		if (vaddr + event->event_size < vaddr)
12172ef23c6dSTakanori Watanabe 			break;
1218c031c93bSTakanori Watanabe 		if (event->event_type == 0 && event->event_size == 0)
1219c031c93bSTakanori Watanabe 			break;
1220c031c93bSTakanori Watanabe #if 0
1221c031c93bSTakanori Watanabe 		{
1222c031c93bSTakanori Watanabe 		unsigned int i, j, k;
1223c031c93bSTakanori Watanabe 
1224c031c93bSTakanori Watanabe 		printf("\n\tsize %d\n\t\t%p ", event->event_size, vaddr);
1225c031c93bSTakanori Watanabe 		for (j = 0, i = 0; i <
1226c031c93bSTakanori Watanabe 		    sizeof(struct TCPAevent) + event->event_size; i++) {
1227c031c93bSTakanori Watanabe 			printf("%02x ", vaddr[i]);
1228c031c93bSTakanori Watanabe 			if ((i+1) % 8 == 0) {
1229c031c93bSTakanori Watanabe 				for (k = 0; k < 8; k++)
1230c031c93bSTakanori Watanabe 					printf("%c", isprint(vaddr[j+k]) ?
1231c031c93bSTakanori Watanabe 					    vaddr[j+k] : '.');
1232c031c93bSTakanori Watanabe 				printf("\n\t\t%p ", &vaddr[i + 1]);
1233c031c93bSTakanori Watanabe 				j = i + 1;
1234c031c93bSTakanori Watanabe 			}
1235c031c93bSTakanori Watanabe 		}
1236c031c93bSTakanori Watanabe 		printf("\n"); }
1237c031c93bSTakanori Watanabe #endif
1238c031c93bSTakanori Watanabe 		acpi_print_tcpa(event);
1239c031c93bSTakanori Watanabe 
1240c031c93bSTakanori Watanabe 		vaddr += sizeof(struct TCPAevent) + event->event_size;
1241c031c93bSTakanori Watanabe 	}
1242c031c93bSTakanori Watanabe 
1243c031c93bSTakanori Watanabe 	printf(END_COMMENT);
1244c031c93bSTakanori Watanabe }
1245877fc2e3STakanori Watanabe static void acpi_handle_tpm2(ACPI_TABLE_HEADER *sdp)
1246877fc2e3STakanori Watanabe {
1247877fc2e3STakanori Watanabe 	ACPI_TABLE_TPM2 *tpm2;
1248877fc2e3STakanori Watanabe 
1249877fc2e3STakanori Watanabe 	printf (BEGIN_COMMENT);
1250877fc2e3STakanori Watanabe 	acpi_print_sdt(sdp);
1251877fc2e3STakanori Watanabe 	tpm2 = (ACPI_TABLE_TPM2 *) sdp;
12527aef7138SCy Schubert 	printf ("\t\tControlArea=%jx\n", tpm2->ControlAddress);
1253877fc2e3STakanori Watanabe 	printf ("\t\tStartMethod=%x\n", tpm2->StartMethod);
1254877fc2e3STakanori Watanabe 	printf (END_COMMENT);
1255877fc2e3STakanori Watanabe }
1256c031c93bSTakanori Watanabe 
1257ec650989SNeel Natu static const char *
1258ec650989SNeel Natu devscope_type2str(int type)
1259ec650989SNeel Natu {
1260ec650989SNeel Natu 	static char typebuf[16];
1261ec650989SNeel Natu 
1262ec650989SNeel Natu 	switch (type) {
1263ec650989SNeel Natu 	case 1:
1264ec650989SNeel Natu 		return ("PCI Endpoint Device");
1265ec650989SNeel Natu 	case 2:
1266ec650989SNeel Natu 		return ("PCI Sub-Hierarchy");
1267ec650989SNeel Natu 	case 3:
1268ec650989SNeel Natu 		return ("IOAPIC");
1269ec650989SNeel Natu 	case 4:
1270ec650989SNeel Natu 		return ("HPET");
1271ec650989SNeel Natu 	default:
1272ec650989SNeel Natu 		snprintf(typebuf, sizeof(typebuf), "%d", type);
1273ec650989SNeel Natu 		return (typebuf);
1274ec650989SNeel Natu 	}
1275ec650989SNeel Natu }
1276ec650989SNeel Natu 
1277ec650989SNeel Natu static int
1278ec650989SNeel Natu acpi_handle_dmar_devscope(void *addr, int remaining)
1279ec650989SNeel Natu {
1280ec650989SNeel Natu 	char sep;
1281ec650989SNeel Natu 	int pathlen;
1282ec650989SNeel Natu 	ACPI_DMAR_PCI_PATH *path, *pathend;
1283ec650989SNeel Natu 	ACPI_DMAR_DEVICE_SCOPE *devscope = addr;
1284ec650989SNeel Natu 
1285ec650989SNeel Natu 	if (remaining < (int)sizeof(ACPI_DMAR_DEVICE_SCOPE))
1286ec650989SNeel Natu 		return (-1);
1287ec650989SNeel Natu 
1288ec650989SNeel Natu 	if (remaining < devscope->Length)
1289ec650989SNeel Natu 		return (-1);
1290ec650989SNeel Natu 
1291ec650989SNeel Natu 	printf("\n");
1292ec650989SNeel Natu 	printf("\t\tType=%s\n", devscope_type2str(devscope->EntryType));
1293ec650989SNeel Natu 	printf("\t\tLength=%d\n", devscope->Length);
1294ec650989SNeel Natu 	printf("\t\tEnumerationId=%d\n", devscope->EnumerationId);
1295ec650989SNeel Natu 	printf("\t\tStartBusNumber=%d\n", devscope->Bus);
1296ec650989SNeel Natu 
1297ec650989SNeel Natu 	path = (ACPI_DMAR_PCI_PATH *)(devscope + 1);
1298ec650989SNeel Natu 	pathlen = devscope->Length - sizeof(ACPI_DMAR_DEVICE_SCOPE);
1299ec650989SNeel Natu 	pathend = path + pathlen / sizeof(ACPI_DMAR_PCI_PATH);
1300ec650989SNeel Natu 	if (path < pathend) {
1301ec650989SNeel Natu 		sep = '{';
1302ec650989SNeel Natu 		printf("\t\tPath=");
1303ec650989SNeel Natu 		do {
1304ec650989SNeel Natu 			printf("%c%d:%d", sep, path->Device, path->Function);
1305ec650989SNeel Natu 			sep=',';
1306ec650989SNeel Natu 			path++;
1307ec650989SNeel Natu 		} while (path < pathend);
1308ec650989SNeel Natu 		printf("}\n");
1309ec650989SNeel Natu 	}
1310ec650989SNeel Natu 
1311ec650989SNeel Natu 	return (devscope->Length);
1312ec650989SNeel Natu }
1313ec650989SNeel Natu 
1314ec650989SNeel Natu static void
1315ec650989SNeel Natu acpi_handle_dmar_drhd(ACPI_DMAR_HARDWARE_UNIT *drhd)
1316ec650989SNeel Natu {
1317ec650989SNeel Natu 	char *cp;
1318ec650989SNeel Natu 	int remaining, consumed;
1319ec650989SNeel Natu 
1320ec650989SNeel Natu 	printf("\n");
1321ec650989SNeel Natu 	printf("\tType=DRHD\n");
1322ec650989SNeel Natu 	printf("\tLength=%d\n", drhd->Header.Length);
1323ec650989SNeel Natu 
1324ec650989SNeel Natu #define	PRINTFLAG(var, flag)	printflag((var), ACPI_DMAR_## flag, #flag)
1325ec650989SNeel Natu 
1326ec650989SNeel Natu 	printf("\tFlags=");
1327ec650989SNeel Natu 	PRINTFLAG(drhd->Flags, INCLUDE_ALL);
1328ec650989SNeel Natu 	PRINTFLAG_END();
1329ec650989SNeel Natu 
1330ec650989SNeel Natu #undef PRINTFLAG
1331ec650989SNeel Natu 
1332ec650989SNeel Natu 	printf("\tSegment=%d\n", drhd->Segment);
13337d369c6eSJung-uk Kim 	printf("\tAddress=0x%016jx\n", (uintmax_t)drhd->Address);
1334ec650989SNeel Natu 
1335ec650989SNeel Natu 	remaining = drhd->Header.Length - sizeof(ACPI_DMAR_HARDWARE_UNIT);
1336ec650989SNeel Natu 	if (remaining > 0)
1337ec650989SNeel Natu 		printf("\tDevice Scope:");
1338ec650989SNeel Natu 	while (remaining > 0) {
1339ec650989SNeel Natu 		cp = (char *)drhd + drhd->Header.Length - remaining;
1340ec650989SNeel Natu 		consumed = acpi_handle_dmar_devscope(cp, remaining);
1341ec650989SNeel Natu 		if (consumed <= 0)
1342ec650989SNeel Natu 			break;
1343ec650989SNeel Natu 		else
1344ec650989SNeel Natu 			remaining -= consumed;
1345ec650989SNeel Natu 	}
1346ec650989SNeel Natu }
1347ec650989SNeel Natu 
1348ec650989SNeel Natu static void
1349ec650989SNeel Natu acpi_handle_dmar_rmrr(ACPI_DMAR_RESERVED_MEMORY *rmrr)
1350ec650989SNeel Natu {
1351ec650989SNeel Natu 	char *cp;
1352ec650989SNeel Natu 	int remaining, consumed;
1353ec650989SNeel Natu 
1354ec650989SNeel Natu 	printf("\n");
1355ec650989SNeel Natu 	printf("\tType=RMRR\n");
1356ec650989SNeel Natu 	printf("\tLength=%d\n", rmrr->Header.Length);
1357ec650989SNeel Natu 	printf("\tSegment=%d\n", rmrr->Segment);
13587d369c6eSJung-uk Kim 	printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rmrr->BaseAddress);
13597d369c6eSJung-uk Kim 	printf("\tLimitAddress=0x%016jx\n", (uintmax_t)rmrr->EndAddress);
1360ec650989SNeel Natu 
1361ec650989SNeel Natu 	remaining = rmrr->Header.Length - sizeof(ACPI_DMAR_RESERVED_MEMORY);
1362ec650989SNeel Natu 	if (remaining > 0)
1363ec650989SNeel Natu 		printf("\tDevice Scope:");
1364ec650989SNeel Natu 	while (remaining > 0) {
1365ec650989SNeel Natu 		cp = (char *)rmrr + rmrr->Header.Length - remaining;
1366ec650989SNeel Natu 		consumed = acpi_handle_dmar_devscope(cp, remaining);
1367ec650989SNeel Natu 		if (consumed <= 0)
1368ec650989SNeel Natu 			break;
1369ec650989SNeel Natu 		else
1370ec650989SNeel Natu 			remaining -= consumed;
1371ec650989SNeel Natu 	}
1372ec650989SNeel Natu }
1373ec650989SNeel Natu 
1374ec650989SNeel Natu static void
1375ec650989SNeel Natu acpi_handle_dmar_atsr(ACPI_DMAR_ATSR *atsr)
1376ec650989SNeel Natu {
1377ec650989SNeel Natu 	char *cp;
1378ec650989SNeel Natu 	int remaining, consumed;
1379ec650989SNeel Natu 
1380ec650989SNeel Natu 	printf("\n");
1381ec650989SNeel Natu 	printf("\tType=ATSR\n");
1382ec650989SNeel Natu 	printf("\tLength=%d\n", atsr->Header.Length);
1383ec650989SNeel Natu 
1384ec650989SNeel Natu #define	PRINTFLAG(var, flag)	printflag((var), ACPI_DMAR_## flag, #flag)
1385ec650989SNeel Natu 
1386ec650989SNeel Natu 	printf("\tFlags=");
1387ec650989SNeel Natu 	PRINTFLAG(atsr->Flags, ALL_PORTS);
1388ec650989SNeel Natu 	PRINTFLAG_END();
1389ec650989SNeel Natu 
1390ec650989SNeel Natu #undef PRINTFLAG
1391ec650989SNeel Natu 
1392ec650989SNeel Natu 	printf("\tSegment=%d\n", atsr->Segment);
1393ec650989SNeel Natu 
1394ec650989SNeel Natu 	remaining = atsr->Header.Length - sizeof(ACPI_DMAR_ATSR);
1395ec650989SNeel Natu 	if (remaining > 0)
1396ec650989SNeel Natu 		printf("\tDevice Scope:");
1397ec650989SNeel Natu 	while (remaining > 0) {
1398ec650989SNeel Natu 		cp = (char *)atsr + atsr->Header.Length - remaining;
1399ec650989SNeel Natu 		consumed = acpi_handle_dmar_devscope(cp, remaining);
1400ec650989SNeel Natu 		if (consumed <= 0)
1401ec650989SNeel Natu 			break;
1402ec650989SNeel Natu 		else
1403ec650989SNeel Natu 			remaining -= consumed;
1404ec650989SNeel Natu 	}
1405ec650989SNeel Natu }
1406ec650989SNeel Natu 
1407ec650989SNeel Natu static void
1408ec650989SNeel Natu acpi_handle_dmar_rhsa(ACPI_DMAR_RHSA *rhsa)
1409ec650989SNeel Natu {
1410ec650989SNeel Natu 
1411ec650989SNeel Natu 	printf("\n");
1412ec650989SNeel Natu 	printf("\tType=RHSA\n");
1413ec650989SNeel Natu 	printf("\tLength=%d\n", rhsa->Header.Length);
14147d369c6eSJung-uk Kim 	printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rhsa->BaseAddress);
1415ec650989SNeel Natu 	printf("\tProximityDomain=0x%08x\n", rhsa->ProximityDomain);
1416ec650989SNeel Natu }
1417ec650989SNeel Natu 
1418ec650989SNeel Natu static int
1419ec650989SNeel Natu acpi_handle_dmar_remapping_structure(void *addr, int remaining)
1420ec650989SNeel Natu {
1421ec650989SNeel Natu 	ACPI_DMAR_HEADER *hdr = addr;
1422ec650989SNeel Natu 
1423ec650989SNeel Natu 	if (remaining < (int)sizeof(ACPI_DMAR_HEADER))
1424ec650989SNeel Natu 		return (-1);
1425ec650989SNeel Natu 
1426ec650989SNeel Natu 	if (remaining < hdr->Length)
1427ec650989SNeel Natu 		return (-1);
1428ec650989SNeel Natu 
1429ec650989SNeel Natu 	switch (hdr->Type) {
1430ec650989SNeel Natu 	case ACPI_DMAR_TYPE_HARDWARE_UNIT:
1431ec650989SNeel Natu 		acpi_handle_dmar_drhd(addr);
1432ec650989SNeel Natu 		break;
1433ec650989SNeel Natu 	case ACPI_DMAR_TYPE_RESERVED_MEMORY:
1434ec650989SNeel Natu 		acpi_handle_dmar_rmrr(addr);
1435ec650989SNeel Natu 		break;
1436313a0c13SJung-uk Kim 	case ACPI_DMAR_TYPE_ROOT_ATS:
1437ec650989SNeel Natu 		acpi_handle_dmar_atsr(addr);
1438ec650989SNeel Natu 		break;
1439313a0c13SJung-uk Kim 	case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
1440ec650989SNeel Natu 		acpi_handle_dmar_rhsa(addr);
1441ec650989SNeel Natu 		break;
1442ec650989SNeel Natu 	default:
1443ec650989SNeel Natu 		printf("\n");
1444ec650989SNeel Natu 		printf("\tType=%d\n", hdr->Type);
1445ec650989SNeel Natu 		printf("\tLength=%d\n", hdr->Length);
1446ec650989SNeel Natu 		break;
1447ec650989SNeel Natu 	}
1448ec650989SNeel Natu 	return (hdr->Length);
1449ec650989SNeel Natu }
1450ec650989SNeel Natu 
1451ec650989SNeel Natu #ifndef ACPI_DMAR_X2APIC_OPT_OUT
1452ec650989SNeel Natu #define	ACPI_DMAR_X2APIC_OPT_OUT	(0x2)
1453ec650989SNeel Natu #endif
1454ec650989SNeel Natu 
1455ec650989SNeel Natu static void
1456ec650989SNeel Natu acpi_handle_dmar(ACPI_TABLE_HEADER *sdp)
1457ec650989SNeel Natu {
1458ec650989SNeel Natu 	char *cp;
1459ec650989SNeel Natu 	int remaining, consumed;
1460ec650989SNeel Natu 	ACPI_TABLE_DMAR *dmar;
1461ec650989SNeel Natu 
1462ec650989SNeel Natu 	printf(BEGIN_COMMENT);
1463ec650989SNeel Natu 	acpi_print_sdt(sdp);
1464ec650989SNeel Natu 	dmar = (ACPI_TABLE_DMAR *)sdp;
1465ec650989SNeel Natu 	printf("\tHost Address Width=%d\n", dmar->Width + 1);
1466ec650989SNeel Natu 
1467ec650989SNeel Natu #define PRINTFLAG(var, flag)	printflag((var), ACPI_DMAR_## flag, #flag)
1468ec650989SNeel Natu 
1469ec650989SNeel Natu 	printf("\tFlags=");
1470ec650989SNeel Natu 	PRINTFLAG(dmar->Flags, INTR_REMAP);
1471ec650989SNeel Natu 	PRINTFLAG(dmar->Flags, X2APIC_OPT_OUT);
1472ec650989SNeel Natu 	PRINTFLAG_END();
1473ec650989SNeel Natu 
1474ec650989SNeel Natu #undef PRINTFLAG
1475ec650989SNeel Natu 
1476ec650989SNeel Natu 	remaining = sdp->Length - sizeof(ACPI_TABLE_DMAR);
1477ec650989SNeel Natu 	while (remaining > 0) {
1478ec650989SNeel Natu 		cp = (char *)sdp + sdp->Length - remaining;
1479ec650989SNeel Natu 		consumed = acpi_handle_dmar_remapping_structure(cp, remaining);
1480ec650989SNeel Natu 		if (consumed <= 0)
1481ec650989SNeel Natu 			break;
1482ec650989SNeel Natu 		else
1483ec650989SNeel Natu 			remaining -= consumed;
1484ec650989SNeel Natu 	}
1485ec650989SNeel Natu 
1486ec650989SNeel Natu 	printf(END_COMMENT);
1487ec650989SNeel Natu }
1488ec650989SNeel Natu 
1489a0333ad1SJohn Baldwin static void
1490986dffafSJohn Baldwin acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp)
1491a0333ad1SJohn Baldwin {
1492a0333ad1SJohn Baldwin 
1493a0333ad1SJohn Baldwin 	printf("\tFlags={");
1494986dffafSJohn Baldwin 	if (mp->Flags & ACPI_SRAT_MEM_ENABLED)
1495a0333ad1SJohn Baldwin 		printf("ENABLED");
1496a0333ad1SJohn Baldwin 	else
1497a0333ad1SJohn Baldwin 		printf("DISABLED");
1498986dffafSJohn Baldwin 	if (mp->Flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)
1499a0333ad1SJohn Baldwin 		printf(",HOT_PLUGGABLE");
1500986dffafSJohn Baldwin 	if (mp->Flags & ACPI_SRAT_MEM_NON_VOLATILE)
1501a0333ad1SJohn Baldwin 		printf(",NON_VOLATILE");
1502a0333ad1SJohn Baldwin 	printf("}\n");
1503986dffafSJohn Baldwin 	printf("\tBase Address=0x%016jx\n", (uintmax_t)mp->BaseAddress);
1504986dffafSJohn Baldwin 	printf("\tLength=0x%016jx\n", (uintmax_t)mp->Length);
1505986dffafSJohn Baldwin 	printf("\tProximity Domain=%d\n", mp->ProximityDomain);
1506a0333ad1SJohn Baldwin }
1507a0333ad1SJohn Baldwin 
150827941afaSEd Maste static const char *srat_types[] = {
150927941afaSEd Maste     [ACPI_SRAT_TYPE_CPU_AFFINITY] = "CPU",
151027941afaSEd Maste     [ACPI_SRAT_TYPE_MEMORY_AFFINITY] = "Memory",
151127941afaSEd Maste     [ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY] = "X2APIC",
1512cebb7b19SEd Maste     [ACPI_SRAT_TYPE_GICC_AFFINITY] = "GICC",
1513cebb7b19SEd Maste     [ACPI_SRAT_TYPE_GIC_ITS_AFFINITY] = "GIC ITS",
151427941afaSEd Maste };
1515a0333ad1SJohn Baldwin 
1516a0333ad1SJohn Baldwin static void
1517986dffafSJohn Baldwin acpi_print_srat(ACPI_SUBTABLE_HEADER *srat)
1518a0333ad1SJohn Baldwin {
1519986dffafSJohn Baldwin 	ACPI_SRAT_CPU_AFFINITY *cpu;
1520986dffafSJohn Baldwin 	ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic;
15212b2b1f42SAndrew Turner 	ACPI_SRAT_GICC_AFFINITY *gic;
1522a0333ad1SJohn Baldwin 
1523c86932b6SMarcelo Araujo 	if (srat->Type < nitems(srat_types))
1524986dffafSJohn Baldwin 		printf("\tType=%s\n", srat_types[srat->Type]);
1525a0333ad1SJohn Baldwin 	else
1526986dffafSJohn Baldwin 		printf("\tType=%d (unknown)\n", srat->Type);
1527986dffafSJohn Baldwin 	switch (srat->Type) {
1528a0333ad1SJohn Baldwin 	case ACPI_SRAT_TYPE_CPU_AFFINITY:
1529986dffafSJohn Baldwin 		cpu = (ACPI_SRAT_CPU_AFFINITY *)srat;
1530986dffafSJohn Baldwin 		acpi_print_srat_cpu(cpu->ApicId,
1531986dffafSJohn Baldwin 		    cpu->ProximityDomainHi[2] << 24 |
1532986dffafSJohn Baldwin 		    cpu->ProximityDomainHi[1] << 16 |
1533986dffafSJohn Baldwin 		    cpu->ProximityDomainHi[0] << 0 |
1534986dffafSJohn Baldwin 		    cpu->ProximityDomainLo, cpu->Flags);
1535a0333ad1SJohn Baldwin 		break;
1536a0333ad1SJohn Baldwin 	case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
1537986dffafSJohn Baldwin 		acpi_print_srat_memory((ACPI_SRAT_MEM_AFFINITY *)srat);
1538a0333ad1SJohn Baldwin 		break;
1539a0333ad1SJohn Baldwin 	case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
1540986dffafSJohn Baldwin 		x2apic = (ACPI_SRAT_X2APIC_CPU_AFFINITY *)srat;
1541986dffafSJohn Baldwin 		acpi_print_srat_cpu(x2apic->ApicId, x2apic->ProximityDomain,
1542986dffafSJohn Baldwin 		    x2apic->Flags);
1543a0333ad1SJohn Baldwin 		break;
15442b2b1f42SAndrew Turner 	case ACPI_SRAT_TYPE_GICC_AFFINITY:
15452b2b1f42SAndrew Turner 		gic = (ACPI_SRAT_GICC_AFFINITY *)srat;
15462b2b1f42SAndrew Turner 		acpi_print_srat_cpu(gic->AcpiProcessorUid, gic->ProximityDomain,
15472b2b1f42SAndrew Turner 		    gic->Flags);
15482b2b1f42SAndrew Turner 		break;
1549a0333ad1SJohn Baldwin 	}
1550a0333ad1SJohn Baldwin }
1551a0333ad1SJohn Baldwin 
1552a0333ad1SJohn Baldwin static void
1553986dffafSJohn Baldwin acpi_handle_srat(ACPI_TABLE_HEADER *sdp)
1554a0333ad1SJohn Baldwin {
1555986dffafSJohn Baldwin 	ACPI_TABLE_SRAT *srat;
1556a0333ad1SJohn Baldwin 
1557a0333ad1SJohn Baldwin 	printf(BEGIN_COMMENT);
1558a0333ad1SJohn Baldwin 	acpi_print_sdt(sdp);
1559986dffafSJohn Baldwin 	srat = (ACPI_TABLE_SRAT *)sdp;
1560986dffafSJohn Baldwin 	printf("\tTable Revision=%d\n", srat->TableRevision);
1561986dffafSJohn Baldwin 	acpi_walk_subtables(sdp, (srat + 1), acpi_print_srat);
1562a0333ad1SJohn Baldwin 	printf(END_COMMENT);
1563a0333ad1SJohn Baldwin }
1564a0333ad1SJohn Baldwin 
1565340c0022SEd Maste static const char *nfit_types[] = {
1566340c0022SEd Maste     [ACPI_NFIT_TYPE_SYSTEM_ADDRESS] = "System Address",
1567340c0022SEd Maste     [ACPI_NFIT_TYPE_MEMORY_MAP] = "Memory Map",
1568340c0022SEd Maste     [ACPI_NFIT_TYPE_INTERLEAVE] = "Interleave",
1569340c0022SEd Maste     [ACPI_NFIT_TYPE_SMBIOS] = "SMBIOS",
1570340c0022SEd Maste     [ACPI_NFIT_TYPE_CONTROL_REGION] = "Control Region",
1571340c0022SEd Maste     [ACPI_NFIT_TYPE_DATA_REGION] = "Data Region",
15721b109c69SAlexander Motin     [ACPI_NFIT_TYPE_FLUSH_ADDRESS] = "Flush Address",
15731b109c69SAlexander Motin     [ACPI_NFIT_TYPE_CAPABILITIES] = "Platform Capabilities"
1574340c0022SEd Maste };
1575340c0022SEd Maste 
1576340c0022SEd Maste 
1577340c0022SEd Maste static void
1578340c0022SEd Maste acpi_print_nfit(ACPI_NFIT_HEADER *nfit)
1579340c0022SEd Maste {
1580340c0022SEd Maste 	char *uuidstr;
1581*3b7935f3SAlexander Motin 	uint32_t m, status;
1582340c0022SEd Maste 
1583340c0022SEd Maste 	ACPI_NFIT_SYSTEM_ADDRESS *sysaddr;
1584340c0022SEd Maste 	ACPI_NFIT_MEMORY_MAP *mmap;
1585340c0022SEd Maste 	ACPI_NFIT_INTERLEAVE *ileave;
1586340c0022SEd Maste 	ACPI_NFIT_SMBIOS *smbios;
1587340c0022SEd Maste 	ACPI_NFIT_CONTROL_REGION *ctlreg;
1588340c0022SEd Maste 	ACPI_NFIT_DATA_REGION *datareg;
1589340c0022SEd Maste 	ACPI_NFIT_FLUSH_ADDRESS *fladdr;
15901b109c69SAlexander Motin 	ACPI_NFIT_CAPABILITIES *caps;
1591340c0022SEd Maste 
1592340c0022SEd Maste 	if (nfit->Type < nitems(nfit_types))
1593340c0022SEd Maste 		printf("\tType=%s\n", nfit_types[nfit->Type]);
1594340c0022SEd Maste 	else
1595340c0022SEd Maste 		printf("\tType=%u (unknown)\n", nfit->Type);
1596340c0022SEd Maste 	switch (nfit->Type) {
1597340c0022SEd Maste 	case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
1598340c0022SEd Maste 		sysaddr = (ACPI_NFIT_SYSTEM_ADDRESS *)nfit;
1599340c0022SEd Maste 		printf("\tRangeIndex=%u\n", (u_int)sysaddr->RangeIndex);
1600340c0022SEd Maste 		printf("\tProximityDomain=%u\n",
1601340c0022SEd Maste 		    (u_int)sysaddr->ProximityDomain);
1602340c0022SEd Maste 		uuid_to_string((uuid_t *)(sysaddr->RangeGuid),
1603340c0022SEd Maste 		    &uuidstr, &status);
1604340c0022SEd Maste 		if (status != uuid_s_ok)
1605340c0022SEd Maste 			errx(1, "uuid_to_string: status=%u", status);
1606340c0022SEd Maste 		printf("\tRangeGuid=%s\n", uuidstr);
1607340c0022SEd Maste 		free(uuidstr);
1608340c0022SEd Maste 		printf("\tAddress=0x%016jx\n", (uintmax_t)sysaddr->Address);
1609340c0022SEd Maste 		printf("\tLength=0x%016jx\n", (uintmax_t)sysaddr->Length);
1610340c0022SEd Maste 		printf("\tMemoryMapping=0x%016jx\n",
1611340c0022SEd Maste 		    (uintmax_t)sysaddr->MemoryMapping);
1612340c0022SEd Maste 
1613340c0022SEd Maste #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_## flag, #flag)
1614340c0022SEd Maste 
1615340c0022SEd Maste 		printf("\tFlags=");
1616340c0022SEd Maste 		PRINTFLAG(sysaddr->Flags, ADD_ONLINE_ONLY);
1617340c0022SEd Maste 		PRINTFLAG(sysaddr->Flags, PROXIMITY_VALID);
1618340c0022SEd Maste 		PRINTFLAG_END();
1619340c0022SEd Maste 
1620340c0022SEd Maste #undef PRINTFLAG
1621340c0022SEd Maste 
1622340c0022SEd Maste 		break;
1623340c0022SEd Maste 	case ACPI_NFIT_TYPE_MEMORY_MAP:
1624340c0022SEd Maste 		mmap = (ACPI_NFIT_MEMORY_MAP *)nfit;
162592d0d6bbSAlexander Motin 		printf("\tDeviceHandle=0x%x\n", (u_int)mmap->DeviceHandle);
162692d0d6bbSAlexander Motin 		printf("\tPhysicalId=0x%04x\n", (u_int)mmap->PhysicalId);
1627340c0022SEd Maste 		printf("\tRegionId=%u\n", (u_int)mmap->RegionId);
1628340c0022SEd Maste 		printf("\tRangeIndex=%u\n", (u_int)mmap->RangeIndex);
1629340c0022SEd Maste 		printf("\tRegionIndex=%u\n", (u_int)mmap->RegionIndex);
1630340c0022SEd Maste 		printf("\tRegionSize=0x%016jx\n", (uintmax_t)mmap->RegionSize);
1631340c0022SEd Maste 		printf("\tRegionOffset=0x%016jx\n",
1632340c0022SEd Maste 		    (uintmax_t)mmap->RegionOffset);
1633340c0022SEd Maste 		printf("\tAddress=0x%016jx\n", (uintmax_t)mmap->Address);
1634340c0022SEd Maste 		printf("\tInterleaveIndex=%u\n", (u_int)mmap->InterleaveIndex);
1635fb1cf2a9SAlexander Motin 		printf("\tInterleaveWays=%u\n", (u_int)mmap->InterleaveWays);
1636340c0022SEd Maste 
1637340c0022SEd Maste #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_MEM_## flag, #flag)
1638340c0022SEd Maste 
1639340c0022SEd Maste 		printf("\tFlags=");
1640340c0022SEd Maste 		PRINTFLAG(mmap->Flags, SAVE_FAILED);
1641340c0022SEd Maste 		PRINTFLAG(mmap->Flags, RESTORE_FAILED);
1642340c0022SEd Maste 		PRINTFLAG(mmap->Flags, FLUSH_FAILED);
1643340c0022SEd Maste 		PRINTFLAG(mmap->Flags, NOT_ARMED);
1644340c0022SEd Maste 		PRINTFLAG(mmap->Flags, HEALTH_OBSERVED);
1645340c0022SEd Maste 		PRINTFLAG(mmap->Flags, HEALTH_ENABLED);
1646340c0022SEd Maste 		PRINTFLAG(mmap->Flags, MAP_FAILED);
1647340c0022SEd Maste 		PRINTFLAG_END();
1648340c0022SEd Maste 
1649340c0022SEd Maste #undef PRINTFLAG
1650340c0022SEd Maste 
1651340c0022SEd Maste 		break;
1652340c0022SEd Maste 	case ACPI_NFIT_TYPE_INTERLEAVE:
1653340c0022SEd Maste 		ileave = (ACPI_NFIT_INTERLEAVE *)nfit;
1654340c0022SEd Maste 		printf("\tInterleaveIndex=%u\n",
1655340c0022SEd Maste 		    (u_int)ileave->InterleaveIndex);
1656340c0022SEd Maste 		printf("\tLineCount=%u\n", (u_int)ileave->LineCount);
1657340c0022SEd Maste 		printf("\tLineSize=%u\n", (u_int)ileave->LineSize);
1658*3b7935f3SAlexander Motin 		for (m = 0; m < ileave->LineCount; m++) {
1659*3b7935f3SAlexander Motin 			printf("\tLine%uOffset=0x%08x\n", (u_int)m + 1,
1660*3b7935f3SAlexander Motin 			    (u_int)ileave->LineOffset[m]);
1661*3b7935f3SAlexander Motin 		}
1662340c0022SEd Maste 		break;
1663340c0022SEd Maste 	case ACPI_NFIT_TYPE_SMBIOS:
1664340c0022SEd Maste 		smbios = (ACPI_NFIT_SMBIOS *)nfit;
1665340c0022SEd Maste 		/* XXX smbios->Data[x] output is not supported */
1666340c0022SEd Maste 		break;
1667340c0022SEd Maste 	case ACPI_NFIT_TYPE_CONTROL_REGION:
1668340c0022SEd Maste 		ctlreg = (ACPI_NFIT_CONTROL_REGION *)nfit;
1669340c0022SEd Maste 		printf("\tRegionIndex=%u\n", (u_int)ctlreg->RegionIndex);
1670340c0022SEd Maste 		printf("\tVendorId=0x%04x\n", (u_int)ctlreg->VendorId);
1671340c0022SEd Maste 		printf("\tDeviceId=0x%04x\n", (u_int)ctlreg->DeviceId);
167235e39fd9SAlexander Motin 		printf("\tRevisionId=0x%02x\n", (u_int)ctlreg->RevisionId);
1673340c0022SEd Maste 		printf("\tSubsystemVendorId=0x%04x\n",
1674340c0022SEd Maste 		    (u_int)ctlreg->SubsystemVendorId);
1675340c0022SEd Maste 		printf("\tSubsystemDeviceId=0x%04x\n",
1676340c0022SEd Maste 		    (u_int)ctlreg->SubsystemDeviceId);
167735e39fd9SAlexander Motin 		printf("\tSubsystemRevisionId=0x%02x\n",
1678340c0022SEd Maste 		    (u_int)ctlreg->SubsystemRevisionId);
1679d4c2de2eSAlexander Motin 		printf("\tValidFields=0x%02x\n", (u_int)ctlreg->ValidFields);
168035e39fd9SAlexander Motin 		printf("\tManufacturingLocation=0x%02x\n",
1681340c0022SEd Maste 		    (u_int)ctlreg->ManufacturingLocation);
168235e39fd9SAlexander Motin 		printf("\tManufacturingDate=%04x\n",
168335e39fd9SAlexander Motin 		    (u_int)be16toh(ctlreg->ManufacturingDate));
168435e39fd9SAlexander Motin 		printf("\tSerialNumber=%08X\n",
168535e39fd9SAlexander Motin 		    (u_int)be32toh(ctlreg->SerialNumber));
1686fb1cf2a9SAlexander Motin 		printf("\tCode=0x%04x\n", (u_int)ctlreg->Code);
1687340c0022SEd Maste 		printf("\tWindows=%u\n", (u_int)ctlreg->Windows);
1688340c0022SEd Maste 		printf("\tWindowSize=0x%016jx\n",
1689340c0022SEd Maste 		    (uintmax_t)ctlreg->WindowSize);
1690340c0022SEd Maste 		printf("\tCommandOffset=0x%016jx\n",
1691340c0022SEd Maste 		    (uintmax_t)ctlreg->CommandOffset);
1692340c0022SEd Maste 		printf("\tCommandSize=0x%016jx\n",
1693340c0022SEd Maste 		    (uintmax_t)ctlreg->CommandSize);
1694340c0022SEd Maste 		printf("\tStatusOffset=0x%016jx\n",
1695340c0022SEd Maste 		    (uintmax_t)ctlreg->StatusOffset);
1696340c0022SEd Maste 		printf("\tStatusSize=0x%016jx\n",
1697340c0022SEd Maste 		    (uintmax_t)ctlreg->StatusSize);
1698340c0022SEd Maste 
1699340c0022SEd Maste #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_## flag, #flag)
1700340c0022SEd Maste 
1701340c0022SEd Maste 		printf("\tFlags=");
1702d4c2de2eSAlexander Motin 		PRINTFLAG(ctlreg->Flags, CONTROL_BUFFERED);
1703340c0022SEd Maste 		PRINTFLAG_END();
1704340c0022SEd Maste 
1705340c0022SEd Maste #undef PRINTFLAG
1706340c0022SEd Maste 
1707340c0022SEd Maste 		break;
1708340c0022SEd Maste 	case ACPI_NFIT_TYPE_DATA_REGION:
1709340c0022SEd Maste 		datareg = (ACPI_NFIT_DATA_REGION *)nfit;
1710340c0022SEd Maste 		printf("\tRegionIndex=%u\n", (u_int)datareg->RegionIndex);
1711340c0022SEd Maste 		printf("\tWindows=%u\n", (u_int)datareg->Windows);
1712340c0022SEd Maste 		printf("\tOffset=0x%016jx\n", (uintmax_t)datareg->Offset);
1713340c0022SEd Maste 		printf("\tSize=0x%016jx\n", (uintmax_t)datareg->Size);
1714340c0022SEd Maste 		printf("\tCapacity=0x%016jx\n", (uintmax_t)datareg->Capacity);
1715340c0022SEd Maste 		printf("\tStartAddress=0x%016jx\n",
1716340c0022SEd Maste 		    (uintmax_t)datareg->StartAddress);
1717340c0022SEd Maste 		break;
1718340c0022SEd Maste 	case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
1719340c0022SEd Maste 		fladdr = (ACPI_NFIT_FLUSH_ADDRESS *)nfit;
1720340c0022SEd Maste 		printf("\tDeviceHandle=%u\n", (u_int)fladdr->DeviceHandle);
1721340c0022SEd Maste 		printf("\tHintCount=%u\n", (u_int)fladdr->HintCount);
1722*3b7935f3SAlexander Motin 		for (m = 0; m < fladdr->HintCount; m++) {
1723*3b7935f3SAlexander Motin 			printf("\tHintAddress%u=0x%016jx\n", (u_int)m + 1,
1724*3b7935f3SAlexander Motin 			    (uintmax_t)fladdr->HintAddress[m]);
1725*3b7935f3SAlexander Motin 		}
1726340c0022SEd Maste 		break;
17271b109c69SAlexander Motin 	case ACPI_NFIT_TYPE_CAPABILITIES:
17281b109c69SAlexander Motin 		caps = (ACPI_NFIT_CAPABILITIES *)nfit;
17291b109c69SAlexander Motin 		printf("\tHighestCapability=%u\n", (u_int)caps->HighestCapability);
17301b109c69SAlexander Motin 
17311b109c69SAlexander Motin #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_CAPABILITY_## flag, #flag)
17321b109c69SAlexander Motin 
17331b109c69SAlexander Motin 		printf("\tCapabilities=");
17341b109c69SAlexander Motin 		PRINTFLAG(caps->Capabilities, CACHE_FLUSH);
17351b109c69SAlexander Motin 		PRINTFLAG(caps->Capabilities, MEM_FLUSH);
17361b109c69SAlexander Motin 		PRINTFLAG(caps->Capabilities, MEM_MIRRORING);
17371b109c69SAlexander Motin 		PRINTFLAG_END();
17381b109c69SAlexander Motin 
17391b109c69SAlexander Motin #undef PRINTFLAG
17401b109c69SAlexander Motin 		break;
1741340c0022SEd Maste 	}
1742340c0022SEd Maste }
1743340c0022SEd Maste 
1744340c0022SEd Maste static void
1745340c0022SEd Maste acpi_handle_nfit(ACPI_TABLE_HEADER *sdp)
1746340c0022SEd Maste {
1747340c0022SEd Maste 	ACPI_TABLE_NFIT *nfit;
1748340c0022SEd Maste 
1749340c0022SEd Maste 	printf(BEGIN_COMMENT);
1750340c0022SEd Maste 	acpi_print_sdt(sdp);
1751340c0022SEd Maste 	nfit = (ACPI_TABLE_NFIT *)sdp;
1752340c0022SEd Maste 	acpi_walk_nfit(sdp, (nfit + 1), acpi_print_nfit);
1753340c0022SEd Maste 	printf(END_COMMENT);
1754340c0022SEd Maste }
1755340c0022SEd Maste 
1756a0333ad1SJohn Baldwin static void
1757986dffafSJohn Baldwin acpi_print_sdt(ACPI_TABLE_HEADER *sdp)
1758c62f1cccSMitsuru IWASAKI {
1759773b6454SNate Lawson 	printf("  ");
1760278f0de6SJung-uk Kim 	acpi_print_string(sdp->Signature, ACPI_NAMESEG_SIZE);
1761c62f1cccSMitsuru IWASAKI 	printf(": Length=%d, Revision=%d, Checksum=%d,\n",
1762986dffafSJohn Baldwin 	       sdp->Length, sdp->Revision, sdp->Checksum);
1763e1e9a4bfSMitsuru IWASAKI 	printf("\tOEMID=");
1764986dffafSJohn Baldwin 	acpi_print_string(sdp->OemId, ACPI_OEM_ID_SIZE);
1765e1e9a4bfSMitsuru IWASAKI 	printf(", OEM Table ID=");
1766986dffafSJohn Baldwin 	acpi_print_string(sdp->OemTableId, ACPI_OEM_TABLE_ID_SIZE);
1767986dffafSJohn Baldwin 	printf(", OEM Revision=0x%x,\n", sdp->OemRevision);
1768e1e9a4bfSMitsuru IWASAKI 	printf("\tCreator ID=");
1769278f0de6SJung-uk Kim 	acpi_print_string(sdp->AslCompilerId, ACPI_NAMESEG_SIZE);
1770986dffafSJohn Baldwin 	printf(", Creator Revision=0x%x\n", sdp->AslCompilerRevision);
1771e1e9a4bfSMitsuru IWASAKI }
1772e1e9a4bfSMitsuru IWASAKI 
1773945137d9SNate Lawson static void
1774986dffafSJohn Baldwin acpi_print_rsdt(ACPI_TABLE_HEADER *rsdp)
1775e1e9a4bfSMitsuru IWASAKI {
1776986dffafSJohn Baldwin 	ACPI_TABLE_RSDT *rsdt;
1777986dffafSJohn Baldwin 	ACPI_TABLE_XSDT *xsdt;
1778e1e9a4bfSMitsuru IWASAKI 	int	i, entries;
1779e1e9a4bfSMitsuru IWASAKI 
1780986dffafSJohn Baldwin 	rsdt = (ACPI_TABLE_RSDT *)rsdp;
1781986dffafSJohn Baldwin 	xsdt = (ACPI_TABLE_XSDT *)rsdp;
1782773b6454SNate Lawson 	printf(BEGIN_COMMENT);
1783773b6454SNate Lawson 	acpi_print_sdt(rsdp);
1784986dffafSJohn Baldwin 	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
1785e1e9a4bfSMitsuru IWASAKI 	printf("\tEntries={ ");
1786e1e9a4bfSMitsuru IWASAKI 	for (i = 0; i < entries; i++) {
1787e1e9a4bfSMitsuru IWASAKI 		if (i > 0)
1788e1e9a4bfSMitsuru IWASAKI 			printf(", ");
1789fe1d0c2dSJung-uk Kim 		if (addr_size == 4)
17907d369c6eSJung-uk Kim 			printf("0x%08x", le32toh(rsdt->TableOffsetEntry[i]));
1791fe1d0c2dSJung-uk Kim 		else
17927d369c6eSJung-uk Kim 			printf("0x%016jx",
17937d369c6eSJung-uk Kim 			    (uintmax_t)le64toh(xsdt->TableOffsetEntry[i]));
1794e1e9a4bfSMitsuru IWASAKI 	}
1795e1e9a4bfSMitsuru IWASAKI 	printf(" }\n");
1796c62f1cccSMitsuru IWASAKI 	printf(END_COMMENT);
1797e1e9a4bfSMitsuru IWASAKI }
1798e1e9a4bfSMitsuru IWASAKI 
17998e6a8737SNate Lawson static const char *acpi_pm_profiles[] = {
18008e6a8737SNate Lawson 	"Unspecified", "Desktop", "Mobile", "Workstation",
18018e6a8737SNate Lawson 	"Enterprise Server", "SOHO Server", "Appliance PC"
18028e6a8737SNate Lawson };
18038e6a8737SNate Lawson 
1804945137d9SNate Lawson static void
1805986dffafSJohn Baldwin acpi_print_fadt(ACPI_TABLE_HEADER *sdp)
1806e1e9a4bfSMitsuru IWASAKI {
1807986dffafSJohn Baldwin 	ACPI_TABLE_FADT *fadt;
18088e6a8737SNate Lawson 	const char *pm;
1809e1e9a4bfSMitsuru IWASAKI 
1810986dffafSJohn Baldwin 	fadt = (ACPI_TABLE_FADT *)sdp;
1811c62f1cccSMitsuru IWASAKI 	printf(BEGIN_COMMENT);
18122177d4e6SNate Lawson 	acpi_print_sdt(sdp);
1813986dffafSJohn Baldwin 	printf(" \tFACS=0x%x, DSDT=0x%x\n", fadt->Facs,
1814986dffafSJohn Baldwin 	       fadt->Dsdt);
1815986dffafSJohn Baldwin 	printf("\tINT_MODEL=%s\n", fadt->Model ? "APIC" : "PIC");
1816986dffafSJohn Baldwin 	if (fadt->PreferredProfile >= sizeof(acpi_pm_profiles) / sizeof(char *))
18178e6a8737SNate Lawson 		pm = "Reserved";
18188e6a8737SNate Lawson 	else
1819986dffafSJohn Baldwin 		pm = acpi_pm_profiles[fadt->PreferredProfile];
1820986dffafSJohn Baldwin 	printf("\tPreferred_PM_Profile=%s (%d)\n", pm, fadt->PreferredProfile);
1821986dffafSJohn Baldwin 	printf("\tSCI_INT=%d\n", fadt->SciInterrupt);
1822986dffafSJohn Baldwin 	printf("\tSMI_CMD=0x%x, ", fadt->SmiCommand);
1823986dffafSJohn Baldwin 	printf("ACPI_ENABLE=0x%x, ", fadt->AcpiEnable);
1824986dffafSJohn Baldwin 	printf("ACPI_DISABLE=0x%x, ", fadt->AcpiDisable);
1825986dffafSJohn Baldwin 	printf("S4BIOS_REQ=0x%x\n", fadt->S4BiosRequest);
1826986dffafSJohn Baldwin 	printf("\tPSTATE_CNT=0x%x\n", fadt->PstateControl);
1827e1e9a4bfSMitsuru IWASAKI 	printf("\tPM1a_EVT_BLK=0x%x-0x%x\n",
1828986dffafSJohn Baldwin 	       fadt->Pm1aEventBlock,
1829986dffafSJohn Baldwin 	       fadt->Pm1aEventBlock + fadt->Pm1EventLength - 1);
1830986dffafSJohn Baldwin 	if (fadt->Pm1bEventBlock != 0)
1831e1e9a4bfSMitsuru IWASAKI 		printf("\tPM1b_EVT_BLK=0x%x-0x%x\n",
1832986dffafSJohn Baldwin 		       fadt->Pm1bEventBlock,
1833986dffafSJohn Baldwin 		       fadt->Pm1bEventBlock + fadt->Pm1EventLength - 1);
1834e1e9a4bfSMitsuru IWASAKI 	printf("\tPM1a_CNT_BLK=0x%x-0x%x\n",
1835986dffafSJohn Baldwin 	       fadt->Pm1aControlBlock,
1836986dffafSJohn Baldwin 	       fadt->Pm1aControlBlock + fadt->Pm1ControlLength - 1);
1837986dffafSJohn Baldwin 	if (fadt->Pm1bControlBlock != 0)
1838e1e9a4bfSMitsuru IWASAKI 		printf("\tPM1b_CNT_BLK=0x%x-0x%x\n",
1839986dffafSJohn Baldwin 		       fadt->Pm1bControlBlock,
1840986dffafSJohn Baldwin 		       fadt->Pm1bControlBlock + fadt->Pm1ControlLength - 1);
1841986dffafSJohn Baldwin 	if (fadt->Pm2ControlBlock != 0)
1842e1e9a4bfSMitsuru IWASAKI 		printf("\tPM2_CNT_BLK=0x%x-0x%x\n",
1843986dffafSJohn Baldwin 		       fadt->Pm2ControlBlock,
1844986dffafSJohn Baldwin 		       fadt->Pm2ControlBlock + fadt->Pm2ControlLength - 1);
1845c08c4e81SNate Lawson 	printf("\tPM_TMR_BLK=0x%x-0x%x\n",
1846986dffafSJohn Baldwin 	       fadt->PmTimerBlock,
1847986dffafSJohn Baldwin 	       fadt->PmTimerBlock + fadt->PmTimerLength - 1);
1848986dffafSJohn Baldwin 	if (fadt->Gpe0Block != 0)
18498e6a8737SNate Lawson 		printf("\tGPE0_BLK=0x%x-0x%x\n",
1850986dffafSJohn Baldwin 		       fadt->Gpe0Block,
1851986dffafSJohn Baldwin 		       fadt->Gpe0Block + fadt->Gpe0BlockLength - 1);
1852986dffafSJohn Baldwin 	if (fadt->Gpe1Block != 0)
18538e6a8737SNate Lawson 		printf("\tGPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n",
1854986dffafSJohn Baldwin 		       fadt->Gpe1Block,
1855986dffafSJohn Baldwin 		       fadt->Gpe1Block + fadt->Gpe1BlockLength - 1,
1856986dffafSJohn Baldwin 		       fadt->Gpe1Base);
1857986dffafSJohn Baldwin 	if (fadt->CstControl != 0)
1858986dffafSJohn Baldwin 		printf("\tCST_CNT=0x%x\n", fadt->CstControl);
185951c1824fSNate Lawson 	printf("\tP_LVL2_LAT=%d us, P_LVL3_LAT=%d us\n",
1860986dffafSJohn Baldwin 	       fadt->C2Latency, fadt->C3Latency);
1861e1e9a4bfSMitsuru IWASAKI 	printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n",
1862986dffafSJohn Baldwin 	       fadt->FlushSize, fadt->FlushStride);
1863e1e9a4bfSMitsuru IWASAKI 	printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n",
1864986dffafSJohn Baldwin 	       fadt->DutyOffset, fadt->DutyWidth);
1865e1e9a4bfSMitsuru IWASAKI 	printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n",
1866986dffafSJohn Baldwin 	       fadt->DayAlarm, fadt->MonthAlarm, fadt->Century);
1867e1e9a4bfSMitsuru IWASAKI 
1868ec650989SNeel Natu #define PRINTFLAG(var, flag)	printflag((var), ACPI_FADT_## flag, #flag)
1869e1e9a4bfSMitsuru IWASAKI 
18708e6a8737SNate Lawson 	printf("\tIAPC_BOOT_ARCH=");
1871986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, LEGACY_DEVICES);
1872986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, 8042);
1873986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, NO_VGA);
1874986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, NO_MSI);
1875986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, NO_ASPM);
1876f6469ce1SAndrew Turner 	PRINTFLAG(fadt->BootFlags, NO_CMOS_RTC);
1877ec650989SNeel Natu 	PRINTFLAG_END();
18788e6a8737SNate Lawson 
18798e6a8737SNate Lawson 	printf("\tFlags=");
1880986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, WBINVD);
1881986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, WBINVD_FLUSH);
1882986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, C1_SUPPORTED);
1883986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, C2_MP_SUPPORTED);
1884986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, POWER_BUTTON);
1885986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, SLEEP_BUTTON);
1886986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, FIXED_RTC);
1887986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, S4_RTC_WAKE);
1888986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, 32BIT_TIMER);
1889986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, DOCKING_SUPPORTED);
1890986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, RESET_REGISTER);
1891986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, SEALED_CASE);
1892986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, HEADLESS);
1893986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, SLEEP_TYPE);
1894986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, PCI_EXPRESS_WAKE);
1895986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, PLATFORM_CLOCK);
1896986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, S4_RTC_VALID);
1897986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, REMOTE_POWER_ON);
1898986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, APIC_CLUSTER);
1899986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, APIC_PHYSICAL);
1900f6469ce1SAndrew Turner 	PRINTFLAG(fadt->Flags, HW_REDUCED);
1901f6469ce1SAndrew Turner 	PRINTFLAG(fadt->Flags, LOW_POWER_S0);
1902ec650989SNeel Natu 	PRINTFLAG_END();
1903e1e9a4bfSMitsuru IWASAKI 
1904e1e9a4bfSMitsuru IWASAKI #undef PRINTFLAG
1905e1e9a4bfSMitsuru IWASAKI 
1906986dffafSJohn Baldwin 	if (fadt->Flags & ACPI_FADT_RESET_REGISTER) {
19078e6a8737SNate Lawson 		printf("\tRESET_REG=");
1908986dffafSJohn Baldwin 		acpi_print_gas(&fadt->ResetRegister);
1909986dffafSJohn Baldwin 		printf(", RESET_VALUE=%#x\n", fadt->ResetValue);
19108e6a8737SNate Lawson 	}
1911c2962974SNate Lawson 	if (acpi_get_fadt_revision(fadt) > 1) {
19127d369c6eSJung-uk Kim 		printf("\tX_FACS=0x%016jx, ", (uintmax_t)fadt->XFacs);
19137d369c6eSJung-uk Kim 		printf("X_DSDT=0x%016jx\n", (uintmax_t)fadt->XDsdt);
1914c08c4e81SNate Lawson 		printf("\tX_PM1a_EVT_BLK=");
1915986dffafSJohn Baldwin 		acpi_print_gas(&fadt->XPm1aEventBlock);
1916986dffafSJohn Baldwin 		if (fadt->XPm1bEventBlock.Address != 0) {
1917c08c4e81SNate Lawson 			printf("\n\tX_PM1b_EVT_BLK=");
1918986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XPm1bEventBlock);
1919c08c4e81SNate Lawson 		}
1920c08c4e81SNate Lawson 		printf("\n\tX_PM1a_CNT_BLK=");
1921986dffafSJohn Baldwin 		acpi_print_gas(&fadt->XPm1aControlBlock);
1922986dffafSJohn Baldwin 		if (fadt->XPm1bControlBlock.Address != 0) {
1923c08c4e81SNate Lawson 			printf("\n\tX_PM1b_CNT_BLK=");
1924986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XPm1bControlBlock);
1925c08c4e81SNate Lawson 		}
1926986dffafSJohn Baldwin 		if (fadt->XPm2ControlBlock.Address != 0) {
1927773b6454SNate Lawson 			printf("\n\tX_PM2_CNT_BLK=");
1928986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XPm2ControlBlock);
1929c08c4e81SNate Lawson 		}
1930773b6454SNate Lawson 		printf("\n\tX_PM_TMR_BLK=");
1931986dffafSJohn Baldwin 		acpi_print_gas(&fadt->XPmTimerBlock);
1932986dffafSJohn Baldwin 		if (fadt->XGpe0Block.Address != 0) {
1933773b6454SNate Lawson 			printf("\n\tX_GPE0_BLK=");
1934986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XGpe0Block);
1935c08c4e81SNate Lawson 		}
1936986dffafSJohn Baldwin 		if (fadt->XGpe1Block.Address != 0) {
1937773b6454SNate Lawson 			printf("\n\tX_GPE1_BLK=");
1938986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XGpe1Block);
1939c08c4e81SNate Lawson 		}
1940773b6454SNate Lawson 		printf("\n");
1941773b6454SNate Lawson 	}
19428e6a8737SNate Lawson 
19438e6a8737SNate Lawson 	printf(END_COMMENT);
19448e6a8737SNate Lawson }
19458e6a8737SNate Lawson 
19468e6a8737SNate Lawson static void
1947986dffafSJohn Baldwin acpi_print_facs(ACPI_TABLE_FACS *facs)
19488e6a8737SNate Lawson {
19498e6a8737SNate Lawson 	printf(BEGIN_COMMENT);
1950986dffafSJohn Baldwin 	printf("  FACS:\tLength=%u, ", facs->Length);
1951986dffafSJohn Baldwin 	printf("HwSig=0x%08x, ", facs->HardwareSignature);
1952986dffafSJohn Baldwin 	printf("Firm_Wake_Vec=0x%08x\n", facs->FirmwareWakingVector);
19538e6a8737SNate Lawson 
1954773b6454SNate Lawson 	printf("\tGlobal_Lock=");
1955986dffafSJohn Baldwin 	if (facs->GlobalLock != 0) {
1956986dffafSJohn Baldwin 		if (facs->GlobalLock & ACPI_GLOCK_PENDING)
19578e6a8737SNate Lawson 			printf("PENDING,");
1958986dffafSJohn Baldwin 		if (facs->GlobalLock & ACPI_GLOCK_OWNED)
19598e6a8737SNate Lawson 			printf("OWNED");
19608e6a8737SNate Lawson 	}
1961773b6454SNate Lawson 	printf("\n");
19628e6a8737SNate Lawson 
1963773b6454SNate Lawson 	printf("\tFlags=");
1964986dffafSJohn Baldwin 	if (facs->Flags & ACPI_FACS_S4_BIOS_PRESENT)
19658e6a8737SNate Lawson 		printf("S4BIOS");
1966773b6454SNate Lawson 	printf("\n");
19678e6a8737SNate Lawson 
19687d369c6eSJung-uk Kim 	if (facs->XFirmwareWakingVector != 0)
19697d369c6eSJung-uk Kim 		printf("\tX_Firm_Wake_Vec=%016jx\n",
19707d369c6eSJung-uk Kim 		    (uintmax_t)facs->XFirmwareWakingVector);
1971986dffafSJohn Baldwin 	printf("\tVersion=%u\n", facs->Version);
19728e6a8737SNate Lawson 
1973c62f1cccSMitsuru IWASAKI 	printf(END_COMMENT);
1974e1e9a4bfSMitsuru IWASAKI }
1975e1e9a4bfSMitsuru IWASAKI 
1976945137d9SNate Lawson static void
1977986dffafSJohn Baldwin acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp)
1978e1e9a4bfSMitsuru IWASAKI {
1979773b6454SNate Lawson 	printf(BEGIN_COMMENT);
1980773b6454SNate Lawson 	acpi_print_sdt(dsdp);
1981773b6454SNate Lawson 	printf(END_COMMENT);
1982e1e9a4bfSMitsuru IWASAKI }
1983e1e9a4bfSMitsuru IWASAKI 
1984e1e9a4bfSMitsuru IWASAKI int
1985e1e9a4bfSMitsuru IWASAKI acpi_checksum(void *p, size_t length)
1986e1e9a4bfSMitsuru IWASAKI {
1987986dffafSJohn Baldwin 	uint8_t *bp;
1988986dffafSJohn Baldwin 	uint8_t sum;
1989e1e9a4bfSMitsuru IWASAKI 
1990e1e9a4bfSMitsuru IWASAKI 	bp = p;
1991e1e9a4bfSMitsuru IWASAKI 	sum = 0;
1992e1e9a4bfSMitsuru IWASAKI 	while (length--)
1993e1e9a4bfSMitsuru IWASAKI 		sum += *bp++;
1994e1e9a4bfSMitsuru IWASAKI 
1995e1e9a4bfSMitsuru IWASAKI 	return (sum);
1996e1e9a4bfSMitsuru IWASAKI }
1997e1e9a4bfSMitsuru IWASAKI 
1998986dffafSJohn Baldwin static ACPI_TABLE_HEADER *
1999e1e9a4bfSMitsuru IWASAKI acpi_map_sdt(vm_offset_t pa)
2000e1e9a4bfSMitsuru IWASAKI {
2001986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *sp;
2002e1e9a4bfSMitsuru IWASAKI 
2003986dffafSJohn Baldwin 	sp = acpi_map_physical(pa, sizeof(ACPI_TABLE_HEADER));
2004986dffafSJohn Baldwin 	sp = acpi_map_physical(pa, sp->Length);
2005e1e9a4bfSMitsuru IWASAKI 	return (sp);
2006e1e9a4bfSMitsuru IWASAKI }
2007e1e9a4bfSMitsuru IWASAKI 
2008945137d9SNate Lawson static void
2009986dffafSJohn Baldwin acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp)
2010e1e9a4bfSMitsuru IWASAKI {
2011c62f1cccSMitsuru IWASAKI 	printf(BEGIN_COMMENT);
2012a74172abSNate Lawson 	printf("  RSD PTR: OEM=");
2013986dffafSJohn Baldwin 	acpi_print_string(rp->OemId, ACPI_OEM_ID_SIZE);
2014986dffafSJohn Baldwin 	printf(", ACPI_Rev=%s (%d)\n", rp->Revision < 2 ? "1.0x" : "2.0x",
2015986dffafSJohn Baldwin 	       rp->Revision);
2016986dffafSJohn Baldwin 	if (rp->Revision < 2) {
2017986dffafSJohn Baldwin 		printf("\tRSDT=0x%08x, cksum=%u\n", rp->RsdtPhysicalAddress,
2018986dffafSJohn Baldwin 		    rp->Checksum);
2019a74172abSNate Lawson 	} else {
20207d369c6eSJung-uk Kim 		printf("\tXSDT=0x%016jx, length=%u, cksum=%u\n",
20217d369c6eSJung-uk Kim 		    (uintmax_t)rp->XsdtPhysicalAddress, rp->Length,
2022986dffafSJohn Baldwin 		    rp->ExtendedChecksum);
2023a74172abSNate Lawson 	}
2024c62f1cccSMitsuru IWASAKI 	printf(END_COMMENT);
2025e1e9a4bfSMitsuru IWASAKI }
2026e1e9a4bfSMitsuru IWASAKI 
2027945137d9SNate Lawson static void
2028986dffafSJohn Baldwin acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp)
2029e1e9a4bfSMitsuru IWASAKI {
2030986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *sdp;
2031986dffafSJohn Baldwin 	ACPI_TABLE_RSDT *rsdt;
2032986dffafSJohn Baldwin 	ACPI_TABLE_XSDT *xsdt;
2033a74172abSNate Lawson 	vm_offset_t addr;
2034a74172abSNate Lawson 	int entries, i;
2035e1e9a4bfSMitsuru IWASAKI 
2036e1e9a4bfSMitsuru IWASAKI 	acpi_print_rsdt(rsdp);
2037986dffafSJohn Baldwin 	rsdt = (ACPI_TABLE_RSDT *)rsdp;
2038986dffafSJohn Baldwin 	xsdt = (ACPI_TABLE_XSDT *)rsdp;
2039986dffafSJohn Baldwin 	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
2040e1e9a4bfSMitsuru IWASAKI 	for (i = 0; i < entries; i++) {
2041fe1d0c2dSJung-uk Kim 		if (addr_size == 4)
2042986dffafSJohn Baldwin 			addr = le32toh(rsdt->TableOffsetEntry[i]);
2043fe1d0c2dSJung-uk Kim 		else
2044986dffafSJohn Baldwin 			addr = le64toh(xsdt->TableOffsetEntry[i]);
2045fe1d0c2dSJung-uk Kim 		if (addr == 0)
2046fe1d0c2dSJung-uk Kim 			continue;
2047986dffafSJohn Baldwin 		sdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
2048986dffafSJohn Baldwin 		if (acpi_checksum(sdp, sdp->Length)) {
20495cf6d493SNate Lawson 			warnx("RSDT entry %d (sig %.4s) is corrupt", i,
2050986dffafSJohn Baldwin 			    sdp->Signature);
20515cf6d493SNate Lawson 			continue;
20525cf6d493SNate Lawson 		}
2053ebc22d04SAlexander Motin 		if (!memcmp(sdp->Signature, ACPI_SIG_BERT, 4))
2054ebc22d04SAlexander Motin 			acpi_handle_bert(sdp);
2055ebc22d04SAlexander Motin 		else if (!memcmp(sdp->Signature, ACPI_SIG_EINJ, 4))
2056ebc22d04SAlexander Motin 			acpi_handle_einj(sdp);
2057ebc22d04SAlexander Motin 		else if (!memcmp(sdp->Signature, ACPI_SIG_ERST, 4))
2058ebc22d04SAlexander Motin 			acpi_handle_erst(sdp);
2059ebc22d04SAlexander Motin 		else if (!memcmp(sdp->Signature, ACPI_SIG_FADT, 4))
20602177d4e6SNate Lawson 			acpi_handle_fadt(sdp);
2061986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_MADT, 4))
2062986dffafSJohn Baldwin 			acpi_handle_madt(sdp);
2063ebc22d04SAlexander Motin 		else if (!memcmp(sdp->Signature, ACPI_SIG_HEST, 4))
2064ebc22d04SAlexander Motin 			acpi_handle_hest(sdp);
2065986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_HPET, 4))
206679d7565cSPeter Wemm 			acpi_handle_hpet(sdp);
2067986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_ECDT, 4))
206855d7ff9eSNate Lawson 			acpi_handle_ecdt(sdp);
2069986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_MCFG, 4))
2070a47e681bSScott Long 			acpi_handle_mcfg(sdp);
207133866658SJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_SLIT, 4))
207233866658SJohn Baldwin 			acpi_handle_slit(sdp);
2073986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_SRAT, 4))
2074a0333ad1SJohn Baldwin 			acpi_handle_srat(sdp);
2075c031c93bSTakanori Watanabe 		else if (!memcmp(sdp->Signature, ACPI_SIG_TCPA, 4))
2076c031c93bSTakanori Watanabe 			acpi_handle_tcpa(sdp);
2077ec650989SNeel Natu 		else if (!memcmp(sdp->Signature, ACPI_SIG_DMAR, 4))
2078ec650989SNeel Natu 			acpi_handle_dmar(sdp);
2079340c0022SEd Maste 		else if (!memcmp(sdp->Signature, ACPI_SIG_NFIT, 4))
2080340c0022SEd Maste 			acpi_handle_nfit(sdp);
2081ed26c389SScott Long 		else if (!memcmp(sdp->Signature, ACPI_SIG_WDDT, 4))
2082ed26c389SScott Long 			acpi_handle_wddt(sdp);
20835857fba5SBen Widawsky 		else if (!memcmp(sdp->Signature, ACPI_SIG_LPIT, 4))
20845857fba5SBen Widawsky 			acpi_handle_lpit(sdp);
2085877fc2e3STakanori Watanabe 		else if (!memcmp(sdp->Signature, ACPI_SIG_TPM2, 4))
2086877fc2e3STakanori Watanabe 			acpi_handle_tpm2(sdp);
2087773b6454SNate Lawson 		else {
2088773b6454SNate Lawson 			printf(BEGIN_COMMENT);
2089773b6454SNate Lawson 			acpi_print_sdt(sdp);
2090773b6454SNate Lawson 			printf(END_COMMENT);
2091773b6454SNate Lawson 		}
2092e1e9a4bfSMitsuru IWASAKI 	}
2093e1e9a4bfSMitsuru IWASAKI }
2094c62f1cccSMitsuru IWASAKI 
2095986dffafSJohn Baldwin ACPI_TABLE_HEADER *
2096476daaecSDag-Erling Smørgrav sdt_load_devmem(void)
2097945137d9SNate Lawson {
2098986dffafSJohn Baldwin 	ACPI_TABLE_RSDP *rp;
2099986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *rsdp;
2100945137d9SNate Lawson 
2101945137d9SNate Lawson 	rp = acpi_find_rsd_ptr();
2102945137d9SNate Lawson 	if (!rp)
2103945137d9SNate Lawson 		errx(1, "Can't find ACPI information");
2104945137d9SNate Lawson 
2105945137d9SNate Lawson 	if (tflag)
2106945137d9SNate Lawson 		acpi_print_rsd_ptr(rp);
2107986dffafSJohn Baldwin 	if (rp->Revision < 2) {
2108986dffafSJohn Baldwin 		rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->RsdtPhysicalAddress);
2109986dffafSJohn Baldwin 		if (memcmp(rsdp->Signature, "RSDT", 4) != 0 ||
2110986dffafSJohn Baldwin 		    acpi_checksum(rsdp, rsdp->Length) != 0)
2111945137d9SNate Lawson 			errx(1, "RSDT is corrupted");
2112a74172abSNate Lawson 		addr_size = sizeof(uint32_t);
2113a74172abSNate Lawson 	} else {
2114986dffafSJohn Baldwin 		rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->XsdtPhysicalAddress);
2115986dffafSJohn Baldwin 		if (memcmp(rsdp->Signature, "XSDT", 4) != 0 ||
2116986dffafSJohn Baldwin 		    acpi_checksum(rsdp, rsdp->Length) != 0)
2117a74172abSNate Lawson 			errx(1, "XSDT is corrupted");
2118a74172abSNate Lawson 		addr_size = sizeof(uint64_t);
2119a74172abSNate Lawson 	}
2120945137d9SNate Lawson 	return (rsdp);
2121945137d9SNate Lawson }
2122c62f1cccSMitsuru IWASAKI 
212362c7bde1SNate Lawson /* Write the DSDT to a file, concatenating any SSDTs (if present). */
2124bfa3f012SMarcel Moolenaar static int
2125986dffafSJohn Baldwin write_dsdt(int fd, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdt)
2126bfa3f012SMarcel Moolenaar {
2127986dffafSJohn Baldwin 	ACPI_TABLE_HEADER sdt;
2128986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *ssdt;
2129bfa3f012SMarcel Moolenaar 	uint8_t sum;
2130bfa3f012SMarcel Moolenaar 
213162c7bde1SNate Lawson 	/* Create a new checksum to account for the DSDT and any SSDTs. */
2132bfa3f012SMarcel Moolenaar 	sdt = *dsdt;
2133bfa3f012SMarcel Moolenaar 	if (rsdt != NULL) {
2134986dffafSJohn Baldwin 		sdt.Checksum = 0;
2135986dffafSJohn Baldwin 		sum = acpi_checksum(dsdt + 1, dsdt->Length -
2136986dffafSJohn Baldwin 		    sizeof(ACPI_TABLE_HEADER));
2137986dffafSJohn Baldwin 		ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, NULL);
2138f7675a56SNate Lawson 		while (ssdt != NULL) {
2139986dffafSJohn Baldwin 			sdt.Length += ssdt->Length - sizeof(ACPI_TABLE_HEADER);
2140986dffafSJohn Baldwin 			sum += acpi_checksum(ssdt + 1,
2141986dffafSJohn Baldwin 			    ssdt->Length - sizeof(ACPI_TABLE_HEADER));
2142986dffafSJohn Baldwin 			ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, ssdt);
2143bfa3f012SMarcel Moolenaar 		}
2144986dffafSJohn Baldwin 		sum += acpi_checksum(&sdt, sizeof(ACPI_TABLE_HEADER));
2145986dffafSJohn Baldwin 		sdt.Checksum -= sum;
2146bfa3f012SMarcel Moolenaar 	}
214762c7bde1SNate Lawson 
214862c7bde1SNate Lawson 	/* Write out the DSDT header and body. */
2149986dffafSJohn Baldwin 	write(fd, &sdt, sizeof(ACPI_TABLE_HEADER));
2150986dffafSJohn Baldwin 	write(fd, dsdt + 1, dsdt->Length - sizeof(ACPI_TABLE_HEADER));
215162c7bde1SNate Lawson 
2152b64e1b67SNate Lawson 	/* Write out any SSDTs (if present.) */
2153f7675a56SNate Lawson 	if (rsdt != NULL) {
2154bfa3f012SMarcel Moolenaar 		ssdt = sdt_from_rsdt(rsdt, "SSDT", NULL);
2155bfa3f012SMarcel Moolenaar 		while (ssdt != NULL) {
2156986dffafSJohn Baldwin 			write(fd, ssdt + 1, ssdt->Length -
2157986dffafSJohn Baldwin 			    sizeof(ACPI_TABLE_HEADER));
2158bfa3f012SMarcel Moolenaar 			ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt);
2159bfa3f012SMarcel Moolenaar 		}
2160bfa3f012SMarcel Moolenaar 	}
2161bfa3f012SMarcel Moolenaar 	return (0);
2162bfa3f012SMarcel Moolenaar }
2163bfa3f012SMarcel Moolenaar 
2164c62f1cccSMitsuru IWASAKI void
2165986dffafSJohn Baldwin dsdt_save_file(char *outfile, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
2166c62f1cccSMitsuru IWASAKI {
2167945137d9SNate Lawson 	int	fd;
2168945137d9SNate Lawson 	mode_t	mode;
2169945137d9SNate Lawson 
2170945137d9SNate Lawson 	assert(outfile != NULL);
2171945137d9SNate Lawson 	mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
2172945137d9SNate Lawson 	fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, mode);
2173945137d9SNate Lawson 	if (fd == -1) {
2174945137d9SNate Lawson 		perror("dsdt_save_file");
2175945137d9SNate Lawson 		return;
2176945137d9SNate Lawson 	}
2177bfa3f012SMarcel Moolenaar 	write_dsdt(fd, rsdt, dsdp);
2178945137d9SNate Lawson 	close(fd);
2179c62f1cccSMitsuru IWASAKI }
2180c62f1cccSMitsuru IWASAKI 
2181945137d9SNate Lawson void
2182986dffafSJohn Baldwin aml_disassemble(ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
2183c62f1cccSMitsuru IWASAKI {
21847e2cc014SDon Lewis 	char buf[PATH_MAX], tmpstr[PATH_MAX], wrkdir[PATH_MAX];
21857e2cc014SDon Lewis 	const char *iname = "/acpdump.din";
21867e2cc014SDon Lewis 	const char *oname = "/acpdump.dsl";
218799065116SJung-uk Kim 	const char *tmpdir;
2188945137d9SNate Lawson 	FILE *fp;
218999065116SJung-uk Kim 	size_t len;
21907e2cc014SDon Lewis 	int fd, status;
21917e2cc014SDon Lewis 	pid_t pid;
2192945137d9SNate Lawson 
219399065116SJung-uk Kim 	tmpdir = getenv("TMPDIR");
219499065116SJung-uk Kim 	if (tmpdir == NULL)
219599065116SJung-uk Kim 		tmpdir = _PATH_TMP;
21967e2cc014SDon Lewis 	if (realpath(tmpdir, buf) == NULL) {
2197d6a6e590SJung-uk Kim 		perror("realpath tmp dir");
219899065116SJung-uk Kim 		return;
219999065116SJung-uk Kim 	}
22007e2cc014SDon Lewis 	len = sizeof(wrkdir) - strlen(iname);
22017e2cc014SDon Lewis 	if ((size_t)snprintf(wrkdir, len, "%s/acpidump.XXXXXX", buf) > len-1 ) {
22027e2cc014SDon Lewis 		fprintf(stderr, "$TMPDIR too long\n");
22037e2cc014SDon Lewis 		return;
22047e2cc014SDon Lewis 	}
22057e2cc014SDon Lewis 	if  (mkdtemp(wrkdir) == NULL) {
22067e2cc014SDon Lewis 		perror("mkdtemp tmp working dir");
22077e2cc014SDon Lewis 		return;
22087e2cc014SDon Lewis 	}
220930bebccaSMaxim Konovalov 	len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, iname);
221030bebccaSMaxim Konovalov 	assert(len <= sizeof(tmpstr) - 1);
22117e2cc014SDon Lewis 	fd = open(tmpstr, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
2212945137d9SNate Lawson 	if (fd < 0) {
2213945137d9SNate Lawson 		perror("iasl tmp file");
2214945137d9SNate Lawson 		return;
2215c62f1cccSMitsuru IWASAKI 	}
2216bfa3f012SMarcel Moolenaar 	write_dsdt(fd, rsdt, dsdp);
2217945137d9SNate Lawson 	close(fd);
2218945137d9SNate Lawson 
2219945137d9SNate Lawson 	/* Run iasl -d on the temp file */
22207e2cc014SDon Lewis 	if ((pid = fork()) == 0) {
2221945137d9SNate Lawson 		close(STDOUT_FILENO);
2222945137d9SNate Lawson 		if (vflag == 0)
2223945137d9SNate Lawson 			close(STDERR_FILENO);
222499065116SJung-uk Kim 		execl("/usr/sbin/iasl", "iasl", "-d", tmpstr, NULL);
2225945137d9SNate Lawson 		err(1, "exec");
2226c62f1cccSMitsuru IWASAKI 	}
22277e2cc014SDon Lewis 	if (pid > 0)
22287e2cc014SDon Lewis 		wait(&status);
22297e2cc014SDon Lewis 	if (unlink(tmpstr) < 0) {
22307e2cc014SDon Lewis 		perror("unlink");
22317e2cc014SDon Lewis 		goto out;
22327e2cc014SDon Lewis 	}
22337e2cc014SDon Lewis 	if (pid < 0) {
22347e2cc014SDon Lewis 		perror("fork");
22357e2cc014SDon Lewis 		goto out;
22367e2cc014SDon Lewis 	}
22377e2cc014SDon Lewis 	if (status != 0) {
22387e2cc014SDon Lewis 		fprintf(stderr, "iast exit status = %d\n", status);
22397e2cc014SDon Lewis 	}
2240945137d9SNate Lawson 
2241945137d9SNate Lawson 	/* Dump iasl's output to stdout */
224230bebccaSMaxim Konovalov 	len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, oname);
224330bebccaSMaxim Konovalov 	assert(len <= sizeof(tmpstr) - 1);
224499065116SJung-uk Kim 	fp = fopen(tmpstr, "r");
22457e2cc014SDon Lewis 	if (unlink(tmpstr) < 0) {
22467e2cc014SDon Lewis 		perror("unlink");
22477e2cc014SDon Lewis 		goto out;
22487e2cc014SDon Lewis 	}
2249945137d9SNate Lawson 	if (fp == NULL) {
2250945137d9SNate Lawson 		perror("iasl tmp file (read)");
22517e2cc014SDon Lewis 		goto out;
2252945137d9SNate Lawson 	}
2253945137d9SNate Lawson 	while ((len = fread(buf, 1, sizeof(buf), fp)) > 0)
2254945137d9SNate Lawson 		fwrite(buf, 1, len, stdout);
2255945137d9SNate Lawson 	fclose(fp);
22567e2cc014SDon Lewis 
22577e2cc014SDon Lewis     out:
22587e2cc014SDon Lewis 	if (rmdir(wrkdir) < 0)
22597e2cc014SDon Lewis 		perror("rmdir");
2260c62f1cccSMitsuru IWASAKI }
2261c62f1cccSMitsuru IWASAKI 
2262945137d9SNate Lawson void
2263986dffafSJohn Baldwin sdt_print_all(ACPI_TABLE_HEADER *rsdp)
2264c62f1cccSMitsuru IWASAKI {
2265945137d9SNate Lawson 	acpi_handle_rsdt(rsdp);
2266c62f1cccSMitsuru IWASAKI }
2267c62f1cccSMitsuru IWASAKI 
2268bfa3f012SMarcel Moolenaar /* Fetch a table matching the given signature via the RSDT. */
2269986dffafSJohn Baldwin ACPI_TABLE_HEADER *
2270986dffafSJohn Baldwin sdt_from_rsdt(ACPI_TABLE_HEADER *rsdp, const char *sig, ACPI_TABLE_HEADER *last)
2271c62f1cccSMitsuru IWASAKI {
2272986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *sdt;
2273986dffafSJohn Baldwin 	ACPI_TABLE_RSDT *rsdt;
2274986dffafSJohn Baldwin 	ACPI_TABLE_XSDT *xsdt;
2275a74172abSNate Lawson 	vm_offset_t addr;
2276a74172abSNate Lawson 	int entries, i;
2277945137d9SNate Lawson 
2278986dffafSJohn Baldwin 	rsdt = (ACPI_TABLE_RSDT *)rsdp;
2279986dffafSJohn Baldwin 	xsdt = (ACPI_TABLE_XSDT *)rsdp;
2280986dffafSJohn Baldwin 	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
2281945137d9SNate Lawson 	for (i = 0; i < entries; i++) {
2282fe1d0c2dSJung-uk Kim 		if (addr_size == 4)
2283986dffafSJohn Baldwin 			addr = le32toh(rsdt->TableOffsetEntry[i]);
2284fe1d0c2dSJung-uk Kim 		else
2285986dffafSJohn Baldwin 			addr = le64toh(xsdt->TableOffsetEntry[i]);
2286fe1d0c2dSJung-uk Kim 		if (addr == 0)
2287fe1d0c2dSJung-uk Kim 			continue;
2288986dffafSJohn Baldwin 		sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
2289bfa3f012SMarcel Moolenaar 		if (last != NULL) {
2290bfa3f012SMarcel Moolenaar 			if (sdt == last)
2291bfa3f012SMarcel Moolenaar 				last = NULL;
2292bfa3f012SMarcel Moolenaar 			continue;
2293bfa3f012SMarcel Moolenaar 		}
2294986dffafSJohn Baldwin 		if (memcmp(sdt->Signature, sig, strlen(sig)))
2295a74172abSNate Lawson 			continue;
2296986dffafSJohn Baldwin 		if (acpi_checksum(sdt, sdt->Length))
2297945137d9SNate Lawson 			errx(1, "RSDT entry %d is corrupt", i);
2298945137d9SNate Lawson 		return (sdt);
2299c62f1cccSMitsuru IWASAKI 	}
2300c62f1cccSMitsuru IWASAKI 
2301945137d9SNate Lawson 	return (NULL);
2302c62f1cccSMitsuru IWASAKI }
2303c62f1cccSMitsuru IWASAKI 
2304986dffafSJohn Baldwin ACPI_TABLE_HEADER *
2305986dffafSJohn Baldwin dsdt_from_fadt(ACPI_TABLE_FADT *fadt)
2306c62f1cccSMitsuru IWASAKI {
2307986dffafSJohn Baldwin 	ACPI_TABLE_HEADER	*sdt;
2308c62f1cccSMitsuru IWASAKI 
2309986dffafSJohn Baldwin 	/* Use the DSDT address if it is version 1, otherwise use XDSDT. */
2310c2962974SNate Lawson 	if (acpi_get_fadt_revision(fadt) == 1)
2311986dffafSJohn Baldwin 		sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt);
23122e71eb12SNate Lawson 	else
2313986dffafSJohn Baldwin 		sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt);
2314986dffafSJohn Baldwin 	if (acpi_checksum(sdt, sdt->Length))
2315945137d9SNate Lawson 		errx(1, "DSDT is corrupt\n");
2316945137d9SNate Lawson 	return (sdt);
2317c62f1cccSMitsuru IWASAKI }
2318