xref: /freebsd/usr.sbin/acpi/acpidump/acpi.c (revision 35e39fd95fda64699b638192f3bab955d0f1cf0c)
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 
222773b6454SNate Lawson 		/*
223c83f0f99SNate Lawson 		 * A few systems (e.g., IBM T23) have an RSDP that claims
224c83f0f99SNate Lawson 		 * revision 2 but the 64 bit addresses are invalid.  If
225c83f0f99SNate Lawson 		 * revision 2 and the 32 bit address is non-zero but the
226c83f0f99SNate Lawson 		 * 32 and 64 bit versions don't match, prefer the 32 bit
227c83f0f99SNate Lawson 		 * version for all subsequent tables.
228773b6454SNate Lawson 		 */
229986dffafSJohn Baldwin 		if (fadt->Facs != 0 &&
230986dffafSJohn Baldwin 		    (fadt->XFacs & 0xffffffff) != fadt->Facs)
231c83f0f99SNate Lawson 			fadt_revision = 1;
232c2962974SNate Lawson 	} else
233c83f0f99SNate Lawson 		fadt_revision = 1;
234c2962974SNate Lawson 	return (fadt_revision);
235c83f0f99SNate Lawson }
236c2962974SNate Lawson 
237c2962974SNate Lawson static void
238986dffafSJohn Baldwin acpi_handle_fadt(ACPI_TABLE_HEADER *sdp)
239c2962974SNate Lawson {
240986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *dsdp;
241986dffafSJohn Baldwin 	ACPI_TABLE_FACS	*facs;
242986dffafSJohn Baldwin 	ACPI_TABLE_FADT *fadt;
243bc711181SAndrew Turner 	vm_offset_t	addr;
244c2962974SNate Lawson 	int		fadt_revision;
245c2962974SNate Lawson 
246986dffafSJohn Baldwin 	fadt = (ACPI_TABLE_FADT *)sdp;
2472177d4e6SNate Lawson 	acpi_print_fadt(sdp);
248c83f0f99SNate Lawson 
249c2962974SNate Lawson 	fadt_revision = acpi_get_fadt_revision(fadt);
250c83f0f99SNate Lawson 	if (fadt_revision == 1)
251bc711181SAndrew Turner 		addr = fadt->Facs;
252773b6454SNate Lawson 	else
253bc711181SAndrew Turner 		addr = fadt->XFacs;
254bc711181SAndrew Turner 	if (addr != 0) {
255bc711181SAndrew Turner 		facs = (ACPI_TABLE_FACS *)acpi_map_sdt(addr);
256bc711181SAndrew Turner 
257bc711181SAndrew Turner 		if (memcmp(facs->Signature, ACPI_SIG_FACS, 4) != 0 ||
258bc711181SAndrew Turner 		    facs->Length < 64)
2598e6a8737SNate Lawson 			errx(1, "FACS is corrupt");
2608e6a8737SNate Lawson 		acpi_print_facs(facs);
261bc711181SAndrew Turner 	}
2628e6a8737SNate Lawson 
263c83f0f99SNate Lawson 	if (fadt_revision == 1)
264986dffafSJohn Baldwin 		dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt);
265773b6454SNate Lawson 	else
266986dffafSJohn Baldwin 		dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt);
267986dffafSJohn Baldwin 	if (acpi_checksum(dsdp, dsdp->Length))
268945137d9SNate Lawson 		errx(1, "DSDT is corrupt");
269945137d9SNate Lawson 	acpi_print_dsdt(dsdp);
270c62f1cccSMitsuru IWASAKI }
271c62f1cccSMitsuru IWASAKI 
272c62f1cccSMitsuru IWASAKI static void
273986dffafSJohn Baldwin acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
274986dffafSJohn Baldwin     void (*action)(ACPI_SUBTABLE_HEADER *))
275986dffafSJohn Baldwin {
276986dffafSJohn Baldwin 	ACPI_SUBTABLE_HEADER *subtable;
277986dffafSJohn Baldwin 	char *end;
278986dffafSJohn Baldwin 
279986dffafSJohn Baldwin 	subtable = first;
280986dffafSJohn Baldwin 	end = (char *)table + table->Length;
281986dffafSJohn Baldwin 	while ((char *)subtable < end) {
282986dffafSJohn Baldwin 		printf("\n");
283f5d0a8f7SEd Maste 		if (subtable->Length < sizeof(ACPI_SUBTABLE_HEADER)) {
284f5d0a8f7SEd Maste 			warnx("invalid subtable length %u", subtable->Length);
285f5d0a8f7SEd Maste 			return;
286f5d0a8f7SEd Maste 		}
287986dffafSJohn Baldwin 		action(subtable);
288986dffafSJohn Baldwin 		subtable = (ACPI_SUBTABLE_HEADER *)((char *)subtable +
289986dffafSJohn Baldwin 		    subtable->Length);
290986dffafSJohn Baldwin 	}
291986dffafSJohn Baldwin }
292986dffafSJohn Baldwin 
293986dffafSJohn Baldwin static void
294340c0022SEd Maste acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first,
295340c0022SEd Maste     void (*action)(ACPI_NFIT_HEADER *))
296340c0022SEd Maste {
297340c0022SEd Maste 	ACPI_NFIT_HEADER *subtable;
298340c0022SEd Maste 	char *end;
299340c0022SEd Maste 
300340c0022SEd Maste 	subtable = first;
301340c0022SEd Maste 	end = (char *)table + table->Length;
302340c0022SEd Maste 	while ((char *)subtable < end) {
303340c0022SEd Maste 		printf("\n");
304340c0022SEd Maste 		if (subtable->Length < sizeof(ACPI_NFIT_HEADER)) {
305340c0022SEd Maste 			warnx("invalid subtable length %u", subtable->Length);
306340c0022SEd Maste 			return;
307340c0022SEd Maste 		}
308340c0022SEd Maste 		action(subtable);
309340c0022SEd Maste 		subtable = (ACPI_NFIT_HEADER *)((char *)subtable +
310340c0022SEd Maste 		    subtable->Length);
311340c0022SEd Maste 	}
312340c0022SEd Maste }
313340c0022SEd Maste 
314340c0022SEd Maste static void
3150a473124SJohn Baldwin acpi_print_cpu(u_char cpu_id)
3160a473124SJohn Baldwin {
3170a473124SJohn Baldwin 
3180a473124SJohn Baldwin 	printf("\tACPI CPU=");
3190a473124SJohn Baldwin 	if (cpu_id == 0xff)
3200a473124SJohn Baldwin 		printf("ALL\n");
3210a473124SJohn Baldwin 	else
3220a473124SJohn Baldwin 		printf("%d\n", (u_int)cpu_id);
3230a473124SJohn Baldwin }
3240a473124SJohn Baldwin 
3250a473124SJohn Baldwin static void
326986dffafSJohn Baldwin acpi_print_cpu_uid(uint32_t uid, char *uid_string)
3270a473124SJohn Baldwin {
328986dffafSJohn Baldwin 
329986dffafSJohn Baldwin 	printf("\tUID=%d", uid);
330986dffafSJohn Baldwin 	if (uid_string != NULL)
331986dffafSJohn Baldwin 		printf(" (%s)", uid_string);
332986dffafSJohn Baldwin 	printf("\n");
333986dffafSJohn Baldwin }
334986dffafSJohn Baldwin 
335986dffafSJohn Baldwin static void
336986dffafSJohn Baldwin acpi_print_local_apic(uint32_t apic_id, uint32_t flags)
337986dffafSJohn Baldwin {
338986dffafSJohn Baldwin 
3390a473124SJohn Baldwin 	printf("\tFlags={");
340986dffafSJohn Baldwin 	if (flags & ACPI_MADT_ENABLED)
3410a473124SJohn Baldwin 		printf("ENABLED");
3420a473124SJohn Baldwin 	else
3430a473124SJohn Baldwin 		printf("DISABLED");
3440a473124SJohn Baldwin 	printf("}\n");
345986dffafSJohn Baldwin 	printf("\tAPIC ID=%d\n", apic_id);
3460a473124SJohn Baldwin }
3470a473124SJohn Baldwin 
3480a473124SJohn Baldwin static void
349986dffafSJohn Baldwin acpi_print_io_apic(uint32_t apic_id, uint32_t int_base, uint64_t apic_addr)
3500a473124SJohn Baldwin {
351986dffafSJohn Baldwin 
352986dffafSJohn Baldwin 	printf("\tAPIC ID=%d\n", apic_id);
3530a473124SJohn Baldwin 	printf("\tINT BASE=%d\n", int_base);
354986dffafSJohn Baldwin 	printf("\tADDR=0x%016jx\n", (uintmax_t)apic_addr);
3550a473124SJohn Baldwin }
3560a473124SJohn Baldwin 
3570a473124SJohn Baldwin static void
358986dffafSJohn Baldwin acpi_print_mps_flags(uint16_t flags)
3590a473124SJohn Baldwin {
3600a473124SJohn Baldwin 
3610a473124SJohn Baldwin 	printf("\tFlags={Polarity=");
362986dffafSJohn Baldwin 	switch (flags & ACPI_MADT_POLARITY_MASK) {
363986dffafSJohn Baldwin 	case ACPI_MADT_POLARITY_CONFORMS:
3640a473124SJohn Baldwin 		printf("conforming");
3650a473124SJohn Baldwin 		break;
366986dffafSJohn Baldwin 	case ACPI_MADT_POLARITY_ACTIVE_HIGH:
3670a473124SJohn Baldwin 		printf("active-hi");
3680a473124SJohn Baldwin 		break;
369986dffafSJohn Baldwin 	case ACPI_MADT_POLARITY_ACTIVE_LOW:
3700a473124SJohn Baldwin 		printf("active-lo");
3710a473124SJohn Baldwin 		break;
3720a473124SJohn Baldwin 	default:
373986dffafSJohn Baldwin 		printf("0x%x", flags & ACPI_MADT_POLARITY_MASK);
3740a473124SJohn Baldwin 		break;
3750a473124SJohn Baldwin 	}
3760a473124SJohn Baldwin 	printf(", Trigger=");
377986dffafSJohn Baldwin 	switch (flags & ACPI_MADT_TRIGGER_MASK) {
378986dffafSJohn Baldwin 	case ACPI_MADT_TRIGGER_CONFORMS:
3790a473124SJohn Baldwin 		printf("conforming");
3800a473124SJohn Baldwin 		break;
381986dffafSJohn Baldwin 	case ACPI_MADT_TRIGGER_EDGE:
3820a473124SJohn Baldwin 		printf("edge");
3830a473124SJohn Baldwin 		break;
384986dffafSJohn Baldwin 	case ACPI_MADT_TRIGGER_LEVEL:
3850a473124SJohn Baldwin 		printf("level");
3860a473124SJohn Baldwin 		break;
3870a473124SJohn Baldwin 	default:
388986dffafSJohn Baldwin 		printf("0x%x", (flags & ACPI_MADT_TRIGGER_MASK) >> 2);
3890a473124SJohn Baldwin 	}
3900a473124SJohn Baldwin 	printf("}\n");
3910a473124SJohn Baldwin }
3920a473124SJohn Baldwin 
3930a473124SJohn Baldwin static void
3942b2b1f42SAndrew Turner acpi_print_gicc_flags(uint32_t flags)
3952b2b1f42SAndrew Turner {
3962b2b1f42SAndrew Turner 
3972b2b1f42SAndrew Turner 	printf("\tFlags={Performance intr=");
3982b2b1f42SAndrew Turner 	if (flags & ACPI_MADT_PERFORMANCE_IRQ_MODE)
3992b2b1f42SAndrew Turner 		printf("edge");
4002b2b1f42SAndrew Turner 	else
4012b2b1f42SAndrew Turner 		printf("level");
4022b2b1f42SAndrew Turner 	printf(", VGIC intr=");
4032b2b1f42SAndrew Turner 	if (flags & ACPI_MADT_VGIC_IRQ_MODE)
4042b2b1f42SAndrew Turner 		printf("edge");
4052b2b1f42SAndrew Turner 	else
4062b2b1f42SAndrew Turner 		printf("level");
4072b2b1f42SAndrew Turner 	printf("}\n");
4082b2b1f42SAndrew Turner }
4092b2b1f42SAndrew Turner 
4102b2b1f42SAndrew Turner static void
411986dffafSJohn Baldwin acpi_print_intr(uint32_t intr, uint16_t mps_flags)
4120a473124SJohn Baldwin {
4130a473124SJohn Baldwin 
414986dffafSJohn Baldwin 	printf("\tINTR=%d\n", intr);
415986dffafSJohn Baldwin 	acpi_print_mps_flags(mps_flags);
416986dffafSJohn Baldwin }
417986dffafSJohn Baldwin 
418986dffafSJohn Baldwin static void
419986dffafSJohn Baldwin acpi_print_local_nmi(u_int lint, uint16_t mps_flags)
420986dffafSJohn Baldwin {
421986dffafSJohn Baldwin 
422986dffafSJohn Baldwin 	printf("\tLINT Pin=%d\n", lint);
4230a473124SJohn Baldwin 	acpi_print_mps_flags(mps_flags);
4240a473124SJohn Baldwin }
4250a473124SJohn Baldwin 
42627941afaSEd Maste static const char *apic_types[] = {
42727941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_APIC] = "Local APIC",
42827941afaSEd Maste     [ACPI_MADT_TYPE_IO_APIC] = "IO APIC",
42927941afaSEd Maste     [ACPI_MADT_TYPE_INTERRUPT_OVERRIDE] = "INT Override",
43027941afaSEd Maste     [ACPI_MADT_TYPE_NMI_SOURCE] = "NMI",
43127941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_APIC_NMI] = "Local APIC NMI",
43227941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE] = "Local APIC Override",
43327941afaSEd Maste     [ACPI_MADT_TYPE_IO_SAPIC] = "IO SAPIC",
43427941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_SAPIC] = "Local SAPIC",
43527941afaSEd Maste     [ACPI_MADT_TYPE_INTERRUPT_SOURCE] = "Platform Interrupt",
43627941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_X2APIC] = "Local X2APIC",
43727941afaSEd Maste     [ACPI_MADT_TYPE_LOCAL_X2APIC_NMI] = "Local X2APIC NMI",
43827941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_INTERRUPT] = "GIC CPU Interface Structure",
43927941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR] = "GIC Distributor Structure",
44027941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_MSI_FRAME] = "GICv2m MSI Frame",
44127941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR] = "GIC Redistributor Structure",
44227941afaSEd Maste     [ACPI_MADT_TYPE_GENERIC_TRANSLATOR] = "GIC ITS Structure"
44327941afaSEd Maste };
44427941afaSEd Maste 
445bf70beceSEd Schouten static const char *platform_int_types[] = { "0 (unknown)", "PMI", "INIT",
4460a473124SJohn Baldwin 					    "Corrected Platform Error" };
4470a473124SJohn Baldwin 
4480a473124SJohn Baldwin static void
449986dffafSJohn Baldwin acpi_print_madt(ACPI_SUBTABLE_HEADER *mp)
4500a473124SJohn Baldwin {
451986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_APIC *lapic;
452986dffafSJohn Baldwin 	ACPI_MADT_IO_APIC *ioapic;
453986dffafSJohn Baldwin 	ACPI_MADT_INTERRUPT_OVERRIDE *over;
454986dffafSJohn Baldwin 	ACPI_MADT_NMI_SOURCE *nmi;
455986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_APIC_NMI *lapic_nmi;
456986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic_over;
457986dffafSJohn Baldwin 	ACPI_MADT_IO_SAPIC *iosapic;
458986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_SAPIC *lsapic;
459986dffafSJohn Baldwin 	ACPI_MADT_INTERRUPT_SOURCE *isrc;
460986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_X2APIC *x2apic;
461986dffafSJohn Baldwin 	ACPI_MADT_LOCAL_X2APIC_NMI *x2apic_nmi;
4622b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_INTERRUPT *gicc;
4632b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_DISTRIBUTOR *gicd;
4642b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_REDISTRIBUTOR *gicr;
4652b2b1f42SAndrew Turner 	ACPI_MADT_GENERIC_TRANSLATOR *gict;
4660a473124SJohn Baldwin 
467c86932b6SMarcelo Araujo 	if (mp->Type < nitems(apic_types))
468986dffafSJohn Baldwin 		printf("\tType=%s\n", apic_types[mp->Type]);
469a0333ad1SJohn Baldwin 	else
470986dffafSJohn Baldwin 		printf("\tType=%d (unknown)\n", mp->Type);
471986dffafSJohn Baldwin 	switch (mp->Type) {
472986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_APIC:
473986dffafSJohn Baldwin 		lapic = (ACPI_MADT_LOCAL_APIC *)mp;
474986dffafSJohn Baldwin 		acpi_print_cpu(lapic->ProcessorId);
475986dffafSJohn Baldwin 		acpi_print_local_apic(lapic->Id, lapic->LapicFlags);
4760a473124SJohn Baldwin 		break;
477986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_IO_APIC:
478986dffafSJohn Baldwin 		ioapic = (ACPI_MADT_IO_APIC *)mp;
479986dffafSJohn Baldwin 		acpi_print_io_apic(ioapic->Id, ioapic->GlobalIrqBase,
480986dffafSJohn Baldwin 		    ioapic->Address);
4810a473124SJohn Baldwin 		break;
482986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
483986dffafSJohn Baldwin 		over = (ACPI_MADT_INTERRUPT_OVERRIDE *)mp;
484986dffafSJohn Baldwin 		printf("\tBUS=%d\n", (u_int)over->Bus);
485986dffafSJohn Baldwin 		printf("\tIRQ=%d\n", (u_int)over->SourceIrq);
486986dffafSJohn Baldwin 		acpi_print_intr(over->GlobalIrq, over->IntiFlags);
4870a473124SJohn Baldwin 		break;
488986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_NMI_SOURCE:
489986dffafSJohn Baldwin 		nmi = (ACPI_MADT_NMI_SOURCE *)mp;
490986dffafSJohn Baldwin 		acpi_print_intr(nmi->GlobalIrq, nmi->IntiFlags);
4910a473124SJohn Baldwin 		break;
492986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
493986dffafSJohn Baldwin 		lapic_nmi = (ACPI_MADT_LOCAL_APIC_NMI *)mp;
494986dffafSJohn Baldwin 		acpi_print_cpu(lapic_nmi->ProcessorId);
495986dffafSJohn Baldwin 		acpi_print_local_nmi(lapic_nmi->Lint, lapic_nmi->IntiFlags);
4960a473124SJohn Baldwin 		break;
497986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
498986dffafSJohn Baldwin 		lapic_over = (ACPI_MADT_LOCAL_APIC_OVERRIDE *)mp;
499945137d9SNate Lawson 		printf("\tLocal APIC ADDR=0x%016jx\n",
500986dffafSJohn Baldwin 		    (uintmax_t)lapic_over->Address);
5010a473124SJohn Baldwin 		break;
502986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_IO_SAPIC:
503986dffafSJohn Baldwin 		iosapic = (ACPI_MADT_IO_SAPIC *)mp;
504986dffafSJohn Baldwin 		acpi_print_io_apic(iosapic->Id, iosapic->GlobalIrqBase,
505986dffafSJohn Baldwin 		    iosapic->Address);
5060a473124SJohn Baldwin 		break;
507986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_SAPIC:
508986dffafSJohn Baldwin 		lsapic = (ACPI_MADT_LOCAL_SAPIC *)mp;
509986dffafSJohn Baldwin 		acpi_print_cpu(lsapic->ProcessorId);
510986dffafSJohn Baldwin 		acpi_print_local_apic(lsapic->Id, lsapic->LapicFlags);
511986dffafSJohn Baldwin 		printf("\tAPIC EID=%d\n", (u_int)lsapic->Eid);
512986dffafSJohn Baldwin 		if (mp->Length > __offsetof(ACPI_MADT_LOCAL_SAPIC, Uid))
513986dffafSJohn Baldwin 			acpi_print_cpu_uid(lsapic->Uid, lsapic->UidString);
5140a473124SJohn Baldwin 		break;
515986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
516986dffafSJohn Baldwin 		isrc = (ACPI_MADT_INTERRUPT_SOURCE *)mp;
517c86932b6SMarcelo Araujo 		if (isrc->Type < nitems(platform_int_types))
518986dffafSJohn Baldwin 			printf("\tType=%s\n", platform_int_types[isrc->Type]);
519986dffafSJohn Baldwin 		else
520986dffafSJohn Baldwin 			printf("\tType=%d (unknown)\n", isrc->Type);
521986dffafSJohn Baldwin 		printf("\tAPIC ID=%d\n", (u_int)isrc->Id);
522986dffafSJohn Baldwin 		printf("\tAPIC EID=%d\n", (u_int)isrc->Eid);
523986dffafSJohn Baldwin 		printf("\tSAPIC Vector=%d\n", (u_int)isrc->IoSapicVector);
524986dffafSJohn Baldwin 		acpi_print_intr(isrc->GlobalIrq, isrc->IntiFlags);
525986dffafSJohn Baldwin 		break;
526986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_X2APIC:
527986dffafSJohn Baldwin 		x2apic = (ACPI_MADT_LOCAL_X2APIC *)mp;
528986dffafSJohn Baldwin 		acpi_print_cpu_uid(x2apic->Uid, NULL);
529986dffafSJohn Baldwin 		acpi_print_local_apic(x2apic->LocalApicId, x2apic->LapicFlags);
530986dffafSJohn Baldwin 		break;
531986dffafSJohn Baldwin 	case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
532986dffafSJohn Baldwin 		x2apic_nmi = (ACPI_MADT_LOCAL_X2APIC_NMI *)mp;
533986dffafSJohn Baldwin 		acpi_print_cpu_uid(x2apic_nmi->Uid, NULL);
534986dffafSJohn Baldwin 		acpi_print_local_nmi(x2apic_nmi->Lint, x2apic_nmi->IntiFlags);
5350a473124SJohn Baldwin 		break;
5362b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
5372b2b1f42SAndrew Turner 		gicc = (ACPI_MADT_GENERIC_INTERRUPT *)mp;
5382b2b1f42SAndrew Turner 		acpi_print_cpu_uid(gicc->Uid, NULL);
5392b2b1f42SAndrew Turner 		printf("\tCPU INTERFACE=%x\n", gicc->CpuInterfaceNumber);
5402b2b1f42SAndrew Turner 		acpi_print_gicc_flags(gicc->Flags);
5412b2b1f42SAndrew Turner 		printf("\tParking Protocol Version=%x\n", gicc->ParkingVersion);
5422b2b1f42SAndrew Turner 		printf("\tPERF INTR=%d\n", gicc->PerformanceInterrupt);
5432b2b1f42SAndrew Turner 		printf("\tParked ADDR=%016jx\n",
5442b2b1f42SAndrew Turner 		    (uintmax_t)gicc->ParkedAddress);
5452b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicc->BaseAddress);
5462b2b1f42SAndrew Turner 		printf("\tGICV=%016jx\n", (uintmax_t)gicc->GicvBaseAddress);
5472b2b1f42SAndrew Turner 		printf("\tGICH=%016jx\n", (uintmax_t)gicc->GichBaseAddress);
5482b2b1f42SAndrew Turner 		printf("\tVGIC INTR=%d\n", gicc->VgicInterrupt);
5492b2b1f42SAndrew Turner 		printf("\tGICR ADDR=%016jx\n",
5502b2b1f42SAndrew Turner 		    (uintmax_t)gicc->GicrBaseAddress);
5512b2b1f42SAndrew Turner 		printf("\tMPIDR=%jx\n", (uintmax_t)gicc->ArmMpidr);
5522b2b1f42SAndrew Turner 		printf("\tEfficency Class=%d\n", (u_int)gicc->EfficiencyClass);
5532b2b1f42SAndrew Turner 		break;
5542b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
5552b2b1f42SAndrew Turner 		gicd = (ACPI_MADT_GENERIC_DISTRIBUTOR *)mp;
5562b2b1f42SAndrew Turner 		printf("\tGIC ID=%d\n", (u_int)gicd->GicId);
5572b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicd->BaseAddress);
5582b2b1f42SAndrew Turner 		printf("\tVector Base=%d\n", gicd->GlobalIrqBase);
5592b2b1f42SAndrew Turner 		printf("\tGIC VERSION=%d\n", (u_int)gicd->Version);
5602b2b1f42SAndrew Turner 		break;
5612b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
5622b2b1f42SAndrew Turner 		gicr = (ACPI_MADT_GENERIC_REDISTRIBUTOR *)mp;
5632b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicr->BaseAddress);
5642b2b1f42SAndrew Turner 		printf("\tLength=%08x\n", gicr->Length);
5652b2b1f42SAndrew Turner 		break;
5662b2b1f42SAndrew Turner 	case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
5672b2b1f42SAndrew Turner 		gict = (ACPI_MADT_GENERIC_TRANSLATOR *)mp;
5682b2b1f42SAndrew Turner 		printf("\tGIC ITS ID=%d\n", gict->TranslationId);
5692b2b1f42SAndrew Turner 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gict->BaseAddress);
5702b2b1f42SAndrew Turner 		break;
5710a473124SJohn Baldwin 	}
5720a473124SJohn Baldwin }
5730a473124SJohn Baldwin 
5740a473124SJohn Baldwin static void
575986dffafSJohn Baldwin acpi_handle_madt(ACPI_TABLE_HEADER *sdp)
5760a473124SJohn Baldwin {
577986dffafSJohn Baldwin 	ACPI_TABLE_MADT *madt;
5780a473124SJohn Baldwin 
579773b6454SNate Lawson 	printf(BEGIN_COMMENT);
580773b6454SNate Lawson 	acpi_print_sdt(sdp);
581986dffafSJohn Baldwin 	madt = (ACPI_TABLE_MADT *)sdp;
582986dffafSJohn Baldwin 	printf("\tLocal APIC ADDR=0x%08x\n", madt->Address);
5830a473124SJohn Baldwin 	printf("\tFlags={");
584986dffafSJohn Baldwin 	if (madt->Flags & ACPI_MADT_PCAT_COMPAT)
5850a473124SJohn Baldwin 		printf("PC-AT");
5860a473124SJohn Baldwin 	printf("}\n");
587986dffafSJohn Baldwin 	acpi_walk_subtables(sdp, (madt + 1), acpi_print_madt);
5880a473124SJohn Baldwin 	printf(END_COMMENT);
5890a473124SJohn Baldwin }
5900a473124SJohn Baldwin 
5910a473124SJohn Baldwin static void
592ebc22d04SAlexander Motin acpi_handle_bert(ACPI_TABLE_HEADER *sdp)
593ebc22d04SAlexander Motin {
594ebc22d04SAlexander Motin 	ACPI_TABLE_BERT *bert;
595ebc22d04SAlexander Motin 
596ebc22d04SAlexander Motin 	printf(BEGIN_COMMENT);
597ebc22d04SAlexander Motin 	acpi_print_sdt(sdp);
598ebc22d04SAlexander Motin 	bert = (ACPI_TABLE_BERT *)sdp;
599ebc22d04SAlexander Motin 	printf("\tRegionLength=%d\n", bert->RegionLength);
600ebc22d04SAlexander Motin 	printf("\tAddress=0x%016jx\n", bert->Address);
601ebc22d04SAlexander Motin 	printf(END_COMMENT);
602ebc22d04SAlexander Motin }
603ebc22d04SAlexander Motin 
604ebc22d04SAlexander Motin static void
605ebc22d04SAlexander Motin acpi_print_whea(ACPI_WHEA_HEADER *w)
606ebc22d04SAlexander Motin {
607ebc22d04SAlexander Motin 
608ebc22d04SAlexander Motin 	printf("\n\tAction=%d\n", w->Action);
609ebc22d04SAlexander Motin 	printf("\tInstruction=%d\n", w->Instruction);
610ebc22d04SAlexander Motin 	printf("\tFlags=%02x\n", w->Flags);
611ebc22d04SAlexander Motin 	printf("\tRegisterRegion=");
612ebc22d04SAlexander Motin 	acpi_print_gas(&w->RegisterRegion);
613ebc22d04SAlexander Motin 	printf("\n\tValue=0x%016jx\n", w->Value);
614ebc22d04SAlexander Motin 	printf("\tMask=0x%016jx\n", w->Mask);
615ebc22d04SAlexander Motin }
616ebc22d04SAlexander Motin 
617ebc22d04SAlexander Motin static void
618ebc22d04SAlexander Motin acpi_handle_einj(ACPI_TABLE_HEADER *sdp)
619ebc22d04SAlexander Motin {
620ebc22d04SAlexander Motin 	ACPI_TABLE_EINJ *einj;
621ebc22d04SAlexander Motin 	ACPI_WHEA_HEADER *w;
622ebc22d04SAlexander Motin 	u_int i;
623ebc22d04SAlexander Motin 
624ebc22d04SAlexander Motin 	printf(BEGIN_COMMENT);
625ebc22d04SAlexander Motin 	acpi_print_sdt(sdp);
626ebc22d04SAlexander Motin 	einj = (ACPI_TABLE_EINJ *)sdp;
627ebc22d04SAlexander Motin 	printf("\tHeaderLength=%d\n", einj->HeaderLength);
628ebc22d04SAlexander Motin 	printf("\tFlags=0x%02x\n", einj->Flags);
629ebc22d04SAlexander Motin 	printf("\tEntries=%d\n", einj->Entries);
630ebc22d04SAlexander Motin 	w = (ACPI_WHEA_HEADER *)(einj + 1);
631ebc22d04SAlexander Motin 	for (i = 0; i < MIN(einj->Entries, (sdp->Length -
632ebc22d04SAlexander Motin 	    sizeof(ACPI_TABLE_EINJ)) / sizeof(ACPI_WHEA_HEADER)); i++)
633ebc22d04SAlexander Motin 		acpi_print_whea(w + i);
634ebc22d04SAlexander Motin 	printf(END_COMMENT);
635ebc22d04SAlexander Motin }
636ebc22d04SAlexander Motin 
637ebc22d04SAlexander Motin static void
638ebc22d04SAlexander Motin acpi_handle_erst(ACPI_TABLE_HEADER *sdp)
639ebc22d04SAlexander Motin {
640ebc22d04SAlexander Motin 	ACPI_TABLE_ERST *erst;
641ebc22d04SAlexander Motin 	ACPI_WHEA_HEADER *w;
642ebc22d04SAlexander Motin 	u_int i;
643ebc22d04SAlexander Motin 
644ebc22d04SAlexander Motin 	printf(BEGIN_COMMENT);
645ebc22d04SAlexander Motin 	acpi_print_sdt(sdp);
646ebc22d04SAlexander Motin 	erst = (ACPI_TABLE_ERST *)sdp;
647ebc22d04SAlexander Motin 	printf("\tHeaderLength=%d\n", erst->HeaderLength);
648ebc22d04SAlexander Motin 	printf("\tEntries=%d\n", erst->Entries);
649ebc22d04SAlexander Motin 	w = (ACPI_WHEA_HEADER *)(erst + 1);
650ebc22d04SAlexander Motin 	for (i = 0; i < MIN(erst->Entries, (sdp->Length -
651ebc22d04SAlexander Motin 	    sizeof(ACPI_TABLE_ERST)) / sizeof(ACPI_WHEA_HEADER)); i++)
652ebc22d04SAlexander Motin 		acpi_print_whea(w + i);
653ebc22d04SAlexander Motin 	printf(END_COMMENT);
654ebc22d04SAlexander Motin }
655ebc22d04SAlexander Motin 
656ebc22d04SAlexander Motin static void
657ebc22d04SAlexander Motin acpi_print_hest_bank(ACPI_HEST_IA_ERROR_BANK *b)
658ebc22d04SAlexander Motin {
659ebc22d04SAlexander Motin 
660ebc22d04SAlexander Motin 	printf("\tBank:\n");
661ebc22d04SAlexander Motin 	printf("\t\tBankNumber=%d\n", b->BankNumber);
662ebc22d04SAlexander Motin 	printf("\t\tClearStatusOnInit=%d\n", b->ClearStatusOnInit);
663ebc22d04SAlexander Motin 	printf("\t\tStatusFormat=%d\n", b->StatusFormat);
664ebc22d04SAlexander Motin 	printf("\t\tControlRegister=%x\n", b->ControlRegister);
665ebc22d04SAlexander Motin 	printf("\t\tControlData=%jx\n", b->ControlData);
666ebc22d04SAlexander Motin 	printf("\t\tStatusRegister=%x\n", b->StatusRegister);
667ebc22d04SAlexander Motin 	printf("\t\tAddressRegister=%x\n", b->AddressRegister);
668ebc22d04SAlexander Motin 	printf("\t\tMiscRegister=%x\n", b->MiscRegister);
669ebc22d04SAlexander Motin }
670ebc22d04SAlexander Motin 
671ebc22d04SAlexander Motin static void
672ebc22d04SAlexander Motin acpi_print_hest_notify(ACPI_HEST_NOTIFY *n)
673ebc22d04SAlexander Motin {
674ebc22d04SAlexander Motin 
675ebc22d04SAlexander Motin 	printf("\t\tType=%d\n", n->Type);
676ebc22d04SAlexander Motin 	printf("\t\tLength=%d\n", n->Length);
677ebc22d04SAlexander Motin 	printf("\t\tConfigWriteEnable=%04x\n", n->ConfigWriteEnable);
678ebc22d04SAlexander Motin 	printf("\t\tPollInterval=%d\n", n->PollInterval);
679ebc22d04SAlexander Motin 	printf("\t\tVector=%d\n", n->Vector);
680ebc22d04SAlexander Motin 	printf("\t\tPollingThresholdValue=%d\n", n->PollingThresholdValue);
681ebc22d04SAlexander Motin 	printf("\t\tPollingThresholdWindow=%d\n", n->PollingThresholdWindow);
682ebc22d04SAlexander Motin 	printf("\t\tErrorThresholdValue=%d\n", n->ErrorThresholdValue);
683ebc22d04SAlexander Motin 	printf("\t\tErrorThresholdWindow=%d\n", n->ErrorThresholdWindow);
684ebc22d04SAlexander Motin }
685ebc22d04SAlexander Motin 
686ebc22d04SAlexander Motin static void
687ebc22d04SAlexander Motin acpi_print_hest_aer(ACPI_HEST_AER_COMMON *a)
688ebc22d04SAlexander Motin {
689ebc22d04SAlexander Motin 
690ebc22d04SAlexander Motin 	printf("\tFlags=%02x\n", a->Flags);
691ebc22d04SAlexander Motin 	printf("\tEnabled=%d\n", a->Enabled);
692ebc22d04SAlexander Motin 	printf("\tRecordsToPreallocate=%d\n", a->RecordsToPreallocate);
693ebc22d04SAlexander Motin 	printf("\tMaxSectionsPerRecord=%d\n", a->MaxSectionsPerRecord);
694ebc22d04SAlexander Motin 	printf("\tBus=%d\n", a->Bus);
695ebc22d04SAlexander Motin 	printf("\tDevice=%d\n", a->Device);
696ebc22d04SAlexander Motin 	printf("\tFunction=%d\n", a->Function);
697ebc22d04SAlexander Motin 	printf("\tDeviceControl=%d\n", a->DeviceControl);
698ebc22d04SAlexander Motin 	printf("\tUncorrectableMask=%d\n", a->UncorrectableMask);
699ebc22d04SAlexander Motin 	printf("\tUncorrectableSeverity=%d\n", a->UncorrectableSeverity);
700ebc22d04SAlexander Motin 	printf("\tCorrectableMask=%d\n", a->CorrectableMask);
701ebc22d04SAlexander Motin 	printf("\tAdvancedCapabilities=%d\n", a->AdvancedCapabilities);
702ebc22d04SAlexander Motin }
703ebc22d04SAlexander Motin 
704ebc22d04SAlexander Motin static int
705ebc22d04SAlexander Motin acpi_handle_hest_structure(void *addr, int remaining)
706ebc22d04SAlexander Motin {
707ebc22d04SAlexander Motin 	ACPI_HEST_HEADER *hdr = addr;
708ebc22d04SAlexander Motin 	int i;
709ebc22d04SAlexander Motin 
710ebc22d04SAlexander Motin 	if (remaining < (int)sizeof(ACPI_HEST_HEADER))
711ebc22d04SAlexander Motin 		return (-1);
712ebc22d04SAlexander Motin 
713ebc22d04SAlexander Motin 	printf("\n\tType=%d\n", hdr->Type);
714ebc22d04SAlexander Motin 	printf("\tSourceId=%d\n", hdr->SourceId);
715ebc22d04SAlexander Motin 	switch (hdr->Type) {
716ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_IA32_CHECK: {
717ebc22d04SAlexander Motin 		ACPI_HEST_IA_MACHINE_CHECK *s = addr;
718ebc22d04SAlexander Motin 		printf("\tFlags=%02x\n", s->Flags);
719ebc22d04SAlexander Motin 		printf("\tEnabled=%d\n", s->Enabled);
720ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
721ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
722ebc22d04SAlexander Motin 		printf("\tGlobalCapabilityData=%jd\n", s->GlobalCapabilityData);
723ebc22d04SAlexander Motin 		printf("\tGlobalControlData=%jd\n", s->GlobalControlData);
724ebc22d04SAlexander Motin 		printf("\tNumHardwareBanks=%d\n", s->NumHardwareBanks);
725ebc22d04SAlexander Motin 		for (i = 0; i < s->NumHardwareBanks; i++) {
726ebc22d04SAlexander Motin 			acpi_print_hest_bank((ACPI_HEST_IA_ERROR_BANK *)
727ebc22d04SAlexander Motin 			    (s + 1) + i);
728ebc22d04SAlexander Motin 		}
729ebc22d04SAlexander Motin 		return (sizeof(*s) + s->NumHardwareBanks *
730ebc22d04SAlexander Motin 		    sizeof(ACPI_HEST_IA_ERROR_BANK));
731ebc22d04SAlexander Motin 	}
732ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: {
733ebc22d04SAlexander Motin 		ACPI_HEST_IA_CORRECTED *s = addr;
734ebc22d04SAlexander Motin 		printf("\tFlags=%02x\n", s->Flags);
735ebc22d04SAlexander Motin 		printf("\tEnabled=%d\n", s->Enabled);
736ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
737ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
738ebc22d04SAlexander Motin 		printf("\tNotify:\n");
739ebc22d04SAlexander Motin 		acpi_print_hest_notify(&s->Notify);
740ebc22d04SAlexander Motin 		printf("\tNumHardwareBanks=%d\n", s->NumHardwareBanks);
741ebc22d04SAlexander Motin 		for (i = 0; i < s->NumHardwareBanks; i++) {
742ebc22d04SAlexander Motin 			acpi_print_hest_bank((ACPI_HEST_IA_ERROR_BANK *)
743ebc22d04SAlexander Motin 			    (s + 1) + i);
744ebc22d04SAlexander Motin 		}
745ebc22d04SAlexander Motin 		return (sizeof(*s) + s->NumHardwareBanks *
746ebc22d04SAlexander Motin 		    sizeof(ACPI_HEST_IA_ERROR_BANK));
747ebc22d04SAlexander Motin 	}
748ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_IA32_NMI: {
749ebc22d04SAlexander Motin 		ACPI_HEST_IA_NMI *s = addr;
750ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
751ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
752ebc22d04SAlexander Motin 		printf("\tMaxRawDataLength=%d\n", s->MaxRawDataLength);
753ebc22d04SAlexander Motin 		return (sizeof(*s));
754ebc22d04SAlexander Motin 	}
755ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_AER_ROOT_PORT: {
756ebc22d04SAlexander Motin 		ACPI_HEST_AER_ROOT *s = addr;
757ebc22d04SAlexander Motin 		acpi_print_hest_aer(&s->Aer);
758ebc22d04SAlexander Motin 		printf("\tRootErrorCommand=%d\n", s->RootErrorCommand);
759ebc22d04SAlexander Motin 		return (sizeof(*s));
760ebc22d04SAlexander Motin 	}
761ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_AER_ENDPOINT: {
762ebc22d04SAlexander Motin 		ACPI_HEST_AER *s = addr;
763ebc22d04SAlexander Motin 		acpi_print_hest_aer(&s->Aer);
764ebc22d04SAlexander Motin 		return (sizeof(*s));
765ebc22d04SAlexander Motin 	}
766ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_AER_BRIDGE: {
767ebc22d04SAlexander Motin 		ACPI_HEST_AER_BRIDGE *s = addr;
768ebc22d04SAlexander Motin 		acpi_print_hest_aer(&s->Aer);
769ebc22d04SAlexander Motin 		printf("\tUncorrectableMask2=%d\n", s->UncorrectableMask2);
770ebc22d04SAlexander Motin 		printf("\tUncorrectableSeverity2=%d\n", s->UncorrectableSeverity2);
771ebc22d04SAlexander Motin 		printf("\tAdvancedCapabilities2=%d\n", s->AdvancedCapabilities2);
772ebc22d04SAlexander Motin 		return (sizeof(*s));
773ebc22d04SAlexander Motin 	}
774ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_GENERIC_ERROR: {
775ebc22d04SAlexander Motin 		ACPI_HEST_GENERIC *s = addr;
776ebc22d04SAlexander Motin 		printf("\tRelatedSourceId=%d\n", s->RelatedSourceId);
777ebc22d04SAlexander Motin 		printf("\tEnabled=%d\n", s->Enabled);
778ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
779ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
780ebc22d04SAlexander Motin 		printf("\tMaxRawDataLength=%d\n", s->MaxRawDataLength);
781ebc22d04SAlexander Motin 		printf("\tErrorStatusAddress=");
782ebc22d04SAlexander Motin 		acpi_print_gas(&s->ErrorStatusAddress);
783ebc22d04SAlexander Motin 		printf("\n");
784ebc22d04SAlexander Motin 		printf("\tNotify:\n");
785ebc22d04SAlexander Motin 		acpi_print_hest_notify(&s->Notify);
786ebc22d04SAlexander Motin 		printf("\tErrorBlockLength=%d\n", s->ErrorBlockLength);
787ebc22d04SAlexander Motin 		return (sizeof(*s));
788ebc22d04SAlexander Motin 	}
789ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_GENERIC_ERROR_V2: {
790ebc22d04SAlexander Motin 		ACPI_HEST_GENERIC_V2 *s = addr;
791ebc22d04SAlexander Motin 		printf("\tRelatedSourceId=%d\n", s->RelatedSourceId);
792ebc22d04SAlexander Motin 		printf("\tEnabled=%d\n", s->Enabled);
793ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
794ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
795ebc22d04SAlexander Motin 		printf("\tMaxRawDataLength=%d\n", s->MaxRawDataLength);
796ebc22d04SAlexander Motin 		printf("\tErrorStatusAddress=");
797ebc22d04SAlexander Motin 		acpi_print_gas(&s->ErrorStatusAddress);
798ebc22d04SAlexander Motin 		printf("\n");
799ebc22d04SAlexander Motin 		printf("\tNotify:\n");
800ebc22d04SAlexander Motin 		acpi_print_hest_notify(&s->Notify);
801ebc22d04SAlexander Motin 		printf("\tErrorBlockLength=%d\n", s->ErrorBlockLength);
802ebc22d04SAlexander Motin 		printf("\tReadAckRegister=");
803ebc22d04SAlexander Motin 		acpi_print_gas(&s->ReadAckRegister);
804ebc22d04SAlexander Motin 		printf("\n");
805ebc22d04SAlexander Motin 		printf("\tReadAckPreserve=%jd\n", s->ReadAckPreserve);
806ebc22d04SAlexander Motin 		printf("\tReadAckWrite=%jd\n", s->ReadAckWrite);
807ebc22d04SAlexander Motin 		return (sizeof(*s));
808ebc22d04SAlexander Motin 	}
809ebc22d04SAlexander Motin 	case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: {
810ebc22d04SAlexander Motin 		ACPI_HEST_IA_DEFERRED_CHECK *s = addr;
811ebc22d04SAlexander Motin 		printf("\tFlags=%02x\n", s->Flags);
812ebc22d04SAlexander Motin 		printf("\tEnabled=%d\n", s->Enabled);
813ebc22d04SAlexander Motin 		printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
814ebc22d04SAlexander Motin 		printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
815ebc22d04SAlexander Motin 		printf("\tNotify:\n");
816ebc22d04SAlexander Motin 		acpi_print_hest_notify(&s->Notify);
817ebc22d04SAlexander Motin 		printf("\tNumHardwareBanks=%d\n", s->NumHardwareBanks);
818ebc22d04SAlexander Motin 		for (i = 0; i < s->NumHardwareBanks; i++) {
819ebc22d04SAlexander Motin 			acpi_print_hest_bank((ACPI_HEST_IA_ERROR_BANK *)
820ebc22d04SAlexander Motin 			    (s + 1) + i);
821ebc22d04SAlexander Motin 		}
822ebc22d04SAlexander Motin 		return (sizeof(*s) + s->NumHardwareBanks *
823ebc22d04SAlexander Motin 		    sizeof(ACPI_HEST_IA_ERROR_BANK));
824ebc22d04SAlexander Motin 	}
825ebc22d04SAlexander Motin 	default:
826ebc22d04SAlexander Motin 		return (-1);
827ebc22d04SAlexander Motin 	}
828ebc22d04SAlexander Motin }
829ebc22d04SAlexander Motin 
830ebc22d04SAlexander Motin static void
831ebc22d04SAlexander Motin acpi_handle_hest(ACPI_TABLE_HEADER *sdp)
832ebc22d04SAlexander Motin {
833ebc22d04SAlexander Motin 	char *cp;
834ebc22d04SAlexander Motin 	int remaining, consumed;
835ebc22d04SAlexander Motin 	ACPI_TABLE_HEST *hest;
836ebc22d04SAlexander Motin 
837ebc22d04SAlexander Motin 	printf(BEGIN_COMMENT);
838ebc22d04SAlexander Motin 	acpi_print_sdt(sdp);
839ebc22d04SAlexander Motin 	hest = (ACPI_TABLE_HEST *)sdp;
840ebc22d04SAlexander Motin 	printf("\tErrorSourceCount=%d\n", hest->ErrorSourceCount);
841ebc22d04SAlexander Motin 
842ebc22d04SAlexander Motin 	remaining = sdp->Length - sizeof(ACPI_TABLE_HEST);
843ebc22d04SAlexander Motin 	while (remaining > 0) {
844ebc22d04SAlexander Motin 		cp = (char *)sdp + sdp->Length - remaining;
845ebc22d04SAlexander Motin 		consumed = acpi_handle_hest_structure(cp, remaining);
846ebc22d04SAlexander Motin 		if (consumed <= 0)
847ebc22d04SAlexander Motin 			break;
848ebc22d04SAlexander Motin 		else
849ebc22d04SAlexander Motin 			remaining -= consumed;
850ebc22d04SAlexander Motin 	}
851ebc22d04SAlexander Motin 	printf(END_COMMENT);
852ebc22d04SAlexander Motin }
853ebc22d04SAlexander Motin 
854ebc22d04SAlexander Motin static void
855986dffafSJohn Baldwin acpi_handle_hpet(ACPI_TABLE_HEADER *sdp)
85679d7565cSPeter Wemm {
857986dffafSJohn Baldwin 	ACPI_TABLE_HPET *hpet;
85879d7565cSPeter Wemm 
859773b6454SNate Lawson 	printf(BEGIN_COMMENT);
860773b6454SNate Lawson 	acpi_print_sdt(sdp);
861986dffafSJohn Baldwin 	hpet = (ACPI_TABLE_HPET *)sdp;
862986dffafSJohn Baldwin 	printf("\tHPET Number=%d\n", hpet->Sequence);
86387f9f09aSTakanori Watanabe 	printf("\tADDR=");
864986dffafSJohn Baldwin 	acpi_print_gas(&hpet->Address);
865ebc22d04SAlexander Motin 	printf("\n\tHW Rev=0x%x\n", hpet->Id & ACPI_HPET_ID_HARDWARE_REV_ID);
866986dffafSJohn Baldwin 	printf("\tComparators=%d\n", (hpet->Id & ACPI_HPET_ID_COMPARATORS) >>
867986dffafSJohn Baldwin 	    8);
868986dffafSJohn Baldwin 	printf("\tCounter Size=%d\n", hpet->Id & ACPI_HPET_ID_COUNT_SIZE_CAP ?
869986dffafSJohn Baldwin 	    1 : 0);
87079d7565cSPeter Wemm 	printf("\tLegacy IRQ routing capable={");
871986dffafSJohn Baldwin 	if (hpet->Id & ACPI_HPET_ID_LEGACY_CAPABLE)
87279d7565cSPeter Wemm 		printf("TRUE}\n");
87379d7565cSPeter Wemm 	else
87479d7565cSPeter Wemm 		printf("FALSE}\n");
875986dffafSJohn Baldwin 	printf("\tPCI Vendor ID=0x%04x\n", hpet->Id >> 16);
876986dffafSJohn Baldwin 	printf("\tMinimal Tick=%d\n", hpet->MinimumTick);
8779785e979SNeel Natu 	printf("\tFlags=0x%02x\n", hpet->Flags);
87879d7565cSPeter Wemm 	printf(END_COMMENT);
87979d7565cSPeter Wemm }
88079d7565cSPeter Wemm 
88179d7565cSPeter Wemm static void
882986dffafSJohn Baldwin acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp)
88355d7ff9eSNate Lawson {
884986dffafSJohn Baldwin 	ACPI_TABLE_ECDT *ecdt;
88555d7ff9eSNate Lawson 
88655d7ff9eSNate Lawson 	printf(BEGIN_COMMENT);
88755d7ff9eSNate Lawson 	acpi_print_sdt(sdp);
888986dffafSJohn Baldwin 	ecdt = (ACPI_TABLE_ECDT *)sdp;
88955d7ff9eSNate Lawson 	printf("\tEC_CONTROL=");
890986dffafSJohn Baldwin 	acpi_print_gas(&ecdt->Control);
89155d7ff9eSNate Lawson 	printf("\n\tEC_DATA=");
892986dffafSJohn Baldwin 	acpi_print_gas(&ecdt->Data);
893986dffafSJohn Baldwin 	printf("\n\tUID=%#x, ", ecdt->Uid);
894986dffafSJohn Baldwin 	printf("GPE_BIT=%#x\n", ecdt->Gpe);
895986dffafSJohn Baldwin 	printf("\tEC_ID=%s\n", ecdt->Id);
89655d7ff9eSNate Lawson 	printf(END_COMMENT);
89755d7ff9eSNate Lawson }
89855d7ff9eSNate Lawson 
89955d7ff9eSNate Lawson static void
900986dffafSJohn Baldwin acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp)
901a47e681bSScott Long {
902986dffafSJohn Baldwin 	ACPI_TABLE_MCFG *mcfg;
903986dffafSJohn Baldwin 	ACPI_MCFG_ALLOCATION *alloc;
904986dffafSJohn Baldwin 	u_int i, entries;
905a47e681bSScott Long 
906a47e681bSScott Long 	printf(BEGIN_COMMENT);
907a47e681bSScott Long 	acpi_print_sdt(sdp);
908986dffafSJohn Baldwin 	mcfg = (ACPI_TABLE_MCFG *)sdp;
909986dffafSJohn Baldwin 	entries = (sdp->Length - sizeof(ACPI_TABLE_MCFG)) /
910986dffafSJohn Baldwin 	    sizeof(ACPI_MCFG_ALLOCATION);
911986dffafSJohn Baldwin 	alloc = (ACPI_MCFG_ALLOCATION *)(mcfg + 1);
912986dffafSJohn Baldwin 	for (i = 0; i < entries; i++, alloc++) {
913a47e681bSScott Long 		printf("\n");
9140c10b85aSJung-uk Kim 		printf("\tBase Address=0x%016jx\n", (uintmax_t)alloc->Address);
915986dffafSJohn Baldwin 		printf("\tSegment Group=0x%04x\n", alloc->PciSegment);
916986dffafSJohn Baldwin 		printf("\tStart Bus=%d\n", alloc->StartBusNumber);
917986dffafSJohn Baldwin 		printf("\tEnd Bus=%d\n", alloc->EndBusNumber);
918a47e681bSScott Long 	}
919a47e681bSScott Long 	printf(END_COMMENT);
920a47e681bSScott Long }
921a47e681bSScott Long 
922a47e681bSScott Long static void
92333866658SJohn Baldwin acpi_handle_slit(ACPI_TABLE_HEADER *sdp)
92433866658SJohn Baldwin {
92533866658SJohn Baldwin 	ACPI_TABLE_SLIT *slit;
92633866658SJohn Baldwin 	UINT64 i, j;
92733866658SJohn Baldwin 
92833866658SJohn Baldwin 	printf(BEGIN_COMMENT);
92933866658SJohn Baldwin 	acpi_print_sdt(sdp);
93033866658SJohn Baldwin 	slit = (ACPI_TABLE_SLIT *)sdp;
9310c10b85aSJung-uk Kim 	printf("\tLocality Count=%ju\n", (uintmax_t)slit->LocalityCount);
93233866658SJohn Baldwin 	printf("\n\t      ");
93333866658SJohn Baldwin 	for (i = 0; i < slit->LocalityCount; i++)
9340c10b85aSJung-uk Kim 		printf(" %3ju", (uintmax_t)i);
93533866658SJohn Baldwin 	printf("\n\t     +");
93633866658SJohn Baldwin 	for (i = 0; i < slit->LocalityCount; i++)
93733866658SJohn Baldwin 		printf("----");
93833866658SJohn Baldwin 	printf("\n");
93933866658SJohn Baldwin 	for (i = 0; i < slit->LocalityCount; i++) {
9400c10b85aSJung-uk Kim 		printf("\t %3ju |", (uintmax_t)i);
94133866658SJohn Baldwin 		for (j = 0; j < slit->LocalityCount; j++)
94233866658SJohn Baldwin 			printf(" %3d",
94333866658SJohn Baldwin 			    slit->Entry[i * slit->LocalityCount + j]);
94433866658SJohn Baldwin 		printf("\n");
94533866658SJohn Baldwin 	}
94633866658SJohn Baldwin 	printf(END_COMMENT);
94733866658SJohn Baldwin }
94833866658SJohn Baldwin 
94933866658SJohn Baldwin static void
950ed26c389SScott Long acpi_handle_wddt(ACPI_TABLE_HEADER *sdp)
951ed26c389SScott Long {
952ed26c389SScott Long 	ACPI_TABLE_WDDT *wddt;
953ed26c389SScott Long 
954ed26c389SScott Long 	printf(BEGIN_COMMENT);
955ed26c389SScott Long 	acpi_print_sdt(sdp);
956ed26c389SScott Long 	wddt = (ACPI_TABLE_WDDT *)sdp;
957ed26c389SScott Long 	printf("\tSpecVersion=0x%04x, TableVersion=0x%04x\n",
958ed26c389SScott Long 	    wddt->SpecVersion, wddt->TableVersion);
959ed26c389SScott Long 	printf("\tPciVendorId=0x%04x, Address=", wddt->PciVendorId);
960ed26c389SScott Long 	acpi_print_gas(&wddt->Address);
961ed26c389SScott Long 	printf("\n\tMaxCount=%u, MinCount=%u, Period=%ums\n",
962ed26c389SScott Long 	    wddt->MaxCount, wddt->MinCount, wddt->Period);
963ed26c389SScott Long 
964ed26c389SScott Long #define	PRINTFLAG(var, flag)	printflag((var), ACPI_WDDT_## flag, #flag)
965ed26c389SScott Long 	printf("\tStatus=");
966ed26c389SScott Long 	PRINTFLAG(wddt->Status, AVAILABLE);
967ed26c389SScott Long 	PRINTFLAG(wddt->Status, ACTIVE);
968ed26c389SScott Long 	PRINTFLAG(wddt->Status, TCO_OS_OWNED);
969ed26c389SScott Long 	PRINTFLAG(wddt->Status, USER_RESET);
970ed26c389SScott Long 	PRINTFLAG(wddt->Status, WDT_RESET);
971ed26c389SScott Long 	PRINTFLAG(wddt->Status, POWER_FAIL);
972ed26c389SScott Long 	PRINTFLAG(wddt->Status, UNKNOWN_RESET);
973ed26c389SScott Long 	PRINTFLAG_END();
974ed26c389SScott Long 	printf("\tCapability=");
975ed26c389SScott Long 	PRINTFLAG(wddt->Capability, AUTO_RESET);
976ed26c389SScott Long 	PRINTFLAG(wddt->Capability, ALERT_SUPPORT);
977ed26c389SScott Long 	PRINTFLAG_END();
978ed26c389SScott Long #undef PRINTFLAG
979ed26c389SScott Long 
980ed26c389SScott Long 	printf(END_COMMENT);
981ed26c389SScott Long }
982ed26c389SScott Long 
983ed26c389SScott Long static void
9845857fba5SBen Widawsky acpi_print_native_lpit(ACPI_LPIT_NATIVE *nl)
9855857fba5SBen Widawsky {
9865857fba5SBen Widawsky 	printf("\tEntryTrigger=");
9875857fba5SBen Widawsky 	acpi_print_gas(&nl->EntryTrigger);
988ebc22d04SAlexander Motin 	printf("\n\tResidency=%u\n", nl->Residency);
9895857fba5SBen Widawsky 	printf("\tLatency=%u\n", nl->Latency);
9905857fba5SBen Widawsky 	if (nl->Header.Flags & ACPI_LPIT_NO_COUNTER)
9915857fba5SBen Widawsky 		printf("\tResidencyCounter=Not Present");
9925857fba5SBen Widawsky 	else {
9935857fba5SBen Widawsky 		printf("\tResidencyCounter=");
9945857fba5SBen Widawsky 		acpi_print_gas(&nl->ResidencyCounter);
995ebc22d04SAlexander Motin 		printf("\n");
9965857fba5SBen Widawsky 	}
9975857fba5SBen Widawsky 	if (nl->CounterFrequency)
9985857fba5SBen Widawsky 		printf("\tCounterFrequency=%ju\n", nl->CounterFrequency);
9995857fba5SBen Widawsky 	else
10005857fba5SBen Widawsky 		printf("\tCounterFrequency=TSC\n");
10015857fba5SBen Widawsky }
10025857fba5SBen Widawsky 
10035857fba5SBen Widawsky static void
10045857fba5SBen Widawsky acpi_print_lpit(ACPI_LPIT_HEADER *lpit)
10055857fba5SBen Widawsky {
10065857fba5SBen Widawsky 	if (lpit->Type == ACPI_LPIT_TYPE_NATIVE_CSTATE)
10075857fba5SBen Widawsky 		printf("\tType=ACPI_LPIT_TYPE_NATIVE_CSTATE\n");
10085857fba5SBen Widawsky 	else
10095857fba5SBen Widawsky 		warnx("unknown LPIT type %u", lpit->Type);
10105857fba5SBen Widawsky 
10115857fba5SBen Widawsky 	printf("\tLength=%u\n", lpit->Length);
10125857fba5SBen Widawsky 	printf("\tUniqueId=0x%04x\n", lpit->UniqueId);
10135857fba5SBen Widawsky #define	PRINTFLAG(var, flag)	printflag((var), ACPI_LPIT_## flag, #flag)
10145857fba5SBen Widawsky 	printf("\tFlags=");
10155857fba5SBen Widawsky 	PRINTFLAG(lpit->Flags, STATE_DISABLED);
10165857fba5SBen Widawsky 	PRINTFLAG_END();
10175857fba5SBen Widawsky #undef PRINTFLAG
10185857fba5SBen Widawsky 
10195857fba5SBen Widawsky 	if (lpit->Type == ACPI_LPIT_TYPE_NATIVE_CSTATE)
10205857fba5SBen Widawsky 		return acpi_print_native_lpit((ACPI_LPIT_NATIVE *)lpit);
10215857fba5SBen Widawsky }
10225857fba5SBen Widawsky 
10235857fba5SBen Widawsky static void
10245857fba5SBen Widawsky acpi_walk_lpit(ACPI_TABLE_HEADER *table, void *first,
10255857fba5SBen Widawsky     void (*action)(ACPI_LPIT_HEADER *))
10265857fba5SBen Widawsky {
10275857fba5SBen Widawsky 	ACPI_LPIT_HEADER *subtable;
10285857fba5SBen Widawsky 	char *end;
10295857fba5SBen Widawsky 
10305857fba5SBen Widawsky 	subtable = first;
10315857fba5SBen Widawsky 	end = (char *)table + table->Length;
10325857fba5SBen Widawsky 	while ((char *)subtable < end) {
10335857fba5SBen Widawsky 		printf("\n");
10345857fba5SBen Widawsky 		if (subtable->Length < sizeof(ACPI_LPIT_HEADER)) {
10355857fba5SBen Widawsky 			warnx("invalid subtable length %u", subtable->Length);
10365857fba5SBen Widawsky 			return;
10375857fba5SBen Widawsky 		}
10385857fba5SBen Widawsky 		action(subtable);
10395857fba5SBen Widawsky 		subtable = (ACPI_LPIT_HEADER *)((char *)subtable +
10405857fba5SBen Widawsky 		    subtable->Length);
10415857fba5SBen Widawsky 	}
10425857fba5SBen Widawsky }
10435857fba5SBen Widawsky 
10445857fba5SBen Widawsky static void
10455857fba5SBen Widawsky acpi_handle_lpit(ACPI_TABLE_HEADER *sdp)
10465857fba5SBen Widawsky {
10475857fba5SBen Widawsky 	ACPI_TABLE_LPIT *lpit;
10485857fba5SBen Widawsky 
10495857fba5SBen Widawsky 	printf(BEGIN_COMMENT);
10505857fba5SBen Widawsky 	acpi_print_sdt(sdp);
10515857fba5SBen Widawsky 	lpit = (ACPI_TABLE_LPIT *)sdp;
10525857fba5SBen Widawsky 	acpi_walk_lpit(sdp, (lpit + 1), acpi_print_lpit);
10535857fba5SBen Widawsky 
10545857fba5SBen Widawsky 	printf(END_COMMENT);
10555857fba5SBen Widawsky }
10565857fba5SBen Widawsky 
10575857fba5SBen Widawsky static void
1058a0333ad1SJohn Baldwin acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain,
1059a0333ad1SJohn Baldwin     uint32_t flags)
1060a0333ad1SJohn Baldwin {
1061a0333ad1SJohn Baldwin 
1062a0333ad1SJohn Baldwin 	printf("\tFlags={");
1063a0333ad1SJohn Baldwin 	if (flags & ACPI_SRAT_CPU_ENABLED)
1064a0333ad1SJohn Baldwin 		printf("ENABLED");
1065a0333ad1SJohn Baldwin 	else
1066a0333ad1SJohn Baldwin 		printf("DISABLED");
1067a0333ad1SJohn Baldwin 	printf("}\n");
1068a0333ad1SJohn Baldwin 	printf("\tAPIC ID=%d\n", apic_id);
1069a0333ad1SJohn Baldwin 	printf("\tProximity Domain=%d\n", proximity_domain);
1070a0333ad1SJohn Baldwin }
1071a0333ad1SJohn Baldwin 
1072c031c93bSTakanori Watanabe static char *
1073c031c93bSTakanori Watanabe acpi_tcpa_evname(struct TCPAevent *event)
1074c031c93bSTakanori Watanabe {
1075c031c93bSTakanori Watanabe 	struct TCPApc_event *pc_event;
1076c031c93bSTakanori Watanabe 	char *eventname = NULL;
1077c031c93bSTakanori Watanabe 
1078c031c93bSTakanori Watanabe 	pc_event = (struct TCPApc_event *)(event + 1);
1079c031c93bSTakanori Watanabe 
1080c031c93bSTakanori Watanabe 	switch(event->event_type) {
1081c031c93bSTakanori Watanabe 	case PREBOOT:
1082c031c93bSTakanori Watanabe 	case POST_CODE:
1083c031c93bSTakanori Watanabe 	case UNUSED:
1084c031c93bSTakanori Watanabe 	case NO_ACTION:
1085c031c93bSTakanori Watanabe 	case SEPARATOR:
1086c031c93bSTakanori Watanabe 	case SCRTM_CONTENTS:
1087c031c93bSTakanori Watanabe 	case SCRTM_VERSION:
1088c031c93bSTakanori Watanabe 	case CPU_MICROCODE:
1089c031c93bSTakanori Watanabe 	case PLATFORM_CONFIG_FLAGS:
1090c031c93bSTakanori Watanabe 	case TABLE_OF_DEVICES:
1091c031c93bSTakanori Watanabe 	case COMPACT_HASH:
1092c031c93bSTakanori Watanabe 	case IPL:
1093c031c93bSTakanori Watanabe 	case IPL_PARTITION_DATA:
1094c031c93bSTakanori Watanabe 	case NONHOST_CODE:
1095c031c93bSTakanori Watanabe 	case NONHOST_CONFIG:
1096c031c93bSTakanori Watanabe 	case NONHOST_INFO:
1097c031c93bSTakanori Watanabe 		asprintf(&eventname, "%s",
1098c031c93bSTakanori Watanabe 		    tcpa_event_type_strings[event->event_type]);
1099c031c93bSTakanori Watanabe 		break;
1100c031c93bSTakanori Watanabe 
1101c031c93bSTakanori Watanabe 	case ACTION:
1102c031c93bSTakanori Watanabe 		eventname = calloc(event->event_size + 1, sizeof(char));
1103c031c93bSTakanori Watanabe 		memcpy(eventname, pc_event, event->event_size);
1104c031c93bSTakanori Watanabe 		break;
1105c031c93bSTakanori Watanabe 
1106c031c93bSTakanori Watanabe 	case EVENT_TAG:
1107c031c93bSTakanori Watanabe 		switch (pc_event->event_id) {
1108c031c93bSTakanori Watanabe 		case SMBIOS:
1109c031c93bSTakanori Watanabe 		case BIS_CERT:
1110c031c93bSTakanori Watanabe 		case CMOS:
1111c031c93bSTakanori Watanabe 		case NVRAM:
1112c031c93bSTakanori Watanabe 		case OPTION_ROM_EXEC:
1113c031c93bSTakanori Watanabe 		case OPTION_ROM_CONFIG:
1114c031c93bSTakanori Watanabe 		case S_CRTM_VERSION:
1115c031c93bSTakanori Watanabe 		case POST_BIOS_ROM:
1116c031c93bSTakanori Watanabe 		case ESCD:
1117c031c93bSTakanori Watanabe 		case OPTION_ROM_MICROCODE:
1118c031c93bSTakanori Watanabe 		case S_CRTM_CONTENTS:
1119c031c93bSTakanori Watanabe 		case POST_CONTENTS:
1120c031c93bSTakanori Watanabe 			asprintf(&eventname, "%s",
1121c031c93bSTakanori Watanabe 			    TCPA_pcclient_strings[pc_event->event_id]);
1122c031c93bSTakanori Watanabe 			break;
1123c031c93bSTakanori Watanabe 
1124c031c93bSTakanori Watanabe 		default:
1125c031c93bSTakanori Watanabe 			asprintf(&eventname, "<unknown tag 0x%02x>",
1126c031c93bSTakanori Watanabe 			    pc_event->event_id);
1127c031c93bSTakanori Watanabe 			break;
1128c031c93bSTakanori Watanabe 		}
1129c031c93bSTakanori Watanabe 		break;
1130c031c93bSTakanori Watanabe 
1131c031c93bSTakanori Watanabe 	default:
1132c031c93bSTakanori Watanabe 		asprintf(&eventname, "<unknown 0x%02x>", event->event_type);
1133c031c93bSTakanori Watanabe 		break;
1134c031c93bSTakanori Watanabe 	}
1135c031c93bSTakanori Watanabe 
1136c031c93bSTakanori Watanabe 	return eventname;
1137c031c93bSTakanori Watanabe }
1138c031c93bSTakanori Watanabe 
1139c031c93bSTakanori Watanabe static void
1140c031c93bSTakanori Watanabe acpi_print_tcpa(struct TCPAevent *event)
1141c031c93bSTakanori Watanabe {
1142c031c93bSTakanori Watanabe 	int i;
1143c031c93bSTakanori Watanabe 	char *eventname;
1144c031c93bSTakanori Watanabe 
1145c031c93bSTakanori Watanabe 	eventname = acpi_tcpa_evname(event);
1146c031c93bSTakanori Watanabe 
1147c031c93bSTakanori Watanabe 	printf("\t%d", event->pcr_index);
1148c031c93bSTakanori Watanabe 	printf(" 0x");
1149c031c93bSTakanori Watanabe 	for (i = 0; i < 20; i++)
1150c031c93bSTakanori Watanabe 		printf("%02x", event->pcr_value[i]);
1151c031c93bSTakanori Watanabe 	printf(" [%s]\n", eventname ? eventname : "<unknown>");
1152c031c93bSTakanori Watanabe 
1153c031c93bSTakanori Watanabe 	free(eventname);
1154c031c93bSTakanori Watanabe }
1155c031c93bSTakanori Watanabe 
1156c031c93bSTakanori Watanabe static void
1157c031c93bSTakanori Watanabe acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp)
1158c031c93bSTakanori Watanabe {
1159c031c93bSTakanori Watanabe 	struct TCPAbody *tcpa;
1160c031c93bSTakanori Watanabe 	struct TCPAevent *event;
1161977fd9daSTakanori Watanabe 	uintmax_t len, paddr;
1162c031c93bSTakanori Watanabe 	unsigned char *vaddr = NULL;
1163c031c93bSTakanori Watanabe 	unsigned char *vend = NULL;
1164c031c93bSTakanori Watanabe 
1165c031c93bSTakanori Watanabe 	printf(BEGIN_COMMENT);
1166c031c93bSTakanori Watanabe 	acpi_print_sdt(sdp);
1167c031c93bSTakanori Watanabe 	tcpa = (struct TCPAbody *) sdp;
1168c031c93bSTakanori Watanabe 
1169c031c93bSTakanori Watanabe 	switch (tcpa->platform_class) {
1170c031c93bSTakanori Watanabe 	case ACPI_TCPA_BIOS_CLIENT:
1171c031c93bSTakanori Watanabe 		len = tcpa->client.log_max_len;
1172c031c93bSTakanori Watanabe 		paddr = tcpa->client.log_start_addr;
1173c031c93bSTakanori Watanabe 		break;
1174c031c93bSTakanori Watanabe 
1175c031c93bSTakanori Watanabe 	case ACPI_TCPA_BIOS_SERVER:
1176c031c93bSTakanori Watanabe 		len = tcpa->server.log_max_len;
1177c031c93bSTakanori Watanabe 		paddr = tcpa->server.log_start_addr;
1178c031c93bSTakanori Watanabe 		break;
1179c031c93bSTakanori Watanabe 
1180c031c93bSTakanori Watanabe 	default:
1181c031c93bSTakanori Watanabe 		printf("XXX");
1182c031c93bSTakanori Watanabe 		printf(END_COMMENT);
1183c031c93bSTakanori Watanabe 		return;
1184c031c93bSTakanori Watanabe 	}
11850e1982f4STakanori Watanabe 	printf("\tClass %u Base Address 0x%jx Length %ju\n\n",
1186c031c93bSTakanori Watanabe 	    tcpa->platform_class, paddr, len);
1187c031c93bSTakanori Watanabe 
1188c031c93bSTakanori Watanabe 	if (len == 0) {
1189c031c93bSTakanori Watanabe 		printf("\tEmpty TCPA table\n");
1190c031c93bSTakanori Watanabe 		printf(END_COMMENT);
1191c031c93bSTakanori Watanabe 		return;
1192c031c93bSTakanori Watanabe 	}
11932ef23c6dSTakanori Watanabe 	if(sdp->Revision == 1){
11942ef23c6dSTakanori Watanabe 		printf("\tOLD TCPA spec log found. Dumping not supported.\n");
11952ef23c6dSTakanori Watanabe 		printf(END_COMMENT);
11962ef23c6dSTakanori Watanabe 		return;
11972ef23c6dSTakanori Watanabe 	}
1198c031c93bSTakanori Watanabe 
1199c031c93bSTakanori Watanabe 	vaddr = (unsigned char *)acpi_map_physical(paddr, len);
1200c031c93bSTakanori Watanabe 	vend = vaddr + len;
1201c031c93bSTakanori Watanabe 
1202c031c93bSTakanori Watanabe 	while (vaddr != NULL) {
12032ef23c6dSTakanori Watanabe 		if ((vaddr + sizeof(struct TCPAevent) >= vend)||
12042ef23c6dSTakanori Watanabe 		    (vaddr + sizeof(struct TCPAevent) < vaddr))
1205c031c93bSTakanori Watanabe 			break;
12060e1982f4STakanori Watanabe 		event = (struct TCPAevent *)(void *)vaddr;
1207c031c93bSTakanori Watanabe 		if (vaddr + event->event_size >= vend)
1208c031c93bSTakanori Watanabe 			break;
12092ef23c6dSTakanori Watanabe 		if (vaddr + event->event_size < vaddr)
12102ef23c6dSTakanori Watanabe 			break;
1211c031c93bSTakanori Watanabe 		if (event->event_type == 0 && event->event_size == 0)
1212c031c93bSTakanori Watanabe 			break;
1213c031c93bSTakanori Watanabe #if 0
1214c031c93bSTakanori Watanabe 		{
1215c031c93bSTakanori Watanabe 		unsigned int i, j, k;
1216c031c93bSTakanori Watanabe 
1217c031c93bSTakanori Watanabe 		printf("\n\tsize %d\n\t\t%p ", event->event_size, vaddr);
1218c031c93bSTakanori Watanabe 		for (j = 0, i = 0; i <
1219c031c93bSTakanori Watanabe 		    sizeof(struct TCPAevent) + event->event_size; i++) {
1220c031c93bSTakanori Watanabe 			printf("%02x ", vaddr[i]);
1221c031c93bSTakanori Watanabe 			if ((i+1) % 8 == 0) {
1222c031c93bSTakanori Watanabe 				for (k = 0; k < 8; k++)
1223c031c93bSTakanori Watanabe 					printf("%c", isprint(vaddr[j+k]) ?
1224c031c93bSTakanori Watanabe 					    vaddr[j+k] : '.');
1225c031c93bSTakanori Watanabe 				printf("\n\t\t%p ", &vaddr[i + 1]);
1226c031c93bSTakanori Watanabe 				j = i + 1;
1227c031c93bSTakanori Watanabe 			}
1228c031c93bSTakanori Watanabe 		}
1229c031c93bSTakanori Watanabe 		printf("\n"); }
1230c031c93bSTakanori Watanabe #endif
1231c031c93bSTakanori Watanabe 		acpi_print_tcpa(event);
1232c031c93bSTakanori Watanabe 
1233c031c93bSTakanori Watanabe 		vaddr += sizeof(struct TCPAevent) + event->event_size;
1234c031c93bSTakanori Watanabe 	}
1235c031c93bSTakanori Watanabe 
1236c031c93bSTakanori Watanabe 	printf(END_COMMENT);
1237c031c93bSTakanori Watanabe }
1238877fc2e3STakanori Watanabe static void acpi_handle_tpm2(ACPI_TABLE_HEADER *sdp)
1239877fc2e3STakanori Watanabe {
1240877fc2e3STakanori Watanabe 	ACPI_TABLE_TPM2 *tpm2;
1241877fc2e3STakanori Watanabe 
1242877fc2e3STakanori Watanabe 	printf (BEGIN_COMMENT);
1243877fc2e3STakanori Watanabe 	acpi_print_sdt(sdp);
1244877fc2e3STakanori Watanabe 	tpm2 = (ACPI_TABLE_TPM2 *) sdp;
12457aef7138SCy Schubert 	printf ("\t\tControlArea=%jx\n", tpm2->ControlAddress);
1246877fc2e3STakanori Watanabe 	printf ("\t\tStartMethod=%x\n", tpm2->StartMethod);
1247877fc2e3STakanori Watanabe 	printf (END_COMMENT);
1248877fc2e3STakanori Watanabe }
1249c031c93bSTakanori Watanabe 
1250ec650989SNeel Natu static const char *
1251ec650989SNeel Natu devscope_type2str(int type)
1252ec650989SNeel Natu {
1253ec650989SNeel Natu 	static char typebuf[16];
1254ec650989SNeel Natu 
1255ec650989SNeel Natu 	switch (type) {
1256ec650989SNeel Natu 	case 1:
1257ec650989SNeel Natu 		return ("PCI Endpoint Device");
1258ec650989SNeel Natu 	case 2:
1259ec650989SNeel Natu 		return ("PCI Sub-Hierarchy");
1260ec650989SNeel Natu 	case 3:
1261ec650989SNeel Natu 		return ("IOAPIC");
1262ec650989SNeel Natu 	case 4:
1263ec650989SNeel Natu 		return ("HPET");
1264ec650989SNeel Natu 	default:
1265ec650989SNeel Natu 		snprintf(typebuf, sizeof(typebuf), "%d", type);
1266ec650989SNeel Natu 		return (typebuf);
1267ec650989SNeel Natu 	}
1268ec650989SNeel Natu }
1269ec650989SNeel Natu 
1270ec650989SNeel Natu static int
1271ec650989SNeel Natu acpi_handle_dmar_devscope(void *addr, int remaining)
1272ec650989SNeel Natu {
1273ec650989SNeel Natu 	char sep;
1274ec650989SNeel Natu 	int pathlen;
1275ec650989SNeel Natu 	ACPI_DMAR_PCI_PATH *path, *pathend;
1276ec650989SNeel Natu 	ACPI_DMAR_DEVICE_SCOPE *devscope = addr;
1277ec650989SNeel Natu 
1278ec650989SNeel Natu 	if (remaining < (int)sizeof(ACPI_DMAR_DEVICE_SCOPE))
1279ec650989SNeel Natu 		return (-1);
1280ec650989SNeel Natu 
1281ec650989SNeel Natu 	if (remaining < devscope->Length)
1282ec650989SNeel Natu 		return (-1);
1283ec650989SNeel Natu 
1284ec650989SNeel Natu 	printf("\n");
1285ec650989SNeel Natu 	printf("\t\tType=%s\n", devscope_type2str(devscope->EntryType));
1286ec650989SNeel Natu 	printf("\t\tLength=%d\n", devscope->Length);
1287ec650989SNeel Natu 	printf("\t\tEnumerationId=%d\n", devscope->EnumerationId);
1288ec650989SNeel Natu 	printf("\t\tStartBusNumber=%d\n", devscope->Bus);
1289ec650989SNeel Natu 
1290ec650989SNeel Natu 	path = (ACPI_DMAR_PCI_PATH *)(devscope + 1);
1291ec650989SNeel Natu 	pathlen = devscope->Length - sizeof(ACPI_DMAR_DEVICE_SCOPE);
1292ec650989SNeel Natu 	pathend = path + pathlen / sizeof(ACPI_DMAR_PCI_PATH);
1293ec650989SNeel Natu 	if (path < pathend) {
1294ec650989SNeel Natu 		sep = '{';
1295ec650989SNeel Natu 		printf("\t\tPath=");
1296ec650989SNeel Natu 		do {
1297ec650989SNeel Natu 			printf("%c%d:%d", sep, path->Device, path->Function);
1298ec650989SNeel Natu 			sep=',';
1299ec650989SNeel Natu 			path++;
1300ec650989SNeel Natu 		} while (path < pathend);
1301ec650989SNeel Natu 		printf("}\n");
1302ec650989SNeel Natu 	}
1303ec650989SNeel Natu 
1304ec650989SNeel Natu 	return (devscope->Length);
1305ec650989SNeel Natu }
1306ec650989SNeel Natu 
1307ec650989SNeel Natu static void
1308ec650989SNeel Natu acpi_handle_dmar_drhd(ACPI_DMAR_HARDWARE_UNIT *drhd)
1309ec650989SNeel Natu {
1310ec650989SNeel Natu 	char *cp;
1311ec650989SNeel Natu 	int remaining, consumed;
1312ec650989SNeel Natu 
1313ec650989SNeel Natu 	printf("\n");
1314ec650989SNeel Natu 	printf("\tType=DRHD\n");
1315ec650989SNeel Natu 	printf("\tLength=%d\n", drhd->Header.Length);
1316ec650989SNeel Natu 
1317ec650989SNeel Natu #define	PRINTFLAG(var, flag)	printflag((var), ACPI_DMAR_## flag, #flag)
1318ec650989SNeel Natu 
1319ec650989SNeel Natu 	printf("\tFlags=");
1320ec650989SNeel Natu 	PRINTFLAG(drhd->Flags, INCLUDE_ALL);
1321ec650989SNeel Natu 	PRINTFLAG_END();
1322ec650989SNeel Natu 
1323ec650989SNeel Natu #undef PRINTFLAG
1324ec650989SNeel Natu 
1325ec650989SNeel Natu 	printf("\tSegment=%d\n", drhd->Segment);
13267d369c6eSJung-uk Kim 	printf("\tAddress=0x%016jx\n", (uintmax_t)drhd->Address);
1327ec650989SNeel Natu 
1328ec650989SNeel Natu 	remaining = drhd->Header.Length - sizeof(ACPI_DMAR_HARDWARE_UNIT);
1329ec650989SNeel Natu 	if (remaining > 0)
1330ec650989SNeel Natu 		printf("\tDevice Scope:");
1331ec650989SNeel Natu 	while (remaining > 0) {
1332ec650989SNeel Natu 		cp = (char *)drhd + drhd->Header.Length - remaining;
1333ec650989SNeel Natu 		consumed = acpi_handle_dmar_devscope(cp, remaining);
1334ec650989SNeel Natu 		if (consumed <= 0)
1335ec650989SNeel Natu 			break;
1336ec650989SNeel Natu 		else
1337ec650989SNeel Natu 			remaining -= consumed;
1338ec650989SNeel Natu 	}
1339ec650989SNeel Natu }
1340ec650989SNeel Natu 
1341ec650989SNeel Natu static void
1342ec650989SNeel Natu acpi_handle_dmar_rmrr(ACPI_DMAR_RESERVED_MEMORY *rmrr)
1343ec650989SNeel Natu {
1344ec650989SNeel Natu 	char *cp;
1345ec650989SNeel Natu 	int remaining, consumed;
1346ec650989SNeel Natu 
1347ec650989SNeel Natu 	printf("\n");
1348ec650989SNeel Natu 	printf("\tType=RMRR\n");
1349ec650989SNeel Natu 	printf("\tLength=%d\n", rmrr->Header.Length);
1350ec650989SNeel Natu 	printf("\tSegment=%d\n", rmrr->Segment);
13517d369c6eSJung-uk Kim 	printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rmrr->BaseAddress);
13527d369c6eSJung-uk Kim 	printf("\tLimitAddress=0x%016jx\n", (uintmax_t)rmrr->EndAddress);
1353ec650989SNeel Natu 
1354ec650989SNeel Natu 	remaining = rmrr->Header.Length - sizeof(ACPI_DMAR_RESERVED_MEMORY);
1355ec650989SNeel Natu 	if (remaining > 0)
1356ec650989SNeel Natu 		printf("\tDevice Scope:");
1357ec650989SNeel Natu 	while (remaining > 0) {
1358ec650989SNeel Natu 		cp = (char *)rmrr + rmrr->Header.Length - remaining;
1359ec650989SNeel Natu 		consumed = acpi_handle_dmar_devscope(cp, remaining);
1360ec650989SNeel Natu 		if (consumed <= 0)
1361ec650989SNeel Natu 			break;
1362ec650989SNeel Natu 		else
1363ec650989SNeel Natu 			remaining -= consumed;
1364ec650989SNeel Natu 	}
1365ec650989SNeel Natu }
1366ec650989SNeel Natu 
1367ec650989SNeel Natu static void
1368ec650989SNeel Natu acpi_handle_dmar_atsr(ACPI_DMAR_ATSR *atsr)
1369ec650989SNeel Natu {
1370ec650989SNeel Natu 	char *cp;
1371ec650989SNeel Natu 	int remaining, consumed;
1372ec650989SNeel Natu 
1373ec650989SNeel Natu 	printf("\n");
1374ec650989SNeel Natu 	printf("\tType=ATSR\n");
1375ec650989SNeel Natu 	printf("\tLength=%d\n", atsr->Header.Length);
1376ec650989SNeel Natu 
1377ec650989SNeel Natu #define	PRINTFLAG(var, flag)	printflag((var), ACPI_DMAR_## flag, #flag)
1378ec650989SNeel Natu 
1379ec650989SNeel Natu 	printf("\tFlags=");
1380ec650989SNeel Natu 	PRINTFLAG(atsr->Flags, ALL_PORTS);
1381ec650989SNeel Natu 	PRINTFLAG_END();
1382ec650989SNeel Natu 
1383ec650989SNeel Natu #undef PRINTFLAG
1384ec650989SNeel Natu 
1385ec650989SNeel Natu 	printf("\tSegment=%d\n", atsr->Segment);
1386ec650989SNeel Natu 
1387ec650989SNeel Natu 	remaining = atsr->Header.Length - sizeof(ACPI_DMAR_ATSR);
1388ec650989SNeel Natu 	if (remaining > 0)
1389ec650989SNeel Natu 		printf("\tDevice Scope:");
1390ec650989SNeel Natu 	while (remaining > 0) {
1391ec650989SNeel Natu 		cp = (char *)atsr + atsr->Header.Length - remaining;
1392ec650989SNeel Natu 		consumed = acpi_handle_dmar_devscope(cp, remaining);
1393ec650989SNeel Natu 		if (consumed <= 0)
1394ec650989SNeel Natu 			break;
1395ec650989SNeel Natu 		else
1396ec650989SNeel Natu 			remaining -= consumed;
1397ec650989SNeel Natu 	}
1398ec650989SNeel Natu }
1399ec650989SNeel Natu 
1400ec650989SNeel Natu static void
1401ec650989SNeel Natu acpi_handle_dmar_rhsa(ACPI_DMAR_RHSA *rhsa)
1402ec650989SNeel Natu {
1403ec650989SNeel Natu 
1404ec650989SNeel Natu 	printf("\n");
1405ec650989SNeel Natu 	printf("\tType=RHSA\n");
1406ec650989SNeel Natu 	printf("\tLength=%d\n", rhsa->Header.Length);
14077d369c6eSJung-uk Kim 	printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rhsa->BaseAddress);
1408ec650989SNeel Natu 	printf("\tProximityDomain=0x%08x\n", rhsa->ProximityDomain);
1409ec650989SNeel Natu }
1410ec650989SNeel Natu 
1411ec650989SNeel Natu static int
1412ec650989SNeel Natu acpi_handle_dmar_remapping_structure(void *addr, int remaining)
1413ec650989SNeel Natu {
1414ec650989SNeel Natu 	ACPI_DMAR_HEADER *hdr = addr;
1415ec650989SNeel Natu 
1416ec650989SNeel Natu 	if (remaining < (int)sizeof(ACPI_DMAR_HEADER))
1417ec650989SNeel Natu 		return (-1);
1418ec650989SNeel Natu 
1419ec650989SNeel Natu 	if (remaining < hdr->Length)
1420ec650989SNeel Natu 		return (-1);
1421ec650989SNeel Natu 
1422ec650989SNeel Natu 	switch (hdr->Type) {
1423ec650989SNeel Natu 	case ACPI_DMAR_TYPE_HARDWARE_UNIT:
1424ec650989SNeel Natu 		acpi_handle_dmar_drhd(addr);
1425ec650989SNeel Natu 		break;
1426ec650989SNeel Natu 	case ACPI_DMAR_TYPE_RESERVED_MEMORY:
1427ec650989SNeel Natu 		acpi_handle_dmar_rmrr(addr);
1428ec650989SNeel Natu 		break;
1429313a0c13SJung-uk Kim 	case ACPI_DMAR_TYPE_ROOT_ATS:
1430ec650989SNeel Natu 		acpi_handle_dmar_atsr(addr);
1431ec650989SNeel Natu 		break;
1432313a0c13SJung-uk Kim 	case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
1433ec650989SNeel Natu 		acpi_handle_dmar_rhsa(addr);
1434ec650989SNeel Natu 		break;
1435ec650989SNeel Natu 	default:
1436ec650989SNeel Natu 		printf("\n");
1437ec650989SNeel Natu 		printf("\tType=%d\n", hdr->Type);
1438ec650989SNeel Natu 		printf("\tLength=%d\n", hdr->Length);
1439ec650989SNeel Natu 		break;
1440ec650989SNeel Natu 	}
1441ec650989SNeel Natu 	return (hdr->Length);
1442ec650989SNeel Natu }
1443ec650989SNeel Natu 
1444ec650989SNeel Natu #ifndef ACPI_DMAR_X2APIC_OPT_OUT
1445ec650989SNeel Natu #define	ACPI_DMAR_X2APIC_OPT_OUT	(0x2)
1446ec650989SNeel Natu #endif
1447ec650989SNeel Natu 
1448ec650989SNeel Natu static void
1449ec650989SNeel Natu acpi_handle_dmar(ACPI_TABLE_HEADER *sdp)
1450ec650989SNeel Natu {
1451ec650989SNeel Natu 	char *cp;
1452ec650989SNeel Natu 	int remaining, consumed;
1453ec650989SNeel Natu 	ACPI_TABLE_DMAR *dmar;
1454ec650989SNeel Natu 
1455ec650989SNeel Natu 	printf(BEGIN_COMMENT);
1456ec650989SNeel Natu 	acpi_print_sdt(sdp);
1457ec650989SNeel Natu 	dmar = (ACPI_TABLE_DMAR *)sdp;
1458ec650989SNeel Natu 	printf("\tHost Address Width=%d\n", dmar->Width + 1);
1459ec650989SNeel Natu 
1460ec650989SNeel Natu #define PRINTFLAG(var, flag)	printflag((var), ACPI_DMAR_## flag, #flag)
1461ec650989SNeel Natu 
1462ec650989SNeel Natu 	printf("\tFlags=");
1463ec650989SNeel Natu 	PRINTFLAG(dmar->Flags, INTR_REMAP);
1464ec650989SNeel Natu 	PRINTFLAG(dmar->Flags, X2APIC_OPT_OUT);
1465ec650989SNeel Natu 	PRINTFLAG_END();
1466ec650989SNeel Natu 
1467ec650989SNeel Natu #undef PRINTFLAG
1468ec650989SNeel Natu 
1469ec650989SNeel Natu 	remaining = sdp->Length - sizeof(ACPI_TABLE_DMAR);
1470ec650989SNeel Natu 	while (remaining > 0) {
1471ec650989SNeel Natu 		cp = (char *)sdp + sdp->Length - remaining;
1472ec650989SNeel Natu 		consumed = acpi_handle_dmar_remapping_structure(cp, remaining);
1473ec650989SNeel Natu 		if (consumed <= 0)
1474ec650989SNeel Natu 			break;
1475ec650989SNeel Natu 		else
1476ec650989SNeel Natu 			remaining -= consumed;
1477ec650989SNeel Natu 	}
1478ec650989SNeel Natu 
1479ec650989SNeel Natu 	printf(END_COMMENT);
1480ec650989SNeel Natu }
1481ec650989SNeel Natu 
1482a0333ad1SJohn Baldwin static void
1483986dffafSJohn Baldwin acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp)
1484a0333ad1SJohn Baldwin {
1485a0333ad1SJohn Baldwin 
1486a0333ad1SJohn Baldwin 	printf("\tFlags={");
1487986dffafSJohn Baldwin 	if (mp->Flags & ACPI_SRAT_MEM_ENABLED)
1488a0333ad1SJohn Baldwin 		printf("ENABLED");
1489a0333ad1SJohn Baldwin 	else
1490a0333ad1SJohn Baldwin 		printf("DISABLED");
1491986dffafSJohn Baldwin 	if (mp->Flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)
1492a0333ad1SJohn Baldwin 		printf(",HOT_PLUGGABLE");
1493986dffafSJohn Baldwin 	if (mp->Flags & ACPI_SRAT_MEM_NON_VOLATILE)
1494a0333ad1SJohn Baldwin 		printf(",NON_VOLATILE");
1495a0333ad1SJohn Baldwin 	printf("}\n");
1496986dffafSJohn Baldwin 	printf("\tBase Address=0x%016jx\n", (uintmax_t)mp->BaseAddress);
1497986dffafSJohn Baldwin 	printf("\tLength=0x%016jx\n", (uintmax_t)mp->Length);
1498986dffafSJohn Baldwin 	printf("\tProximity Domain=%d\n", mp->ProximityDomain);
1499a0333ad1SJohn Baldwin }
1500a0333ad1SJohn Baldwin 
150127941afaSEd Maste static const char *srat_types[] = {
150227941afaSEd Maste     [ACPI_SRAT_TYPE_CPU_AFFINITY] = "CPU",
150327941afaSEd Maste     [ACPI_SRAT_TYPE_MEMORY_AFFINITY] = "Memory",
150427941afaSEd Maste     [ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY] = "X2APIC",
1505cebb7b19SEd Maste     [ACPI_SRAT_TYPE_GICC_AFFINITY] = "GICC",
1506cebb7b19SEd Maste     [ACPI_SRAT_TYPE_GIC_ITS_AFFINITY] = "GIC ITS",
150727941afaSEd Maste };
1508a0333ad1SJohn Baldwin 
1509a0333ad1SJohn Baldwin static void
1510986dffafSJohn Baldwin acpi_print_srat(ACPI_SUBTABLE_HEADER *srat)
1511a0333ad1SJohn Baldwin {
1512986dffafSJohn Baldwin 	ACPI_SRAT_CPU_AFFINITY *cpu;
1513986dffafSJohn Baldwin 	ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic;
15142b2b1f42SAndrew Turner 	ACPI_SRAT_GICC_AFFINITY *gic;
1515a0333ad1SJohn Baldwin 
1516c86932b6SMarcelo Araujo 	if (srat->Type < nitems(srat_types))
1517986dffafSJohn Baldwin 		printf("\tType=%s\n", srat_types[srat->Type]);
1518a0333ad1SJohn Baldwin 	else
1519986dffafSJohn Baldwin 		printf("\tType=%d (unknown)\n", srat->Type);
1520986dffafSJohn Baldwin 	switch (srat->Type) {
1521a0333ad1SJohn Baldwin 	case ACPI_SRAT_TYPE_CPU_AFFINITY:
1522986dffafSJohn Baldwin 		cpu = (ACPI_SRAT_CPU_AFFINITY *)srat;
1523986dffafSJohn Baldwin 		acpi_print_srat_cpu(cpu->ApicId,
1524986dffafSJohn Baldwin 		    cpu->ProximityDomainHi[2] << 24 |
1525986dffafSJohn Baldwin 		    cpu->ProximityDomainHi[1] << 16 |
1526986dffafSJohn Baldwin 		    cpu->ProximityDomainHi[0] << 0 |
1527986dffafSJohn Baldwin 		    cpu->ProximityDomainLo, cpu->Flags);
1528a0333ad1SJohn Baldwin 		break;
1529a0333ad1SJohn Baldwin 	case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
1530986dffafSJohn Baldwin 		acpi_print_srat_memory((ACPI_SRAT_MEM_AFFINITY *)srat);
1531a0333ad1SJohn Baldwin 		break;
1532a0333ad1SJohn Baldwin 	case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
1533986dffafSJohn Baldwin 		x2apic = (ACPI_SRAT_X2APIC_CPU_AFFINITY *)srat;
1534986dffafSJohn Baldwin 		acpi_print_srat_cpu(x2apic->ApicId, x2apic->ProximityDomain,
1535986dffafSJohn Baldwin 		    x2apic->Flags);
1536a0333ad1SJohn Baldwin 		break;
15372b2b1f42SAndrew Turner 	case ACPI_SRAT_TYPE_GICC_AFFINITY:
15382b2b1f42SAndrew Turner 		gic = (ACPI_SRAT_GICC_AFFINITY *)srat;
15392b2b1f42SAndrew Turner 		acpi_print_srat_cpu(gic->AcpiProcessorUid, gic->ProximityDomain,
15402b2b1f42SAndrew Turner 		    gic->Flags);
15412b2b1f42SAndrew Turner 		break;
1542a0333ad1SJohn Baldwin 	}
1543a0333ad1SJohn Baldwin }
1544a0333ad1SJohn Baldwin 
1545a0333ad1SJohn Baldwin static void
1546986dffafSJohn Baldwin acpi_handle_srat(ACPI_TABLE_HEADER *sdp)
1547a0333ad1SJohn Baldwin {
1548986dffafSJohn Baldwin 	ACPI_TABLE_SRAT *srat;
1549a0333ad1SJohn Baldwin 
1550a0333ad1SJohn Baldwin 	printf(BEGIN_COMMENT);
1551a0333ad1SJohn Baldwin 	acpi_print_sdt(sdp);
1552986dffafSJohn Baldwin 	srat = (ACPI_TABLE_SRAT *)sdp;
1553986dffafSJohn Baldwin 	printf("\tTable Revision=%d\n", srat->TableRevision);
1554986dffafSJohn Baldwin 	acpi_walk_subtables(sdp, (srat + 1), acpi_print_srat);
1555a0333ad1SJohn Baldwin 	printf(END_COMMENT);
1556a0333ad1SJohn Baldwin }
1557a0333ad1SJohn Baldwin 
1558340c0022SEd Maste static const char *nfit_types[] = {
1559340c0022SEd Maste     [ACPI_NFIT_TYPE_SYSTEM_ADDRESS] = "System Address",
1560340c0022SEd Maste     [ACPI_NFIT_TYPE_MEMORY_MAP] = "Memory Map",
1561340c0022SEd Maste     [ACPI_NFIT_TYPE_INTERLEAVE] = "Interleave",
1562340c0022SEd Maste     [ACPI_NFIT_TYPE_SMBIOS] = "SMBIOS",
1563340c0022SEd Maste     [ACPI_NFIT_TYPE_CONTROL_REGION] = "Control Region",
1564340c0022SEd Maste     [ACPI_NFIT_TYPE_DATA_REGION] = "Data Region",
15651b109c69SAlexander Motin     [ACPI_NFIT_TYPE_FLUSH_ADDRESS] = "Flush Address",
15661b109c69SAlexander Motin     [ACPI_NFIT_TYPE_CAPABILITIES] = "Platform Capabilities"
1567340c0022SEd Maste };
1568340c0022SEd Maste 
1569340c0022SEd Maste 
1570340c0022SEd Maste static void
1571340c0022SEd Maste acpi_print_nfit(ACPI_NFIT_HEADER *nfit)
1572340c0022SEd Maste {
1573340c0022SEd Maste 	char *uuidstr;
1574340c0022SEd Maste 	uint32_t status;
1575340c0022SEd Maste 
1576340c0022SEd Maste 	ACPI_NFIT_SYSTEM_ADDRESS *sysaddr;
1577340c0022SEd Maste 	ACPI_NFIT_MEMORY_MAP *mmap;
1578340c0022SEd Maste 	ACPI_NFIT_INTERLEAVE *ileave;
1579340c0022SEd Maste 	ACPI_NFIT_SMBIOS *smbios;
1580340c0022SEd Maste 	ACPI_NFIT_CONTROL_REGION *ctlreg;
1581340c0022SEd Maste 	ACPI_NFIT_DATA_REGION *datareg;
1582340c0022SEd Maste 	ACPI_NFIT_FLUSH_ADDRESS *fladdr;
15831b109c69SAlexander Motin 	ACPI_NFIT_CAPABILITIES *caps;
1584340c0022SEd Maste 
1585340c0022SEd Maste 	if (nfit->Type < nitems(nfit_types))
1586340c0022SEd Maste 		printf("\tType=%s\n", nfit_types[nfit->Type]);
1587340c0022SEd Maste 	else
1588340c0022SEd Maste 		printf("\tType=%u (unknown)\n", nfit->Type);
1589340c0022SEd Maste 	switch (nfit->Type) {
1590340c0022SEd Maste 	case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
1591340c0022SEd Maste 		sysaddr = (ACPI_NFIT_SYSTEM_ADDRESS *)nfit;
1592340c0022SEd Maste 		printf("\tRangeIndex=%u\n", (u_int)sysaddr->RangeIndex);
1593340c0022SEd Maste 		printf("\tProximityDomain=%u\n",
1594340c0022SEd Maste 		    (u_int)sysaddr->ProximityDomain);
1595340c0022SEd Maste 		uuid_to_string((uuid_t *)(sysaddr->RangeGuid),
1596340c0022SEd Maste 		    &uuidstr, &status);
1597340c0022SEd Maste 		if (status != uuid_s_ok)
1598340c0022SEd Maste 			errx(1, "uuid_to_string: status=%u", status);
1599340c0022SEd Maste 		printf("\tRangeGuid=%s\n", uuidstr);
1600340c0022SEd Maste 		free(uuidstr);
1601340c0022SEd Maste 		printf("\tAddress=0x%016jx\n", (uintmax_t)sysaddr->Address);
1602340c0022SEd Maste 		printf("\tLength=0x%016jx\n", (uintmax_t)sysaddr->Length);
1603340c0022SEd Maste 		printf("\tMemoryMapping=0x%016jx\n",
1604340c0022SEd Maste 		    (uintmax_t)sysaddr->MemoryMapping);
1605340c0022SEd Maste 
1606340c0022SEd Maste #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_## flag, #flag)
1607340c0022SEd Maste 
1608340c0022SEd Maste 		printf("\tFlags=");
1609340c0022SEd Maste 		PRINTFLAG(sysaddr->Flags, ADD_ONLINE_ONLY);
1610340c0022SEd Maste 		PRINTFLAG(sysaddr->Flags, PROXIMITY_VALID);
1611340c0022SEd Maste 		PRINTFLAG_END();
1612340c0022SEd Maste 
1613340c0022SEd Maste #undef PRINTFLAG
1614340c0022SEd Maste 
1615340c0022SEd Maste 		break;
1616340c0022SEd Maste 	case ACPI_NFIT_TYPE_MEMORY_MAP:
1617340c0022SEd Maste 		mmap = (ACPI_NFIT_MEMORY_MAP *)nfit;
1618340c0022SEd Maste 		printf("\tDeviceHandle=%u\n", (u_int)mmap->DeviceHandle);
1619340c0022SEd Maste 		printf("\tPhysicalId=%u\n", (u_int)mmap->PhysicalId);
1620340c0022SEd Maste 		printf("\tRegionId=%u\n", (u_int)mmap->RegionId);
1621340c0022SEd Maste 		printf("\tRangeIndex=%u\n", (u_int)mmap->RangeIndex);
1622340c0022SEd Maste 		printf("\tRegionIndex=%u\n", (u_int)mmap->RegionIndex);
1623340c0022SEd Maste 		printf("\tRegionSize=0x%016jx\n", (uintmax_t)mmap->RegionSize);
1624340c0022SEd Maste 		printf("\tRegionOffset=0x%016jx\n",
1625340c0022SEd Maste 		    (uintmax_t)mmap->RegionOffset);
1626340c0022SEd Maste 		printf("\tAddress=0x%016jx\n", (uintmax_t)mmap->Address);
1627340c0022SEd Maste 		printf("\tInterleaveIndex=%u\n", (u_int)mmap->InterleaveIndex);
1628fb1cf2a9SAlexander Motin 		printf("\tInterleaveWays=%u\n", (u_int)mmap->InterleaveWays);
1629340c0022SEd Maste 
1630340c0022SEd Maste #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_MEM_## flag, #flag)
1631340c0022SEd Maste 
1632340c0022SEd Maste 		printf("\tFlags=");
1633340c0022SEd Maste 		PRINTFLAG(mmap->Flags, SAVE_FAILED);
1634340c0022SEd Maste 		PRINTFLAG(mmap->Flags, RESTORE_FAILED);
1635340c0022SEd Maste 		PRINTFLAG(mmap->Flags, FLUSH_FAILED);
1636340c0022SEd Maste 		PRINTFLAG(mmap->Flags, NOT_ARMED);
1637340c0022SEd Maste 		PRINTFLAG(mmap->Flags, HEALTH_OBSERVED);
1638340c0022SEd Maste 		PRINTFLAG(mmap->Flags, HEALTH_ENABLED);
1639340c0022SEd Maste 		PRINTFLAG(mmap->Flags, MAP_FAILED);
1640340c0022SEd Maste 		PRINTFLAG_END();
1641340c0022SEd Maste 
1642340c0022SEd Maste #undef PRINTFLAG
1643340c0022SEd Maste 
1644340c0022SEd Maste 		break;
1645340c0022SEd Maste 	case ACPI_NFIT_TYPE_INTERLEAVE:
1646340c0022SEd Maste 		ileave = (ACPI_NFIT_INTERLEAVE *)nfit;
1647340c0022SEd Maste 		printf("\tInterleaveIndex=%u\n",
1648340c0022SEd Maste 		    (u_int)ileave->InterleaveIndex);
1649340c0022SEd Maste 		printf("\tLineCount=%u\n", (u_int)ileave->LineCount);
1650340c0022SEd Maste 		printf("\tLineSize=%u\n", (u_int)ileave->LineSize);
1651340c0022SEd Maste 		/* XXX ileave->LineOffset[i] output is not supported */
1652340c0022SEd Maste 		break;
1653340c0022SEd Maste 	case ACPI_NFIT_TYPE_SMBIOS:
1654340c0022SEd Maste 		smbios = (ACPI_NFIT_SMBIOS *)nfit;
1655340c0022SEd Maste 		/* XXX smbios->Data[x] output is not supported */
1656340c0022SEd Maste 		break;
1657340c0022SEd Maste 	case ACPI_NFIT_TYPE_CONTROL_REGION:
1658340c0022SEd Maste 		ctlreg = (ACPI_NFIT_CONTROL_REGION *)nfit;
1659340c0022SEd Maste 		printf("\tRegionIndex=%u\n", (u_int)ctlreg->RegionIndex);
1660340c0022SEd Maste 		printf("\tVendorId=0x%04x\n", (u_int)ctlreg->VendorId);
1661340c0022SEd Maste 		printf("\tDeviceId=0x%04x\n", (u_int)ctlreg->DeviceId);
1662*35e39fd9SAlexander Motin 		printf("\tRevisionId=0x%02x\n", (u_int)ctlreg->RevisionId);
1663340c0022SEd Maste 		printf("\tSubsystemVendorId=0x%04x\n",
1664340c0022SEd Maste 		    (u_int)ctlreg->SubsystemVendorId);
1665340c0022SEd Maste 		printf("\tSubsystemDeviceId=0x%04x\n",
1666340c0022SEd Maste 		    (u_int)ctlreg->SubsystemDeviceId);
1667*35e39fd9SAlexander Motin 		printf("\tSubsystemRevisionId=0x%02x\n",
1668340c0022SEd Maste 		    (u_int)ctlreg->SubsystemRevisionId);
1669d4c2de2eSAlexander Motin 		printf("\tValidFields=0x%02x\n", (u_int)ctlreg->ValidFields);
1670*35e39fd9SAlexander Motin 		printf("\tManufacturingLocation=0x%02x\n",
1671340c0022SEd Maste 		    (u_int)ctlreg->ManufacturingLocation);
1672*35e39fd9SAlexander Motin 		printf("\tManufacturingDate=%04x\n",
1673*35e39fd9SAlexander Motin 		    (u_int)be16toh(ctlreg->ManufacturingDate));
1674*35e39fd9SAlexander Motin 		printf("\tSerialNumber=%08X\n",
1675*35e39fd9SAlexander Motin 		    (u_int)be32toh(ctlreg->SerialNumber));
1676fb1cf2a9SAlexander Motin 		printf("\tCode=0x%04x\n", (u_int)ctlreg->Code);
1677340c0022SEd Maste 		printf("\tWindows=%u\n", (u_int)ctlreg->Windows);
1678340c0022SEd Maste 		printf("\tWindowSize=0x%016jx\n",
1679340c0022SEd Maste 		    (uintmax_t)ctlreg->WindowSize);
1680340c0022SEd Maste 		printf("\tCommandOffset=0x%016jx\n",
1681340c0022SEd Maste 		    (uintmax_t)ctlreg->CommandOffset);
1682340c0022SEd Maste 		printf("\tCommandSize=0x%016jx\n",
1683340c0022SEd Maste 		    (uintmax_t)ctlreg->CommandSize);
1684340c0022SEd Maste 		printf("\tStatusOffset=0x%016jx\n",
1685340c0022SEd Maste 		    (uintmax_t)ctlreg->StatusOffset);
1686340c0022SEd Maste 		printf("\tStatusSize=0x%016jx\n",
1687340c0022SEd Maste 		    (uintmax_t)ctlreg->StatusSize);
1688340c0022SEd Maste 
1689340c0022SEd Maste #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_## flag, #flag)
1690340c0022SEd Maste 
1691340c0022SEd Maste 		printf("\tFlags=");
1692d4c2de2eSAlexander Motin 		PRINTFLAG(ctlreg->Flags, CONTROL_BUFFERED);
1693340c0022SEd Maste 		PRINTFLAG_END();
1694340c0022SEd Maste 
1695340c0022SEd Maste #undef PRINTFLAG
1696340c0022SEd Maste 
1697340c0022SEd Maste 		break;
1698340c0022SEd Maste 	case ACPI_NFIT_TYPE_DATA_REGION:
1699340c0022SEd Maste 		datareg = (ACPI_NFIT_DATA_REGION *)nfit;
1700340c0022SEd Maste 		printf("\tRegionIndex=%u\n", (u_int)datareg->RegionIndex);
1701340c0022SEd Maste 		printf("\tWindows=%u\n", (u_int)datareg->Windows);
1702340c0022SEd Maste 		printf("\tOffset=0x%016jx\n", (uintmax_t)datareg->Offset);
1703340c0022SEd Maste 		printf("\tSize=0x%016jx\n", (uintmax_t)datareg->Size);
1704340c0022SEd Maste 		printf("\tCapacity=0x%016jx\n", (uintmax_t)datareg->Capacity);
1705340c0022SEd Maste 		printf("\tStartAddress=0x%016jx\n",
1706340c0022SEd Maste 		    (uintmax_t)datareg->StartAddress);
1707340c0022SEd Maste 		break;
1708340c0022SEd Maste 	case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
1709340c0022SEd Maste 		fladdr = (ACPI_NFIT_FLUSH_ADDRESS *)nfit;
1710340c0022SEd Maste 		printf("\tDeviceHandle=%u\n", (u_int)fladdr->DeviceHandle);
1711340c0022SEd Maste 		printf("\tHintCount=%u\n", (u_int)fladdr->HintCount);
1712340c0022SEd Maste 		/* XXX fladdr->HintAddress[i] output is not supported */
1713340c0022SEd Maste 		break;
17141b109c69SAlexander Motin 	case ACPI_NFIT_TYPE_CAPABILITIES:
17151b109c69SAlexander Motin 		caps = (ACPI_NFIT_CAPABILITIES *)nfit;
17161b109c69SAlexander Motin 		printf("\tHighestCapability=%u\n", (u_int)caps->HighestCapability);
17171b109c69SAlexander Motin 
17181b109c69SAlexander Motin #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_CAPABILITY_## flag, #flag)
17191b109c69SAlexander Motin 
17201b109c69SAlexander Motin 		printf("\tCapabilities=");
17211b109c69SAlexander Motin 		PRINTFLAG(caps->Capabilities, CACHE_FLUSH);
17221b109c69SAlexander Motin 		PRINTFLAG(caps->Capabilities, MEM_FLUSH);
17231b109c69SAlexander Motin 		PRINTFLAG(caps->Capabilities, MEM_MIRRORING);
17241b109c69SAlexander Motin 		PRINTFLAG_END();
17251b109c69SAlexander Motin 
17261b109c69SAlexander Motin #undef PRINTFLAG
17271b109c69SAlexander Motin 		break;
1728340c0022SEd Maste 	}
1729340c0022SEd Maste }
1730340c0022SEd Maste 
1731340c0022SEd Maste static void
1732340c0022SEd Maste acpi_handle_nfit(ACPI_TABLE_HEADER *sdp)
1733340c0022SEd Maste {
1734340c0022SEd Maste 	ACPI_TABLE_NFIT *nfit;
1735340c0022SEd Maste 
1736340c0022SEd Maste 	printf(BEGIN_COMMENT);
1737340c0022SEd Maste 	acpi_print_sdt(sdp);
1738340c0022SEd Maste 	nfit = (ACPI_TABLE_NFIT *)sdp;
1739340c0022SEd Maste 	acpi_walk_nfit(sdp, (nfit + 1), acpi_print_nfit);
1740340c0022SEd Maste 	printf(END_COMMENT);
1741340c0022SEd Maste }
1742340c0022SEd Maste 
1743a0333ad1SJohn Baldwin static void
1744986dffafSJohn Baldwin acpi_print_sdt(ACPI_TABLE_HEADER *sdp)
1745c62f1cccSMitsuru IWASAKI {
1746773b6454SNate Lawson 	printf("  ");
1747278f0de6SJung-uk Kim 	acpi_print_string(sdp->Signature, ACPI_NAMESEG_SIZE);
1748c62f1cccSMitsuru IWASAKI 	printf(": Length=%d, Revision=%d, Checksum=%d,\n",
1749986dffafSJohn Baldwin 	       sdp->Length, sdp->Revision, sdp->Checksum);
1750e1e9a4bfSMitsuru IWASAKI 	printf("\tOEMID=");
1751986dffafSJohn Baldwin 	acpi_print_string(sdp->OemId, ACPI_OEM_ID_SIZE);
1752e1e9a4bfSMitsuru IWASAKI 	printf(", OEM Table ID=");
1753986dffafSJohn Baldwin 	acpi_print_string(sdp->OemTableId, ACPI_OEM_TABLE_ID_SIZE);
1754986dffafSJohn Baldwin 	printf(", OEM Revision=0x%x,\n", sdp->OemRevision);
1755e1e9a4bfSMitsuru IWASAKI 	printf("\tCreator ID=");
1756278f0de6SJung-uk Kim 	acpi_print_string(sdp->AslCompilerId, ACPI_NAMESEG_SIZE);
1757986dffafSJohn Baldwin 	printf(", Creator Revision=0x%x\n", sdp->AslCompilerRevision);
1758e1e9a4bfSMitsuru IWASAKI }
1759e1e9a4bfSMitsuru IWASAKI 
1760945137d9SNate Lawson static void
1761986dffafSJohn Baldwin acpi_print_rsdt(ACPI_TABLE_HEADER *rsdp)
1762e1e9a4bfSMitsuru IWASAKI {
1763986dffafSJohn Baldwin 	ACPI_TABLE_RSDT *rsdt;
1764986dffafSJohn Baldwin 	ACPI_TABLE_XSDT *xsdt;
1765e1e9a4bfSMitsuru IWASAKI 	int	i, entries;
1766e1e9a4bfSMitsuru IWASAKI 
1767986dffafSJohn Baldwin 	rsdt = (ACPI_TABLE_RSDT *)rsdp;
1768986dffafSJohn Baldwin 	xsdt = (ACPI_TABLE_XSDT *)rsdp;
1769773b6454SNate Lawson 	printf(BEGIN_COMMENT);
1770773b6454SNate Lawson 	acpi_print_sdt(rsdp);
1771986dffafSJohn Baldwin 	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
1772e1e9a4bfSMitsuru IWASAKI 	printf("\tEntries={ ");
1773e1e9a4bfSMitsuru IWASAKI 	for (i = 0; i < entries; i++) {
1774e1e9a4bfSMitsuru IWASAKI 		if (i > 0)
1775e1e9a4bfSMitsuru IWASAKI 			printf(", ");
1776fe1d0c2dSJung-uk Kim 		if (addr_size == 4)
17777d369c6eSJung-uk Kim 			printf("0x%08x", le32toh(rsdt->TableOffsetEntry[i]));
1778fe1d0c2dSJung-uk Kim 		else
17797d369c6eSJung-uk Kim 			printf("0x%016jx",
17807d369c6eSJung-uk Kim 			    (uintmax_t)le64toh(xsdt->TableOffsetEntry[i]));
1781e1e9a4bfSMitsuru IWASAKI 	}
1782e1e9a4bfSMitsuru IWASAKI 	printf(" }\n");
1783c62f1cccSMitsuru IWASAKI 	printf(END_COMMENT);
1784e1e9a4bfSMitsuru IWASAKI }
1785e1e9a4bfSMitsuru IWASAKI 
17868e6a8737SNate Lawson static const char *acpi_pm_profiles[] = {
17878e6a8737SNate Lawson 	"Unspecified", "Desktop", "Mobile", "Workstation",
17888e6a8737SNate Lawson 	"Enterprise Server", "SOHO Server", "Appliance PC"
17898e6a8737SNate Lawson };
17908e6a8737SNate Lawson 
1791945137d9SNate Lawson static void
1792986dffafSJohn Baldwin acpi_print_fadt(ACPI_TABLE_HEADER *sdp)
1793e1e9a4bfSMitsuru IWASAKI {
1794986dffafSJohn Baldwin 	ACPI_TABLE_FADT *fadt;
17958e6a8737SNate Lawson 	const char *pm;
1796e1e9a4bfSMitsuru IWASAKI 
1797986dffafSJohn Baldwin 	fadt = (ACPI_TABLE_FADT *)sdp;
1798c62f1cccSMitsuru IWASAKI 	printf(BEGIN_COMMENT);
17992177d4e6SNate Lawson 	acpi_print_sdt(sdp);
1800986dffafSJohn Baldwin 	printf(" \tFACS=0x%x, DSDT=0x%x\n", fadt->Facs,
1801986dffafSJohn Baldwin 	       fadt->Dsdt);
1802986dffafSJohn Baldwin 	printf("\tINT_MODEL=%s\n", fadt->Model ? "APIC" : "PIC");
1803986dffafSJohn Baldwin 	if (fadt->PreferredProfile >= sizeof(acpi_pm_profiles) / sizeof(char *))
18048e6a8737SNate Lawson 		pm = "Reserved";
18058e6a8737SNate Lawson 	else
1806986dffafSJohn Baldwin 		pm = acpi_pm_profiles[fadt->PreferredProfile];
1807986dffafSJohn Baldwin 	printf("\tPreferred_PM_Profile=%s (%d)\n", pm, fadt->PreferredProfile);
1808986dffafSJohn Baldwin 	printf("\tSCI_INT=%d\n", fadt->SciInterrupt);
1809986dffafSJohn Baldwin 	printf("\tSMI_CMD=0x%x, ", fadt->SmiCommand);
1810986dffafSJohn Baldwin 	printf("ACPI_ENABLE=0x%x, ", fadt->AcpiEnable);
1811986dffafSJohn Baldwin 	printf("ACPI_DISABLE=0x%x, ", fadt->AcpiDisable);
1812986dffafSJohn Baldwin 	printf("S4BIOS_REQ=0x%x\n", fadt->S4BiosRequest);
1813986dffafSJohn Baldwin 	printf("\tPSTATE_CNT=0x%x\n", fadt->PstateControl);
1814e1e9a4bfSMitsuru IWASAKI 	printf("\tPM1a_EVT_BLK=0x%x-0x%x\n",
1815986dffafSJohn Baldwin 	       fadt->Pm1aEventBlock,
1816986dffafSJohn Baldwin 	       fadt->Pm1aEventBlock + fadt->Pm1EventLength - 1);
1817986dffafSJohn Baldwin 	if (fadt->Pm1bEventBlock != 0)
1818e1e9a4bfSMitsuru IWASAKI 		printf("\tPM1b_EVT_BLK=0x%x-0x%x\n",
1819986dffafSJohn Baldwin 		       fadt->Pm1bEventBlock,
1820986dffafSJohn Baldwin 		       fadt->Pm1bEventBlock + fadt->Pm1EventLength - 1);
1821e1e9a4bfSMitsuru IWASAKI 	printf("\tPM1a_CNT_BLK=0x%x-0x%x\n",
1822986dffafSJohn Baldwin 	       fadt->Pm1aControlBlock,
1823986dffafSJohn Baldwin 	       fadt->Pm1aControlBlock + fadt->Pm1ControlLength - 1);
1824986dffafSJohn Baldwin 	if (fadt->Pm1bControlBlock != 0)
1825e1e9a4bfSMitsuru IWASAKI 		printf("\tPM1b_CNT_BLK=0x%x-0x%x\n",
1826986dffafSJohn Baldwin 		       fadt->Pm1bControlBlock,
1827986dffafSJohn Baldwin 		       fadt->Pm1bControlBlock + fadt->Pm1ControlLength - 1);
1828986dffafSJohn Baldwin 	if (fadt->Pm2ControlBlock != 0)
1829e1e9a4bfSMitsuru IWASAKI 		printf("\tPM2_CNT_BLK=0x%x-0x%x\n",
1830986dffafSJohn Baldwin 		       fadt->Pm2ControlBlock,
1831986dffafSJohn Baldwin 		       fadt->Pm2ControlBlock + fadt->Pm2ControlLength - 1);
1832c08c4e81SNate Lawson 	printf("\tPM_TMR_BLK=0x%x-0x%x\n",
1833986dffafSJohn Baldwin 	       fadt->PmTimerBlock,
1834986dffafSJohn Baldwin 	       fadt->PmTimerBlock + fadt->PmTimerLength - 1);
1835986dffafSJohn Baldwin 	if (fadt->Gpe0Block != 0)
18368e6a8737SNate Lawson 		printf("\tGPE0_BLK=0x%x-0x%x\n",
1837986dffafSJohn Baldwin 		       fadt->Gpe0Block,
1838986dffafSJohn Baldwin 		       fadt->Gpe0Block + fadt->Gpe0BlockLength - 1);
1839986dffafSJohn Baldwin 	if (fadt->Gpe1Block != 0)
18408e6a8737SNate Lawson 		printf("\tGPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n",
1841986dffafSJohn Baldwin 		       fadt->Gpe1Block,
1842986dffafSJohn Baldwin 		       fadt->Gpe1Block + fadt->Gpe1BlockLength - 1,
1843986dffafSJohn Baldwin 		       fadt->Gpe1Base);
1844986dffafSJohn Baldwin 	if (fadt->CstControl != 0)
1845986dffafSJohn Baldwin 		printf("\tCST_CNT=0x%x\n", fadt->CstControl);
184651c1824fSNate Lawson 	printf("\tP_LVL2_LAT=%d us, P_LVL3_LAT=%d us\n",
1847986dffafSJohn Baldwin 	       fadt->C2Latency, fadt->C3Latency);
1848e1e9a4bfSMitsuru IWASAKI 	printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n",
1849986dffafSJohn Baldwin 	       fadt->FlushSize, fadt->FlushStride);
1850e1e9a4bfSMitsuru IWASAKI 	printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n",
1851986dffafSJohn Baldwin 	       fadt->DutyOffset, fadt->DutyWidth);
1852e1e9a4bfSMitsuru IWASAKI 	printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n",
1853986dffafSJohn Baldwin 	       fadt->DayAlarm, fadt->MonthAlarm, fadt->Century);
1854e1e9a4bfSMitsuru IWASAKI 
1855ec650989SNeel Natu #define PRINTFLAG(var, flag)	printflag((var), ACPI_FADT_## flag, #flag)
1856e1e9a4bfSMitsuru IWASAKI 
18578e6a8737SNate Lawson 	printf("\tIAPC_BOOT_ARCH=");
1858986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, LEGACY_DEVICES);
1859986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, 8042);
1860986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, NO_VGA);
1861986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, NO_MSI);
1862986dffafSJohn Baldwin 	PRINTFLAG(fadt->BootFlags, NO_ASPM);
1863f6469ce1SAndrew Turner 	PRINTFLAG(fadt->BootFlags, NO_CMOS_RTC);
1864ec650989SNeel Natu 	PRINTFLAG_END();
18658e6a8737SNate Lawson 
18668e6a8737SNate Lawson 	printf("\tFlags=");
1867986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, WBINVD);
1868986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, WBINVD_FLUSH);
1869986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, C1_SUPPORTED);
1870986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, C2_MP_SUPPORTED);
1871986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, POWER_BUTTON);
1872986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, SLEEP_BUTTON);
1873986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, FIXED_RTC);
1874986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, S4_RTC_WAKE);
1875986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, 32BIT_TIMER);
1876986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, DOCKING_SUPPORTED);
1877986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, RESET_REGISTER);
1878986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, SEALED_CASE);
1879986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, HEADLESS);
1880986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, SLEEP_TYPE);
1881986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, PCI_EXPRESS_WAKE);
1882986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, PLATFORM_CLOCK);
1883986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, S4_RTC_VALID);
1884986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, REMOTE_POWER_ON);
1885986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, APIC_CLUSTER);
1886986dffafSJohn Baldwin 	PRINTFLAG(fadt->Flags, APIC_PHYSICAL);
1887f6469ce1SAndrew Turner 	PRINTFLAG(fadt->Flags, HW_REDUCED);
1888f6469ce1SAndrew Turner 	PRINTFLAG(fadt->Flags, LOW_POWER_S0);
1889ec650989SNeel Natu 	PRINTFLAG_END();
1890e1e9a4bfSMitsuru IWASAKI 
1891e1e9a4bfSMitsuru IWASAKI #undef PRINTFLAG
1892e1e9a4bfSMitsuru IWASAKI 
1893986dffafSJohn Baldwin 	if (fadt->Flags & ACPI_FADT_RESET_REGISTER) {
18948e6a8737SNate Lawson 		printf("\tRESET_REG=");
1895986dffafSJohn Baldwin 		acpi_print_gas(&fadt->ResetRegister);
1896986dffafSJohn Baldwin 		printf(", RESET_VALUE=%#x\n", fadt->ResetValue);
18978e6a8737SNate Lawson 	}
1898c2962974SNate Lawson 	if (acpi_get_fadt_revision(fadt) > 1) {
18997d369c6eSJung-uk Kim 		printf("\tX_FACS=0x%016jx, ", (uintmax_t)fadt->XFacs);
19007d369c6eSJung-uk Kim 		printf("X_DSDT=0x%016jx\n", (uintmax_t)fadt->XDsdt);
1901c08c4e81SNate Lawson 		printf("\tX_PM1a_EVT_BLK=");
1902986dffafSJohn Baldwin 		acpi_print_gas(&fadt->XPm1aEventBlock);
1903986dffafSJohn Baldwin 		if (fadt->XPm1bEventBlock.Address != 0) {
1904c08c4e81SNate Lawson 			printf("\n\tX_PM1b_EVT_BLK=");
1905986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XPm1bEventBlock);
1906c08c4e81SNate Lawson 		}
1907c08c4e81SNate Lawson 		printf("\n\tX_PM1a_CNT_BLK=");
1908986dffafSJohn Baldwin 		acpi_print_gas(&fadt->XPm1aControlBlock);
1909986dffafSJohn Baldwin 		if (fadt->XPm1bControlBlock.Address != 0) {
1910c08c4e81SNate Lawson 			printf("\n\tX_PM1b_CNT_BLK=");
1911986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XPm1bControlBlock);
1912c08c4e81SNate Lawson 		}
1913986dffafSJohn Baldwin 		if (fadt->XPm2ControlBlock.Address != 0) {
1914773b6454SNate Lawson 			printf("\n\tX_PM2_CNT_BLK=");
1915986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XPm2ControlBlock);
1916c08c4e81SNate Lawson 		}
1917773b6454SNate Lawson 		printf("\n\tX_PM_TMR_BLK=");
1918986dffafSJohn Baldwin 		acpi_print_gas(&fadt->XPmTimerBlock);
1919986dffafSJohn Baldwin 		if (fadt->XGpe0Block.Address != 0) {
1920773b6454SNate Lawson 			printf("\n\tX_GPE0_BLK=");
1921986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XGpe0Block);
1922c08c4e81SNate Lawson 		}
1923986dffafSJohn Baldwin 		if (fadt->XGpe1Block.Address != 0) {
1924773b6454SNate Lawson 			printf("\n\tX_GPE1_BLK=");
1925986dffafSJohn Baldwin 			acpi_print_gas(&fadt->XGpe1Block);
1926c08c4e81SNate Lawson 		}
1927773b6454SNate Lawson 		printf("\n");
1928773b6454SNate Lawson 	}
19298e6a8737SNate Lawson 
19308e6a8737SNate Lawson 	printf(END_COMMENT);
19318e6a8737SNate Lawson }
19328e6a8737SNate Lawson 
19338e6a8737SNate Lawson static void
1934986dffafSJohn Baldwin acpi_print_facs(ACPI_TABLE_FACS *facs)
19358e6a8737SNate Lawson {
19368e6a8737SNate Lawson 	printf(BEGIN_COMMENT);
1937986dffafSJohn Baldwin 	printf("  FACS:\tLength=%u, ", facs->Length);
1938986dffafSJohn Baldwin 	printf("HwSig=0x%08x, ", facs->HardwareSignature);
1939986dffafSJohn Baldwin 	printf("Firm_Wake_Vec=0x%08x\n", facs->FirmwareWakingVector);
19408e6a8737SNate Lawson 
1941773b6454SNate Lawson 	printf("\tGlobal_Lock=");
1942986dffafSJohn Baldwin 	if (facs->GlobalLock != 0) {
1943986dffafSJohn Baldwin 		if (facs->GlobalLock & ACPI_GLOCK_PENDING)
19448e6a8737SNate Lawson 			printf("PENDING,");
1945986dffafSJohn Baldwin 		if (facs->GlobalLock & ACPI_GLOCK_OWNED)
19468e6a8737SNate Lawson 			printf("OWNED");
19478e6a8737SNate Lawson 	}
1948773b6454SNate Lawson 	printf("\n");
19498e6a8737SNate Lawson 
1950773b6454SNate Lawson 	printf("\tFlags=");
1951986dffafSJohn Baldwin 	if (facs->Flags & ACPI_FACS_S4_BIOS_PRESENT)
19528e6a8737SNate Lawson 		printf("S4BIOS");
1953773b6454SNate Lawson 	printf("\n");
19548e6a8737SNate Lawson 
19557d369c6eSJung-uk Kim 	if (facs->XFirmwareWakingVector != 0)
19567d369c6eSJung-uk Kim 		printf("\tX_Firm_Wake_Vec=%016jx\n",
19577d369c6eSJung-uk Kim 		    (uintmax_t)facs->XFirmwareWakingVector);
1958986dffafSJohn Baldwin 	printf("\tVersion=%u\n", facs->Version);
19598e6a8737SNate Lawson 
1960c62f1cccSMitsuru IWASAKI 	printf(END_COMMENT);
1961e1e9a4bfSMitsuru IWASAKI }
1962e1e9a4bfSMitsuru IWASAKI 
1963945137d9SNate Lawson static void
1964986dffafSJohn Baldwin acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp)
1965e1e9a4bfSMitsuru IWASAKI {
1966773b6454SNate Lawson 	printf(BEGIN_COMMENT);
1967773b6454SNate Lawson 	acpi_print_sdt(dsdp);
1968773b6454SNate Lawson 	printf(END_COMMENT);
1969e1e9a4bfSMitsuru IWASAKI }
1970e1e9a4bfSMitsuru IWASAKI 
1971e1e9a4bfSMitsuru IWASAKI int
1972e1e9a4bfSMitsuru IWASAKI acpi_checksum(void *p, size_t length)
1973e1e9a4bfSMitsuru IWASAKI {
1974986dffafSJohn Baldwin 	uint8_t *bp;
1975986dffafSJohn Baldwin 	uint8_t sum;
1976e1e9a4bfSMitsuru IWASAKI 
1977e1e9a4bfSMitsuru IWASAKI 	bp = p;
1978e1e9a4bfSMitsuru IWASAKI 	sum = 0;
1979e1e9a4bfSMitsuru IWASAKI 	while (length--)
1980e1e9a4bfSMitsuru IWASAKI 		sum += *bp++;
1981e1e9a4bfSMitsuru IWASAKI 
1982e1e9a4bfSMitsuru IWASAKI 	return (sum);
1983e1e9a4bfSMitsuru IWASAKI }
1984e1e9a4bfSMitsuru IWASAKI 
1985986dffafSJohn Baldwin static ACPI_TABLE_HEADER *
1986e1e9a4bfSMitsuru IWASAKI acpi_map_sdt(vm_offset_t pa)
1987e1e9a4bfSMitsuru IWASAKI {
1988986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *sp;
1989e1e9a4bfSMitsuru IWASAKI 
1990986dffafSJohn Baldwin 	sp = acpi_map_physical(pa, sizeof(ACPI_TABLE_HEADER));
1991986dffafSJohn Baldwin 	sp = acpi_map_physical(pa, sp->Length);
1992e1e9a4bfSMitsuru IWASAKI 	return (sp);
1993e1e9a4bfSMitsuru IWASAKI }
1994e1e9a4bfSMitsuru IWASAKI 
1995945137d9SNate Lawson static void
1996986dffafSJohn Baldwin acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp)
1997e1e9a4bfSMitsuru IWASAKI {
1998c62f1cccSMitsuru IWASAKI 	printf(BEGIN_COMMENT);
1999a74172abSNate Lawson 	printf("  RSD PTR: OEM=");
2000986dffafSJohn Baldwin 	acpi_print_string(rp->OemId, ACPI_OEM_ID_SIZE);
2001986dffafSJohn Baldwin 	printf(", ACPI_Rev=%s (%d)\n", rp->Revision < 2 ? "1.0x" : "2.0x",
2002986dffafSJohn Baldwin 	       rp->Revision);
2003986dffafSJohn Baldwin 	if (rp->Revision < 2) {
2004986dffafSJohn Baldwin 		printf("\tRSDT=0x%08x, cksum=%u\n", rp->RsdtPhysicalAddress,
2005986dffafSJohn Baldwin 		    rp->Checksum);
2006a74172abSNate Lawson 	} else {
20077d369c6eSJung-uk Kim 		printf("\tXSDT=0x%016jx, length=%u, cksum=%u\n",
20087d369c6eSJung-uk Kim 		    (uintmax_t)rp->XsdtPhysicalAddress, rp->Length,
2009986dffafSJohn Baldwin 		    rp->ExtendedChecksum);
2010a74172abSNate Lawson 	}
2011c62f1cccSMitsuru IWASAKI 	printf(END_COMMENT);
2012e1e9a4bfSMitsuru IWASAKI }
2013e1e9a4bfSMitsuru IWASAKI 
2014945137d9SNate Lawson static void
2015986dffafSJohn Baldwin acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp)
2016e1e9a4bfSMitsuru IWASAKI {
2017986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *sdp;
2018986dffafSJohn Baldwin 	ACPI_TABLE_RSDT *rsdt;
2019986dffafSJohn Baldwin 	ACPI_TABLE_XSDT *xsdt;
2020a74172abSNate Lawson 	vm_offset_t addr;
2021a74172abSNate Lawson 	int entries, i;
2022e1e9a4bfSMitsuru IWASAKI 
2023e1e9a4bfSMitsuru IWASAKI 	acpi_print_rsdt(rsdp);
2024986dffafSJohn Baldwin 	rsdt = (ACPI_TABLE_RSDT *)rsdp;
2025986dffafSJohn Baldwin 	xsdt = (ACPI_TABLE_XSDT *)rsdp;
2026986dffafSJohn Baldwin 	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
2027e1e9a4bfSMitsuru IWASAKI 	for (i = 0; i < entries; i++) {
2028fe1d0c2dSJung-uk Kim 		if (addr_size == 4)
2029986dffafSJohn Baldwin 			addr = le32toh(rsdt->TableOffsetEntry[i]);
2030fe1d0c2dSJung-uk Kim 		else
2031986dffafSJohn Baldwin 			addr = le64toh(xsdt->TableOffsetEntry[i]);
2032fe1d0c2dSJung-uk Kim 		if (addr == 0)
2033fe1d0c2dSJung-uk Kim 			continue;
2034986dffafSJohn Baldwin 		sdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
2035986dffafSJohn Baldwin 		if (acpi_checksum(sdp, sdp->Length)) {
20365cf6d493SNate Lawson 			warnx("RSDT entry %d (sig %.4s) is corrupt", i,
2037986dffafSJohn Baldwin 			    sdp->Signature);
20385cf6d493SNate Lawson 			continue;
20395cf6d493SNate Lawson 		}
2040ebc22d04SAlexander Motin 		if (!memcmp(sdp->Signature, ACPI_SIG_BERT, 4))
2041ebc22d04SAlexander Motin 			acpi_handle_bert(sdp);
2042ebc22d04SAlexander Motin 		else if (!memcmp(sdp->Signature, ACPI_SIG_EINJ, 4))
2043ebc22d04SAlexander Motin 			acpi_handle_einj(sdp);
2044ebc22d04SAlexander Motin 		else if (!memcmp(sdp->Signature, ACPI_SIG_ERST, 4))
2045ebc22d04SAlexander Motin 			acpi_handle_erst(sdp);
2046ebc22d04SAlexander Motin 		else if (!memcmp(sdp->Signature, ACPI_SIG_FADT, 4))
20472177d4e6SNate Lawson 			acpi_handle_fadt(sdp);
2048986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_MADT, 4))
2049986dffafSJohn Baldwin 			acpi_handle_madt(sdp);
2050ebc22d04SAlexander Motin 		else if (!memcmp(sdp->Signature, ACPI_SIG_HEST, 4))
2051ebc22d04SAlexander Motin 			acpi_handle_hest(sdp);
2052986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_HPET, 4))
205379d7565cSPeter Wemm 			acpi_handle_hpet(sdp);
2054986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_ECDT, 4))
205555d7ff9eSNate Lawson 			acpi_handle_ecdt(sdp);
2056986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_MCFG, 4))
2057a47e681bSScott Long 			acpi_handle_mcfg(sdp);
205833866658SJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_SLIT, 4))
205933866658SJohn Baldwin 			acpi_handle_slit(sdp);
2060986dffafSJohn Baldwin 		else if (!memcmp(sdp->Signature, ACPI_SIG_SRAT, 4))
2061a0333ad1SJohn Baldwin 			acpi_handle_srat(sdp);
2062c031c93bSTakanori Watanabe 		else if (!memcmp(sdp->Signature, ACPI_SIG_TCPA, 4))
2063c031c93bSTakanori Watanabe 			acpi_handle_tcpa(sdp);
2064ec650989SNeel Natu 		else if (!memcmp(sdp->Signature, ACPI_SIG_DMAR, 4))
2065ec650989SNeel Natu 			acpi_handle_dmar(sdp);
2066340c0022SEd Maste 		else if (!memcmp(sdp->Signature, ACPI_SIG_NFIT, 4))
2067340c0022SEd Maste 			acpi_handle_nfit(sdp);
2068ed26c389SScott Long 		else if (!memcmp(sdp->Signature, ACPI_SIG_WDDT, 4))
2069ed26c389SScott Long 			acpi_handle_wddt(sdp);
20705857fba5SBen Widawsky 		else if (!memcmp(sdp->Signature, ACPI_SIG_LPIT, 4))
20715857fba5SBen Widawsky 			acpi_handle_lpit(sdp);
2072877fc2e3STakanori Watanabe 		else if (!memcmp(sdp->Signature, ACPI_SIG_TPM2, 4))
2073877fc2e3STakanori Watanabe 			acpi_handle_tpm2(sdp);
2074773b6454SNate Lawson 		else {
2075773b6454SNate Lawson 			printf(BEGIN_COMMENT);
2076773b6454SNate Lawson 			acpi_print_sdt(sdp);
2077773b6454SNate Lawson 			printf(END_COMMENT);
2078773b6454SNate Lawson 		}
2079e1e9a4bfSMitsuru IWASAKI 	}
2080e1e9a4bfSMitsuru IWASAKI }
2081c62f1cccSMitsuru IWASAKI 
2082986dffafSJohn Baldwin ACPI_TABLE_HEADER *
2083476daaecSDag-Erling Smørgrav sdt_load_devmem(void)
2084945137d9SNate Lawson {
2085986dffafSJohn Baldwin 	ACPI_TABLE_RSDP *rp;
2086986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *rsdp;
2087945137d9SNate Lawson 
2088945137d9SNate Lawson 	rp = acpi_find_rsd_ptr();
2089945137d9SNate Lawson 	if (!rp)
2090945137d9SNate Lawson 		errx(1, "Can't find ACPI information");
2091945137d9SNate Lawson 
2092945137d9SNate Lawson 	if (tflag)
2093945137d9SNate Lawson 		acpi_print_rsd_ptr(rp);
2094986dffafSJohn Baldwin 	if (rp->Revision < 2) {
2095986dffafSJohn Baldwin 		rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->RsdtPhysicalAddress);
2096986dffafSJohn Baldwin 		if (memcmp(rsdp->Signature, "RSDT", 4) != 0 ||
2097986dffafSJohn Baldwin 		    acpi_checksum(rsdp, rsdp->Length) != 0)
2098945137d9SNate Lawson 			errx(1, "RSDT is corrupted");
2099a74172abSNate Lawson 		addr_size = sizeof(uint32_t);
2100a74172abSNate Lawson 	} else {
2101986dffafSJohn Baldwin 		rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->XsdtPhysicalAddress);
2102986dffafSJohn Baldwin 		if (memcmp(rsdp->Signature, "XSDT", 4) != 0 ||
2103986dffafSJohn Baldwin 		    acpi_checksum(rsdp, rsdp->Length) != 0)
2104a74172abSNate Lawson 			errx(1, "XSDT is corrupted");
2105a74172abSNate Lawson 		addr_size = sizeof(uint64_t);
2106a74172abSNate Lawson 	}
2107945137d9SNate Lawson 	return (rsdp);
2108945137d9SNate Lawson }
2109c62f1cccSMitsuru IWASAKI 
211062c7bde1SNate Lawson /* Write the DSDT to a file, concatenating any SSDTs (if present). */
2111bfa3f012SMarcel Moolenaar static int
2112986dffafSJohn Baldwin write_dsdt(int fd, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdt)
2113bfa3f012SMarcel Moolenaar {
2114986dffafSJohn Baldwin 	ACPI_TABLE_HEADER sdt;
2115986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *ssdt;
2116bfa3f012SMarcel Moolenaar 	uint8_t sum;
2117bfa3f012SMarcel Moolenaar 
211862c7bde1SNate Lawson 	/* Create a new checksum to account for the DSDT and any SSDTs. */
2119bfa3f012SMarcel Moolenaar 	sdt = *dsdt;
2120bfa3f012SMarcel Moolenaar 	if (rsdt != NULL) {
2121986dffafSJohn Baldwin 		sdt.Checksum = 0;
2122986dffafSJohn Baldwin 		sum = acpi_checksum(dsdt + 1, dsdt->Length -
2123986dffafSJohn Baldwin 		    sizeof(ACPI_TABLE_HEADER));
2124986dffafSJohn Baldwin 		ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, NULL);
2125f7675a56SNate Lawson 		while (ssdt != NULL) {
2126986dffafSJohn Baldwin 			sdt.Length += ssdt->Length - sizeof(ACPI_TABLE_HEADER);
2127986dffafSJohn Baldwin 			sum += acpi_checksum(ssdt + 1,
2128986dffafSJohn Baldwin 			    ssdt->Length - sizeof(ACPI_TABLE_HEADER));
2129986dffafSJohn Baldwin 			ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, ssdt);
2130bfa3f012SMarcel Moolenaar 		}
2131986dffafSJohn Baldwin 		sum += acpi_checksum(&sdt, sizeof(ACPI_TABLE_HEADER));
2132986dffafSJohn Baldwin 		sdt.Checksum -= sum;
2133bfa3f012SMarcel Moolenaar 	}
213462c7bde1SNate Lawson 
213562c7bde1SNate Lawson 	/* Write out the DSDT header and body. */
2136986dffafSJohn Baldwin 	write(fd, &sdt, sizeof(ACPI_TABLE_HEADER));
2137986dffafSJohn Baldwin 	write(fd, dsdt + 1, dsdt->Length - sizeof(ACPI_TABLE_HEADER));
213862c7bde1SNate Lawson 
2139b64e1b67SNate Lawson 	/* Write out any SSDTs (if present.) */
2140f7675a56SNate Lawson 	if (rsdt != NULL) {
2141bfa3f012SMarcel Moolenaar 		ssdt = sdt_from_rsdt(rsdt, "SSDT", NULL);
2142bfa3f012SMarcel Moolenaar 		while (ssdt != NULL) {
2143986dffafSJohn Baldwin 			write(fd, ssdt + 1, ssdt->Length -
2144986dffafSJohn Baldwin 			    sizeof(ACPI_TABLE_HEADER));
2145bfa3f012SMarcel Moolenaar 			ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt);
2146bfa3f012SMarcel Moolenaar 		}
2147bfa3f012SMarcel Moolenaar 	}
2148bfa3f012SMarcel Moolenaar 	return (0);
2149bfa3f012SMarcel Moolenaar }
2150bfa3f012SMarcel Moolenaar 
2151c62f1cccSMitsuru IWASAKI void
2152986dffafSJohn Baldwin dsdt_save_file(char *outfile, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
2153c62f1cccSMitsuru IWASAKI {
2154945137d9SNate Lawson 	int	fd;
2155945137d9SNate Lawson 	mode_t	mode;
2156945137d9SNate Lawson 
2157945137d9SNate Lawson 	assert(outfile != NULL);
2158945137d9SNate Lawson 	mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
2159945137d9SNate Lawson 	fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, mode);
2160945137d9SNate Lawson 	if (fd == -1) {
2161945137d9SNate Lawson 		perror("dsdt_save_file");
2162945137d9SNate Lawson 		return;
2163945137d9SNate Lawson 	}
2164bfa3f012SMarcel Moolenaar 	write_dsdt(fd, rsdt, dsdp);
2165945137d9SNate Lawson 	close(fd);
2166c62f1cccSMitsuru IWASAKI }
2167c62f1cccSMitsuru IWASAKI 
2168945137d9SNate Lawson void
2169986dffafSJohn Baldwin aml_disassemble(ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
2170c62f1cccSMitsuru IWASAKI {
21717e2cc014SDon Lewis 	char buf[PATH_MAX], tmpstr[PATH_MAX], wrkdir[PATH_MAX];
21727e2cc014SDon Lewis 	const char *iname = "/acpdump.din";
21737e2cc014SDon Lewis 	const char *oname = "/acpdump.dsl";
217499065116SJung-uk Kim 	const char *tmpdir;
2175945137d9SNate Lawson 	FILE *fp;
217699065116SJung-uk Kim 	size_t len;
21777e2cc014SDon Lewis 	int fd, status;
21787e2cc014SDon Lewis 	pid_t pid;
2179945137d9SNate Lawson 
218099065116SJung-uk Kim 	tmpdir = getenv("TMPDIR");
218199065116SJung-uk Kim 	if (tmpdir == NULL)
218299065116SJung-uk Kim 		tmpdir = _PATH_TMP;
21837e2cc014SDon Lewis 	if (realpath(tmpdir, buf) == NULL) {
2184d6a6e590SJung-uk Kim 		perror("realpath tmp dir");
218599065116SJung-uk Kim 		return;
218699065116SJung-uk Kim 	}
21877e2cc014SDon Lewis 	len = sizeof(wrkdir) - strlen(iname);
21887e2cc014SDon Lewis 	if ((size_t)snprintf(wrkdir, len, "%s/acpidump.XXXXXX", buf) > len-1 ) {
21897e2cc014SDon Lewis 		fprintf(stderr, "$TMPDIR too long\n");
21907e2cc014SDon Lewis 		return;
21917e2cc014SDon Lewis 	}
21927e2cc014SDon Lewis 	if  (mkdtemp(wrkdir) == NULL) {
21937e2cc014SDon Lewis 		perror("mkdtemp tmp working dir");
21947e2cc014SDon Lewis 		return;
21957e2cc014SDon Lewis 	}
219630bebccaSMaxim Konovalov 	len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, iname);
219730bebccaSMaxim Konovalov 	assert(len <= sizeof(tmpstr) - 1);
21987e2cc014SDon Lewis 	fd = open(tmpstr, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
2199945137d9SNate Lawson 	if (fd < 0) {
2200945137d9SNate Lawson 		perror("iasl tmp file");
2201945137d9SNate Lawson 		return;
2202c62f1cccSMitsuru IWASAKI 	}
2203bfa3f012SMarcel Moolenaar 	write_dsdt(fd, rsdt, dsdp);
2204945137d9SNate Lawson 	close(fd);
2205945137d9SNate Lawson 
2206945137d9SNate Lawson 	/* Run iasl -d on the temp file */
22077e2cc014SDon Lewis 	if ((pid = fork()) == 0) {
2208945137d9SNate Lawson 		close(STDOUT_FILENO);
2209945137d9SNate Lawson 		if (vflag == 0)
2210945137d9SNate Lawson 			close(STDERR_FILENO);
221199065116SJung-uk Kim 		execl("/usr/sbin/iasl", "iasl", "-d", tmpstr, NULL);
2212945137d9SNate Lawson 		err(1, "exec");
2213c62f1cccSMitsuru IWASAKI 	}
22147e2cc014SDon Lewis 	if (pid > 0)
22157e2cc014SDon Lewis 		wait(&status);
22167e2cc014SDon Lewis 	if (unlink(tmpstr) < 0) {
22177e2cc014SDon Lewis 		perror("unlink");
22187e2cc014SDon Lewis 		goto out;
22197e2cc014SDon Lewis 	}
22207e2cc014SDon Lewis 	if (pid < 0) {
22217e2cc014SDon Lewis 		perror("fork");
22227e2cc014SDon Lewis 		goto out;
22237e2cc014SDon Lewis 	}
22247e2cc014SDon Lewis 	if (status != 0) {
22257e2cc014SDon Lewis 		fprintf(stderr, "iast exit status = %d\n", status);
22267e2cc014SDon Lewis 	}
2227945137d9SNate Lawson 
2228945137d9SNate Lawson 	/* Dump iasl's output to stdout */
222930bebccaSMaxim Konovalov 	len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, oname);
223030bebccaSMaxim Konovalov 	assert(len <= sizeof(tmpstr) - 1);
223199065116SJung-uk Kim 	fp = fopen(tmpstr, "r");
22327e2cc014SDon Lewis 	if (unlink(tmpstr) < 0) {
22337e2cc014SDon Lewis 		perror("unlink");
22347e2cc014SDon Lewis 		goto out;
22357e2cc014SDon Lewis 	}
2236945137d9SNate Lawson 	if (fp == NULL) {
2237945137d9SNate Lawson 		perror("iasl tmp file (read)");
22387e2cc014SDon Lewis 		goto out;
2239945137d9SNate Lawson 	}
2240945137d9SNate Lawson 	while ((len = fread(buf, 1, sizeof(buf), fp)) > 0)
2241945137d9SNate Lawson 		fwrite(buf, 1, len, stdout);
2242945137d9SNate Lawson 	fclose(fp);
22437e2cc014SDon Lewis 
22447e2cc014SDon Lewis     out:
22457e2cc014SDon Lewis 	if (rmdir(wrkdir) < 0)
22467e2cc014SDon Lewis 		perror("rmdir");
2247c62f1cccSMitsuru IWASAKI }
2248c62f1cccSMitsuru IWASAKI 
2249945137d9SNate Lawson void
2250986dffafSJohn Baldwin sdt_print_all(ACPI_TABLE_HEADER *rsdp)
2251c62f1cccSMitsuru IWASAKI {
2252945137d9SNate Lawson 	acpi_handle_rsdt(rsdp);
2253c62f1cccSMitsuru IWASAKI }
2254c62f1cccSMitsuru IWASAKI 
2255bfa3f012SMarcel Moolenaar /* Fetch a table matching the given signature via the RSDT. */
2256986dffafSJohn Baldwin ACPI_TABLE_HEADER *
2257986dffafSJohn Baldwin sdt_from_rsdt(ACPI_TABLE_HEADER *rsdp, const char *sig, ACPI_TABLE_HEADER *last)
2258c62f1cccSMitsuru IWASAKI {
2259986dffafSJohn Baldwin 	ACPI_TABLE_HEADER *sdt;
2260986dffafSJohn Baldwin 	ACPI_TABLE_RSDT *rsdt;
2261986dffafSJohn Baldwin 	ACPI_TABLE_XSDT *xsdt;
2262a74172abSNate Lawson 	vm_offset_t addr;
2263a74172abSNate Lawson 	int entries, i;
2264945137d9SNate Lawson 
2265986dffafSJohn Baldwin 	rsdt = (ACPI_TABLE_RSDT *)rsdp;
2266986dffafSJohn Baldwin 	xsdt = (ACPI_TABLE_XSDT *)rsdp;
2267986dffafSJohn Baldwin 	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
2268945137d9SNate Lawson 	for (i = 0; i < entries; i++) {
2269fe1d0c2dSJung-uk Kim 		if (addr_size == 4)
2270986dffafSJohn Baldwin 			addr = le32toh(rsdt->TableOffsetEntry[i]);
2271fe1d0c2dSJung-uk Kim 		else
2272986dffafSJohn Baldwin 			addr = le64toh(xsdt->TableOffsetEntry[i]);
2273fe1d0c2dSJung-uk Kim 		if (addr == 0)
2274fe1d0c2dSJung-uk Kim 			continue;
2275986dffafSJohn Baldwin 		sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
2276bfa3f012SMarcel Moolenaar 		if (last != NULL) {
2277bfa3f012SMarcel Moolenaar 			if (sdt == last)
2278bfa3f012SMarcel Moolenaar 				last = NULL;
2279bfa3f012SMarcel Moolenaar 			continue;
2280bfa3f012SMarcel Moolenaar 		}
2281986dffafSJohn Baldwin 		if (memcmp(sdt->Signature, sig, strlen(sig)))
2282a74172abSNate Lawson 			continue;
2283986dffafSJohn Baldwin 		if (acpi_checksum(sdt, sdt->Length))
2284945137d9SNate Lawson 			errx(1, "RSDT entry %d is corrupt", i);
2285945137d9SNate Lawson 		return (sdt);
2286c62f1cccSMitsuru IWASAKI 	}
2287c62f1cccSMitsuru IWASAKI 
2288945137d9SNate Lawson 	return (NULL);
2289c62f1cccSMitsuru IWASAKI }
2290c62f1cccSMitsuru IWASAKI 
2291986dffafSJohn Baldwin ACPI_TABLE_HEADER *
2292986dffafSJohn Baldwin dsdt_from_fadt(ACPI_TABLE_FADT *fadt)
2293c62f1cccSMitsuru IWASAKI {
2294986dffafSJohn Baldwin 	ACPI_TABLE_HEADER	*sdt;
2295c62f1cccSMitsuru IWASAKI 
2296986dffafSJohn Baldwin 	/* Use the DSDT address if it is version 1, otherwise use XDSDT. */
2297c2962974SNate Lawson 	if (acpi_get_fadt_revision(fadt) == 1)
2298986dffafSJohn Baldwin 		sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt);
22992e71eb12SNate Lawson 	else
2300986dffafSJohn Baldwin 		sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt);
2301986dffafSJohn Baldwin 	if (acpi_checksum(sdt, sdt->Length))
2302945137d9SNate Lawson 		errx(1, "DSDT is corrupt\n");
2303945137d9SNate Lawson 	return (sdt);
2304c62f1cccSMitsuru IWASAKI }
2305