xref: /netbsd-src/usr.sbin/acpitools/acpidump/acpi.c (revision 636c2f2b35295d34177baf1559e449596983c900)
1*636c2f2bSmsaitoh /* $NetBSD: acpi.c,v 1.56 2024/05/12 23:00:21 msaitoh Exp $ */
253e202c1Schristos 
353e202c1Schristos /*-
453e202c1Schristos  * Copyright (c) 1998 Doug Rabson
553e202c1Schristos  * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
653e202c1Schristos  * All rights reserved.
753e202c1Schristos  *
853e202c1Schristos  * Redistribution and use in source and binary forms, with or without
953e202c1Schristos  * modification, are permitted provided that the following conditions
1053e202c1Schristos  * are met:
1153e202c1Schristos  * 1. Redistributions of source code must retain the above copyright
1253e202c1Schristos  *    notice, this list of conditions and the following disclaimer.
1353e202c1Schristos  * 2. Redistributions in binary form must reproduce the above copyright
1453e202c1Schristos  *    notice, this list of conditions and the following disclaimer in the
1553e202c1Schristos  *    documentation and/or other materials provided with the distribution.
1653e202c1Schristos  *
1753e202c1Schristos  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1853e202c1Schristos  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1953e202c1Schristos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2053e202c1Schristos  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2153e202c1Schristos  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2253e202c1Schristos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2353e202c1Schristos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2453e202c1Schristos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2553e202c1Schristos  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2653e202c1Schristos  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2753e202c1Schristos  * SUCH DAMAGE.
2853e202c1Schristos  *
29c359a213Smsaitoh  *	$FreeBSD: head/usr.sbin/acpi/acpidump/acpi.c 321299 2017-07-20 17:36:17Z emaste $
3053e202c1Schristos  */
3109f2089bScegger 
3253e202c1Schristos #include <sys/cdefs.h>
33*636c2f2bSmsaitoh __RCSID("$NetBSD: acpi.c,v 1.56 2024/05/12 23:00:21 msaitoh Exp $");
3453e202c1Schristos 
3553e202c1Schristos #include <sys/param.h>
3609f2089bScegger #include <sys/endian.h>
3753e202c1Schristos #include <sys/stat.h>
3809f2089bScegger #include <sys/wait.h>
3953e202c1Schristos #include <assert.h>
4053e202c1Schristos #include <err.h>
4153e202c1Schristos #include <fcntl.h>
4209f2089bScegger #include <paths.h>
43055f8b85Smsaitoh #include <stdbool.h>
4453e202c1Schristos #include <stdio.h>
4509f2089bScegger #include <stdint.h>
4609f2089bScegger #include <stdlib.h>
4753e202c1Schristos #include <string.h>
4809f2089bScegger #include <unistd.h>
4909f2089bScegger #include <stddef.h>
50792e611dSmsaitoh #include <uuid.h>
5153e202c1Schristos 
5253e202c1Schristos #include "acpidump.h"
5353e202c1Schristos 
5453e202c1Schristos #define BEGIN_COMMENT	"/*\n"
5553e202c1Schristos #define END_COMMENT	" */\n"
5653e202c1Schristos 
57055f8b85Smsaitoh /* Commonly used helper functions */
5809f2089bScegger static void	acpi_print_string(char *s, size_t length);
59055f8b85Smsaitoh static void	acpi_print_tabs(unsigned int n);
60055f8b85Smsaitoh static void	acpi_dump_bytes(uint8_t *p, uint32_t len, unsigned int ntabs);
61055f8b85Smsaitoh static void	acpi_dump_table(ACPI_TABLE_HEADER *sdp);
6209f2089bScegger static void	acpi_print_gas(ACPI_GENERIC_ADDRESS *gas);
6309f2089bScegger static void	acpi_print_pci(uint16_t vendorid, uint16_t deviceid,
6409f2089bScegger 		    uint8_t seg, uint8_t bus, uint8_t device, uint8_t func);
655d527485Smsaitoh static void	acpi_print_pci_sbdf(uint8_t seg, uint8_t bus, uint8_t device,
6609f2089bScegger 		    uint8_t func);
6709f2089bScegger #ifdef notyet
6809f2089bScegger static void	acpi_print_hest_generic_status(ACPI_HEST_GENERIC_STATUS *);
6909f2089bScegger static void	acpi_print_hest_generic_data(ACPI_HEST_GENERIC_DATA *);
7009f2089bScegger #endif
7109f2089bScegger static void	acpi_print_whea(ACPI_WHEA_HEADER *whea,
7209f2089bScegger 		    void (*print_action)(ACPI_WHEA_HEADER *),
7309f2089bScegger 		    void (*print_ins)(ACPI_WHEA_HEADER *),
7409f2089bScegger 		    void (*print_flags)(ACPI_WHEA_HEADER *));
758f0f46f9Smsaitoh static uint64_t	acpi_select_address(uint32_t, uint64_t);
76055f8b85Smsaitoh 
77055f8b85Smsaitoh /* Handlers for each table */
7809f2089bScegger static void	acpi_handle_fadt(ACPI_TABLE_HEADER *fadt);
7909f2089bScegger static void	acpi_print_cpu(u_char cpu_id);
8009f2089bScegger static void	acpi_print_cpu_uid(uint32_t uid, char *uid_string);
8109f2089bScegger static void	acpi_print_local_apic(uint32_t apic_id, uint32_t flags);
8209f2089bScegger static void	acpi_print_io_apic(uint32_t apic_id, uint32_t int_base,
8309f2089bScegger 		    uint64_t apic_addr);
8409f2089bScegger static void	acpi_print_mps_flags(uint16_t flags);
8509f2089bScegger static void	acpi_print_intr(uint32_t intr, uint16_t mps_flags);
86bbb9ad67Srillig static void	acpi_print_local_nmi(u_int local_int, uint16_t mps_flags);
8709f2089bScegger static void	acpi_print_madt(ACPI_SUBTABLE_HEADER *mp);
8809f2089bScegger static void	acpi_handle_bert(ACPI_TABLE_HEADER *sdp);
89755dd632Smsaitoh static void	acpi_handle_bgrt(ACPI_TABLE_HEADER *sdp);
9009f2089bScegger static void	acpi_handle_boot(ACPI_TABLE_HEADER *sdp);
9109f2089bScegger static void	acpi_handle_cpep(ACPI_TABLE_HEADER *sdp);
92055f8b85Smsaitoh static void	acpi_handle_csrt(ACPI_TABLE_HEADER *sdp);
9309f2089bScegger static void	acpi_handle_dbgp(ACPI_TABLE_HEADER *sdp);
945d527485Smsaitoh static void	acpi_handle_dbg2(ACPI_TABLE_HEADER *sdp);
9509f2089bScegger static void	acpi_handle_einj(ACPI_TABLE_HEADER *sdp);
9609f2089bScegger static void	acpi_handle_erst(ACPI_TABLE_HEADER *sdp);
97aba8816bSmsaitoh static void	acpi_handle_gtdt(ACPI_TABLE_HEADER *sdp);
9809f2089bScegger static void	acpi_handle_hest(ACPI_TABLE_HEADER *sdp);
99c0f969c5Smsaitoh static void	acpi_handle_iort(ACPI_TABLE_HEADER *sdp);
1003de33cabSmsaitoh static void	acpi_handle_lpit(ACPI_TABLE_HEADER *sdp);
10109f2089bScegger static void	acpi_handle_madt(ACPI_TABLE_HEADER *sdp);
10209f2089bScegger static void	acpi_handle_msct(ACPI_TABLE_HEADER *sdp);
10309f2089bScegger static void	acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp);
10409f2089bScegger static void	acpi_handle_hpet(ACPI_TABLE_HEADER *sdp);
10509f2089bScegger static void	acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp);
1060eb6f089Sjmcneill static void	acpi_handle_pcct(ACPI_TABLE_HEADER *sdp);
107aba8816bSmsaitoh static void	acpi_handle_pptt(ACPI_TABLE_HEADER *sdp);
10809f2089bScegger static void	acpi_handle_sbst(ACPI_TABLE_HEADER *sdp);
10909f2089bScegger static void	acpi_handle_slit(ACPI_TABLE_HEADER *sdp);
11009f2089bScegger static void	acpi_handle_spcr(ACPI_TABLE_HEADER *sdp);
1115d527485Smsaitoh static void	acpi_handle_spmi(ACPI_TABLE_HEADER *sdp);
112597a86a6Smsaitoh static void	acpi_print_srat_cpu(uint8_t type, uint32_t apic_id,
11309f2089bScegger 		    uint32_t proximity_domain,
114597a86a6Smsaitoh 		    uint32_t flags, uint32_t clockdomain, uint8_t sapic_eid);
11509f2089bScegger static void	acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp);
11609f2089bScegger static void	acpi_print_srat(ACPI_SUBTABLE_HEADER *srat);
11709f2089bScegger static void	acpi_handle_srat(ACPI_TABLE_HEADER *sdp);
11809f2089bScegger static void	acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp);
1190e3f83efSmaxv static void	acpi_handle_tpm2(ACPI_TABLE_HEADER *sdp);
120792e611dSmsaitoh static void	acpi_print_nfit(ACPI_NFIT_HEADER *nfit);
121792e611dSmsaitoh static void	acpi_handle_nfit(ACPI_TABLE_HEADER *sdp);
1225d527485Smsaitoh static void	acpi_handle_uefi(ACPI_TABLE_HEADER *sdp);
12309f2089bScegger static void	acpi_handle_waet(ACPI_TABLE_HEADER *sdp);
12409f2089bScegger static void	acpi_handle_wdat(ACPI_TABLE_HEADER *sdp);
1255d527485Smsaitoh static void	acpi_handle_wddt(ACPI_TABLE_HEADER *sdp);
12609f2089bScegger static void	acpi_handle_wdrt(ACPI_TABLE_HEADER *sdp);
12709f2089bScegger static void	acpi_print_sdt(ACPI_TABLE_HEADER *sdp);
12809f2089bScegger static void	acpi_print_fadt(ACPI_TABLE_HEADER *sdp);
12909f2089bScegger static void	acpi_print_facs(ACPI_TABLE_FACS *facs);
13009f2089bScegger static void	acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp);
13109f2089bScegger static ACPI_TABLE_HEADER *acpi_map_sdt(vm_offset_t pa);
13209f2089bScegger static void	acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp);
13309f2089bScegger static void	acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp);
13409f2089bScegger static void	acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
13509f2089bScegger 		    void (*action)(ACPI_SUBTABLE_HEADER *));
136792e611dSmsaitoh static void	acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first,
137792e611dSmsaitoh 		    void (*action)(ACPI_NFIT_HEADER *));
13809f2089bScegger 
13909f2089bScegger /* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up. */
14009f2089bScegger static int addr_size;
14153e202c1Schristos 
142c359a213Smsaitoh /* Strings used in the TCPA table */
143c359a213Smsaitoh static const char *tcpa_event_type_strings[] = {
144c359a213Smsaitoh 	"PREBOOT Certificate",
145c359a213Smsaitoh 	"POST Code",
146c359a213Smsaitoh 	"Unused",
147c359a213Smsaitoh 	"No Action",
148c359a213Smsaitoh 	"Separator",
149c359a213Smsaitoh 	"Action",
150c359a213Smsaitoh 	"Event Tag",
151c359a213Smsaitoh 	"S-CRTM Contents",
152c359a213Smsaitoh 	"S-CRTM Version",
153c359a213Smsaitoh 	"CPU Microcode",
154c359a213Smsaitoh 	"Platform Config Flags",
155c359a213Smsaitoh 	"Table of Devices",
156c359a213Smsaitoh 	"Compact Hash",
157c359a213Smsaitoh 	"IPL",
158c359a213Smsaitoh 	"IPL Partition Data",
159c359a213Smsaitoh 	"Non-Host Code",
160c359a213Smsaitoh 	"Non-Host Config",
161c359a213Smsaitoh 	"Non-Host Info"
162c359a213Smsaitoh };
163c359a213Smsaitoh 
164c359a213Smsaitoh static const char *TCPA_pcclient_strings[] = {
165c359a213Smsaitoh 	"<undefined>",
166c359a213Smsaitoh 	"SMBIOS",
167c359a213Smsaitoh 	"BIS Certificate",
168c359a213Smsaitoh 	"POST BIOS ROM Strings",
169c359a213Smsaitoh 	"ESCD",
170c359a213Smsaitoh 	"CMOS",
171c359a213Smsaitoh 	"NVRAM",
172c359a213Smsaitoh 	"Option ROM Execute",
173c359a213Smsaitoh 	"Option ROM Configurateion",
174c359a213Smsaitoh 	"<undefined>",
175c359a213Smsaitoh 	"Option ROM Microcode Update ",
176c359a213Smsaitoh 	"S-CRTM Version String",
177c359a213Smsaitoh 	"S-CRTM Contents",
178c359a213Smsaitoh 	"POST Contents",
179c359a213Smsaitoh 	"Table of Devices",
180c359a213Smsaitoh };
181c359a213Smsaitoh 
182c359a213Smsaitoh #define	PRINTFLAG_END()		printflag_end()
183c359a213Smsaitoh 
184c359a213Smsaitoh static char pf_sep = '{';
185c359a213Smsaitoh 
186c359a213Smsaitoh static void
printflag_end(void)187c359a213Smsaitoh printflag_end(void)
188c359a213Smsaitoh {
189c359a213Smsaitoh 
190ff98ea46Smsaitoh 	if (pf_sep == ',') {
191c359a213Smsaitoh 		printf("}");
192ff98ea46Smsaitoh 	} else if (pf_sep == '{') {
193ff98ea46Smsaitoh 		printf("{}");
194c359a213Smsaitoh 	}
195ff98ea46Smsaitoh 	pf_sep = '{';
196c359a213Smsaitoh 	printf("\n");
197c359a213Smsaitoh }
198c359a213Smsaitoh 
199c359a213Smsaitoh static void
printflag(uint64_t var,uint64_t mask,const char * name)200c359a213Smsaitoh printflag(uint64_t var, uint64_t mask, const char *name)
201c359a213Smsaitoh {
202c359a213Smsaitoh 
203c359a213Smsaitoh 	if (var & mask) {
204c359a213Smsaitoh 		printf("%c%s", pf_sep, name);
205c359a213Smsaitoh 		pf_sep = ',';
206c359a213Smsaitoh 	}
207c359a213Smsaitoh }
208c359a213Smsaitoh 
20953e202c1Schristos static void
acpi_print_string(char * s,size_t length)21009f2089bScegger acpi_print_string(char *s, size_t length)
21153e202c1Schristos {
21253e202c1Schristos 	int	c;
21353e202c1Schristos 
21453e202c1Schristos 	/* Trim trailing spaces and NULLs */
21553e202c1Schristos 	while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0'))
21653e202c1Schristos 		length--;
21753e202c1Schristos 
21853e202c1Schristos 	while (length--) {
21953e202c1Schristos 		c = *s++;
2209836c964Smsaitoh 		if (c == '\0')
2219836c964Smsaitoh 			return;
22253e202c1Schristos 		putchar(c);
22353e202c1Schristos 	}
22453e202c1Schristos }
22553e202c1Schristos 
22653e202c1Schristos static void
acpi_print_gas(ACPI_GENERIC_ADDRESS * gas)22709f2089bScegger acpi_print_gas(ACPI_GENERIC_ADDRESS *gas)
22853e202c1Schristos {
22909f2089bScegger 	switch (gas->SpaceId) {
23050d91653Smsaitoh 	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
231c359a213Smsaitoh 		if (gas->BitWidth <= 32)
232c359a213Smsaitoh 			printf("0x%08x:%u[%u] (Memory)",
233c359a213Smsaitoh 			    (u_int)gas->Address, gas->BitOffset,
234c359a213Smsaitoh 			    gas->BitWidth);
235c359a213Smsaitoh 		else
236c359a213Smsaitoh 			printf("0x%016jx:%u[%u] (Memory)",
237c359a213Smsaitoh 			    (uintmax_t)gas->Address, gas->BitOffset,
238c359a213Smsaitoh 			    gas->BitWidth);
23909f2089bScegger 		break;
24050d91653Smsaitoh 	case ACPI_ADR_SPACE_SYSTEM_IO:
241c359a213Smsaitoh 		printf("0x%02x:%u[%u] (IO)", (u_int)gas->Address,
24209f2089bScegger 		    gas->BitOffset, gas->BitWidth);
24309f2089bScegger 		break;
24450d91653Smsaitoh 	case ACPI_ADR_SPACE_PCI_CONFIG:
24509f2089bScegger 		printf("%x:%x+0x%x (PCI)", (uint16_t)(gas->Address >> 32),
24609f2089bScegger 		       (uint16_t)((gas->Address >> 16) & 0xffff),
24709f2089bScegger 		       (uint16_t)gas->Address);
24809f2089bScegger 		break;
24909f2089bScegger 	/* XXX How to handle these below? */
25050d91653Smsaitoh 	case ACPI_ADR_SPACE_EC:
25109f2089bScegger 		printf("0x%x:%u[%u] (EC)", (uint16_t)gas->Address,
25209f2089bScegger 		       gas->BitOffset, gas->BitWidth);
25309f2089bScegger 		break;
25450d91653Smsaitoh 	case ACPI_ADR_SPACE_SMBUS:
25509f2089bScegger 		printf("0x%x:%u[%u] (SMBus)", (uint16_t)gas->Address,
25609f2089bScegger 		       gas->BitOffset, gas->BitWidth);
25709f2089bScegger 		break;
25850d91653Smsaitoh 	case ACPI_ADR_SPACE_CMOS:
25950d91653Smsaitoh 	case ACPI_ADR_SPACE_PCI_BAR_TARGET:
26050d91653Smsaitoh 	case ACPI_ADR_SPACE_IPMI:
26150d91653Smsaitoh 	case ACPI_ADR_SPACE_GPIO:
26250d91653Smsaitoh 	case ACPI_ADR_SPACE_GSBUS:
26350d91653Smsaitoh 	case ACPI_ADR_SPACE_PLATFORM_COMM:
26450d91653Smsaitoh 	case ACPI_ADR_SPACE_FIXED_HARDWARE:
26509f2089bScegger 	default:
266084106f3Smsaitoh 		printf("0x%016jx (SpaceID=%hhu)", (uintmax_t)gas->Address,
267084106f3Smsaitoh 		    gas->SpaceId);
26809f2089bScegger 		break;
26909f2089bScegger 	}
27053e202c1Schristos }
27153e202c1Schristos 
27253e202c1Schristos static void
acpi_print_pci(uint16_t vendorid,uint16_t deviceid,uint8_t seg,uint8_t bus,uint8_t device,uint8_t func)27309f2089bScegger acpi_print_pci(uint16_t vendorid, uint16_t deviceid,
27409f2089bScegger     uint8_t seg, uint8_t bus, uint8_t device, uint8_t func)
27553e202c1Schristos {
27609f2089bScegger 	if (vendorid == 0xffff && deviceid == 0xffff) {
27709f2089bScegger 		printf("\tPCI Device=NONE\n");
27809f2089bScegger 		return;
27909f2089bScegger 	}
28053e202c1Schristos 
28109f2089bScegger 	printf("\tPCI device={\n");
28209f2089bScegger 	printf("\t\tVendor=0x%x\n", vendorid);
28309f2089bScegger 	printf("\t\tDevice=0x%x\n", deviceid);
28409f2089bScegger 	printf("\n");
28509f2089bScegger 	printf("\t\tSegment Group=%d\n", seg);
28609f2089bScegger 	printf("\t\tBus=%d\n", bus);
28709f2089bScegger 	printf("\t\tDevice=%d\n", device);
28809f2089bScegger 	printf("\t\tFunction=%d\n", func);
28909f2089bScegger 	printf("\t}\n");
29053e202c1Schristos }
29153e202c1Schristos 
29253e202c1Schristos static void
acpi_print_pci_sbdf(uint8_t seg,uint8_t bus,uint8_t device,uint8_t func)2935d527485Smsaitoh acpi_print_pci_sbdf(uint8_t seg, uint8_t bus, uint8_t device, uint8_t func)
29453e202c1Schristos {
29509f2089bScegger 	if (bus == 0xff && device == 0xff && func == 0xff) {
29609f2089bScegger 		printf("\tPCI Device=NONE\n");
29709f2089bScegger 		return;
29853e202c1Schristos 	}
29953e202c1Schristos 
30009f2089bScegger 	printf("\tPCI device={\n");
30109f2089bScegger 	printf("\t\tSegment Group=%d\n", seg);
30209f2089bScegger 	printf("\t\tBus=%d\n", bus);
30309f2089bScegger 	printf("\t\tDevice=%d\n", device);
30409f2089bScegger 	printf("\t\tFunction=%d\n", func);
30509f2089bScegger 	printf("\t}\n");
30609f2089bScegger }
30709f2089bScegger 
30809f2089bScegger #ifdef notyet
30909f2089bScegger static void
acpi_print_hest_errorseverity(uint32_t error)31009f2089bScegger acpi_print_hest_errorseverity(uint32_t error)
31109f2089bScegger {
31209f2089bScegger 	printf("\tError Severity={ ");
31309f2089bScegger 	switch (error) {
31409f2089bScegger 	case 0:
31509f2089bScegger 		printf("Recoverable");
31609f2089bScegger 		break;
31709f2089bScegger 	case 1:
31809f2089bScegger 		printf("Fatal");
31909f2089bScegger 		break;
32009f2089bScegger 	case 2:
32109f2089bScegger 		printf("Corrected");
32209f2089bScegger 		break;
32309f2089bScegger 	case 3:
32409f2089bScegger 		printf("None");
32509f2089bScegger 		break;
32609f2089bScegger 	default:
32709f2089bScegger 		printf("%d (reserved)", error);
32809f2089bScegger 		break;
32909f2089bScegger 	}
33009f2089bScegger 	printf("}\n");
33109f2089bScegger }
33209f2089bScegger #endif
33309f2089bScegger 
33409f2089bScegger static void
acpi_print_hest_errorbank(ACPI_HEST_IA_ERROR_BANK * bank)33509f2089bScegger acpi_print_hest_errorbank(ACPI_HEST_IA_ERROR_BANK *bank)
33609f2089bScegger {
33709f2089bScegger 	printf("\n");
33809f2089bScegger 	printf("\tBank Number=%d\n", bank->BankNumber);
33909f2089bScegger 	printf("\tClear Status On Init={%s}\n",
34009f2089bScegger 		bank->ClearStatusOnInit ? "NO" : "YES");
34109f2089bScegger 	printf("\tStatus Data Format={ ");
34209f2089bScegger 	switch (bank->StatusFormat) {
34309f2089bScegger 	case 0:
34409f2089bScegger 		printf("IA32 MCA");
34509f2089bScegger 		break;
34609f2089bScegger 	case 1:
34709f2089bScegger 		printf("EMT64 MCA");
34809f2089bScegger 		break;
34909f2089bScegger 	case 2:
35009f2089bScegger 		printf("AMD64 MCA");
35109f2089bScegger 		break;
35209f2089bScegger 	}
35309f2089bScegger 	printf(" }\n");
35409f2089bScegger 
35509f2089bScegger 	if (bank->ControlRegister)
35609f2089bScegger 		printf("\tControl Register=0x%x\n", bank->ControlRegister);
35709f2089bScegger 	printf("\tControl Init Data=0x%"PRIx64"\n", bank->ControlData);
35809f2089bScegger 	printf("\tStatus MSR=0x%x\n", bank->StatusRegister);
35909f2089bScegger 	printf("\tAddress MSR=0x%x\n", bank->AddressRegister);
36009f2089bScegger 	printf("\tMisc MSR=0x%x\n", bank->MiscRegister);
36109f2089bScegger }
36209f2089bScegger 
36309f2089bScegger static void
acpi_print_hest_header(ACPI_HEST_HEADER * hest)36409f2089bScegger acpi_print_hest_header(ACPI_HEST_HEADER *hest)
36509f2089bScegger {
36609f2089bScegger 	printf("\tType={");
36709f2089bScegger 	switch (hest->Type) {
36809f2089bScegger 	case ACPI_HEST_TYPE_IA32_CHECK:
36909f2089bScegger 		printf("IA32 Machine Check Exception");
37009f2089bScegger 		break;
37109f2089bScegger 	case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
3720f0f0fe4Smsaitoh 		printf("IA32 Corrected Machine Check");
37309f2089bScegger 		break;
37409f2089bScegger 	case ACPI_HEST_TYPE_IA32_NMI:
3750f0f0fe4Smsaitoh 		printf("IA32 Non-Maskable Interrupt");
37609f2089bScegger 		break;
37709f2089bScegger 	case ACPI_HEST_TYPE_NOT_USED3:
37809f2089bScegger 	case ACPI_HEST_TYPE_NOT_USED4:
37909f2089bScegger 	case ACPI_HEST_TYPE_NOT_USED5:
3800f0f0fe4Smsaitoh 		printf("unused type: %d", hest->Type);
38109f2089bScegger 		break;
38209f2089bScegger 	case ACPI_HEST_TYPE_AER_ROOT_PORT:
3830f0f0fe4Smsaitoh 		printf("PCI Express Root Port AER");
38409f2089bScegger 		break;
38509f2089bScegger 	case ACPI_HEST_TYPE_AER_ENDPOINT:
3860f0f0fe4Smsaitoh 		printf("PCI Express Endpoint AER");
38709f2089bScegger 		break;
38809f2089bScegger 	case ACPI_HEST_TYPE_AER_BRIDGE:
3890f0f0fe4Smsaitoh 		printf("PCI Express/PCI-X Bridge AER");
39009f2089bScegger 		break;
39109f2089bScegger 	case ACPI_HEST_TYPE_GENERIC_ERROR:
3920f0f0fe4Smsaitoh 		printf("Generic Hardware Error Source");
39309f2089bScegger 		break;
394792e611dSmsaitoh 	case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
3950f0f0fe4Smsaitoh 		printf("Generic Hardware Error Source version 2");
396792e611dSmsaitoh 		break;
39709f2089bScegger 	case ACPI_HEST_TYPE_RESERVED:
39809f2089bScegger 	default:
3990f0f0fe4Smsaitoh 		printf("Reserved (%d)", hest->Type);
40009f2089bScegger 		break;
40109f2089bScegger 	}
40209f2089bScegger 	printf("}\n");
40309f2089bScegger 	printf("\tSourceId=%d\n", hest->SourceId);
40409f2089bScegger }
40509f2089bScegger 
40609f2089bScegger static void
acpi_print_hest_aer_common(ACPI_HEST_AER_COMMON * data)40709f2089bScegger acpi_print_hest_aer_common(ACPI_HEST_AER_COMMON *data)
40809f2089bScegger {
409761e1e94Smsaitoh 
410761e1e94Smsaitoh #define PRINTFLAG(var, flag)	printflag((var), ACPI_HEST_## flag, #flag)
411761e1e94Smsaitoh 
412761e1e94Smsaitoh 	printf("\tFlags=");
413761e1e94Smsaitoh 	PRINTFLAG(data->Flags, FIRMWARE_FIRST);
414761e1e94Smsaitoh 	PRINTFLAG(data->Flags, GLOBAL);
415761e1e94Smsaitoh 	PRINTFLAG(data->Flags, GHES_ASSIST);
416761e1e94Smsaitoh 	PRINTFLAG_END();
417761e1e94Smsaitoh 
418761e1e94Smsaitoh #undef PRINTFLAG
419761e1e94Smsaitoh 
42009f2089bScegger 	printf("\tEnabled={ %s ", data->Flags ? "YES" : "NO");
42109f2089bScegger 	if (data->Flags & ACPI_HEST_FIRMWARE_FIRST)
42209f2089bScegger 		printf("(ignored) ");
42309f2089bScegger 	printf("}\n");
42409f2089bScegger 	printf("\tNumber of Record to pre-allocate=%d\n",
42509f2089bScegger 		data->RecordsToPreallocate);
42609f2089bScegger 	printf("\tMax. Sections per Record=%d\n", data->MaxSectionsPerRecord);
42709f2089bScegger 	if (!(data->Flags & ACPI_HEST_GLOBAL))
4285d527485Smsaitoh 		acpi_print_pci_sbdf(0, data->Bus, data->Device, data->Function);
42909f2089bScegger 	printf("\tDevice Control=0x%x\n", data->DeviceControl);
43009f2089bScegger 	printf("\tUncorrectable Error Mask Register=0x%x\n",
43109f2089bScegger 		data->UncorrectableMask);
43209f2089bScegger 	printf("\tUncorrectable Error Severity Register=0x%x\n",
43309f2089bScegger 		data->UncorrectableSeverity);
43409f2089bScegger 	printf("\tCorrectable Error Mask Register=0x%x\n",
43509f2089bScegger 		data->CorrectableMask);
43609f2089bScegger 	printf("\tAdvanced Capabilities Register=0x%x\n",
43709f2089bScegger 		data->AdvancedCapabilities);
43809f2089bScegger }
43909f2089bScegger 
44009f2089bScegger static void
acpi_print_hest_notify(ACPI_HEST_NOTIFY * notify)44109f2089bScegger acpi_print_hest_notify(ACPI_HEST_NOTIFY *notify)
44209f2089bScegger {
44309f2089bScegger 	printf("\tHW Error Notification={\n");
44409f2089bScegger 	printf("\t\tType={");
44509f2089bScegger 	switch (notify->Type) {
44609f2089bScegger 	case ACPI_HEST_NOTIFY_POLLED:
44709f2089bScegger 		printf("POLLED");
44809f2089bScegger 		break;
44909f2089bScegger 	case ACPI_HEST_NOTIFY_EXTERNAL:
45009f2089bScegger 		printf("EXTERN");
45109f2089bScegger 		break;
45209f2089bScegger 	case ACPI_HEST_NOTIFY_LOCAL:
45309f2089bScegger 		printf("LOCAL");
45409f2089bScegger 		break;
45509f2089bScegger 	case ACPI_HEST_NOTIFY_SCI:
45609f2089bScegger 		printf("SCI");
45709f2089bScegger 		break;
45809f2089bScegger 	case ACPI_HEST_NOTIFY_NMI:
45909f2089bScegger 		printf("NMI");
46009f2089bScegger 		break;
461792e611dSmsaitoh 	case ACPI_HEST_NOTIFY_CMCI:
462792e611dSmsaitoh 		printf("CMCI");
463792e611dSmsaitoh 		break;
464792e611dSmsaitoh 	case ACPI_HEST_NOTIFY_MCE:
465792e611dSmsaitoh 		printf("MCE");
466792e611dSmsaitoh 		break;
467792e611dSmsaitoh 	case ACPI_HEST_NOTIFY_GPIO:
468792e611dSmsaitoh 		printf("GPIO-Signal");
469792e611dSmsaitoh 		break;
470792e611dSmsaitoh 	case ACPI_HEST_NOTIFY_SEA:
471792e611dSmsaitoh 		printf("ARMv8 SEA");
472792e611dSmsaitoh 		break;
473792e611dSmsaitoh 	case ACPI_HEST_NOTIFY_SEI:
474792e611dSmsaitoh 		printf("ARMv8 SEI");
475792e611dSmsaitoh 		break;
476792e611dSmsaitoh 	case ACPI_HEST_NOTIFY_GSIV:
477792e611dSmsaitoh 		printf("External Interrupt - GSIV");
478792e611dSmsaitoh 		break;
47909f2089bScegger 	case ACPI_HEST_NOTIFY_RESERVED:
48009f2089bScegger 		printf("RESERVED");
48109f2089bScegger 		break;
48209f2089bScegger 	default:
48309f2089bScegger 		printf("%d (reserved)", notify->Type);
48409f2089bScegger 		break;
48509f2089bScegger 	}
48609f2089bScegger 	printf("}\n");
48709f2089bScegger 
48809f2089bScegger 	printf("\t\tLength=%d\n", notify->Length);
489084106f3Smsaitoh 
490084106f3Smsaitoh #define PRINTFLAG(var, flag)	printflag((var), ACPI_HEST_## flag, #flag)
491084106f3Smsaitoh 
492084106f3Smsaitoh 	printf("\t\tConfig Write Enable=");
493084106f3Smsaitoh 	PRINTFLAG(notify->ConfigWriteEnable, TYPE);
494084106f3Smsaitoh 	PRINTFLAG(notify->ConfigWriteEnable, POLL_INTERVAL);
495084106f3Smsaitoh 	PRINTFLAG(notify->ConfigWriteEnable, POLL_THRESHOLD_VALUE);
496084106f3Smsaitoh 	PRINTFLAG(notify->ConfigWriteEnable, POLL_THRESHOLD_WINDOW);
497084106f3Smsaitoh 	PRINTFLAG(notify->ConfigWriteEnable, ERR_THRESHOLD_VALUE);
498084106f3Smsaitoh 	PRINTFLAG(notify->ConfigWriteEnable, ERR_THRESHOLD_WINDOW);
499084106f3Smsaitoh 	PRINTFLAG_END();
500084106f3Smsaitoh 
501084106f3Smsaitoh #undef PRINTFLAG
50209f2089bScegger 
50309f2089bScegger 	printf("\t\tPoll Interval=%d msec\n", notify->PollInterval);
50409f2089bScegger 	printf("\t\tInterrupt Vector=%d\n", notify->Vector);
50509f2089bScegger 	printf("\t\tSwitch To Polling Threshold Value=%d\n",
50609f2089bScegger 		notify->PollingThresholdValue);
50709f2089bScegger 	printf("\t\tSwitch To Polling Threshold Window=%d msec\n",
50809f2089bScegger 		notify->PollingThresholdWindow);
50909f2089bScegger 	printf("\t\tError Threshold Value=%d\n",
51009f2089bScegger 		notify->ErrorThresholdValue);
51109f2089bScegger 	printf("\t\tError Threshold Window=%d msec\n",
51209f2089bScegger 		notify->ErrorThresholdWindow);
51309f2089bScegger 	printf("\t}\n");
51409f2089bScegger }
51509f2089bScegger 
51609f2089bScegger #ifdef notyet
51709f2089bScegger static void
acpi_print_hest_generic_status(ACPI_HEST_GENERIC_STATUS * data)51809f2089bScegger acpi_print_hest_generic_status(ACPI_HEST_GENERIC_STATUS *data)
51909f2089bScegger {
52009f2089bScegger 	uint32_t i, pos, entries;
52109f2089bScegger 	ACPI_HEST_GENERIC_DATA *gen;
52209f2089bScegger 
52309f2089bScegger 	entries = data->BlockStatus & ACPI_HEST_ERROR_ENTRY_COUNT;
52409f2089bScegger 
52509f2089bScegger 	printf("\tGeneric Error Status={\n");
52609f2089bScegger 	printf("\t\tBlock Status={ ");
52709f2089bScegger 	if (data->BlockStatus & ACPI_HEST_UNCORRECTABLE)
52809f2089bScegger 		printf("UNCORRECTABLE");
52909f2089bScegger 	if (data->BlockStatus & ACPI_HEST_CORRECTABLE)
53009f2089bScegger 		printf("CORRECTABLE");
53109f2089bScegger 	if (data->BlockStatus & ACPI_HEST_MULTIPLE_UNCORRECTABLE)
53209f2089bScegger 		printf("MULTIPLE UNCORRECTABLE");
53309f2089bScegger 	if (data->BlockStatus & ACPI_HEST_MULTIPLE_CORRECTABLE)
53409f2089bScegger 		printf("MULTIPLE CORRECTABLE");
53509f2089bScegger 	printf(" }\n");
53609f2089bScegger 	printf("\t\tEntry Count=%d\n", entries);
53709f2089bScegger 	printf("\t\tRaw Data Offset=%d\n", data->RawDataOffset);
53809f2089bScegger 	printf("\t\tRaw Data Length=%d\n", data->RawDataLength);
53909f2089bScegger 	printf("\t\tData Length=%d\n", data->DataLength);
54009f2089bScegger 	printf("\t");
54109f2089bScegger 	acpi_print_hest_errorseverity(data->ErrorSeverity);
54209f2089bScegger 	printf("\t}\n");
54309f2089bScegger 
54409f2089bScegger 	pos = sizeof(ACPI_HEST_GENERIC_STATUS);
54509f2089bScegger 	for (i = 0; i < entries; i++) {
54609f2089bScegger 		gen = (ACPI_HEST_GENERIC_DATA *)((char *)data + pos);
54709f2089bScegger 		acpi_print_hest_generic_data(gen);
54809f2089bScegger 		pos += sizeof(ACPI_HEST_GENERIC_DATA);
54909f2089bScegger 	}
55009f2089bScegger }
55109f2089bScegger #endif
55209f2089bScegger 
55309f2089bScegger #ifdef notyet
55409f2089bScegger static void
acpi_print_hest_generic_data(ACPI_HEST_GENERIC_DATA * data)55509f2089bScegger acpi_print_hest_generic_data(ACPI_HEST_GENERIC_DATA *data)
55609f2089bScegger {
55709f2089bScegger 	printf("\tGeneric Error Data={\n");
55809f2089bScegger 	printf("\t\tSectionType=");
55909f2089bScegger 	acpi_print_string((char *)data->SectionType, sizeof(data->SectionType));
56009f2089bScegger 	printf("\n\t");
56109f2089bScegger 	acpi_print_hest_errorseverity(data->ErrorSeverity);
56209f2089bScegger 	printf("\t\tRevision=0x%x\n", data->Revision);
56309f2089bScegger 	printf("\t\tValidation Bits=0x%x\n", data->ValidationBits);
56409f2089bScegger 	printf("\t\tFlags=0x%x\n", data->Flags);
56509f2089bScegger 	printf("\t\tData Length=%d\n", data->ErrorDataLength);
56609f2089bScegger 	printf("\t\tField Replication Unit Id=");
56709f2089bScegger 	acpi_print_string((char *)data->FruId, sizeof(data->FruId));
56809f2089bScegger 	printf("\n");
56909f2089bScegger 	printf("\t\tField Replication Unit=");
57009f2089bScegger 	acpi_print_string((char *)data->FruText, sizeof(data->FruText));
57109f2089bScegger 	printf("\n");
57209f2089bScegger 	printf("\t}\n");
57309f2089bScegger }
57409f2089bScegger #endif
57509f2089bScegger 
57609f2089bScegger static void
acpi_print_whea(ACPI_WHEA_HEADER * whea,void (* print_action)(ACPI_WHEA_HEADER *),void (* print_ins)(ACPI_WHEA_HEADER *),void (* print_flags)(ACPI_WHEA_HEADER *))57709f2089bScegger acpi_print_whea(ACPI_WHEA_HEADER *whea,
57809f2089bScegger     void (*print_action)(ACPI_WHEA_HEADER *),
57909f2089bScegger     void (*print_ins)(ACPI_WHEA_HEADER *),
58009f2089bScegger     void (*print_flags)(ACPI_WHEA_HEADER *))
58109f2089bScegger {
58209f2089bScegger 	printf("\n");
58309f2089bScegger 
58409f2089bScegger 	print_action(whea);
58509f2089bScegger 	print_ins(whea);
58609f2089bScegger 	if (print_flags)
58709f2089bScegger 		print_flags(whea);
58809f2089bScegger 	printf("\tRegisterRegion=");
58909f2089bScegger 	acpi_print_gas(&whea->RegisterRegion);
59009f2089bScegger 	printf("\n");
59109f2089bScegger 	printf("\tMASK=0x%08"PRIx64"\n", whea->Mask);
59209f2089bScegger }
59309f2089bScegger 
59409f2089bScegger static void
acpi_print_hest_ia32_check(ACPI_HEST_IA_MACHINE_CHECK * data)59509f2089bScegger acpi_print_hest_ia32_check(ACPI_HEST_IA_MACHINE_CHECK *data)
59609f2089bScegger {
59709f2089bScegger 	uint32_t i, pos;
59809f2089bScegger 	ACPI_HEST_IA_ERROR_BANK *bank;
59909f2089bScegger 
60009f2089bScegger 	acpi_print_hest_header(&data->Header);
60109f2089bScegger 	printf("\tFlags={ ");
60209f2089bScegger 	if (data->Flags & ACPI_HEST_FIRMWARE_FIRST)
60309f2089bScegger 		printf("FIRMWARE_FIRST");
60409f2089bScegger 	printf(" }\n");
60509f2089bScegger 	printf("\tEnabled={ %s }\n", data->Enabled ? "YES" : "NO");
60609f2089bScegger 	printf("\tNumber of Record to pre-allocate=%d\n",
60709f2089bScegger 		data->RecordsToPreallocate);
60809f2089bScegger 	printf("\tMax Sections per Record=%d\n",
60909f2089bScegger 		data->MaxSectionsPerRecord);
61009f2089bScegger 	printf("\tGlobal Capability Init Data=0x%"PRIx64"\n",
61109f2089bScegger 		data->GlobalCapabilityData);
61209f2089bScegger 	printf("\tGlobal Control Init Data=0x%"PRIx64"\n",
61309f2089bScegger 		data->GlobalControlData);
61409f2089bScegger 	printf("\tNumber of Hardware Error Reporting Banks=%d\n",
61509f2089bScegger 		data->NumHardwareBanks);
61609f2089bScegger 
61709f2089bScegger 	pos = sizeof(ACPI_HEST_IA_MACHINE_CHECK);
61809f2089bScegger 	for (i = 0; i < data->NumHardwareBanks; i++) {
61909f2089bScegger 		bank = (ACPI_HEST_IA_ERROR_BANK *)((char *)data + pos);
62009f2089bScegger 		acpi_print_hest_errorbank(bank);
62109f2089bScegger 		pos += sizeof(ACPI_HEST_IA_ERROR_BANK);
62209f2089bScegger 	}
62309f2089bScegger }
62409f2089bScegger 
62509f2089bScegger static void
acpi_print_hest_ia32_correctedcheck(ACPI_HEST_IA_CORRECTED * data)62609f2089bScegger acpi_print_hest_ia32_correctedcheck(ACPI_HEST_IA_CORRECTED *data)
62709f2089bScegger {
62809f2089bScegger 	uint32_t i, pos;
62909f2089bScegger 	ACPI_HEST_IA_ERROR_BANK *bank;
63009f2089bScegger 
63109f2089bScegger 	acpi_print_hest_header(&data->Header);
63209f2089bScegger 	printf("\tFlags={ ");
63309f2089bScegger 	if (data->Flags & ACPI_HEST_FIRMWARE_FIRST)
63409f2089bScegger 		printf("FIRMWARE_FIRST");
63509f2089bScegger 	printf(" }\n");
63609f2089bScegger 	printf("\tEnabled={ %s }\n", data->Enabled ? "YES" : "NO");
63709f2089bScegger 	printf("\tNumber of Record to pre-allocate=%d\n",
63809f2089bScegger 		data->RecordsToPreallocate);
63909f2089bScegger 	printf("\tMax Sections per Record=%d\n",
64009f2089bScegger 		data->MaxSectionsPerRecord);
64109f2089bScegger 	acpi_print_hest_notify(&data->Notify);
64209f2089bScegger 
64309f2089bScegger 	printf("\tNumber of Hardware Error Reporting Banks=%d\n",
64409f2089bScegger 		data->NumHardwareBanks);
64509f2089bScegger 
64609f2089bScegger 	pos = sizeof(ACPI_HEST_IA_MACHINE_CHECK);
64709f2089bScegger 	for (i = 0; i < data->NumHardwareBanks; i++) {
64809f2089bScegger 		bank = (ACPI_HEST_IA_ERROR_BANK *)((char *)data + pos);
64909f2089bScegger 		acpi_print_hest_errorbank(bank);
65009f2089bScegger 		pos += sizeof(ACPI_HEST_IA_ERROR_BANK);
65109f2089bScegger 	}
65209f2089bScegger }
65309f2089bScegger 
65409f2089bScegger static void
acpi_print_hest_ia32_nmi(ACPI_HEST_IA_NMI * data)65509f2089bScegger acpi_print_hest_ia32_nmi(ACPI_HEST_IA_NMI *data)
65609f2089bScegger {
65709f2089bScegger 	acpi_print_hest_header(&data->Header);
65809f2089bScegger 	printf("\tNumber of Record to pre-allocate=%d\n",
65909f2089bScegger 		data->RecordsToPreallocate);
66009f2089bScegger 	printf("\tMax Sections per Record=%d\n",
66109f2089bScegger 		data->MaxSectionsPerRecord);
66209f2089bScegger 	printf("\tMax Raw Data Length=%d\n",
66309f2089bScegger 		data->MaxRawDataLength);
66409f2089bScegger }
66509f2089bScegger 
66609f2089bScegger static void
acpi_print_hest_aer_root(ACPI_HEST_AER_ROOT * data)66709f2089bScegger acpi_print_hest_aer_root(ACPI_HEST_AER_ROOT *data)
66809f2089bScegger {
66909f2089bScegger 	acpi_print_hest_header(&data->Header);
67009f2089bScegger 	acpi_print_hest_aer_common(&data->Aer);
67109f2089bScegger 	printf("Root Error Command Register=0x%x\n", data->RootErrorCommand);
67209f2089bScegger }
67309f2089bScegger 
67409f2089bScegger static void
acpi_print_hest_aer_endpoint(ACPI_HEST_AER * data)67509f2089bScegger acpi_print_hest_aer_endpoint(ACPI_HEST_AER *data)
67609f2089bScegger {
67709f2089bScegger 	acpi_print_hest_header(&data->Header);
67809f2089bScegger 	acpi_print_hest_aer_common(&data->Aer);
67909f2089bScegger }
68009f2089bScegger 
68109f2089bScegger static void
acpi_print_hest_aer_bridge(ACPI_HEST_AER_BRIDGE * data)68209f2089bScegger acpi_print_hest_aer_bridge(ACPI_HEST_AER_BRIDGE *data)
68309f2089bScegger {
68409f2089bScegger 	acpi_print_hest_header(&data->Header);
68509f2089bScegger 	acpi_print_hest_aer_common(&data->Aer);
68609f2089bScegger 
68709f2089bScegger 	printf("\tSecondary Uncorrectable Error Mask Register=0x%x\n",
68809f2089bScegger 		data->UncorrectableMask2);
68909f2089bScegger 	printf("\tSecondary Uncorrectable Error Severity Register=0x%x\n",
69009f2089bScegger 		data->UncorrectableSeverity2);
69109f2089bScegger 	printf("\tSecondory Advanced Capabilities Register=0x%x\n",
69209f2089bScegger 		data->AdvancedCapabilities2);
69309f2089bScegger }
69409f2089bScegger 
69509f2089bScegger static void
acpi_print_hest_generic(ACPI_HEST_GENERIC * data)69609f2089bScegger acpi_print_hest_generic(ACPI_HEST_GENERIC *data)
69709f2089bScegger {
69809f2089bScegger 	acpi_print_hest_header(&data->Header);
69909f2089bScegger 	if (data->RelatedSourceId != 0xffff)
70009f2089bScegger 		printf("\tReleated SourceId=%d\n", data->RelatedSourceId);
70109f2089bScegger 	printf("\tEnabled={%s}\n", data->Enabled ? "YES" : "NO");
702084106f3Smsaitoh 	printf("\tNumber of Records to pre-allocate=%u\n",
70309f2089bScegger 		data->RecordsToPreallocate);
704084106f3Smsaitoh 	printf("\tMax Sections per Record=%u\n", data->MaxSectionsPerRecord);
705084106f3Smsaitoh 	printf("\tMax Raw Data Length=%u\n", data->MaxRawDataLength);
70609f2089bScegger 	printf("\tError Status Address=");
70709f2089bScegger 	acpi_print_gas(&data->ErrorStatusAddress);
7080f0f0fe4Smsaitoh 	printf("\n");
70909f2089bScegger 	acpi_print_hest_notify(&data->Notify);
710084106f3Smsaitoh 	printf("\tError Block Length=%u\n", data->ErrorBlockLength);
71109f2089bScegger }
71209f2089bScegger 
71309f2089bScegger static void
acpi_print_hest_generic_v2(ACPI_HEST_GENERIC_V2 * data)714792e611dSmsaitoh acpi_print_hest_generic_v2(ACPI_HEST_GENERIC_V2 *data)
715792e611dSmsaitoh {
716792e611dSmsaitoh 
717792e611dSmsaitoh 	/* The first 64 bytes are the same as ACPI_HEST_GENERIC */
718792e611dSmsaitoh 	acpi_print_hest_generic((ACPI_HEST_GENERIC *)data);
719792e611dSmsaitoh 
720792e611dSmsaitoh 	printf("\tError Status Address");
721792e611dSmsaitoh 	acpi_print_gas(&data->ReadAckRegister);
722800ead4eSmsaitoh 	printf("\n\tRead Ack Preserve=0x%016jx\n",
723792e611dSmsaitoh 	    (uintmax_t)data->ReadAckPreserve);
724792e611dSmsaitoh 	printf("\tRead Ack Write=0x%016jx\n",
725792e611dSmsaitoh 	    (uintmax_t)data->ReadAckWrite);
726792e611dSmsaitoh }
727792e611dSmsaitoh 
728792e611dSmsaitoh static void
acpi_handle_hest(ACPI_TABLE_HEADER * sdp)72909f2089bScegger acpi_handle_hest(ACPI_TABLE_HEADER *sdp)
73009f2089bScegger {
73109f2089bScegger 	ACPI_TABLE_HEST *hest;
73209f2089bScegger 	ACPI_HEST_HEADER *subhest;
73309f2089bScegger 	uint32_t i, pos;
73409f2089bScegger 
73509f2089bScegger 	printf(BEGIN_COMMENT);
73609f2089bScegger 	acpi_print_sdt(sdp);
73709f2089bScegger 	hest = (ACPI_TABLE_HEST *)sdp;
73809f2089bScegger 
73909f2089bScegger 	printf("\tError Source Count=%d\n", hest->ErrorSourceCount);
74009f2089bScegger 	pos = sizeof(ACPI_TABLE_HEST);
74109f2089bScegger 	for (i = 0; i < hest->ErrorSourceCount; i++) {
74209f2089bScegger 		subhest = (ACPI_HEST_HEADER *)((char *)hest + pos);
74309f2089bScegger 		printf("\n");
74409f2089bScegger 
74509f2089bScegger 		switch (subhest->Type) {
74609f2089bScegger 		case ACPI_HEST_TYPE_IA32_CHECK:
747084106f3Smsaitoh 			acpi_print_hest_ia32_check(
748084106f3Smsaitoh 				(ACPI_HEST_IA_MACHINE_CHECK *)subhest);
74909f2089bScegger 			pos += sizeof(ACPI_HEST_IA_MACHINE_CHECK);
75009f2089bScegger 			break;
75109f2089bScegger 
75209f2089bScegger 		case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK:
753084106f3Smsaitoh 			acpi_print_hest_ia32_correctedcheck(
754084106f3Smsaitoh 				(ACPI_HEST_IA_CORRECTED *)subhest);
75509f2089bScegger 			pos += sizeof(ACPI_HEST_IA_CORRECTED);
75609f2089bScegger 			break;
75709f2089bScegger 
75809f2089bScegger 		case ACPI_HEST_TYPE_IA32_NMI:
759084106f3Smsaitoh 			acpi_print_hest_ia32_nmi(
760084106f3Smsaitoh 				(ACPI_HEST_IA_NMI *)subhest);
76109f2089bScegger 			pos += sizeof(ACPI_HEST_IA_NMI);
76209f2089bScegger 			break;
76309f2089bScegger 
76409f2089bScegger 		case ACPI_HEST_TYPE_NOT_USED3:
76509f2089bScegger 		case ACPI_HEST_TYPE_NOT_USED4:
76609f2089bScegger 		case ACPI_HEST_TYPE_NOT_USED5:
76709f2089bScegger 			pos += sizeof(ACPI_HEST_HEADER);
76809f2089bScegger 			break;
76909f2089bScegger 
77009f2089bScegger 		case ACPI_HEST_TYPE_AER_ROOT_PORT:
771084106f3Smsaitoh 			acpi_print_hest_aer_root((ACPI_HEST_AER_ROOT *)subhest);
77209f2089bScegger 			pos += sizeof(ACPI_HEST_AER_ROOT);
77309f2089bScegger 			break;
77409f2089bScegger 
77509f2089bScegger 		case ACPI_HEST_TYPE_AER_ENDPOINT:
776084106f3Smsaitoh 			acpi_print_hest_aer_endpoint((ACPI_HEST_AER *)subhest);
777084106f3Smsaitoh 			pos += sizeof(ACPI_HEST_AER);
77809f2089bScegger 			break;
77909f2089bScegger 
78009f2089bScegger 		case ACPI_HEST_TYPE_AER_BRIDGE:
781084106f3Smsaitoh 			acpi_print_hest_aer_bridge((ACPI_HEST_AER_BRIDGE *)subhest);
78209f2089bScegger 			pos += sizeof(ACPI_HEST_AER_BRIDGE);
78309f2089bScegger 			break;
78409f2089bScegger 
78509f2089bScegger 		case ACPI_HEST_TYPE_GENERIC_ERROR:
786084106f3Smsaitoh 			acpi_print_hest_generic((ACPI_HEST_GENERIC *)subhest);
78709f2089bScegger 			pos += sizeof(ACPI_HEST_GENERIC);
78809f2089bScegger 			break;
78909f2089bScegger 
790792e611dSmsaitoh 		case ACPI_HEST_TYPE_GENERIC_ERROR_V2:
791084106f3Smsaitoh 			acpi_print_hest_generic_v2(
792084106f3Smsaitoh 				(ACPI_HEST_GENERIC_V2 *)subhest);
793792e611dSmsaitoh 			pos += sizeof(ACPI_HEST_GENERIC_V2);
794792e611dSmsaitoh 			break;
795792e611dSmsaitoh 
79609f2089bScegger 		case ACPI_HEST_TYPE_RESERVED:
79709f2089bScegger 		default:
79809f2089bScegger 			pos += sizeof(ACPI_HEST_HEADER);
79909f2089bScegger 			break;
80009f2089bScegger 		}
80109f2089bScegger 	}
80209f2089bScegger 
80309f2089bScegger 	printf(END_COMMENT);
80409f2089bScegger }
80509f2089bScegger 
8068f0f46f9Smsaitoh static uint64_t
acpi_select_address(uint32_t addr32,uint64_t addr64)8078f0f46f9Smsaitoh acpi_select_address(uint32_t addr32, uint64_t addr64)
8088f0f46f9Smsaitoh {
8098f0f46f9Smsaitoh 
8108f0f46f9Smsaitoh 	if (addr64 == 0)
8118f0f46f9Smsaitoh 		return addr32;
8128f0f46f9Smsaitoh 
8138f0f46f9Smsaitoh 	if ((addr32 != 0) && ((addr64 & 0xfffffff) != addr32)) {
8148f0f46f9Smsaitoh 		/*
8158f0f46f9Smsaitoh 		 * A few systems (e.g., IBM T23) have an RSDP that claims
8168f0f46f9Smsaitoh 		 * revision 2 but the 64 bit addresses are invalid.  If
8178f0f46f9Smsaitoh 		 * revision 2 and the 32 bit address is non-zero but the
8188f0f46f9Smsaitoh 		 * 32 and 64 bit versions don't match, prefer the 32 bit
8198f0f46f9Smsaitoh 		 * version for all subsequent tables.
8208f0f46f9Smsaitoh 		 */
8218f0f46f9Smsaitoh 		return addr32;
8228f0f46f9Smsaitoh 	}
8238f0f46f9Smsaitoh 
8248f0f46f9Smsaitoh 	return addr64;
8258f0f46f9Smsaitoh }
8268f0f46f9Smsaitoh 
82709f2089bScegger static void
acpi_handle_fadt(ACPI_TABLE_HEADER * sdp)82809f2089bScegger acpi_handle_fadt(ACPI_TABLE_HEADER *sdp)
82953e202c1Schristos {
83009f2089bScegger 	ACPI_TABLE_HEADER *dsdp;
83109f2089bScegger 	ACPI_TABLE_FACS	*facs;
83209f2089bScegger 	ACPI_TABLE_FADT *fadt;
83309f2089bScegger 
83409f2089bScegger 	fadt = (ACPI_TABLE_FADT *)sdp;
83509f2089bScegger 	acpi_print_fadt(sdp);
83609f2089bScegger 
83743db5d20Sjmcneill 	if (acpi_select_address(fadt->Facs, fadt->XFacs) == 0) {
83843db5d20Sjmcneill 		if ((fadt->Flags & ACPI_FADT_HW_REDUCED) == 0)
83943db5d20Sjmcneill 			errx(EXIT_FAILURE, "Missing FACS and HW_REDUCED_ACPI flag not set in FADT");
840962d94c5Sjmcneill 	} else if ((fadt->Flags & ACPI_FADT_HW_REDUCED) == 0) {
8418f0f46f9Smsaitoh 		facs = (ACPI_TABLE_FACS *)acpi_map_sdt(
8428f0f46f9Smsaitoh 			acpi_select_address(fadt->Facs, fadt->XFacs));
84309f2089bScegger 		if (memcmp(facs->Signature, ACPI_SIG_FACS, 4) != 0 || facs->Length < 64)
84409f2089bScegger 			errx(EXIT_FAILURE, "FACS is corrupt");
84509f2089bScegger 		acpi_print_facs(facs);
84643db5d20Sjmcneill 	}
84709f2089bScegger 
8488f0f46f9Smsaitoh 	dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(
8498f0f46f9Smsaitoh 		acpi_select_address(fadt->Dsdt, fadt->XDsdt));
8509ffd9444Smsaitoh 	if (memcmp(dsdp->Signature, ACPI_SIG_DSDT, 4) != 0)
8519ffd9444Smsaitoh 		errx(EXIT_FAILURE, "DSDT signature mismatch");
85209f2089bScegger 	if (acpi_checksum(dsdp, dsdp->Length))
85309f2089bScegger 		errx(EXIT_FAILURE, "DSDT is corrupt");
85409f2089bScegger 	acpi_print_dsdt(dsdp);
85509f2089bScegger }
85609f2089bScegger 
85709f2089bScegger static void
acpi_walk_subtables(ACPI_TABLE_HEADER * table,void * first,void (* action)(ACPI_SUBTABLE_HEADER *))85809f2089bScegger acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
85909f2089bScegger     void (*action)(ACPI_SUBTABLE_HEADER *))
86009f2089bScegger {
86109f2089bScegger 	ACPI_SUBTABLE_HEADER *subtable;
86209f2089bScegger 	char *end;
86309f2089bScegger 
86409f2089bScegger 	subtable = first;
86509f2089bScegger 	end = (char *)table + table->Length;
86609f2089bScegger 	while ((char *)subtable < end) {
86709f2089bScegger 		printf("\n");
868c359a213Smsaitoh 		if (subtable->Length < sizeof(ACPI_SUBTABLE_HEADER)) {
869c359a213Smsaitoh 			warnx("invalid subtable length %u", subtable->Length);
870c359a213Smsaitoh 			return;
871c359a213Smsaitoh 		}
87209f2089bScegger 		action(subtable);
87309f2089bScegger 		subtable = (ACPI_SUBTABLE_HEADER *)((char *)subtable +
87409f2089bScegger 		    subtable->Length);
87509f2089bScegger 	}
87609f2089bScegger }
87709f2089bScegger 
87809f2089bScegger static void
acpi_walk_nfit(ACPI_TABLE_HEADER * table,void * first,void (* action)(ACPI_NFIT_HEADER *))879792e611dSmsaitoh acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first,
880792e611dSmsaitoh     void (*action)(ACPI_NFIT_HEADER *))
881792e611dSmsaitoh {
882792e611dSmsaitoh 	ACPI_NFIT_HEADER *subtable;
883792e611dSmsaitoh 	char *end;
884792e611dSmsaitoh 
885792e611dSmsaitoh 	subtable = first;
886792e611dSmsaitoh 	end = (char *)table + table->Length;
887792e611dSmsaitoh 	while ((char *)subtable < end) {
888792e611dSmsaitoh 		printf("\n");
889792e611dSmsaitoh 		if (subtable->Length < sizeof(ACPI_NFIT_HEADER)) {
890792e611dSmsaitoh 			warnx("invalid subtable length %u", subtable->Length);
891792e611dSmsaitoh 			return;
892792e611dSmsaitoh 		}
893792e611dSmsaitoh 		action(subtable);
894792e611dSmsaitoh 		subtable = (ACPI_NFIT_HEADER *)((char *)subtable +
895792e611dSmsaitoh 		    subtable->Length);
896792e611dSmsaitoh 	}
897792e611dSmsaitoh }
898792e611dSmsaitoh 
899792e611dSmsaitoh static void
acpi_print_cpu(u_char cpu_id)90009f2089bScegger acpi_print_cpu(u_char cpu_id)
90109f2089bScegger {
90209f2089bScegger 
90309f2089bScegger 	printf("\tACPI CPU=");
90409f2089bScegger 	if (cpu_id == 0xff)
90509f2089bScegger 		printf("ALL\n");
90609f2089bScegger 	else
90709f2089bScegger 		printf("%d\n", (u_int)cpu_id);
90809f2089bScegger }
90909f2089bScegger 
91009f2089bScegger static void
acpi_print_cpu_uid(uint32_t uid,char * uid_string)91109f2089bScegger acpi_print_cpu_uid(uint32_t uid, char *uid_string)
91209f2089bScegger {
91309f2089bScegger 
91409f2089bScegger 	printf("\tUID=%d", uid);
91509f2089bScegger 	if (uid_string != NULL)
91609f2089bScegger 		printf(" (%s)", uid_string);
91709f2089bScegger 	printf("\n");
91809f2089bScegger }
91909f2089bScegger 
92009f2089bScegger static void
acpi_print_local_apic(uint32_t apic_id,uint32_t flags)92109f2089bScegger acpi_print_local_apic(uint32_t apic_id, uint32_t flags)
92209f2089bScegger {
92309f2089bScegger 
92409f2089bScegger 	printf("\tFlags={");
92509f2089bScegger 	if (flags & ACPI_MADT_ENABLED)
92609f2089bScegger 		printf("ENABLED");
92709f2089bScegger 	else
92809f2089bScegger 		printf("DISABLED");
92909f2089bScegger 	printf("}\n");
93009f2089bScegger 	printf("\tAPIC ID=%d\n", apic_id);
93109f2089bScegger }
93209f2089bScegger 
93309f2089bScegger static void
acpi_print_io_apic(uint32_t apic_id,uint32_t int_base,uint64_t apic_addr)93409f2089bScegger acpi_print_io_apic(uint32_t apic_id, uint32_t int_base, uint64_t apic_addr)
93509f2089bScegger {
93609f2089bScegger 
93709f2089bScegger 	printf("\tAPIC ID=%d\n", apic_id);
93809f2089bScegger 	printf("\tINT BASE=%d\n", int_base);
93909f2089bScegger 	printf("\tADDR=0x%016jx\n", (uintmax_t)apic_addr);
94009f2089bScegger }
94109f2089bScegger 
94209f2089bScegger static void
acpi_print_mps_flags(uint16_t flags)94309f2089bScegger acpi_print_mps_flags(uint16_t flags)
94409f2089bScegger {
94509f2089bScegger 
94609f2089bScegger 	printf("\tFlags={Polarity=");
94709f2089bScegger 	switch (flags & ACPI_MADT_POLARITY_MASK) {
94809f2089bScegger 	case ACPI_MADT_POLARITY_CONFORMS:
94909f2089bScegger 		printf("conforming");
95009f2089bScegger 		break;
95109f2089bScegger 	case ACPI_MADT_POLARITY_ACTIVE_HIGH:
95209f2089bScegger 		printf("active-hi");
95309f2089bScegger 		break;
95409f2089bScegger 	case ACPI_MADT_POLARITY_ACTIVE_LOW:
95509f2089bScegger 		printf("active-lo");
95609f2089bScegger 		break;
95709f2089bScegger 	default:
95809f2089bScegger 		printf("0x%x", flags & ACPI_MADT_POLARITY_MASK);
95909f2089bScegger 		break;
96009f2089bScegger 	}
96109f2089bScegger 	printf(", Trigger=");
96209f2089bScegger 	switch (flags & ACPI_MADT_TRIGGER_MASK) {
96309f2089bScegger 	case ACPI_MADT_TRIGGER_CONFORMS:
96409f2089bScegger 		printf("conforming");
96509f2089bScegger 		break;
96609f2089bScegger 	case ACPI_MADT_TRIGGER_EDGE:
96709f2089bScegger 		printf("edge");
96809f2089bScegger 		break;
96909f2089bScegger 	case ACPI_MADT_TRIGGER_LEVEL:
97009f2089bScegger 		printf("level");
97109f2089bScegger 		break;
97209f2089bScegger 	default:
97309f2089bScegger 		printf("0x%x", (flags & ACPI_MADT_TRIGGER_MASK) >> 2);
97409f2089bScegger 	}
97509f2089bScegger 	printf("}\n");
97609f2089bScegger }
97709f2089bScegger 
97809f2089bScegger static void
acpi_print_gicc_flags(uint32_t flags)979c359a213Smsaitoh acpi_print_gicc_flags(uint32_t flags)
980c359a213Smsaitoh {
981c359a213Smsaitoh 
982f1a52620Sskrll 	printf("\tFlags={");
983f1a52620Sskrll 	if (flags & ACPI_MADT_ENABLED)
984f1a52620Sskrll 		printf("enabled");
985f1a52620Sskrll 	else
986f1a52620Sskrll 		printf("disabled");
987f1a52620Sskrll 	printf(", Performance intr=");
988c359a213Smsaitoh 	if (flags & ACPI_MADT_PERFORMANCE_IRQ_MODE)
989c359a213Smsaitoh 		printf("edge");
990c359a213Smsaitoh 	else
991c359a213Smsaitoh 		printf("level");
992c359a213Smsaitoh 	printf(", VGIC intr=");
993c359a213Smsaitoh 	if (flags & ACPI_MADT_VGIC_IRQ_MODE)
994c359a213Smsaitoh 		printf("edge");
995c359a213Smsaitoh 	else
996c359a213Smsaitoh 		printf("level");
997c359a213Smsaitoh 	printf("}\n");
998c359a213Smsaitoh }
999c359a213Smsaitoh 
1000c359a213Smsaitoh static void
acpi_print_intr(uint32_t intr,uint16_t mps_flags)100109f2089bScegger acpi_print_intr(uint32_t intr, uint16_t mps_flags)
100209f2089bScegger {
100309f2089bScegger 
100409f2089bScegger 	printf("\tINTR=%d\n", intr);
100509f2089bScegger 	acpi_print_mps_flags(mps_flags);
100609f2089bScegger }
100709f2089bScegger 
100809f2089bScegger static void
acpi_print_local_nmi(u_int local_int,uint16_t mps_flags)1009bbb9ad67Srillig acpi_print_local_nmi(u_int local_int, uint16_t mps_flags)
101009f2089bScegger {
101109f2089bScegger 
1012bbb9ad67Srillig 	printf("\tLINT Pin=%d\n", local_int);
101309f2089bScegger 	acpi_print_mps_flags(mps_flags);
101409f2089bScegger }
101509f2089bScegger 
1016c359a213Smsaitoh static const char *apic_types[] = {
1017c359a213Smsaitoh     [ACPI_MADT_TYPE_LOCAL_APIC] = "Local APIC",
1018c359a213Smsaitoh     [ACPI_MADT_TYPE_IO_APIC] = "IO APIC",
1019c359a213Smsaitoh     [ACPI_MADT_TYPE_INTERRUPT_OVERRIDE] = "INT Override",
1020c359a213Smsaitoh     [ACPI_MADT_TYPE_NMI_SOURCE] = "NMI",
1021c359a213Smsaitoh     [ACPI_MADT_TYPE_LOCAL_APIC_NMI] = "Local APIC NMI",
1022c359a213Smsaitoh     [ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE] = "Local APIC Override",
1023c359a213Smsaitoh     [ACPI_MADT_TYPE_IO_SAPIC] = "IO SAPIC",
1024c359a213Smsaitoh     [ACPI_MADT_TYPE_LOCAL_SAPIC] = "Local SAPIC",
1025c359a213Smsaitoh     [ACPI_MADT_TYPE_INTERRUPT_SOURCE] = "Platform Interrupt",
1026c359a213Smsaitoh     [ACPI_MADT_TYPE_LOCAL_X2APIC] = "Local X2APIC",
1027c359a213Smsaitoh     [ACPI_MADT_TYPE_LOCAL_X2APIC_NMI] = "Local X2APIC NMI",
1028c359a213Smsaitoh     [ACPI_MADT_TYPE_GENERIC_INTERRUPT] = "GIC CPU Interface Structure",
1029c359a213Smsaitoh     [ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR] = "GIC Distributor Structure",
1030c359a213Smsaitoh     [ACPI_MADT_TYPE_GENERIC_MSI_FRAME] = "GICv2m MSI Frame",
1031c359a213Smsaitoh     [ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR] = "GIC Redistributor Structure",
1032c359a213Smsaitoh     [ACPI_MADT_TYPE_GENERIC_TRANSLATOR] = "GIC ITS Structure"
1033c359a213Smsaitoh };
1034c359a213Smsaitoh 
1035c359a213Smsaitoh static const char *platform_int_types[] = { "0 (unknown)", "PMI", "INIT",
103609f2089bScegger 					    "Corrected Platform Error" };
103709f2089bScegger 
103809f2089bScegger static void
acpi_print_gicm_flags(ACPI_MADT_GENERIC_MSI_FRAME * gicm)1039792e611dSmsaitoh acpi_print_gicm_flags(ACPI_MADT_GENERIC_MSI_FRAME *gicm)
1040792e611dSmsaitoh {
1041792e611dSmsaitoh 	uint32_t flags = gicm->Flags;
1042792e611dSmsaitoh 
1043792e611dSmsaitoh 	printf("\tFLAGS={");
1044792e611dSmsaitoh 	if (flags & ACPI_MADT_OVERRIDE_SPI_VALUES)
1045792e611dSmsaitoh 		printf("SPI Count/Base Select");
1046792e611dSmsaitoh 	printf("}\n");
1047792e611dSmsaitoh }
1048792e611dSmsaitoh 
1049792e611dSmsaitoh static void
acpi_print_madt(ACPI_SUBTABLE_HEADER * mp)105009f2089bScegger acpi_print_madt(ACPI_SUBTABLE_HEADER *mp)
105109f2089bScegger {
105209f2089bScegger 	ACPI_MADT_LOCAL_APIC *lapic;
105309f2089bScegger 	ACPI_MADT_IO_APIC *ioapic;
105409f2089bScegger 	ACPI_MADT_INTERRUPT_OVERRIDE *over;
105509f2089bScegger 	ACPI_MADT_NMI_SOURCE *nmi;
105609f2089bScegger 	ACPI_MADT_LOCAL_APIC_NMI *lapic_nmi;
105709f2089bScegger 	ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic_over;
105809f2089bScegger 	ACPI_MADT_IO_SAPIC *iosapic;
105909f2089bScegger 	ACPI_MADT_LOCAL_SAPIC *lsapic;
106009f2089bScegger 	ACPI_MADT_INTERRUPT_SOURCE *isrc;
106109f2089bScegger 	ACPI_MADT_LOCAL_X2APIC *x2apic;
106209f2089bScegger 	ACPI_MADT_LOCAL_X2APIC_NMI *x2apic_nmi;
1063c359a213Smsaitoh 	ACPI_MADT_GENERIC_INTERRUPT *gicc;
1064c359a213Smsaitoh 	ACPI_MADT_GENERIC_DISTRIBUTOR *gicd;
1065792e611dSmsaitoh 	ACPI_MADT_GENERIC_MSI_FRAME *gicm;
1066c359a213Smsaitoh 	ACPI_MADT_GENERIC_REDISTRIBUTOR *gicr;
1067c359a213Smsaitoh 	ACPI_MADT_GENERIC_TRANSLATOR *gict;
106809f2089bScegger 
1069c359a213Smsaitoh 	if (mp->Type < __arraycount(apic_types))
107009f2089bScegger 		printf("\tType=%s\n", apic_types[mp->Type]);
107109f2089bScegger 	else
107209f2089bScegger 		printf("\tType=%d (unknown)\n", mp->Type);
107309f2089bScegger 	switch (mp->Type) {
107409f2089bScegger 	case ACPI_MADT_TYPE_LOCAL_APIC:
107509f2089bScegger 		lapic = (ACPI_MADT_LOCAL_APIC *)mp;
107609f2089bScegger 		acpi_print_cpu(lapic->ProcessorId);
107709f2089bScegger 		acpi_print_local_apic(lapic->Id, lapic->LapicFlags);
107809f2089bScegger 		break;
107909f2089bScegger 	case ACPI_MADT_TYPE_IO_APIC:
108009f2089bScegger 		ioapic = (ACPI_MADT_IO_APIC *)mp;
108109f2089bScegger 		acpi_print_io_apic(ioapic->Id, ioapic->GlobalIrqBase,
108209f2089bScegger 		    ioapic->Address);
108309f2089bScegger 		break;
108409f2089bScegger 	case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
108509f2089bScegger 		over = (ACPI_MADT_INTERRUPT_OVERRIDE *)mp;
108609f2089bScegger 		printf("\tBUS=%d\n", (u_int)over->Bus);
108709f2089bScegger 		printf("\tIRQ=%d\n", (u_int)over->SourceIrq);
108809f2089bScegger 		acpi_print_intr(over->GlobalIrq, over->IntiFlags);
108909f2089bScegger 		break;
109009f2089bScegger 	case ACPI_MADT_TYPE_NMI_SOURCE:
109109f2089bScegger 		nmi = (ACPI_MADT_NMI_SOURCE *)mp;
109209f2089bScegger 		acpi_print_intr(nmi->GlobalIrq, nmi->IntiFlags);
109309f2089bScegger 		break;
109409f2089bScegger 	case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
109509f2089bScegger 		lapic_nmi = (ACPI_MADT_LOCAL_APIC_NMI *)mp;
109609f2089bScegger 		acpi_print_cpu(lapic_nmi->ProcessorId);
109709f2089bScegger 		acpi_print_local_nmi(lapic_nmi->Lint, lapic_nmi->IntiFlags);
109809f2089bScegger 		break;
109909f2089bScegger 	case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
110009f2089bScegger 		lapic_over = (ACPI_MADT_LOCAL_APIC_OVERRIDE *)mp;
110109f2089bScegger 		printf("\tLocal APIC ADDR=0x%016jx\n",
110209f2089bScegger 		    (uintmax_t)lapic_over->Address);
110309f2089bScegger 		break;
110409f2089bScegger 	case ACPI_MADT_TYPE_IO_SAPIC:
110509f2089bScegger 		iosapic = (ACPI_MADT_IO_SAPIC *)mp;
110609f2089bScegger 		acpi_print_io_apic(iosapic->Id, iosapic->GlobalIrqBase,
110709f2089bScegger 		    iosapic->Address);
110809f2089bScegger 		break;
110909f2089bScegger 	case ACPI_MADT_TYPE_LOCAL_SAPIC:
111009f2089bScegger 		lsapic = (ACPI_MADT_LOCAL_SAPIC *)mp;
111109f2089bScegger 		acpi_print_cpu(lsapic->ProcessorId);
111209f2089bScegger 		acpi_print_local_apic(lsapic->Id, lsapic->LapicFlags);
111309f2089bScegger 		printf("\tAPIC EID=%d\n", (u_int)lsapic->Eid);
111409f2089bScegger 		if (mp->Length > offsetof(ACPI_MADT_LOCAL_SAPIC, Uid))
111509f2089bScegger 			acpi_print_cpu_uid(lsapic->Uid, lsapic->UidString);
111609f2089bScegger 		break;
111709f2089bScegger 	case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
111809f2089bScegger 		isrc = (ACPI_MADT_INTERRUPT_SOURCE *)mp;
1119c359a213Smsaitoh 		if (isrc->Type < __arraycount(platform_int_types))
112009f2089bScegger 			printf("\tType=%s\n", platform_int_types[isrc->Type]);
112109f2089bScegger 		else
112209f2089bScegger 			printf("\tType=%d (unknown)\n", isrc->Type);
112309f2089bScegger 		printf("\tAPIC ID=%d\n", (u_int)isrc->Id);
112409f2089bScegger 		printf("\tAPIC EID=%d\n", (u_int)isrc->Eid);
112509f2089bScegger 		printf("\tSAPIC Vector=%d\n", (u_int)isrc->IoSapicVector);
112609f2089bScegger 		acpi_print_intr(isrc->GlobalIrq, isrc->IntiFlags);
112709f2089bScegger 		break;
112809f2089bScegger 	case ACPI_MADT_TYPE_LOCAL_X2APIC:
112909f2089bScegger 		x2apic = (ACPI_MADT_LOCAL_X2APIC *)mp;
113009f2089bScegger 		acpi_print_cpu_uid(x2apic->Uid, NULL);
113109f2089bScegger 		acpi_print_local_apic(x2apic->LocalApicId, x2apic->LapicFlags);
113209f2089bScegger 		break;
113309f2089bScegger 	case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
113409f2089bScegger 		x2apic_nmi = (ACPI_MADT_LOCAL_X2APIC_NMI *)mp;
113509f2089bScegger 		acpi_print_cpu_uid(x2apic_nmi->Uid, NULL);
113609f2089bScegger 		acpi_print_local_nmi(x2apic_nmi->Lint, x2apic_nmi->IntiFlags);
113709f2089bScegger 		break;
1138c359a213Smsaitoh 	case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
1139c359a213Smsaitoh 		gicc = (ACPI_MADT_GENERIC_INTERRUPT *)mp;
1140c359a213Smsaitoh 		acpi_print_cpu_uid(gicc->Uid, NULL);
1141c359a213Smsaitoh 		printf("\tCPU INTERFACE=%x\n", gicc->CpuInterfaceNumber);
1142c359a213Smsaitoh 		acpi_print_gicc_flags(gicc->Flags);
1143c359a213Smsaitoh 		printf("\tParking Protocol Version=%x\n", gicc->ParkingVersion);
1144c359a213Smsaitoh 		printf("\tPERF INTR=%d\n", gicc->PerformanceInterrupt);
1145c359a213Smsaitoh 		printf("\tParked ADDR=%016jx\n",
1146c359a213Smsaitoh 		    (uintmax_t)gicc->ParkedAddress);
1147c359a213Smsaitoh 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicc->BaseAddress);
1148c359a213Smsaitoh 		printf("\tGICV=%016jx\n", (uintmax_t)gicc->GicvBaseAddress);
1149c359a213Smsaitoh 		printf("\tGICH=%016jx\n", (uintmax_t)gicc->GichBaseAddress);
1150c359a213Smsaitoh 		printf("\tVGIC INTR=%d\n", gicc->VgicInterrupt);
1151c359a213Smsaitoh 		printf("\tGICR ADDR=%016jx\n",
1152c359a213Smsaitoh 		    (uintmax_t)gicc->GicrBaseAddress);
1153c359a213Smsaitoh 		printf("\tMPIDR=%jx\n", (uintmax_t)gicc->ArmMpidr);
1154cdc507f0Sandvar 		printf("\tEfficiency Class=%d\n", (u_int)gicc->EfficiencyClass);
1155c359a213Smsaitoh 		break;
1156c359a213Smsaitoh 	case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
1157c359a213Smsaitoh 		gicd = (ACPI_MADT_GENERIC_DISTRIBUTOR *)mp;
1158c359a213Smsaitoh 		printf("\tGIC ID=%d\n", (u_int)gicd->GicId);
1159c359a213Smsaitoh 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicd->BaseAddress);
1160c359a213Smsaitoh 		printf("\tVector Base=%d\n", gicd->GlobalIrqBase);
1161c359a213Smsaitoh 		printf("\tGIC VERSION=%d\n", (u_int)gicd->Version);
1162c359a213Smsaitoh 		break;
1163792e611dSmsaitoh 	case ACPI_MADT_TYPE_GENERIC_MSI_FRAME:
1164792e611dSmsaitoh 		gicm = (ACPI_MADT_GENERIC_MSI_FRAME*)mp;
1165792e611dSmsaitoh 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicm->BaseAddress);
1166792e611dSmsaitoh 		acpi_print_gicm_flags(gicm);
1167792e611dSmsaitoh 		printf("\tSPI Count=%u\n", gicm->SpiCount);
1168792e611dSmsaitoh 		printf("\tSPI Base=%u\n", gicm->SpiBase);
1169792e611dSmsaitoh 		break;
1170c359a213Smsaitoh 	case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
1171c359a213Smsaitoh 		gicr = (ACPI_MADT_GENERIC_REDISTRIBUTOR *)mp;
1172c359a213Smsaitoh 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gicr->BaseAddress);
1173c359a213Smsaitoh 		printf("\tLength=%08x\n", gicr->Length);
1174c359a213Smsaitoh 		break;
1175c359a213Smsaitoh 	case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
1176c359a213Smsaitoh 		gict = (ACPI_MADT_GENERIC_TRANSLATOR *)mp;
1177c359a213Smsaitoh 		printf("\tGIC ITS ID=%d\n", gict->TranslationId);
1178c359a213Smsaitoh 		printf("\tBase ADDR=%016jx\n", (uintmax_t)gict->BaseAddress);
1179c359a213Smsaitoh 		break;
118009f2089bScegger 	}
118109f2089bScegger }
118209f2089bScegger 
118309f2089bScegger #ifdef notyet
118409f2089bScegger static void
acpi_print_bert_region(ACPI_BERT_REGION * region)118509f2089bScegger acpi_print_bert_region(ACPI_BERT_REGION *region)
118609f2089bScegger {
118709f2089bScegger 	uint32_t i, pos, entries;
118809f2089bScegger 	ACPI_HEST_GENERIC_DATA *data;
118909f2089bScegger 
119009f2089bScegger 	printf("\n");
119109f2089bScegger 	printf("\tBlockStatus={ ");
119209f2089bScegger 
119309f2089bScegger 	if (region->BlockStatus & ACPI_BERT_UNCORRECTABLE)
119409f2089bScegger 		printf("Uncorrectable");
119509f2089bScegger 	if (region->BlockStatus & ACPI_BERT_CORRECTABLE)
119609f2089bScegger 		printf("Correctable");
119709f2089bScegger 	if (region->BlockStatus & ACPI_BERT_MULTIPLE_UNCORRECTABLE)
119809f2089bScegger 		printf("Multiple Uncorrectable");
119909f2089bScegger 	if (region->BlockStatus & ACPI_BERT_MULTIPLE_CORRECTABLE)
120009f2089bScegger 		printf("Multiple Correctable");
120109f2089bScegger 	entries = region->BlockStatus & ACPI_BERT_ERROR_ENTRY_COUNT;
120209f2089bScegger 	printf(", Error Entry Count=%d", entries);
120309f2089bScegger 	printf("}\n");
120409f2089bScegger 
120509f2089bScegger 	printf("\tRaw Data Offset=0x%x\n", region->RawDataOffset);
120609f2089bScegger 	printf("\tRaw Data Length=0x%x\n", region->RawDataLength);
120709f2089bScegger 	printf("\tData Length=0x%x\n", region->DataLength);
120809f2089bScegger 
120909f2089bScegger 	acpi_print_hest_errorseverity(region->ErrorSeverity);
121009f2089bScegger 
121109f2089bScegger 	pos = sizeof(ACPI_BERT_REGION);
121209f2089bScegger 	for (i = 0; i < entries; i++) {
121309f2089bScegger 		data = (ACPI_HEST_GENERIC_DATA *)((char *)region + pos);
121409f2089bScegger 		acpi_print_hest_generic_data(data);
121509f2089bScegger 		pos += sizeof(ACPI_HEST_GENERIC_DATA);
121609f2089bScegger 	}
121709f2089bScegger }
121809f2089bScegger #endif
121909f2089bScegger 
122009f2089bScegger static void
acpi_handle_bert(ACPI_TABLE_HEADER * sdp)122109f2089bScegger acpi_handle_bert(ACPI_TABLE_HEADER *sdp)
122209f2089bScegger {
122309f2089bScegger 	ACPI_TABLE_BERT *bert;
122453e202c1Schristos 
122553e202c1Schristos 	printf(BEGIN_COMMENT);
122609f2089bScegger 	acpi_print_sdt(sdp);
122709f2089bScegger 	bert = (ACPI_TABLE_BERT *)sdp;
122809f2089bScegger 
122909f2089bScegger 	printf("\tLength of Boot Error Region=%d bytes\n", bert->RegionLength);
123009f2089bScegger 	printf("\tPhysical Address of Region=0x%"PRIx64"\n", bert->Address);
123109f2089bScegger 
123253e202c1Schristos 	printf(END_COMMENT);
123353e202c1Schristos }
123453e202c1Schristos 
123509f2089bScegger static void
acpi_handle_bgrt(ACPI_TABLE_HEADER * sdp)1236755dd632Smsaitoh acpi_handle_bgrt(ACPI_TABLE_HEADER *sdp)
1237755dd632Smsaitoh {
1238755dd632Smsaitoh 	ACPI_TABLE_BGRT *bgrt;
1239755dd632Smsaitoh 	unsigned int degree;
1240755dd632Smsaitoh 
1241755dd632Smsaitoh 	printf(BEGIN_COMMENT);
1242755dd632Smsaitoh 	acpi_print_sdt(sdp);
1243755dd632Smsaitoh 	bgrt = (ACPI_TABLE_BGRT *)sdp;
1244755dd632Smsaitoh 
1245755dd632Smsaitoh 	printf("\tVersion=%hu\n", bgrt->Version);
1246755dd632Smsaitoh 	degree = ((unsigned int)(bgrt->Status & ACPI_BGRT_ORIENTATION_OFFSET)
1247755dd632Smsaitoh 	    >> 1) * 90;
1248755dd632Smsaitoh 	printf("\tDegree=%u\n", degree);
12490b54191aSmaya 	printf("\tDisplayed=%u\n", bgrt->Status & ACPI_BGRT_DISPLAYED);
1250755dd632Smsaitoh 	printf("\tImage Type=");
1251755dd632Smsaitoh 	switch (bgrt->ImageType) {
1252755dd632Smsaitoh 	case 0:
1253755dd632Smsaitoh 		printf("Bitmap\n");
1254755dd632Smsaitoh 		break;
1255755dd632Smsaitoh 	default:
1256755dd632Smsaitoh 		printf("reserved (0x%hhx)\n", bgrt->ImageType);
1257755dd632Smsaitoh 		break;
1258755dd632Smsaitoh 	}
1259755dd632Smsaitoh 	printf("\tImage Address=0x%"PRIx64"\n", bgrt->ImageAddress);
1260755dd632Smsaitoh 	printf("\tImage Offset X=0x%08x\n", bgrt->ImageOffsetX);
1261755dd632Smsaitoh 	printf("\tImage Offset Y=0x%08x\n", bgrt->ImageOffsetY);
1262755dd632Smsaitoh 
1263755dd632Smsaitoh 	printf(END_COMMENT);
1264755dd632Smsaitoh }
1265755dd632Smsaitoh 
1266755dd632Smsaitoh static void
acpi_handle_boot(ACPI_TABLE_HEADER * sdp)126709f2089bScegger acpi_handle_boot(ACPI_TABLE_HEADER *sdp)
126853e202c1Schristos {
126909f2089bScegger 	ACPI_TABLE_BOOT *boot;
127053e202c1Schristos 
127153e202c1Schristos 	printf(BEGIN_COMMENT);
127209f2089bScegger 	acpi_print_sdt(sdp);
127309f2089bScegger 	boot = (ACPI_TABLE_BOOT *)sdp;
127409f2089bScegger 	printf("\tCMOS Index=0x%02x\n", boot->CmosIndex);
127509f2089bScegger 	printf(END_COMMENT);
127609f2089bScegger }
127709f2089bScegger 
127809f2089bScegger static void
acpi_handle_cpep(ACPI_TABLE_HEADER * sdp)127909f2089bScegger acpi_handle_cpep(ACPI_TABLE_HEADER *sdp)
128009f2089bScegger {
128109f2089bScegger 	ACPI_TABLE_CPEP *cpep;
128209f2089bScegger 	ACPI_CPEP_POLLING *poll;
128309f2089bScegger 	uint32_t cpep_pos;
128409f2089bScegger 
128509f2089bScegger 	printf(BEGIN_COMMENT);
128609f2089bScegger 	acpi_print_sdt(sdp);
128709f2089bScegger 	cpep = (ACPI_TABLE_CPEP *)sdp;
128809f2089bScegger 
128909f2089bScegger 	cpep_pos = sizeof(ACPI_TABLE_CPEP);
129009f2089bScegger 	while (cpep_pos < sdp->Length) {
129109f2089bScegger 		poll = (ACPI_CPEP_POLLING *)((char *)cpep + cpep_pos);
129209f2089bScegger 		acpi_print_cpu(poll->Id);
129309f2089bScegger 		printf("\tACPI CPU EId=%d\n", poll->Eid);
129409f2089bScegger 		printf("\tPoll Interval=%d msec\n", poll->Interval);
129509f2089bScegger 		cpep_pos += sizeof(ACPI_CPEP_POLLING);
129609f2089bScegger 	}
129709f2089bScegger 	printf(END_COMMENT);
129809f2089bScegger }
129909f2089bScegger 
130009f2089bScegger static void
acpi_print_csrt_resource_group(ACPI_CSRT_GROUP * grp)1301055f8b85Smsaitoh acpi_print_csrt_resource_group(ACPI_CSRT_GROUP *grp)
1302055f8b85Smsaitoh {
1303055f8b85Smsaitoh 	ACPI_CSRT_DESCRIPTOR *desc;
1304055f8b85Smsaitoh 
1305055f8b85Smsaitoh 	printf("\tLength=%u\n", grp->Length);
1306055f8b85Smsaitoh 	printf("\tVendorId=");
1307055f8b85Smsaitoh 	acpi_print_string((char *)&grp->VendorId, 4);
1308055f8b85Smsaitoh 	printf("\n");
1309055f8b85Smsaitoh 	if (grp->SubvendorId != 0) {
1310055f8b85Smsaitoh 		printf("\tSubvendorId=");
1311055f8b85Smsaitoh 		acpi_print_string((char *)&grp->SubvendorId, 4);
1312055f8b85Smsaitoh 		printf("\n");
1313055f8b85Smsaitoh 	}
1314055f8b85Smsaitoh 	printf("\tDeviceId=0x%08x\n", grp->DeviceId);
1315055f8b85Smsaitoh 	if (grp->SubdeviceId != 0)
1316055f8b85Smsaitoh 		printf("\tSubdeviceId=0x%08x\n", grp->SubdeviceId);
1317055f8b85Smsaitoh 	printf("\tRevision=%hu\n", grp->Revision);
1318055f8b85Smsaitoh 	printf("\tSharedInfoLength=%u\n", grp->SharedInfoLength);
1319055f8b85Smsaitoh 
1320055f8b85Smsaitoh 	/* Next is Shared Info */
1321055f8b85Smsaitoh 	if (grp->SharedInfoLength != 0) {
1322055f8b85Smsaitoh 		printf("\tShared Info ");
1323055f8b85Smsaitoh 		acpi_dump_bytes((uint8_t *)(grp + 1),
1324055f8b85Smsaitoh 		    grp->SharedInfoLength, 1);
1325055f8b85Smsaitoh 	}
1326055f8b85Smsaitoh 
1327055f8b85Smsaitoh 	/* And then, Resource Descriptors */
1328055f8b85Smsaitoh 	desc = (ACPI_CSRT_DESCRIPTOR *)
1329055f8b85Smsaitoh 	    ((vaddr_t)(grp + 1) + grp->SharedInfoLength);
1330055f8b85Smsaitoh 	while (desc < (ACPI_CSRT_DESCRIPTOR *)((vaddr_t)grp + grp->Length)) {
1331055f8b85Smsaitoh 		bool unknownsubytpe = false;
1332055f8b85Smsaitoh 		printf("\n\tLength=%u\n", desc->Length);
1333055f8b85Smsaitoh 		printf("\tResource Type=");
1334055f8b85Smsaitoh 		switch (desc->Type) {
1335055f8b85Smsaitoh 		case ACPI_CSRT_TYPE_INTERRUPT:
1336055f8b85Smsaitoh 			printf("Interrupt");
1337055f8b85Smsaitoh 			switch (desc->Subtype) {
1338055f8b85Smsaitoh 			case ACPI_CSRT_XRUPT_LINE:
1339055f8b85Smsaitoh 				printf("(Interrupt line)\n");
1340055f8b85Smsaitoh 				break;
1341055f8b85Smsaitoh 			case ACPI_CSRT_XRUPT_CONTROLLER:
1342055f8b85Smsaitoh 				printf("(Interrupt controller)\n");
1343055f8b85Smsaitoh 				break;
1344055f8b85Smsaitoh 			default:
1345055f8b85Smsaitoh 				unknownsubytpe = true;
1346055f8b85Smsaitoh 				break;
1347055f8b85Smsaitoh 			}
1348055f8b85Smsaitoh 			break;
1349055f8b85Smsaitoh 		case ACPI_CSRT_TYPE_TIMER:
1350055f8b85Smsaitoh 			printf("Timer");
1351055f8b85Smsaitoh 			switch (desc->Subtype) {
1352055f8b85Smsaitoh 			case ACPI_CSRT_TIMER:
1353055f8b85Smsaitoh 				printf("\n");
1354055f8b85Smsaitoh 				break;
1355055f8b85Smsaitoh 			default:
1356055f8b85Smsaitoh 				unknownsubytpe = true;
1357055f8b85Smsaitoh 				break;
1358055f8b85Smsaitoh 			}
1359055f8b85Smsaitoh 			break;
1360055f8b85Smsaitoh 		case ACPI_CSRT_TYPE_DMA:
1361055f8b85Smsaitoh 			printf("DMA");
1362055f8b85Smsaitoh 			switch (desc->Subtype) {
1363055f8b85Smsaitoh 			case ACPI_CSRT_DMA_CHANNEL:
1364055f8b85Smsaitoh 				printf("(DMA channel)\n");
1365055f8b85Smsaitoh 				break;
1366055f8b85Smsaitoh 			case ACPI_CSRT_DMA_CONTROLLER:
1367055f8b85Smsaitoh 				printf("(DMA controller)\n");
1368055f8b85Smsaitoh 				break;
1369055f8b85Smsaitoh 			default:
1370055f8b85Smsaitoh 				unknownsubytpe = true;
1371055f8b85Smsaitoh 				break;
1372055f8b85Smsaitoh 			}
1373055f8b85Smsaitoh 			break;
1374055f8b85Smsaitoh 		case 0x0004: /* XXX Platform Security */
1375055f8b85Smsaitoh 			printf("Platform Security");
1376055f8b85Smsaitoh 			switch (desc->Subtype) {
1377055f8b85Smsaitoh 			case 0x0001:
1378055f8b85Smsaitoh 				printf("\n");
1379055f8b85Smsaitoh 				/* Platform Security */
1380055f8b85Smsaitoh 				break;
1381055f8b85Smsaitoh 			default:
1382055f8b85Smsaitoh 				unknownsubytpe = true;
1383055f8b85Smsaitoh 				break;
1384055f8b85Smsaitoh 			}
1385055f8b85Smsaitoh 			break;
1386055f8b85Smsaitoh 		default:
1387055f8b85Smsaitoh 			printf("Unknown (%hx)\n", desc->Type);
1388055f8b85Smsaitoh 			break;
1389055f8b85Smsaitoh 		}
1390055f8b85Smsaitoh 		if (unknownsubytpe)
1391055f8b85Smsaitoh 			printf("(unknown subtype(%hx))\n", desc->Subtype);
1392055f8b85Smsaitoh 
1393055f8b85Smsaitoh 		printf("\tUID=0x%08x\n", desc->Uid);
1394055f8b85Smsaitoh 		printf("\tVendor defined info ");
1395055f8b85Smsaitoh 		acpi_dump_bytes((uint8_t *)(desc + 1),
1396055f8b85Smsaitoh 		    desc->Length - sizeof(ACPI_CSRT_DESCRIPTOR), 1);
1397055f8b85Smsaitoh 
1398055f8b85Smsaitoh 		/* Next */
1399055f8b85Smsaitoh 		desc = (ACPI_CSRT_DESCRIPTOR *)((vaddr_t)desc + desc->Length);
1400055f8b85Smsaitoh 	}
1401055f8b85Smsaitoh }
1402055f8b85Smsaitoh 
1403055f8b85Smsaitoh static void
acpi_handle_csrt(ACPI_TABLE_HEADER * sdp)1404055f8b85Smsaitoh acpi_handle_csrt(ACPI_TABLE_HEADER *sdp)
1405055f8b85Smsaitoh {
1406055f8b85Smsaitoh 	ACPI_CSRT_GROUP *grp;
1407055f8b85Smsaitoh 	uint totallen = sdp->Length;
1408055f8b85Smsaitoh 
1409055f8b85Smsaitoh 	printf(BEGIN_COMMENT);
1410055f8b85Smsaitoh 	acpi_print_sdt(sdp);
1411055f8b85Smsaitoh 	grp = (ACPI_CSRT_GROUP *)(sdp + 1);
1412055f8b85Smsaitoh 
1413055f8b85Smsaitoh 	while (grp < (ACPI_CSRT_GROUP *)((vaddr_t)sdp + totallen)) {
1414055f8b85Smsaitoh 		printf("\n");
1415055f8b85Smsaitoh 		acpi_print_csrt_resource_group(grp);
1416055f8b85Smsaitoh 
1417055f8b85Smsaitoh 		/* Next */
1418055f8b85Smsaitoh 		grp = (ACPI_CSRT_GROUP *)((vaddr_t)grp + grp->Length);
1419055f8b85Smsaitoh 	}
1420055f8b85Smsaitoh 
1421055f8b85Smsaitoh 	printf(END_COMMENT);
1422055f8b85Smsaitoh }
1423055f8b85Smsaitoh 
1424055f8b85Smsaitoh static void
acpi_handle_dbgp(ACPI_TABLE_HEADER * sdp)142509f2089bScegger acpi_handle_dbgp(ACPI_TABLE_HEADER *sdp)
142609f2089bScegger {
142709f2089bScegger 	ACPI_TABLE_DBGP *dbgp;
142809f2089bScegger 
142909f2089bScegger 	printf(BEGIN_COMMENT);
143009f2089bScegger 	acpi_print_sdt(sdp);
143109f2089bScegger 	dbgp = (ACPI_TABLE_DBGP *)sdp;
143209f2089bScegger 	printf("\tType={");
143309f2089bScegger 	switch (dbgp->Type) {
143409f2089bScegger 	case 0:
143509f2089bScegger 		printf("full 16550");
143609f2089bScegger 		break;
143709f2089bScegger 	case 1:
143809f2089bScegger 		printf("subset of 16550");
143909f2089bScegger 		break;
144009f2089bScegger 	}
144109f2089bScegger 	printf("}\n");
14420fd02e45Smsaitoh 	printf("\tDebugPort=");
144309f2089bScegger 	acpi_print_gas(&dbgp->DebugPort);
14440fd02e45Smsaitoh 	printf("\n");
144509f2089bScegger 	printf(END_COMMENT);
144609f2089bScegger }
144709f2089bScegger 
1448b04bf7f2Smsaitoh /* This function is used by DBG2 and SPCR. */
1449b04bf7f2Smsaitoh static void
acpi_print_dbg2_serial_subtype(uint16_t subtype)1450b04bf7f2Smsaitoh acpi_print_dbg2_serial_subtype(uint16_t subtype)
1451b04bf7f2Smsaitoh {
1452b04bf7f2Smsaitoh 
1453b04bf7f2Smsaitoh 	switch (subtype) {
1454b04bf7f2Smsaitoh 	case ACPI_DBG2_16550_COMPATIBLE:
1455b04bf7f2Smsaitoh 		printf("Fully 16550 compatible\n");
1456b04bf7f2Smsaitoh 		break;
1457b04bf7f2Smsaitoh 	case ACPI_DBG2_16550_SUBSET:
1458b04bf7f2Smsaitoh 		printf("16550 subset with DBGP Rev. 1\n");
1459b04bf7f2Smsaitoh 		break;
1460b04bf7f2Smsaitoh 	case ACPI_DBG2_ARM_PL011:
1461b04bf7f2Smsaitoh 		printf("ARM PL011\n");
1462b04bf7f2Smsaitoh 		break;
1463b04bf7f2Smsaitoh 	case ACPI_DBG2_ARM_SBSA_32BIT:
1464b04bf7f2Smsaitoh 		printf("ARM SBSA 32bit only\n");
1465b04bf7f2Smsaitoh 		break;
1466b04bf7f2Smsaitoh 	case ACPI_DBG2_ARM_SBSA_GENERIC:
1467b04bf7f2Smsaitoh 		printf("ARM SBSA Generic\n");
1468b04bf7f2Smsaitoh 		break;
1469b04bf7f2Smsaitoh 	case ACPI_DBG2_ARM_DCC:
1470b04bf7f2Smsaitoh 		printf("ARM DCC\n");
1471b04bf7f2Smsaitoh 		break;
1472b04bf7f2Smsaitoh 	case ACPI_DBG2_BCM2835:
1473b04bf7f2Smsaitoh 		printf("BCM2835\n");
1474b04bf7f2Smsaitoh 		break;
1475b04bf7f2Smsaitoh 	default:
1476b04bf7f2Smsaitoh 		printf("reserved (%04hx)\n", subtype);
1477b04bf7f2Smsaitoh 		break;
1478b04bf7f2Smsaitoh 	}
1479b04bf7f2Smsaitoh }
1480b04bf7f2Smsaitoh 
148109f2089bScegger static void
acpi_print_dbg2_device(ACPI_DBG2_DEVICE * dev)14825d527485Smsaitoh acpi_print_dbg2_device(ACPI_DBG2_DEVICE *dev)
14835d527485Smsaitoh {
14845d527485Smsaitoh 
14855d527485Smsaitoh 	printf("\t\tRevision=%u\n", dev->Revision);
14865d527485Smsaitoh 	printf("\t\tLength=%u\n", dev->Length);
14875d527485Smsaitoh 	printf("\t\tRegisterCount=%u\n", dev->RegisterCount);
14885d527485Smsaitoh 
14895d527485Smsaitoh 	printf("\t\tNamepath=");
14905d527485Smsaitoh 	acpi_print_string((char *)((vaddr_t)dev + dev->NamepathOffset),
14915d527485Smsaitoh 	    dev->NamepathLength);
14925d527485Smsaitoh 	printf("\n");
14935d527485Smsaitoh 
14945d527485Smsaitoh 	if (dev->OemDataLength) {
14955d527485Smsaitoh 		printf("\t\tOemDataLength=%u\n", dev->OemDataLength);
14965d527485Smsaitoh 		printf("\t\tOemDataOffset=%u\n", dev->OemDataOffset);
14975d527485Smsaitoh 		/* XXX need dump */
14985d527485Smsaitoh 	}
14995d527485Smsaitoh 
15005d527485Smsaitoh 	printf("\t\tPortType=");
15015d527485Smsaitoh 	switch (dev->PortType) {
15025d527485Smsaitoh 	case ACPI_DBG2_SERIAL_PORT:
15035d527485Smsaitoh 		printf("Serial\n" "\t\tPortSubtype=");
1504b04bf7f2Smsaitoh 		acpi_print_dbg2_serial_subtype(dev->PortSubtype);
15055d527485Smsaitoh 		break;
15065d527485Smsaitoh 	case ACPI_DBG2_1394_PORT:
15075d527485Smsaitoh 		printf("IEEE1394\n" "\t\tPortSubtype=");
15085d527485Smsaitoh 		if (dev->PortSubtype == ACPI_DBG2_1394_STANDARD)
15095d527485Smsaitoh 			printf("Standard\n");
15105d527485Smsaitoh 		else
15115d527485Smsaitoh 			printf("reserved (%04hx)\n", dev->PortSubtype);
15125d527485Smsaitoh 		break;
15135d527485Smsaitoh 	case ACPI_DBG2_USB_PORT:
15145d527485Smsaitoh 		printf("USB\n" "\t\tPortSubtype=");
15155d527485Smsaitoh 		switch (dev->PortSubtype) {
15165d527485Smsaitoh 		case ACPI_DBG2_USB_XHCI:
15175d527485Smsaitoh 			printf("XHCIn");
15185d527485Smsaitoh 			break;
15195d527485Smsaitoh 		case ACPI_DBG2_USB_EHCI:
15205d527485Smsaitoh 			printf("EHCI\n");
15215d527485Smsaitoh 			break;
15225d527485Smsaitoh 		default:
15235d527485Smsaitoh 			printf("reserved (%04hx)\n", dev->PortSubtype);
15245d527485Smsaitoh 			break;
15255d527485Smsaitoh 		}
15265d527485Smsaitoh 		break;
15275d527485Smsaitoh 	case ACPI_DBG2_NET_PORT:
15285d527485Smsaitoh 		printf("Net\n" "\t\tPciVendorID=%04x\n", dev->PortSubtype);
15295d527485Smsaitoh 		break;
15305d527485Smsaitoh 	default:
15315d527485Smsaitoh 		printf("reserved (%04hx)\n", dev->PortType);
15325d527485Smsaitoh 		printf("\t\tPortSubtype=reserved (%04hx)\n", dev->PortSubtype);
15335d527485Smsaitoh 		break;
15345d527485Smsaitoh 	}
15355d527485Smsaitoh 
15365d527485Smsaitoh 	printf("\t\tBaseAddressOffset=0x%04x\n", dev->BaseAddressOffset);
15375d527485Smsaitoh 	printf("\t\tAddressSizeOffset=0x%04x\n", dev->AddressSizeOffset);
15385d527485Smsaitoh }
15395d527485Smsaitoh 
15405d527485Smsaitoh static void
acpi_handle_dbg2(ACPI_TABLE_HEADER * sdp)15415d527485Smsaitoh acpi_handle_dbg2(ACPI_TABLE_HEADER *sdp)
15425d527485Smsaitoh {
15435d527485Smsaitoh 	ACPI_TABLE_DBG2 *dbg2;
15445d527485Smsaitoh 	ACPI_DBG2_DEVICE *device;
15455d527485Smsaitoh 	unsigned int i;
15465d527485Smsaitoh 
15475d527485Smsaitoh 	printf(BEGIN_COMMENT);
15485d527485Smsaitoh 	acpi_print_sdt(sdp);
15495d527485Smsaitoh 	dbg2 = (ACPI_TABLE_DBG2 *)sdp;
15505d527485Smsaitoh 
15515d527485Smsaitoh 	printf("\tCount=%u\n", dbg2->InfoCount);
15525d527485Smsaitoh 	device = (ACPI_DBG2_DEVICE *)((vaddr_t)sdp + dbg2->InfoOffset);
15535d527485Smsaitoh 	for (i = 0; i < dbg2->InfoCount; i++) {
15545d527485Smsaitoh 		printf("\tDevice %u={\n", i);
15555d527485Smsaitoh 		acpi_print_dbg2_device(device);
15565d527485Smsaitoh 		printf("\t}\n");
15575d527485Smsaitoh 		device++;
15585d527485Smsaitoh 	}
15595d527485Smsaitoh 
15605d527485Smsaitoh 	printf(END_COMMENT);
15615d527485Smsaitoh }
15625d527485Smsaitoh 
15635d527485Smsaitoh static void
acpi_print_einj_action(ACPI_WHEA_HEADER * whea)156409f2089bScegger acpi_print_einj_action(ACPI_WHEA_HEADER *whea)
156509f2089bScegger {
156609f2089bScegger 	printf("\tACTION={");
156709f2089bScegger 	switch (whea->Action) {
156809f2089bScegger 	case ACPI_EINJ_BEGIN_OPERATION:
156909f2089bScegger 		printf("Begin Operation");
157009f2089bScegger 		break;
157109f2089bScegger 	case ACPI_EINJ_GET_TRIGGER_TABLE:
157209f2089bScegger 		printf("Get Trigger Table");
157309f2089bScegger 		break;
157409f2089bScegger 	case ACPI_EINJ_SET_ERROR_TYPE:
157509f2089bScegger 		printf("Set Error Type");
157609f2089bScegger 		break;
157709f2089bScegger 	case ACPI_EINJ_GET_ERROR_TYPE:
157809f2089bScegger 		printf("Get Error Type");
157909f2089bScegger 		break;
158009f2089bScegger 	case ACPI_EINJ_END_OPERATION:
158109f2089bScegger 		printf("End Operation");
158209f2089bScegger 		break;
158309f2089bScegger 	case ACPI_EINJ_EXECUTE_OPERATION:
158409f2089bScegger 		printf("Execute Operation");
158509f2089bScegger 		break;
158609f2089bScegger 	case ACPI_EINJ_CHECK_BUSY_STATUS:
158709f2089bScegger 		printf("Check Busy Status");
158809f2089bScegger 		break;
158909f2089bScegger 	case ACPI_EINJ_GET_COMMAND_STATUS:
159009f2089bScegger 		printf("Get Command Status");
159109f2089bScegger 		break;
1592792e611dSmsaitoh 	case ACPI_EINJ_SET_ERROR_TYPE_WITH_ADDRESS:
1593792e611dSmsaitoh 		printf("Set Error Type With Address");
1594792e611dSmsaitoh 		break;
1595792e611dSmsaitoh 	case ACPI_EINJ_GET_EXECUTE_TIMINGS:
1596792e611dSmsaitoh 		printf("Get Execute Operation Timings");
1597792e611dSmsaitoh 		break;
159809f2089bScegger 	case ACPI_EINJ_ACTION_RESERVED:
159909f2089bScegger 		printf("Preserved");
160009f2089bScegger 		break;
160109f2089bScegger 	case ACPI_EINJ_TRIGGER_ERROR:
160209f2089bScegger 		printf("Trigger Error");
160309f2089bScegger 		break;
160409f2089bScegger 	default:
160509f2089bScegger 		printf("%d", whea->Action);
160609f2089bScegger 		break;
160709f2089bScegger 	}
160809f2089bScegger 	printf("}\n");
160909f2089bScegger }
161009f2089bScegger 
161109f2089bScegger static void
acpi_print_einj_instruction(ACPI_WHEA_HEADER * whea)161209f2089bScegger acpi_print_einj_instruction(ACPI_WHEA_HEADER *whea)
161309f2089bScegger {
161409f2089bScegger 	uint32_t ins = whea->Instruction;
161509f2089bScegger 
161609f2089bScegger 	printf("\tINSTRUCTION={");
161709f2089bScegger 	switch (ins) {
161809f2089bScegger 	case ACPI_EINJ_READ_REGISTER:
161909f2089bScegger 		printf("Read Register");
162009f2089bScegger 		break;
162109f2089bScegger 	case ACPI_EINJ_READ_REGISTER_VALUE:
162209f2089bScegger 		printf("Read Register Value");
162309f2089bScegger 		break;
162409f2089bScegger 	case ACPI_EINJ_WRITE_REGISTER:
162509f2089bScegger 		printf("Write Register");
162609f2089bScegger 		break;
162709f2089bScegger 	case ACPI_EINJ_WRITE_REGISTER_VALUE:
162809f2089bScegger 		printf("Write Register Value");
162909f2089bScegger 		break;
163009f2089bScegger 	case ACPI_EINJ_NOOP:
163109f2089bScegger 		printf("Noop");
163209f2089bScegger 		break;
163309f2089bScegger 	case ACPI_EINJ_INSTRUCTION_RESERVED:
163409f2089bScegger 		printf("Reserved");
163509f2089bScegger 		break;
163609f2089bScegger 	default:
163709f2089bScegger 		printf("%d", ins);
163809f2089bScegger 		break;
163909f2089bScegger 	}
164009f2089bScegger 	printf("}\n");
164109f2089bScegger }
164209f2089bScegger 
164309f2089bScegger static void
acpi_print_einj_flags(ACPI_WHEA_HEADER * whea)164409f2089bScegger acpi_print_einj_flags(ACPI_WHEA_HEADER *whea)
164509f2089bScegger {
164609f2089bScegger 	uint32_t flags = whea->Flags;
164709f2089bScegger 
164809f2089bScegger 	printf("\tFLAGS={");
164909f2089bScegger 	if (flags & ACPI_EINJ_PRESERVE)
165009f2089bScegger 		printf("PRESERVED");
165109f2089bScegger 	printf("}\n");
165209f2089bScegger }
165309f2089bScegger 
165409f2089bScegger static void
acpi_handle_einj(ACPI_TABLE_HEADER * sdp)165509f2089bScegger acpi_handle_einj(ACPI_TABLE_HEADER *sdp)
165609f2089bScegger {
165709f2089bScegger 	ACPI_TABLE_EINJ *einj;
165809f2089bScegger 	ACPI_EINJ_ENTRY *einj_entry;
165909f2089bScegger 	uint32_t einj_pos;
166009f2089bScegger 	u_int i;
166109f2089bScegger 
166209f2089bScegger 	printf(BEGIN_COMMENT);
166309f2089bScegger 	acpi_print_sdt(sdp);
166409f2089bScegger 	einj = (ACPI_TABLE_EINJ *)sdp;
166509f2089bScegger 
166609f2089bScegger 	printf("\tHeader Length=%d\n", einj->HeaderLength);
166709f2089bScegger 	printf("\tFlags=0x%x\n", einj->Flags);
166809f2089bScegger 	printf("\tEntries=%d\n", einj->Entries);
166909f2089bScegger 
167009f2089bScegger 	einj_pos = sizeof(ACPI_TABLE_EINJ);
167109f2089bScegger 	for (i = 0; i < einj->Entries; i++) {
167209f2089bScegger 		einj_entry = (ACPI_EINJ_ENTRY *)((char *)einj + einj_pos);
167309f2089bScegger 		acpi_print_whea(&einj_entry->WheaHeader,
167409f2089bScegger 		    acpi_print_einj_action, acpi_print_einj_instruction,
167509f2089bScegger 		    acpi_print_einj_flags);
167609f2089bScegger 		einj_pos += sizeof(ACPI_EINJ_ENTRY);
167709f2089bScegger 	}
167809f2089bScegger 	printf(END_COMMENT);
167909f2089bScegger }
168009f2089bScegger 
168109f2089bScegger static void
acpi_print_erst_action(ACPI_WHEA_HEADER * whea)168209f2089bScegger acpi_print_erst_action(ACPI_WHEA_HEADER *whea)
168309f2089bScegger {
168409f2089bScegger 	printf("\tACTION={");
168509f2089bScegger 	switch (whea->Action) {
168609f2089bScegger 	case ACPI_ERST_BEGIN_WRITE:
168709f2089bScegger 		printf("Begin Write");
168809f2089bScegger 		break;
168909f2089bScegger 	case ACPI_ERST_BEGIN_READ:
169009f2089bScegger 		printf("Begin Read");
169109f2089bScegger 		break;
169209f2089bScegger 	case ACPI_ERST_BEGIN_CLEAR:
169309f2089bScegger 		printf("Begin Clear");
169409f2089bScegger 		break;
169509f2089bScegger 	case ACPI_ERST_END:
169609f2089bScegger 		printf("End");
169709f2089bScegger 		break;
169809f2089bScegger 	case ACPI_ERST_SET_RECORD_OFFSET:
169909f2089bScegger 		printf("Set Record Offset");
170009f2089bScegger 		break;
170109f2089bScegger 	case ACPI_ERST_EXECUTE_OPERATION:
170209f2089bScegger 		printf("Execute Operation");
170309f2089bScegger 		break;
170409f2089bScegger 	case ACPI_ERST_CHECK_BUSY_STATUS:
170509f2089bScegger 		printf("Check Busy Status");
170609f2089bScegger 		break;
170709f2089bScegger 	case ACPI_ERST_GET_COMMAND_STATUS:
170809f2089bScegger 		printf("Get Command Status");
170909f2089bScegger 		break;
171009f2089bScegger 	case ACPI_ERST_GET_RECORD_ID:
171109f2089bScegger 		printf("Get Record ID");
171209f2089bScegger 		break;
171309f2089bScegger 	case ACPI_ERST_SET_RECORD_ID:
171409f2089bScegger 		printf("Set Record ID");
171509f2089bScegger 		break;
171609f2089bScegger 	case ACPI_ERST_GET_RECORD_COUNT:
171709f2089bScegger 		printf("Get Record Count");
171809f2089bScegger 		break;
171909f2089bScegger 	case ACPI_ERST_BEGIN_DUMMY_WRIITE:
172009f2089bScegger 		printf("Begin Dummy Write");
172109f2089bScegger 		break;
172209f2089bScegger 	case ACPI_ERST_NOT_USED:
172309f2089bScegger 		printf("Unused");
172409f2089bScegger 		break;
172509f2089bScegger 	case ACPI_ERST_GET_ERROR_RANGE:
172609f2089bScegger 		printf("Get Error Range");
172709f2089bScegger 		break;
172809f2089bScegger 	case ACPI_ERST_GET_ERROR_LENGTH:
172909f2089bScegger 		printf("Get Error Length");
173009f2089bScegger 		break;
173109f2089bScegger 	case ACPI_ERST_GET_ERROR_ATTRIBUTES:
173209f2089bScegger 		printf("Get Error Attributes");
173309f2089bScegger 		break;
1734792e611dSmsaitoh 	case ACPI_ERST_EXECUTE_TIMINGS:
1735792e611dSmsaitoh 		printf("Execute Operation Timings");
1736792e611dSmsaitoh 		break;
173709f2089bScegger 	case ACPI_ERST_ACTION_RESERVED:
173809f2089bScegger 		printf("Reserved");
173909f2089bScegger 		break;
174009f2089bScegger 	default:
174109f2089bScegger 		printf("%d", whea->Action);
174209f2089bScegger 		break;
174309f2089bScegger 	}
174409f2089bScegger 	printf("}\n");
174509f2089bScegger }
174609f2089bScegger 
174709f2089bScegger static void
acpi_print_erst_instruction(ACPI_WHEA_HEADER * whea)174809f2089bScegger acpi_print_erst_instruction(ACPI_WHEA_HEADER *whea)
174909f2089bScegger {
175009f2089bScegger 	printf("\tINSTRUCTION={");
175109f2089bScegger 	switch (whea->Instruction) {
175209f2089bScegger 	case ACPI_ERST_READ_REGISTER:
175309f2089bScegger 		printf("Read Register");
175409f2089bScegger 		break;
175509f2089bScegger 	case ACPI_ERST_READ_REGISTER_VALUE:
175609f2089bScegger 		printf("Read Register Value");
175709f2089bScegger 		break;
175809f2089bScegger 	case ACPI_ERST_WRITE_REGISTER:
175909f2089bScegger 		printf("Write Register");
176009f2089bScegger 		break;
176109f2089bScegger 	case ACPI_ERST_WRITE_REGISTER_VALUE:
176209f2089bScegger 		printf("Write Register Value");
176309f2089bScegger 		break;
176409f2089bScegger 	case ACPI_ERST_NOOP:
176509f2089bScegger 		printf("Noop");
176609f2089bScegger 		break;
176709f2089bScegger 	case ACPI_ERST_LOAD_VAR1:
176809f2089bScegger 		printf("Load Var1");
176909f2089bScegger 		break;
177009f2089bScegger 	case ACPI_ERST_LOAD_VAR2:
177109f2089bScegger 		printf("Load Var2");
177209f2089bScegger 		break;
177309f2089bScegger 	case ACPI_ERST_STORE_VAR1:
177409f2089bScegger 		printf("Store Var1");
177509f2089bScegger 		break;
177609f2089bScegger 	case ACPI_ERST_ADD:
177709f2089bScegger 		printf("Add");
177809f2089bScegger 		break;
177909f2089bScegger 	case ACPI_ERST_SUBTRACT:
178009f2089bScegger 		printf("Subtract");
178109f2089bScegger 		break;
178209f2089bScegger 	case ACPI_ERST_ADD_VALUE:
178309f2089bScegger 		printf("Add Value");
178409f2089bScegger 		break;
178509f2089bScegger 	case ACPI_ERST_SUBTRACT_VALUE:
178609f2089bScegger 		printf("Subtract Value");
178709f2089bScegger 		break;
178809f2089bScegger 	case ACPI_ERST_STALL:
178909f2089bScegger 		printf("Stall");
179009f2089bScegger 		break;
179109f2089bScegger 	case ACPI_ERST_STALL_WHILE_TRUE:
179209f2089bScegger 		printf("Stall While True");
179309f2089bScegger 		break;
179409f2089bScegger 	case ACPI_ERST_SKIP_NEXT_IF_TRUE:
179509f2089bScegger 		printf("Skip Next If True");
179609f2089bScegger 		break;
179709f2089bScegger 	case ACPI_ERST_GOTO:
179809f2089bScegger 		printf("Goto");
179909f2089bScegger 		break;
180009f2089bScegger 	case ACPI_ERST_SET_SRC_ADDRESS_BASE:
180109f2089bScegger 		printf("Set Src Address Base");
180209f2089bScegger 		break;
180309f2089bScegger 	case ACPI_ERST_SET_DST_ADDRESS_BASE:
180409f2089bScegger 		printf("Set Dst Address Base");
180509f2089bScegger 		break;
180609f2089bScegger 	case ACPI_ERST_MOVE_DATA:
180709f2089bScegger 		printf("Move Data");
180809f2089bScegger 		break;
180909f2089bScegger 	case ACPI_ERST_INSTRUCTION_RESERVED:
181009f2089bScegger 		printf("Reserved");
181109f2089bScegger 		break;
181209f2089bScegger 	default:
181309f2089bScegger 		printf("%d (reserved)", whea->Instruction);
181409f2089bScegger 		break;
181509f2089bScegger 	}
181609f2089bScegger 	printf("}\n");
181709f2089bScegger }
181809f2089bScegger 
181909f2089bScegger static void
acpi_print_erst_flags(ACPI_WHEA_HEADER * whea)182009f2089bScegger acpi_print_erst_flags(ACPI_WHEA_HEADER *whea)
182109f2089bScegger {
182209f2089bScegger 	uint32_t flags = whea->Flags;
182309f2089bScegger 
182409f2089bScegger 	printf("\tFLAGS={");
182509f2089bScegger 	if (flags & ACPI_ERST_PRESERVE)
182609f2089bScegger 		printf("PRESERVED");
182709f2089bScegger 	printf("}\n");
182809f2089bScegger }
182909f2089bScegger 
183009f2089bScegger static void
acpi_handle_erst(ACPI_TABLE_HEADER * sdp)183109f2089bScegger acpi_handle_erst(ACPI_TABLE_HEADER *sdp)
183209f2089bScegger {
183309f2089bScegger 	ACPI_TABLE_ERST *erst;
183409f2089bScegger 	ACPI_ERST_ENTRY *erst_entry;
183509f2089bScegger 	uint32_t erst_pos;
183609f2089bScegger 	u_int i;
183709f2089bScegger 
183809f2089bScegger 	printf(BEGIN_COMMENT);
183909f2089bScegger 	acpi_print_sdt(sdp);
184009f2089bScegger 	erst = (ACPI_TABLE_ERST *)sdp;
184109f2089bScegger 
184209f2089bScegger 	printf("\tHeader Length=%d\n", erst->HeaderLength);
184309f2089bScegger 	printf("\tEntries=%d\n", erst->Entries);
184409f2089bScegger 
184509f2089bScegger 	erst_pos = sizeof(ACPI_TABLE_ERST);
184609f2089bScegger 	for (i = 0; i < erst->Entries; i++) {
184709f2089bScegger 		erst_entry = (ACPI_ERST_ENTRY *)((char *)erst + erst_pos);
184809f2089bScegger 		acpi_print_whea(&erst_entry->WheaHeader,
184909f2089bScegger 		    acpi_print_erst_action, acpi_print_erst_instruction,
185009f2089bScegger 		    acpi_print_erst_flags);
185109f2089bScegger 		erst_pos += sizeof(ACPI_ERST_ENTRY);
185209f2089bScegger 	}
185309f2089bScegger 	printf(END_COMMENT);
185409f2089bScegger }
185509f2089bScegger 
185609f2089bScegger static void
acpi_print_gtd_timer(const char * name,uint32_t interrupt,uint32_t flags)1857aba8816bSmsaitoh acpi_print_gtd_timer(const char *name, uint32_t interrupt, uint32_t flags)
1858aba8816bSmsaitoh {
1859aba8816bSmsaitoh 
1860aba8816bSmsaitoh 	printf("\t%s Timer GSIV=%d\n", name, interrupt);
1861aba8816bSmsaitoh 	printf("\t%s Flags={Mode=", name);
1862aba8816bSmsaitoh 	if (flags & ACPI_GTDT_INTERRUPT_MODE)
1863aba8816bSmsaitoh 		printf("edge");
1864aba8816bSmsaitoh 	else
1865aba8816bSmsaitoh 		printf("level");
1866aba8816bSmsaitoh 	printf(", Polarity=");
1867aba8816bSmsaitoh 	if (flags & ACPI_GTDT_INTERRUPT_POLARITY)
1868aba8816bSmsaitoh 		printf("active-lo");
1869aba8816bSmsaitoh 	else
1870aba8816bSmsaitoh 		printf("active-hi");
1871aba8816bSmsaitoh 	if (flags & ACPI_GTDT_ALWAYS_ON)
1872aba8816bSmsaitoh 		printf(", always-on");
1873aba8816bSmsaitoh 	printf("}\n");
1874aba8816bSmsaitoh }
1875aba8816bSmsaitoh 
1876aba8816bSmsaitoh static void
acpi_print_gtd_block_timer_flags(const char * name,uint32_t interrupt,uint32_t flags)1877aba8816bSmsaitoh acpi_print_gtd_block_timer_flags(const char *name, uint32_t interrupt,
1878aba8816bSmsaitoh     uint32_t flags)
1879aba8816bSmsaitoh {
1880aba8816bSmsaitoh 
1881aba8816bSmsaitoh 	printf("\t\t%s Timer GSIV=%d\n", name, interrupt);
1882aba8816bSmsaitoh 	printf("\t\t%s Timer Flags={Mode=", name);
1883aba8816bSmsaitoh 	if (flags & ACPI_GTDT_GT_IRQ_MODE)
1884aba8816bSmsaitoh 		printf("Secure");
1885aba8816bSmsaitoh 	else
1886aba8816bSmsaitoh 		printf("Non-Secure");
1887aba8816bSmsaitoh 	printf(", Polarity=");
1888aba8816bSmsaitoh 	if (flags & ACPI_GTDT_GT_IRQ_POLARITY)
1889aba8816bSmsaitoh 		printf("active-lo");
1890aba8816bSmsaitoh 	else
1891aba8816bSmsaitoh 		printf("active-hi");
1892aba8816bSmsaitoh 	printf("}\n");
1893aba8816bSmsaitoh }
1894aba8816bSmsaitoh 
1895aba8816bSmsaitoh static void
acpi_print_gtblock(ACPI_GTDT_TIMER_BLOCK * gtblock)1896aba8816bSmsaitoh acpi_print_gtblock(ACPI_GTDT_TIMER_BLOCK *gtblock)
1897aba8816bSmsaitoh {
1898aba8816bSmsaitoh 	ACPI_GTDT_TIMER_ENTRY *entry;
1899aba8816bSmsaitoh 	unsigned int i;
1900aba8816bSmsaitoh 
1901aba8816bSmsaitoh 	printf("\tType=GT Block\n");
1902aba8816bSmsaitoh 	printf("\tLength=%d\n", gtblock->Header.Length);
1903aba8816bSmsaitoh 	/* XXX might not 8byte aligned */
1904aba8816bSmsaitoh 	printf("\tBlockAddress=%016jx\n",
1905aba8816bSmsaitoh 	    (uintmax_t)gtblock->BlockAddress);
1906aba8816bSmsaitoh 
1907aba8816bSmsaitoh 	printf("\tGT Block Timer Count=%d\n", gtblock->TimerCount);
1908aba8816bSmsaitoh 	entry = (ACPI_GTDT_TIMER_ENTRY *)((vaddr_t)gtblock
1909aba8816bSmsaitoh 	    + gtblock->TimerOffset);
1910aba8816bSmsaitoh 	for (i = 0; i < gtblock->TimerCount; i++) {
1911aba8816bSmsaitoh 		printf("\n");
1912aba8816bSmsaitoh 		if (entry >= (ACPI_GTDT_TIMER_ENTRY *)((vaddr_t)gtblock
1913aba8816bSmsaitoh 		    + gtblock->Header.Length)) {
1914aba8816bSmsaitoh 			printf("\\ttWrong Timer entry\n");
1915aba8816bSmsaitoh 			break;
1916aba8816bSmsaitoh 		}
1917aba8816bSmsaitoh 		printf("\t\tFrame Number=%d\n", entry->FrameNumber);
1918aba8816bSmsaitoh 		/* XXX might not 8byte aligned */
1919aba8816bSmsaitoh 		printf("\t\tBaseAddress=%016jx\n",
1920aba8816bSmsaitoh 		    (uintmax_t)entry->BaseAddress);
1921aba8816bSmsaitoh 		/* XXX might not 8byte aligned */
1922aba8816bSmsaitoh 		printf("\t\tEl0BaseAddress=%016jx\n",
1923aba8816bSmsaitoh 		    (uintmax_t)entry->El0BaseAddress);
1924aba8816bSmsaitoh 
1925aba8816bSmsaitoh 		acpi_print_gtd_block_timer_flags("Physical",
1926aba8816bSmsaitoh 		    entry->TimerInterrupt, entry->TimerFlags);
1927aba8816bSmsaitoh 		acpi_print_gtd_block_timer_flags("Virtual",
1928aba8816bSmsaitoh 		    entry->VirtualTimerInterrupt, entry->VirtualTimerFlags);
1929aba8816bSmsaitoh 
1930aba8816bSmsaitoh 		printf("\t\tCommon Flags={Mode=");
1931aba8816bSmsaitoh 		if (entry->CommonFlags & ACPI_GTDT_GT_IS_SECURE_TIMER)
1932aba8816bSmsaitoh 			printf("Secure");
1933aba8816bSmsaitoh 		else
1934aba8816bSmsaitoh 			printf("Non-Secure");
1935aba8816bSmsaitoh 		if (entry->CommonFlags & ACPI_GTDT_GT_ALWAYS_ON)
1936aba8816bSmsaitoh 			printf(", always-on");
1937aba8816bSmsaitoh 		printf("}\n");
1938aba8816bSmsaitoh 
1939aba8816bSmsaitoh 		entry++;
1940aba8816bSmsaitoh 	}
1941aba8816bSmsaitoh }
1942aba8816bSmsaitoh 
1943aba8816bSmsaitoh static void
acpi_print_sbsa_watchdog(ACPI_GTDT_WATCHDOG * wdog)1944aba8816bSmsaitoh acpi_print_sbsa_watchdog(ACPI_GTDT_WATCHDOG *wdog)
1945aba8816bSmsaitoh {
1946aba8816bSmsaitoh 
1947aba8816bSmsaitoh 	printf("\tType=Watchdog GT\n");
1948aba8816bSmsaitoh 	printf("\tLength=%d\n", wdog->Header.Length);
1949aba8816bSmsaitoh 	/* XXX might not 8byte aligned */
1950aba8816bSmsaitoh 	printf("\tRefreshFrameAddress=%016jx\n",
1951aba8816bSmsaitoh 	    (uintmax_t)wdog->RefreshFrameAddress);
1952aba8816bSmsaitoh 	/* XXX might not 8byte aligned */
1953aba8816bSmsaitoh 	printf("\tControlFrameAddress=%016jx\n",
1954aba8816bSmsaitoh 	    (uintmax_t)wdog->ControlFrameAddress);
1955aba8816bSmsaitoh 	printf("\tGSIV=%d\n", wdog->TimerInterrupt);
1956aba8816bSmsaitoh 
1957aba8816bSmsaitoh 	printf("\tFlags={Mode=");
1958aba8816bSmsaitoh 	if (wdog->TimerFlags & ACPI_GTDT_WATCHDOG_IRQ_MODE)
1959aba8816bSmsaitoh 		printf("edge");
1960aba8816bSmsaitoh 	else
1961aba8816bSmsaitoh 		printf("level");
1962aba8816bSmsaitoh 	printf(", Polarity=");
1963aba8816bSmsaitoh 	if (wdog->TimerFlags & ACPI_GTDT_WATCHDOG_IRQ_POLARITY)
1964aba8816bSmsaitoh 		printf("active-lo");
1965aba8816bSmsaitoh 	else
1966aba8816bSmsaitoh 		printf("active-hi");
1967aba8816bSmsaitoh 	if (wdog->TimerFlags & ACPI_GTDT_WATCHDOG_SECURE)
1968aba8816bSmsaitoh 		printf(", Secure");
1969aba8816bSmsaitoh 	else
1970aba8816bSmsaitoh 		printf(", Non-Secure");
1971aba8816bSmsaitoh 	printf("}\n");
1972aba8816bSmsaitoh }
1973aba8816bSmsaitoh 
1974aba8816bSmsaitoh static void
acpi_handle_gtdt(ACPI_TABLE_HEADER * sdp)1975aba8816bSmsaitoh acpi_handle_gtdt(ACPI_TABLE_HEADER *sdp)
1976aba8816bSmsaitoh {
1977aba8816bSmsaitoh 	ACPI_TABLE_GTDT *gtdt;
1978aba8816bSmsaitoh 	ACPI_GTDT_HEADER *hdr;
1979aba8816bSmsaitoh 	u_int i;
1980aba8816bSmsaitoh 
1981aba8816bSmsaitoh 	printf(BEGIN_COMMENT);
1982aba8816bSmsaitoh 	acpi_print_sdt(sdp);
1983aba8816bSmsaitoh 	gtdt = (ACPI_TABLE_GTDT *)sdp;
1984aba8816bSmsaitoh 
1985aba8816bSmsaitoh 	printf("\tCounterBlockAddresss=%016jx\n",
1986aba8816bSmsaitoh 	    (uintmax_t)gtdt->CounterBlockAddresss); /* XXX not 8byte aligned */
1987aba8816bSmsaitoh 	printf("\tCounterReadBlockAddress=%016jx\n",
1988aba8816bSmsaitoh 	    (uintmax_t)gtdt->CounterReadBlockAddress);
1989aba8816bSmsaitoh 
1990aba8816bSmsaitoh #define PRINTTIMER(gtdt, name) acpi_print_gtd_timer(	\
1991aba8816bSmsaitoh 		#name, (gtdt)-> name## Interrupt,	\
1992aba8816bSmsaitoh 	(gtdt)-> name ## Flags)
1993aba8816bSmsaitoh 
1994aba8816bSmsaitoh 	PRINTTIMER(gtdt, SecureEl1);
1995aba8816bSmsaitoh 	PRINTTIMER(gtdt, NonSecureEl1);
1996aba8816bSmsaitoh 	PRINTTIMER(gtdt, VirtualTimer);
1997aba8816bSmsaitoh 	PRINTTIMER(gtdt, NonSecureEl2);
1998aba8816bSmsaitoh 
1999aba8816bSmsaitoh #undef PRINTTIMER
2000aba8816bSmsaitoh 
2001aba8816bSmsaitoh 	printf("\tPlatform Timer Count=%d\n", gtdt->PlatformTimerCount);
2002aba8816bSmsaitoh 
2003aba8816bSmsaitoh 	hdr = (ACPI_GTDT_HEADER *)((vaddr_t)sdp + gtdt->PlatformTimerOffset);
2004aba8816bSmsaitoh 	for (i = 0; i < gtdt->PlatformTimerCount; i++) {
2005aba8816bSmsaitoh 		printf("\n");
2006aba8816bSmsaitoh 		if (hdr >= (ACPI_GTDT_HEADER *)((vaddr_t)sdp + sdp->Length)) {
2007aba8816bSmsaitoh 			printf("\tWrong GTDT header"
2008aba8816bSmsaitoh 			    "(type = %hhu, length = %hu)\n",
2009aba8816bSmsaitoh 			    hdr->Type, hdr->Length);
2010aba8816bSmsaitoh 			break;
2011aba8816bSmsaitoh 		}
2012aba8816bSmsaitoh 
2013aba8816bSmsaitoh 		switch (hdr->Type) {
2014aba8816bSmsaitoh 		case ACPI_GTDT_TYPE_TIMER_BLOCK:
2015aba8816bSmsaitoh 			acpi_print_gtblock((ACPI_GTDT_TIMER_BLOCK *)hdr);
2016aba8816bSmsaitoh 			break;
2017aba8816bSmsaitoh 		case ACPI_GTDT_TYPE_WATCHDOG:
2018aba8816bSmsaitoh 			acpi_print_sbsa_watchdog((ACPI_GTDT_WATCHDOG *)hdr);
2019aba8816bSmsaitoh 			break;
2020aba8816bSmsaitoh 		default:
2021aba8816bSmsaitoh 			printf("\tUnknown Platform Timer Type"
2022aba8816bSmsaitoh 			    "(type = %hhu, length = %hu)\n",
2023aba8816bSmsaitoh 			    hdr->Type, hdr->Length);
2024aba8816bSmsaitoh 			break;
2025aba8816bSmsaitoh 		}
2026aba8816bSmsaitoh 		/* Next */
2027aba8816bSmsaitoh 		hdr = (ACPI_GTDT_HEADER *)((vaddr_t)hdr + hdr->Length);
2028aba8816bSmsaitoh 	}
2029aba8816bSmsaitoh 	printf(END_COMMENT);
2030aba8816bSmsaitoh }
2031aba8816bSmsaitoh 
2032aba8816bSmsaitoh static void
acpi_handle_madt(ACPI_TABLE_HEADER * sdp)203309f2089bScegger acpi_handle_madt(ACPI_TABLE_HEADER *sdp)
203409f2089bScegger {
203509f2089bScegger 	ACPI_TABLE_MADT *madt;
203609f2089bScegger 
203709f2089bScegger 	printf(BEGIN_COMMENT);
203809f2089bScegger 	acpi_print_sdt(sdp);
203909f2089bScegger 	madt = (ACPI_TABLE_MADT *)sdp;
204009f2089bScegger 	printf("\tLocal APIC ADDR=0x%08x\n", madt->Address);
204109f2089bScegger 	printf("\tFlags={");
204209f2089bScegger 	if (madt->Flags & ACPI_MADT_PCAT_COMPAT)
204309f2089bScegger 		printf("PC-AT");
204409f2089bScegger 	printf("}\n");
204509f2089bScegger 	acpi_walk_subtables(sdp, (madt + 1), acpi_print_madt);
204609f2089bScegger 	printf(END_COMMENT);
204709f2089bScegger }
204809f2089bScegger 
204909f2089bScegger static void
acpi_handle_hpet(ACPI_TABLE_HEADER * sdp)205009f2089bScegger acpi_handle_hpet(ACPI_TABLE_HEADER *sdp)
205109f2089bScegger {
205209f2089bScegger 	ACPI_TABLE_HPET *hpet;
205309f2089bScegger 
205409f2089bScegger 	printf(BEGIN_COMMENT);
205509f2089bScegger 	acpi_print_sdt(sdp);
205609f2089bScegger 	hpet = (ACPI_TABLE_HPET *)sdp;
205709f2089bScegger 	printf("\tHPET Number=%d\n", hpet->Sequence);
205809f2089bScegger 	printf("\tADDR=");
205909f2089bScegger 	acpi_print_gas(&hpet->Address);
2060800ead4eSmsaitoh 	printf("\n\tHW Rev=0x%x\n", hpet->Id & ACPI_HPET_ID_HARDWARE_REV_ID);
206109f2089bScegger 	printf("\tComparators=%d\n", (hpet->Id & ACPI_HPET_ID_COMPARATORS) >>
206209f2089bScegger 	    8);
206309f2089bScegger 	printf("\tCounter Size=%d\n", hpet->Id & ACPI_HPET_ID_COUNT_SIZE_CAP ?
206409f2089bScegger 	    1 : 0);
206509f2089bScegger 	printf("\tLegacy IRQ routing capable={");
206609f2089bScegger 	if (hpet->Id & ACPI_HPET_ID_LEGACY_CAPABLE)
206709f2089bScegger 		printf("TRUE}\n");
206809f2089bScegger 	else
206909f2089bScegger 		printf("FALSE}\n");
207009f2089bScegger 	printf("\tPCI Vendor ID=0x%04x\n", hpet->Id >> 16);
207109f2089bScegger 	printf("\tMinimal Tick=%d\n", hpet->MinimumTick);
2072c359a213Smsaitoh 	printf("\tFlags=0x%02x\n", hpet->Flags);
207309f2089bScegger 	printf(END_COMMENT);
207409f2089bScegger }
207509f2089bScegger 
2076c0f969c5Smsaitoh /*
2077c0f969c5Smsaitoh  * IORT
2078c0f969c5Smsaitoh  * I/O Remapping Table
2079c0f969c5Smsaitoh  */
2080c0f969c5Smsaitoh 
2081c0f969c5Smsaitoh static void acpi_print_iort_its_group(ACPI_IORT_NODE *);
2082c0f969c5Smsaitoh static void acpi_print_iort_named_component(ACPI_IORT_NODE *);
2083c0f969c5Smsaitoh static void acpi_print_iort_root_complex(ACPI_IORT_NODE *);
2084c0f969c5Smsaitoh static void acpi_print_iort_smmuv1v2(ACPI_IORT_NODE *);
2085c0f969c5Smsaitoh static void acpi_print_iort_smmuv3(ACPI_IORT_NODE *);
2086c0f969c5Smsaitoh 
2087c0f969c5Smsaitoh struct iort_node_list {
2088c0f969c5Smsaitoh 	uint8_t	Type;
2089c0f969c5Smsaitoh 	const char *gname;
2090c0f969c5Smsaitoh 	void (*func)(ACPI_IORT_NODE *);
2091c0f969c5Smsaitoh } iort_node_list [] = {
2092c0f969c5Smsaitoh #define NDMAC(name)	ACPI_IORT_NODE_## name
2093c0f969c5Smsaitoh #define PRFN(name)	acpi_print_iort_## name
2094c0f969c5Smsaitoh 	{ NDMAC(ITS_GROUP),	   "ITS group",       PRFN(its_group)},
2095c0f969c5Smsaitoh 	{ NDMAC(NAMED_COMPONENT),  "Named component", PRFN(named_component)},
2096c0f969c5Smsaitoh 	{ NDMAC(PCI_ROOT_COMPLEX), "Root complex",    PRFN(root_complex)},
2097c0f969c5Smsaitoh 	{ NDMAC(SMMU),		   "SMMUv1 or v2",    PRFN(smmuv1v2)},
2098c0f969c5Smsaitoh 	{ NDMAC(SMMU_V3),	   "SMMUv3",	      PRFN(smmuv3)},
2099c0f969c5Smsaitoh 	{ 255, NULL, NULL},
2100c0f969c5Smsaitoh #undef NDMAC
2101c0f969c5Smsaitoh #undef PRFN
2102c0f969c5Smsaitoh };
2103c0f969c5Smsaitoh 
2104c0f969c5Smsaitoh static void
acpi_print_iort_memory_access(ACPI_IORT_MEMORY_ACCESS * memacc)2105c0f969c5Smsaitoh acpi_print_iort_memory_access(ACPI_IORT_MEMORY_ACCESS *memacc)
2106c0f969c5Smsaitoh {
2107c0f969c5Smsaitoh 
2108c0f969c5Smsaitoh 	printf("\tMemory Access={\n");
2109c0f969c5Smsaitoh 	printf("\t\tCacheCoherency=");
2110c0f969c5Smsaitoh 	switch (memacc->CacheCoherency) {
2111c0f969c5Smsaitoh 	case ACPI_IORT_NODE_COHERENT:
2112c0f969c5Smsaitoh 		printf("Fully coherent\n");
2113c0f969c5Smsaitoh 		break;
2114c0f969c5Smsaitoh 	case ACPI_IORT_NODE_NOT_COHERENT:
2115c0f969c5Smsaitoh 		printf("Not coherent\n");
2116c0f969c5Smsaitoh 		break;
2117c0f969c5Smsaitoh 	default:
2118c45fbc6eSandvar 		printf("reserved (%u)\n", memacc->CacheCoherency);
2119c0f969c5Smsaitoh 		break;
2120c0f969c5Smsaitoh 	}
2121c0f969c5Smsaitoh 	printf("\t\tAllocation Hints=");
2122c0f969c5Smsaitoh #define	PRINTFLAG(var, flag)	printflag((var), ACPI_IORT_HT_## flag, #flag)
2123c0f969c5Smsaitoh 		PRINTFLAG(memacc->Hints, TRANSIENT);
2124c0f969c5Smsaitoh 		PRINTFLAG(memacc->Hints, WRITE);
2125c0f969c5Smsaitoh 		PRINTFLAG(memacc->Hints, READ);
2126c0f969c5Smsaitoh 		PRINTFLAG(memacc->Hints, OVERRIDE);
2127c0f969c5Smsaitoh 		PRINTFLAG_END();
2128c0f969c5Smsaitoh #undef PRINTFLAG
2129c0f969c5Smsaitoh 	printf("\t\tMemory Access Flags=");
2130c0f969c5Smsaitoh #define	PRINTFLAG(var, flag)	printflag((var), ACPI_IORT_MF_## flag, #flag)
2131c0f969c5Smsaitoh 		PRINTFLAG(memacc->MemoryFlags, COHERENCY);
2132c0f969c5Smsaitoh 		PRINTFLAG(memacc->MemoryFlags, ATTRIBUTES);
2133c0f969c5Smsaitoh 		PRINTFLAG_END();
2134c0f969c5Smsaitoh #undef PRINTFLAG
2135c0f969c5Smsaitoh 	printf("\t}\n");
2136c0f969c5Smsaitoh }
2137c0f969c5Smsaitoh 
2138c0f969c5Smsaitoh static void
acpi_print_iort_its_group(ACPI_IORT_NODE * node)2139c0f969c5Smsaitoh acpi_print_iort_its_group(ACPI_IORT_NODE *node)
2140c0f969c5Smsaitoh {
2141c0f969c5Smsaitoh 	ACPI_IORT_ITS_GROUP *itsg = (ACPI_IORT_ITS_GROUP *)node->NodeData;
2142c0f969c5Smsaitoh 	uint32_t *idp;
2143c0f969c5Smsaitoh 	unsigned int i;
2144c0f969c5Smsaitoh 
2145c0f969c5Smsaitoh 	idp = itsg->Identifiers;
2146c0f969c5Smsaitoh 	for (i = 0; i < itsg->ItsCount; i++)
2147c0f969c5Smsaitoh 		printf("\tGIC ITS ID=%d\n", idp[i]);
2148c0f969c5Smsaitoh }
2149c0f969c5Smsaitoh 
2150c0f969c5Smsaitoh static void
acpi_print_iort_named_component(ACPI_IORT_NODE * node)2151c0f969c5Smsaitoh acpi_print_iort_named_component(ACPI_IORT_NODE *node)
2152c0f969c5Smsaitoh {
2153c0f969c5Smsaitoh 	ACPI_IORT_NAMED_COMPONENT *ncomp
2154c0f969c5Smsaitoh 	    = (ACPI_IORT_NAMED_COMPONENT *)node->NodeData;
2155c0f969c5Smsaitoh 
2156c0f969c5Smsaitoh #define	PRINTFLAG(var, flag)	printflag((var), ACPI_IORT_NC_## flag, #flag)
2157c0f969c5Smsaitoh 	printf("\tNode Flags={PASID_BITS=%u",
2158c0f969c5Smsaitoh 	    (ncomp->NodeFlags & ACPI_IORT_NC_PASID_BITS) >> 1);
2159c0f969c5Smsaitoh 	pf_sep = ',';
2160c0f969c5Smsaitoh 	PRINTFLAG(ncomp->NodeFlags, STALL_SUPPORTED);
2161c0f969c5Smsaitoh 	PRINTFLAG_END();
2162c0f969c5Smsaitoh #undef PRINTFLAG
2163c0f969c5Smsaitoh 	acpi_print_iort_memory_access(
2164c0f969c5Smsaitoh 		(ACPI_IORT_MEMORY_ACCESS *)&ncomp->MemoryProperties);
2165c0f969c5Smsaitoh 	printf("\tMemory address size=%hhu\n", ncomp->MemoryAddressLimit);
2166c0f969c5Smsaitoh 	printf("\tDevice object Name=%s\n", ncomp->DeviceName);
2167c0f969c5Smsaitoh }
2168c0f969c5Smsaitoh 
2169c0f969c5Smsaitoh static void
acpi_print_iort_root_complex(ACPI_IORT_NODE * node)2170c0f969c5Smsaitoh acpi_print_iort_root_complex(ACPI_IORT_NODE *node)
2171c0f969c5Smsaitoh {
2172c0f969c5Smsaitoh 	ACPI_IORT_ROOT_COMPLEX *rcmp
2173c0f969c5Smsaitoh 	    = (ACPI_IORT_ROOT_COMPLEX *)node->NodeData;
2174c0f969c5Smsaitoh 
2175c0f969c5Smsaitoh 	acpi_print_iort_memory_access(
2176c0f969c5Smsaitoh 		(ACPI_IORT_MEMORY_ACCESS *)&rcmp->MemoryProperties);
2177c0f969c5Smsaitoh 	printf("\tATS Attribute=%s\n",
2178c0f969c5Smsaitoh 	    (rcmp->AtsAttribute & ACPI_IORT_ATS_SUPPORTED)
2179c0f969c5Smsaitoh 	    ? "supported" : "not supported");
2180c0f969c5Smsaitoh 	printf("\tPCI Segment=%u\n", rcmp->PciSegmentNumber);
2181c0f969c5Smsaitoh 	printf("\tMemory address size limit=%hhu\n", rcmp->MemoryAddressLimit);
2182c0f969c5Smsaitoh }
2183c0f969c5Smsaitoh 
2184c0f969c5Smsaitoh static void
acpi_print_iort_smmuv1v2_intflags(uint32_t flags)2185c0f969c5Smsaitoh acpi_print_iort_smmuv1v2_intflags(uint32_t flags)
2186c0f969c5Smsaitoh {
2187c0f969c5Smsaitoh 
2188c0f969c5Smsaitoh 	printf("{Mode=");
2189c0f969c5Smsaitoh 	if (flags & 0x01)
2190c0f969c5Smsaitoh 		printf("edge");
2191c0f969c5Smsaitoh 	else
2192c0f969c5Smsaitoh 		printf("level");
2193c0f969c5Smsaitoh 	printf("}\n");
2194c0f969c5Smsaitoh }
2195c0f969c5Smsaitoh 
2196c0f969c5Smsaitoh static void
acpi_print_iort_smmuv1v2(ACPI_IORT_NODE * node)2197c0f969c5Smsaitoh acpi_print_iort_smmuv1v2(ACPI_IORT_NODE *node)
2198c0f969c5Smsaitoh {
2199c0f969c5Smsaitoh 	ACPI_IORT_SMMU *smmu = (ACPI_IORT_SMMU *)node->NodeData;
2200c0f969c5Smsaitoh 	ACPI_IORT_SMMU_GSI *gsi;
2201c0f969c5Smsaitoh 	uint64_t *iarray;
2202c0f969c5Smsaitoh 	unsigned int i;
2203c0f969c5Smsaitoh 
2204c0f969c5Smsaitoh 	printf("\tBase Address=%016jx\n", (uintmax_t)smmu->BaseAddress);
2205c0f969c5Smsaitoh 	printf("\tSpan=%016jx\n", (uintmax_t)smmu->Span);
2206c0f969c5Smsaitoh 	printf("\tModel=");
2207c0f969c5Smsaitoh 	switch (smmu->Model) {
2208c0f969c5Smsaitoh 	case ACPI_IORT_SMMU_V1:
2209c0f969c5Smsaitoh 		printf("Generic SMMUv1\n");
2210c0f969c5Smsaitoh 		break;
2211c0f969c5Smsaitoh 	case ACPI_IORT_SMMU_V2:
2212c0f969c5Smsaitoh 		printf("Generic SMMUv2\n");
2213c0f969c5Smsaitoh 		break;
2214c0f969c5Smsaitoh 	case ACPI_IORT_SMMU_CORELINK_MMU400:
2215c0f969c5Smsaitoh 		printf("Arm Corelink MMU-400\n");
2216c0f969c5Smsaitoh 		break;
2217c0f969c5Smsaitoh 	case ACPI_IORT_SMMU_CORELINK_MMU500:
2218c0f969c5Smsaitoh 		printf("Arm Corelink MMU-500\n");
2219c0f969c5Smsaitoh 		break;
2220c0f969c5Smsaitoh 	case ACPI_IORT_SMMU_CORELINK_MMU401:
2221c0f969c5Smsaitoh 		printf("Arm Corelink MMU-401\n");
2222c0f969c5Smsaitoh 		break;
2223c0f969c5Smsaitoh 	case ACPI_IORT_SMMU_CAVIUM_THUNDERX:
2224c0f969c5Smsaitoh 		printf("Cavium ThunderX SMMUv2\n");
2225c0f969c5Smsaitoh 		break;
2226c0f969c5Smsaitoh 	default:
2227c0f969c5Smsaitoh 		printf("reserved (%u)\n", smmu->Model);
2228c0f969c5Smsaitoh 		break;
2229c0f969c5Smsaitoh 	}
2230c0f969c5Smsaitoh #define	PRINTFLAG(var, flag)	printflag((var), ACPI_IORT_SMMU_## flag, #flag)
2231c0f969c5Smsaitoh 	printf("\tFlags=");
2232c0f969c5Smsaitoh 	PRINTFLAG(smmu->Flags, DVM_SUPPORTED);
2233c0f969c5Smsaitoh 	PRINTFLAG(smmu->Flags, COHERENT_WALK);
2234c0f969c5Smsaitoh 	PRINTFLAG_END();
2235c0f969c5Smsaitoh #undef PRINTFLAG
2236c0f969c5Smsaitoh 
2237c0f969c5Smsaitoh 	gsi = (ACPI_IORT_SMMU_GSI *)((vaddr_t)node
2238c0f969c5Smsaitoh 	    + smmu->GlobalInterruptOffset);
2239c0f969c5Smsaitoh 	printf("\tNSgIrpt=%u\n", gsi->NSgIrpt);
2240c0f969c5Smsaitoh 	printf("\tNSgIrptFlags=");
2241c0f969c5Smsaitoh 	acpi_print_iort_smmuv1v2_intflags(gsi->NSgIrptFlags);
2242c0f969c5Smsaitoh 	printf("\tNSgCfgIrpt=%u\n", gsi->NSgCfgIrpt);
2243c0f969c5Smsaitoh 	printf("\tNSgCfgIrptFlags=");
2244c0f969c5Smsaitoh 	acpi_print_iort_smmuv1v2_intflags(gsi->NSgCfgIrptFlags);
2245c0f969c5Smsaitoh 
2246c0f969c5Smsaitoh 	if (smmu->ContextInterruptCount != 0) {
2247c0f969c5Smsaitoh 		iarray = (uint64_t *)((vaddr_t)node
2248c0f969c5Smsaitoh 		    + smmu->ContextInterruptOffset);
2249c0f969c5Smsaitoh 		printf("\tContext Interrupts={\n");
2250c0f969c5Smsaitoh 		for (i = 0; i < smmu->ContextInterruptCount; i++) {
2251c0f969c5Smsaitoh 			printf("\t\tGSIV=%u\n",
2252c0f969c5Smsaitoh 			    (uint32_t)(iarray[i] & 0xffffffff));
2253c0f969c5Smsaitoh 			printf("\t\tFlags=%u\n", (uint32_t)(iarray[i] >> 32));
2254c0f969c5Smsaitoh 		}
2255c0f969c5Smsaitoh 	}
2256c0f969c5Smsaitoh 	if (smmu->PmuInterruptCount != 0) {
2257c0f969c5Smsaitoh 		iarray = (uint64_t *)((vaddr_t)node
2258c0f969c5Smsaitoh 		    + smmu->PmuInterruptOffset);
2259c0f969c5Smsaitoh 		printf("\tPmu Interrupts={\n");
2260c0f969c5Smsaitoh 		for (i = 0; i < smmu->PmuInterruptCount; i++) {
2261c0f969c5Smsaitoh 			printf("\t\tGSIV=%u\n",
2262c0f969c5Smsaitoh 			    (uint32_t)(iarray[i] & 0xffffffff));
2263c0f969c5Smsaitoh 			printf("\t\tFlags=%u\n", (uint32_t)(iarray[i] >> 32));
2264c0f969c5Smsaitoh 		}
2265c0f969c5Smsaitoh 	}
2266c0f969c5Smsaitoh }
2267c0f969c5Smsaitoh 
2268c0f969c5Smsaitoh static void
acpi_print_iort_smmuv3(ACPI_IORT_NODE * node)2269c0f969c5Smsaitoh acpi_print_iort_smmuv3(ACPI_IORT_NODE *node)
2270c0f969c5Smsaitoh {
2271c0f969c5Smsaitoh 	ACPI_IORT_SMMU_V3 *smmu = (ACPI_IORT_SMMU_V3 *)node->NodeData;
2272c0f969c5Smsaitoh 	uint8_t httuo;
2273c0f969c5Smsaitoh 
2274c0f969c5Smsaitoh 	printf("\tBase Address=%016jx\n", (uintmax_t)smmu->BaseAddress);
2275c0f969c5Smsaitoh #define	PRINTFLAG(var, flag)	printflag((var), ACPI_IORT_SMMU_V3_## flag, \
2276c0f969c5Smsaitoh 	    #flag)
2277c0f969c5Smsaitoh 	httuo = __SHIFTOUT(smmu->Flags, ACPI_IORT_SMMU_V3_HTTU_OVERRIDE);
2278c0f969c5Smsaitoh 	printf("\tFlags={HTTU Override=%hhx", httuo);
2279c0f969c5Smsaitoh 	pf_sep = ',';
2280c0f969c5Smsaitoh 	PRINTFLAG(smmu->Flags, HTTU_OVERRIDE);
2281c0f969c5Smsaitoh 	PRINTFLAG(smmu->Flags, COHACC_OVERRIDE);
2282c0f969c5Smsaitoh 	PRINTFLAG(smmu->Flags, PXM_VALID);
2283c0f969c5Smsaitoh 	PRINTFLAG_END();
2284c0f969c5Smsaitoh #undef PRINTFLAG
2285c0f969c5Smsaitoh 	printf("\tVATOS Address=%016jx\n", (uintmax_t)smmu->VatosAddress);
2286c0f969c5Smsaitoh 	printf("\tModel=");
2287c0f969c5Smsaitoh 	switch (smmu->Model) {
2288c0f969c5Smsaitoh 	case ACPI_IORT_SMMU_V3_GENERIC:
2289c0f969c5Smsaitoh 		printf("Generic SMMUv3\n");
2290c0f969c5Smsaitoh 		break;
2291c0f969c5Smsaitoh 	case ACPI_IORT_SMMU_V3_HISILICON_HI161X:
2292c0f969c5Smsaitoh 		printf("HiSilicon Hi161x SMMU-v3\n");
2293c0f969c5Smsaitoh 		break;
2294c0f969c5Smsaitoh 	case ACPI_IORT_SMMU_V3_CAVIUM_CN99XX:
2295c0f969c5Smsaitoh 		printf("Cavium CN99xx SMMU-v3\n");
2296c0f969c5Smsaitoh 		break;
2297c0f969c5Smsaitoh 	default:
2298c0f969c5Smsaitoh 		printf("reserved (%u)\n", smmu->Model);
2299c0f969c5Smsaitoh 		break;
2300c0f969c5Smsaitoh 	}
2301c0f969c5Smsaitoh 
2302c0f969c5Smsaitoh 	printf("\tEvent GSIV=%u\n", smmu->EventGsiv);
2303c0f969c5Smsaitoh 	printf("\tPRI GSIV=%u\n", smmu->PriGsiv);
2304c0f969c5Smsaitoh 	printf("\tGERR GSIV=%u\n", smmu->GerrGsiv);
2305c0f969c5Smsaitoh 	printf("\tSync GSIV=%u\n", smmu->SyncGsiv);
2306c0f969c5Smsaitoh 	printf("\tProximity domain=%u\n", smmu->Pxm);
2307c0f969c5Smsaitoh 
2308a136e22aSandvar 	/* XXX should we print the referred contents? */
2309c0f969c5Smsaitoh 	printf("\tDevice ID mapping index=%u\n", smmu->IdMappingIndex);
2310c0f969c5Smsaitoh }
2311c0f969c5Smsaitoh 
2312c0f969c5Smsaitoh static void
acpi_print_iort_node(ACPI_IORT_NODE * node)2313c0f969c5Smsaitoh acpi_print_iort_node(ACPI_IORT_NODE *node)
2314c0f969c5Smsaitoh {
2315c0f969c5Smsaitoh 	ACPI_IORT_ID_MAPPING *mapping;
2316c0f969c5Smsaitoh 	uint32_t offset;
2317c0f969c5Smsaitoh 	int datasize;
2318c0f969c5Smsaitoh 	bool dodump = false;
2319c0f969c5Smsaitoh 	struct iort_node_list *list;
2320c0f969c5Smsaitoh 	unsigned int i;
2321c0f969c5Smsaitoh 
2322c0f969c5Smsaitoh 	printf("\tLength=%hu\n", node->Length);
2323c0f969c5Smsaitoh 	printf("\tRevision=%hhu\n", node->Revision);
2324c0f969c5Smsaitoh 	printf("\tType=");
2325c0f969c5Smsaitoh 
2326c0f969c5Smsaitoh 	datasize = node->MappingOffset - offsetof(ACPI_IORT_NODE, NodeData);
2327c0f969c5Smsaitoh 	if (datasize != 0)
2328c0f969c5Smsaitoh 		dodump = true;
2329c0f969c5Smsaitoh 
2330c0f969c5Smsaitoh 	for (list = iort_node_list; list->gname != NULL; list++) {
2331c0f969c5Smsaitoh 		if (node->Type == list->Type) {
2332c0f969c5Smsaitoh 			printf("%s\n", list->gname);
2333c0f969c5Smsaitoh 			if (dodump)
2334c0f969c5Smsaitoh 				(*list->func)(node);
2335c0f969c5Smsaitoh 			break;
2336c0f969c5Smsaitoh 		}
2337c0f969c5Smsaitoh 	}
2338c0f969c5Smsaitoh 	if (list->gname == NULL)
2339c0f969c5Smsaitoh 		printf("reserved (0x%hhx)\n", node->Type);
2340c0f969c5Smsaitoh 
2341c0f969c5Smsaitoh 	printf("\tMappingCount=%u\n", node->MappingCount);
2342c0f969c5Smsaitoh 	if (node->MappingCount == 0)
2343c0f969c5Smsaitoh 		return;
2344c0f969c5Smsaitoh 
2345c0f969c5Smsaitoh 	offset = node->MappingOffset;
2346c0f969c5Smsaitoh 	printf("\tMapping offset=%u\n", offset);
2347c0f969c5Smsaitoh 	for (i = 0; i < node->MappingCount; i++) {
2348c0f969c5Smsaitoh 		mapping = (ACPI_IORT_ID_MAPPING *)((vaddr_t)node + offset);
2349c0f969c5Smsaitoh 		printf("\tMapping={\n");
2350c0f969c5Smsaitoh 		printf("\t\tInput base=%u\n", mapping->InputBase);
2351c0f969c5Smsaitoh 		printf("\t\tCount=%u\n", mapping->IdCount);
2352c0f969c5Smsaitoh 		printf("\t\tOutput base=%u\n", mapping->OutputBase);
2353c0f969c5Smsaitoh 		printf("\t\tOutput reference offset=%u\n",
2354c0f969c5Smsaitoh 		    mapping->OutputReference);
2355c0f969c5Smsaitoh #define	PRINTFLAG(var, flag)	printflag((var), ACPI_IORT_ID_## flag, #flag)
2356c0f969c5Smsaitoh 		printf("\t\tFlags=");
2357c0f969c5Smsaitoh 		PRINTFLAG(mapping->Flags, SINGLE_MAPPING);
2358c0f969c5Smsaitoh 		PRINTFLAG_END();
2359c0f969c5Smsaitoh #undef PRINTFLAG
2360c0f969c5Smsaitoh 		printf("\t}\n");
2361c0f969c5Smsaitoh 		offset += sizeof(ACPI_IORT_ID_MAPPING);
2362c0f969c5Smsaitoh 	}
2363c0f969c5Smsaitoh }
2364c0f969c5Smsaitoh 
2365c0f969c5Smsaitoh static void
acpi_handle_iort(ACPI_TABLE_HEADER * sdp)2366c0f969c5Smsaitoh acpi_handle_iort(ACPI_TABLE_HEADER *sdp)
2367c0f969c5Smsaitoh {
2368c0f969c5Smsaitoh 	ACPI_TABLE_IORT *iort;
2369c0f969c5Smsaitoh 	ACPI_IORT_NODE *node;
2370c0f969c5Smsaitoh 	unsigned int i;
2371c0f969c5Smsaitoh 
2372c0f969c5Smsaitoh 	printf(BEGIN_COMMENT);
2373c0f969c5Smsaitoh 	acpi_print_sdt(sdp);
2374c0f969c5Smsaitoh 	iort = (ACPI_TABLE_IORT *)sdp;
2375c0f969c5Smsaitoh 	printf("\tIORT Nodes=%u\n", iort->NodeCount);
2376c0f969c5Smsaitoh 	printf("\tNode offset=%u\n", iort->NodeOffset);
2377c0f969c5Smsaitoh 
2378c0f969c5Smsaitoh 	node = (ACPI_IORT_NODE *)((vaddr_t)iort + iort->NodeOffset);
2379c0f969c5Smsaitoh 	for (i = 0; i < iort->NodeCount; i++) {
2380c0f969c5Smsaitoh 		printf("\n");
2381c0f969c5Smsaitoh 		acpi_print_iort_node(node);
2382c0f969c5Smsaitoh 
2383c0f969c5Smsaitoh 		/* Next */
2384c0f969c5Smsaitoh 		node = (ACPI_IORT_NODE *)((vaddr_t)node + node->Length);
2385c0f969c5Smsaitoh 	}
2386c0f969c5Smsaitoh 
2387c0f969c5Smsaitoh 	printf(END_COMMENT);
2388c0f969c5Smsaitoh }
2389c0f969c5Smsaitoh 
239009f2089bScegger static void
acpi_print_native_lpit(ACPI_LPIT_NATIVE * nl)23913de33cabSmsaitoh acpi_print_native_lpit(ACPI_LPIT_NATIVE *nl)
23923de33cabSmsaitoh {
23933de33cabSmsaitoh 	printf("\tEntryTrigger=");
23943de33cabSmsaitoh 	acpi_print_gas(&nl->EntryTrigger);
2395800ead4eSmsaitoh 	printf("\n\tResidency=%u\n", nl->Residency);
23963de33cabSmsaitoh 	printf("\tLatency=%u\n", nl->Latency);
23973de33cabSmsaitoh 	if (nl->Header.Flags & ACPI_LPIT_NO_COUNTER)
23983de33cabSmsaitoh 		printf("\tResidencyCounter=Not Present");
23993de33cabSmsaitoh 	else {
24003de33cabSmsaitoh 		printf("\tResidencyCounter=");
24013de33cabSmsaitoh 		acpi_print_gas(&nl->ResidencyCounter);
2402800ead4eSmsaitoh 		printf("\n");
24033de33cabSmsaitoh 	}
24043de33cabSmsaitoh 	if (nl->CounterFrequency)
24053de33cabSmsaitoh 		printf("\tCounterFrequency=%ju\n", nl->CounterFrequency);
24063de33cabSmsaitoh 	else
24073de33cabSmsaitoh 		printf("\tCounterFrequency=TSC\n");
24083de33cabSmsaitoh }
24093de33cabSmsaitoh 
24103de33cabSmsaitoh static void
acpi_print_lpit(ACPI_LPIT_HEADER * lpit)24113de33cabSmsaitoh acpi_print_lpit(ACPI_LPIT_HEADER *lpit)
24123de33cabSmsaitoh {
24133de33cabSmsaitoh 	if (lpit->Type == ACPI_LPIT_TYPE_NATIVE_CSTATE)
24143de33cabSmsaitoh 		printf("\tType=ACPI_LPIT_TYPE_NATIVE_CSTATE\n");
24153de33cabSmsaitoh 	else
24163de33cabSmsaitoh 		warnx("unknown LPIT type %u", lpit->Type);
24173de33cabSmsaitoh 
24183de33cabSmsaitoh 	printf("\tLength=%u\n", lpit->Length);
24193de33cabSmsaitoh 	printf("\tUniqueId=0x%04x\n", lpit->UniqueId);
24203de33cabSmsaitoh #define	PRINTFLAG(var, flag)	printflag((var), ACPI_LPIT_## flag, #flag)
24213de33cabSmsaitoh 	printf("\tFlags=");
24223de33cabSmsaitoh 	PRINTFLAG(lpit->Flags, STATE_DISABLED);
24233de33cabSmsaitoh 	PRINTFLAG_END();
24243de33cabSmsaitoh #undef PRINTFLAG
24253de33cabSmsaitoh 
24263de33cabSmsaitoh 	if (lpit->Type == ACPI_LPIT_TYPE_NATIVE_CSTATE)
2427bbb9ad67Srillig 		acpi_print_native_lpit((ACPI_LPIT_NATIVE *)lpit);
24283de33cabSmsaitoh }
24293de33cabSmsaitoh 
24303de33cabSmsaitoh static void
acpi_walk_lpit(ACPI_TABLE_HEADER * table,void * first,void (* action)(ACPI_LPIT_HEADER *))24313de33cabSmsaitoh acpi_walk_lpit(ACPI_TABLE_HEADER *table, void *first,
24323de33cabSmsaitoh     void (*action)(ACPI_LPIT_HEADER *))
24333de33cabSmsaitoh {
24343de33cabSmsaitoh 	ACPI_LPIT_HEADER *subtable;
24353de33cabSmsaitoh 	char *end;
24363de33cabSmsaitoh 
24373de33cabSmsaitoh 	subtable = first;
24383de33cabSmsaitoh 	end = (char *)table + table->Length;
24393de33cabSmsaitoh 	while ((char *)subtable < end) {
24403de33cabSmsaitoh 		printf("\n");
24413de33cabSmsaitoh 		if (subtable->Length < sizeof(ACPI_LPIT_HEADER)) {
24423de33cabSmsaitoh 			warnx("invalid subtable length %u", subtable->Length);
24433de33cabSmsaitoh 			return;
24443de33cabSmsaitoh 		}
24453de33cabSmsaitoh 		action(subtable);
24463de33cabSmsaitoh 		subtable = (ACPI_LPIT_HEADER *)((char *)subtable +
24473de33cabSmsaitoh 		    subtable->Length);
24483de33cabSmsaitoh 	}
24493de33cabSmsaitoh }
24503de33cabSmsaitoh 
24513de33cabSmsaitoh static void
acpi_handle_lpit(ACPI_TABLE_HEADER * sdp)24523de33cabSmsaitoh acpi_handle_lpit(ACPI_TABLE_HEADER *sdp)
24533de33cabSmsaitoh {
24543de33cabSmsaitoh 	ACPI_TABLE_LPIT *lpit;
24553de33cabSmsaitoh 
24563de33cabSmsaitoh 	printf(BEGIN_COMMENT);
24573de33cabSmsaitoh 	acpi_print_sdt(sdp);
24583de33cabSmsaitoh 	lpit = (ACPI_TABLE_LPIT *)sdp;
24593de33cabSmsaitoh 	acpi_walk_lpit(sdp, (lpit + 1), acpi_print_lpit);
24603de33cabSmsaitoh 
24613de33cabSmsaitoh 	printf(END_COMMENT);
24623de33cabSmsaitoh }
24633de33cabSmsaitoh 
24643de33cabSmsaitoh static void
acpi_handle_msct(ACPI_TABLE_HEADER * sdp)246509f2089bScegger acpi_handle_msct(ACPI_TABLE_HEADER *sdp)
246609f2089bScegger {
246709f2089bScegger 	ACPI_TABLE_MSCT *msct;
246809f2089bScegger 	ACPI_MSCT_PROXIMITY *msctentry;
246909f2089bScegger 	uint32_t pos;
247009f2089bScegger 
247109f2089bScegger 	printf(BEGIN_COMMENT);
247209f2089bScegger 	acpi_print_sdt(sdp);
247309f2089bScegger 	msct = (ACPI_TABLE_MSCT *)sdp;
247409f2089bScegger 
247509f2089bScegger 	printf("\tProximity Offset=0x%x\n", msct->ProximityOffset);
247609f2089bScegger 	printf("\tMax Proximity Domains=%d\n", msct->MaxProximityDomains);
247709f2089bScegger 	printf("\tMax Clock Domains=%d\n", msct->MaxClockDomains);
247809f2089bScegger 	printf("\tMax Physical Address=0x%"PRIx64"\n", msct->MaxAddress);
247909f2089bScegger 
248009f2089bScegger 	pos = msct->ProximityOffset;
248109f2089bScegger 	while (pos < msct->Header.Length) {
248209f2089bScegger 		msctentry = (ACPI_MSCT_PROXIMITY *)((char *)msct + pos);
248309f2089bScegger 		pos += msctentry->Length;
248409f2089bScegger 
248509f2089bScegger 		printf("\n");
248609f2089bScegger 		printf("\tRevision=%d\n", msctentry->Revision);
248709f2089bScegger 		printf("\tLength=%d\n", msctentry->Length);
248809f2089bScegger 		printf("\tRange Start=%d\n", msctentry->RangeStart);
248909f2089bScegger 		printf("\tRange End=%d\n", msctentry->RangeEnd);
249009f2089bScegger 		printf("\tProcessor Capacity=%d\n",
249109f2089bScegger 		    msctentry->ProcessorCapacity);
249209f2089bScegger 		printf("\tMemory Capacity=0x%"PRIx64" byte\n",
249309f2089bScegger 		    msctentry->MemoryCapacity);
249409f2089bScegger 	}
249509f2089bScegger 
249609f2089bScegger 	printf(END_COMMENT);
249709f2089bScegger }
249809f2089bScegger 
249909f2089bScegger static void
acpi_handle_ecdt(ACPI_TABLE_HEADER * sdp)250009f2089bScegger acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp)
250109f2089bScegger {
250209f2089bScegger 	ACPI_TABLE_ECDT *ecdt;
250309f2089bScegger 
250409f2089bScegger 	printf(BEGIN_COMMENT);
250509f2089bScegger 	acpi_print_sdt(sdp);
250609f2089bScegger 	ecdt = (ACPI_TABLE_ECDT *)sdp;
250709f2089bScegger 	printf("\tEC_CONTROL=");
250809f2089bScegger 	acpi_print_gas(&ecdt->Control);
250909f2089bScegger 	printf("\n\tEC_DATA=");
251009f2089bScegger 	acpi_print_gas(&ecdt->Data);
251109f2089bScegger 	printf("\n\tUID=%#x, ", ecdt->Uid);
251209f2089bScegger 	printf("GPE_BIT=%#x\n", ecdt->Gpe);
251309f2089bScegger 	printf("\tEC_ID=%s\n", ecdt->Id);
251409f2089bScegger 	printf(END_COMMENT);
251509f2089bScegger }
251609f2089bScegger 
251709f2089bScegger static void
acpi_handle_mcfg(ACPI_TABLE_HEADER * sdp)251809f2089bScegger acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp)
251909f2089bScegger {
252009f2089bScegger 	ACPI_TABLE_MCFG *mcfg;
252109f2089bScegger 	ACPI_MCFG_ALLOCATION *alloc;
252209f2089bScegger 	u_int i, entries;
252309f2089bScegger 
252409f2089bScegger 	printf(BEGIN_COMMENT);
252509f2089bScegger 	acpi_print_sdt(sdp);
252609f2089bScegger 	mcfg = (ACPI_TABLE_MCFG *)sdp;
252709f2089bScegger 	entries = (sdp->Length - sizeof(ACPI_TABLE_MCFG)) /
252809f2089bScegger 	    sizeof(ACPI_MCFG_ALLOCATION);
252909f2089bScegger 	alloc = (ACPI_MCFG_ALLOCATION *)(mcfg + 1);
253009f2089bScegger 	for (i = 0; i < entries; i++, alloc++) {
253109f2089bScegger 		printf("\n");
2532c359a213Smsaitoh 		printf("\tBase Address=0x%016jx\n", (uintmax_t)alloc->Address);
253309f2089bScegger 		printf("\tSegment Group=0x%04x\n", alloc->PciSegment);
253409f2089bScegger 		printf("\tStart Bus=%d\n", alloc->StartBusNumber);
253509f2089bScegger 		printf("\tEnd Bus=%d\n", alloc->EndBusNumber);
253609f2089bScegger 	}
253709f2089bScegger 	printf(END_COMMENT);
253809f2089bScegger }
253909f2089bScegger 
254009f2089bScegger static void
acpi_print_pcct_subspace(ACPI_PCCT_SUBSPACE * subspace)25410eb6f089Sjmcneill acpi_print_pcct_subspace(ACPI_PCCT_SUBSPACE *subspace)
25420eb6f089Sjmcneill {
25430eb6f089Sjmcneill 	printf("\tType=Generic Subspace\n");
25440eb6f089Sjmcneill 	printf("\tBase Address=0x%016jx\n", subspace->BaseAddress);
25450eb6f089Sjmcneill 	printf("\tLength=%jd\n", subspace->Length);
25460eb6f089Sjmcneill 	printf("\tDoorbell Address=");
25470eb6f089Sjmcneill 	acpi_print_gas(&subspace->DoorbellRegister);
25480eb6f089Sjmcneill 	printf("\n");
25490eb6f089Sjmcneill 	printf("\tDoorbell Preserve=0x%016jx\n", subspace->PreserveMask);
25500eb6f089Sjmcneill 	printf("\tDoorbell Write=0x%016jx\n", subspace->WriteMask);
25510eb6f089Sjmcneill 	printf("\tLatency=%u us\n", subspace->Latency);
25520eb6f089Sjmcneill 	printf("\tMax Access Rate=%u\n", subspace->MaxAccessRate);
25530eb6f089Sjmcneill 	printf("\tMin Turnaround Time=%u us\n", subspace->MinTurnaroundTime);
25540eb6f089Sjmcneill }
25550eb6f089Sjmcneill 
25560eb6f089Sjmcneill static void
acpi_print_pcct_hw_reduced(ACPI_PCCT_HW_REDUCED * subspace)25570eb6f089Sjmcneill acpi_print_pcct_hw_reduced(ACPI_PCCT_HW_REDUCED *subspace)
25580eb6f089Sjmcneill {
25590eb6f089Sjmcneill 	printf("\tType=HW-reduced Subspace\n");
25600eb6f089Sjmcneill 	printf("\tPlatform Interrupt=%u", subspace->PlatformInterrupt);
25610eb6f089Sjmcneill 	if (subspace->Flags & ACPI_PCCT_INTERRUPT_POLARITY) {
25620eb6f089Sjmcneill 		printf(", Edge triggered");
25630eb6f089Sjmcneill 	} else {
25640eb6f089Sjmcneill 		printf(", Level triggered");
25650eb6f089Sjmcneill 	}
25660eb6f089Sjmcneill 	if (subspace->Flags & ACPI_PCCT_INTERRUPT_MODE) {
25670eb6f089Sjmcneill 		printf(", Active low");
25680eb6f089Sjmcneill 	} else {
25690eb6f089Sjmcneill 		printf(", Active high");
25700eb6f089Sjmcneill 	}
25710eb6f089Sjmcneill 	printf("\n");
25720eb6f089Sjmcneill 	printf("\tBase Address=0x%016jx\n", subspace->BaseAddress);
25730eb6f089Sjmcneill 	printf("\tLength=%jd\n", subspace->Length);
25740eb6f089Sjmcneill 	printf("\tDoorbell Register=");
25750eb6f089Sjmcneill 	acpi_print_gas(&subspace->DoorbellRegister);
25760eb6f089Sjmcneill 	printf("\n");
25770eb6f089Sjmcneill 	printf("\tDoorbell Preserve=0x%016jx\n", subspace->PreserveMask);
25780eb6f089Sjmcneill 	printf("\tDoorbell Write=0x%016jx\n", subspace->WriteMask);
25790eb6f089Sjmcneill 	printf("\tLatency=%u us\n", subspace->Latency);
25800eb6f089Sjmcneill 	printf("\tMax Access Rate=%u\n", subspace->MaxAccessRate);
25810eb6f089Sjmcneill 	printf("\tMin Turnaround Time=%u us\n", subspace->MinTurnaroundTime);
25820eb6f089Sjmcneill }
25830eb6f089Sjmcneill 
25840eb6f089Sjmcneill static void
acpi_print_pcct_hw_reduced_type2(ACPI_PCCT_HW_REDUCED_TYPE2 * subspace)25850eb6f089Sjmcneill acpi_print_pcct_hw_reduced_type2(ACPI_PCCT_HW_REDUCED_TYPE2 *subspace)
25860eb6f089Sjmcneill {
25870eb6f089Sjmcneill 	printf("\tType=HW-reduced Subspace Type 2\n");
25880eb6f089Sjmcneill 	printf("\tPlatform Interrupt=%u", subspace->PlatformInterrupt);
25890eb6f089Sjmcneill 	if (subspace->Flags & ACPI_PCCT_INTERRUPT_POLARITY) {
25900eb6f089Sjmcneill 		printf(", Edge triggered");
25910eb6f089Sjmcneill 	} else {
25920eb6f089Sjmcneill 		printf(", Level triggered");
25930eb6f089Sjmcneill 	}
25940eb6f089Sjmcneill 	if (subspace->Flags & ACPI_PCCT_INTERRUPT_MODE) {
25950eb6f089Sjmcneill 		printf(", Active low");
25960eb6f089Sjmcneill 	} else {
25970eb6f089Sjmcneill 		printf(", Active high");
25980eb6f089Sjmcneill 	}
25990eb6f089Sjmcneill 	printf("\n");
26000eb6f089Sjmcneill 	printf("\tBase Address=0x%016jx\n", subspace->BaseAddress);
26010eb6f089Sjmcneill 	printf("\tLength=%jd\n", subspace->Length);
26020eb6f089Sjmcneill 	printf("\tDoorbell Register=");
26030eb6f089Sjmcneill 	acpi_print_gas(&subspace->DoorbellRegister);
26040eb6f089Sjmcneill 	printf("\n");
26050eb6f089Sjmcneill 	printf("\tDoorbell Preserve=0x%016jx\n", subspace->PreserveMask);
26060eb6f089Sjmcneill 	printf("\tDoorbell Write=0x%016jx\n", subspace->WriteMask);
26070eb6f089Sjmcneill 	printf("\tLatency=%u us\n", subspace->Latency);
26080eb6f089Sjmcneill 	printf("\tMax Access Rate=%u\n", subspace->MaxAccessRate);
26090eb6f089Sjmcneill 	printf("\tMin Turnaround Time=%u us\n", subspace->MinTurnaroundTime);
26100eb6f089Sjmcneill 	printf("\tPlatform Interrupt Ack Register=");
26110eb6f089Sjmcneill 	acpi_print_gas(&subspace->PlatformAckRegister);
26120eb6f089Sjmcneill 	printf("\n");
26130eb6f089Sjmcneill 	printf("\tPlatform Interrupt Ack Preserve=0x%016jx\n", subspace->AckPreserveMask);
26140eb6f089Sjmcneill 	printf("\tPlatform Interrupt Ack Write=0x%016jx\n", subspace->AckWriteMask);
26150eb6f089Sjmcneill }
26160eb6f089Sjmcneill 
26170eb6f089Sjmcneill static void
acpi_print_pcct_ext_pcc_master(ACPI_PCCT_EXT_PCC_MASTER * subspace)26180eb6f089Sjmcneill acpi_print_pcct_ext_pcc_master(ACPI_PCCT_EXT_PCC_MASTER *subspace)
26190eb6f089Sjmcneill {
26200eb6f089Sjmcneill 	printf("\tType=Extended PCC Master Subspace\n");
26210eb6f089Sjmcneill 	printf("\tPlatform Interrupt=%u", subspace->PlatformInterrupt);
26220eb6f089Sjmcneill 	if (subspace->Flags & ACPI_PCCT_INTERRUPT_POLARITY) {
26230eb6f089Sjmcneill 		printf(", Edge triggered");
26240eb6f089Sjmcneill 	} else {
26250eb6f089Sjmcneill 		printf(", Level triggered");
26260eb6f089Sjmcneill 	}
26270eb6f089Sjmcneill 	if (subspace->Flags & ACPI_PCCT_INTERRUPT_MODE) {
26280eb6f089Sjmcneill 		printf(", Active low");
26290eb6f089Sjmcneill 	} else {
26300eb6f089Sjmcneill 		printf(", Active high");
26310eb6f089Sjmcneill 	}
26320eb6f089Sjmcneill 	printf("\n");
26330eb6f089Sjmcneill 	printf("\tBase Address=0x%016jx\n", subspace->BaseAddress);
26340eb6f089Sjmcneill 	printf("\tLength=%d\n", subspace->Length);
26350eb6f089Sjmcneill 	printf("\tDoorbell Register=");
26360eb6f089Sjmcneill 	acpi_print_gas(&subspace->DoorbellRegister);
26370eb6f089Sjmcneill 	printf("\n");
26380eb6f089Sjmcneill 	printf("\tDoorbell Preserve=0x%016jx\n", subspace->PreserveMask);
26390eb6f089Sjmcneill 	printf("\tDoorbell Write=0x%016jx\n", subspace->WriteMask);
26400eb6f089Sjmcneill 	printf("\tLatency=%u us\n", subspace->Latency);
26410eb6f089Sjmcneill 	printf("\tMax Access Rate=%u\n", subspace->MaxAccessRate);
26420eb6f089Sjmcneill 	printf("\tMin Turnaround Time=%u us\n", subspace->MinTurnaroundTime);
26430eb6f089Sjmcneill 	printf("\tPlatform Interrupt Ack Register=");
26440eb6f089Sjmcneill 	acpi_print_gas(&subspace->PlatformAckRegister);
26450eb6f089Sjmcneill 	printf("\n");
26460eb6f089Sjmcneill 	printf("\tPlatform Interrupt Ack Preserve=0x%016jx\n", subspace->AckPreserveMask);
26470eb6f089Sjmcneill 	printf("\tPlatform Interrupt Ack Set=0x%016jx\n", subspace->AckSetMask);
26480eb6f089Sjmcneill 	printf("\tCommand Complete Register=");
26490eb6f089Sjmcneill 	acpi_print_gas(&subspace->CmdCompleteRegister);
26500eb6f089Sjmcneill 	printf("\n");
26510eb6f089Sjmcneill 	printf("\tCommand Complete Mask=0x%016jx\n", subspace->CmdCompleteMask);
26520eb6f089Sjmcneill 	printf("\tCommand Update Register=");
26530eb6f089Sjmcneill 	acpi_print_gas(&subspace->CmdUpdateRegister);
26540eb6f089Sjmcneill 	printf("\n");
26550eb6f089Sjmcneill 	printf("\tCommand Update Preserve Mask=0x%016jx\n", subspace->CmdUpdatePreserveMask);
2656798fdf3fSjmcneill 	printf("\tCommand Update Set Mask=0x%016jx\n", subspace->CmdUpdateSetMask);
26570eb6f089Sjmcneill 	printf("\tError Status Register=");
26580eb6f089Sjmcneill 	acpi_print_gas(&subspace->ErrorStatusRegister);
26590eb6f089Sjmcneill 	printf("\n");
26600eb6f089Sjmcneill 	printf("\tError Status Mask=0x%016jx\n", subspace->ErrorStatusMask);
26610eb6f089Sjmcneill }
26620eb6f089Sjmcneill 
26630eb6f089Sjmcneill static void
acpi_print_pcct_ext_pcc_slave(ACPI_PCCT_EXT_PCC_SLAVE * subspace)26640eb6f089Sjmcneill acpi_print_pcct_ext_pcc_slave(ACPI_PCCT_EXT_PCC_SLAVE *subspace)
26650eb6f089Sjmcneill {
26660eb6f089Sjmcneill 	printf("\tType=Extended PCC Slave Subspace\n");
26670eb6f089Sjmcneill 	printf("\tPlatform Interrupt=%u", subspace->PlatformInterrupt);
26680eb6f089Sjmcneill 	if (subspace->Flags & ACPI_PCCT_INTERRUPT_POLARITY) {
26690eb6f089Sjmcneill 		printf(", Edge triggered");
26700eb6f089Sjmcneill 	} else {
26710eb6f089Sjmcneill 		printf(", Level triggered");
26720eb6f089Sjmcneill 	}
26730eb6f089Sjmcneill 	if (subspace->Flags & ACPI_PCCT_INTERRUPT_MODE) {
26740eb6f089Sjmcneill 		printf(", Active low");
26750eb6f089Sjmcneill 	} else {
26760eb6f089Sjmcneill 		printf(", Active high");
26770eb6f089Sjmcneill 	}
26780eb6f089Sjmcneill 	printf("\n");
26790eb6f089Sjmcneill 	printf("\tBase Address=0x%016jx\n", subspace->BaseAddress);
26800eb6f089Sjmcneill 	printf("\tLength=%d\n", subspace->Length);
26810eb6f089Sjmcneill 	printf("\tDoorbell Register=");
26820eb6f089Sjmcneill 	acpi_print_gas(&subspace->DoorbellRegister);
26830eb6f089Sjmcneill 	printf("\n");
26840eb6f089Sjmcneill 	printf("\tDoorbell Preserve=0x%016jx\n", subspace->PreserveMask);
26850eb6f089Sjmcneill 	printf("\tDoorbell Write=0x%016jx\n", subspace->WriteMask);
26860eb6f089Sjmcneill 	printf("\tLatency=%u us\n", subspace->Latency);
26870eb6f089Sjmcneill 	printf("\tMax Access Rate=%u\n", subspace->MaxAccessRate);
26880eb6f089Sjmcneill 	printf("\tMin Turnaround Time=%u us\n", subspace->MinTurnaroundTime);
26890eb6f089Sjmcneill 	printf("\tPlatform Interrupt Ack Register=");
26900eb6f089Sjmcneill 	acpi_print_gas(&subspace->PlatformAckRegister);
26910eb6f089Sjmcneill 	printf("\n");
26920eb6f089Sjmcneill 	printf("\tPlatform Interrupt Ack Preserve=0x%016jx\n", subspace->AckPreserveMask);
26930eb6f089Sjmcneill 	printf("\tPlatform Interrupt Ack Set=0x%016jx\n", subspace->AckSetMask);
26940eb6f089Sjmcneill 	printf("\tCommand Complete Register=");
26950eb6f089Sjmcneill 	acpi_print_gas(&subspace->CmdCompleteRegister);
26960eb6f089Sjmcneill 	printf("\n");
26970eb6f089Sjmcneill 	printf("\tCommand Complete Mask=0x%016jx\n", subspace->CmdCompleteMask);
26980eb6f089Sjmcneill 	printf("\tCommand Update Register=");
26990eb6f089Sjmcneill 	acpi_print_gas(&subspace->CmdUpdateRegister);
27000eb6f089Sjmcneill 	printf("\n");
27010eb6f089Sjmcneill 	printf("\tCommand Update Preserve Mask=0x%016jx\n", subspace->CmdUpdatePreserveMask);
2702798fdf3fSjmcneill 	printf("\tCommand Update Set Mask=0x%016jx\n", subspace->CmdUpdateSetMask);
27030eb6f089Sjmcneill 	printf("\tError Status Register=");
27040eb6f089Sjmcneill 	acpi_print_gas(&subspace->ErrorStatusRegister);
27050eb6f089Sjmcneill 	printf("\n");
27060eb6f089Sjmcneill 	printf("\tError Status Mask=0x%016jx\n", subspace->ErrorStatusMask);
27070eb6f089Sjmcneill }
27080eb6f089Sjmcneill 
27090eb6f089Sjmcneill static void
acpi_print_pcct(ACPI_SUBTABLE_HEADER * hdr)27100eb6f089Sjmcneill acpi_print_pcct(ACPI_SUBTABLE_HEADER *hdr)
27110eb6f089Sjmcneill {
27120eb6f089Sjmcneill 	switch (hdr->Type) {
27130eb6f089Sjmcneill 	case ACPI_PCCT_TYPE_GENERIC_SUBSPACE:
27140eb6f089Sjmcneill 		acpi_print_pcct_subspace((ACPI_PCCT_SUBSPACE *)hdr);
27150eb6f089Sjmcneill 		break;
27160eb6f089Sjmcneill 	case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE:
27170eb6f089Sjmcneill 		acpi_print_pcct_hw_reduced((ACPI_PCCT_HW_REDUCED *)hdr);
27180eb6f089Sjmcneill 		break;
27190eb6f089Sjmcneill 	case ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2:
27200eb6f089Sjmcneill 		acpi_print_pcct_hw_reduced_type2((ACPI_PCCT_HW_REDUCED_TYPE2 *)hdr);
27210eb6f089Sjmcneill 		break;
27220eb6f089Sjmcneill 	case ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE:
27230eb6f089Sjmcneill 		acpi_print_pcct_ext_pcc_master((ACPI_PCCT_EXT_PCC_MASTER *)hdr);
27240eb6f089Sjmcneill 		break;
27250eb6f089Sjmcneill 	case ACPI_PCCT_TYPE_EXT_PCC_SLAVE_SUBSPACE:
27260eb6f089Sjmcneill 		acpi_print_pcct_ext_pcc_slave((ACPI_PCCT_EXT_PCC_SLAVE *)hdr);
27270eb6f089Sjmcneill 		break;
27280eb6f089Sjmcneill 	default:
27290eb6f089Sjmcneill 		printf("\tUnknown structure"
27300eb6f089Sjmcneill 		    "(type = %hhu, length = %hhu)\n",
27310eb6f089Sjmcneill 		    hdr->Type, hdr->Length);
27320eb6f089Sjmcneill 		break;
27330eb6f089Sjmcneill 	}
27340eb6f089Sjmcneill }
27350eb6f089Sjmcneill 
27360eb6f089Sjmcneill static void
acpi_handle_pcct(ACPI_TABLE_HEADER * sdp)27370eb6f089Sjmcneill acpi_handle_pcct(ACPI_TABLE_HEADER *sdp)
27380eb6f089Sjmcneill {
27390eb6f089Sjmcneill 	ACPI_TABLE_PCCT *pcct;
27400eb6f089Sjmcneill 
27410eb6f089Sjmcneill 	printf(BEGIN_COMMENT);
27420eb6f089Sjmcneill 	acpi_print_sdt(sdp);
27430eb6f089Sjmcneill 
27440eb6f089Sjmcneill 	pcct = (ACPI_TABLE_PCCT *)sdp;
27450eb6f089Sjmcneill #define PRINTFLAG(var, flag)	printflag((var), ACPI_PCCT_## flag, #flag)
27460eb6f089Sjmcneill 	printf("\tFlags=");
27470eb6f089Sjmcneill 	PRINTFLAG(pcct->Flags, DOORBELL);
27480eb6f089Sjmcneill 	PRINTFLAG_END();
27490eb6f089Sjmcneill #undef PRINTFLAG
27500eb6f089Sjmcneill 
27510eb6f089Sjmcneill 	acpi_walk_subtables(sdp, (pcct + 1), acpi_print_pcct);
27520eb6f089Sjmcneill 
27530eb6f089Sjmcneill 	printf(END_COMMENT);
27540eb6f089Sjmcneill }
27550eb6f089Sjmcneill 
27560eb6f089Sjmcneill static void
acpi_print_pptt_processor(ACPI_PPTT_PROCESSOR * processor)2757aba8816bSmsaitoh acpi_print_pptt_processor(ACPI_PPTT_PROCESSOR *processor)
2758aba8816bSmsaitoh {
2759aba8816bSmsaitoh 	uint32_t *private;
2760aba8816bSmsaitoh 	unsigned int i;
2761aba8816bSmsaitoh 
2762aba8816bSmsaitoh 	printf("\tType=processor\n");
2763aba8816bSmsaitoh 	printf("\tLength=%d\n", processor->Header.Length);
2764aba8816bSmsaitoh #define PRINTFLAG(var, flag)	printflag((var), ACPI_PPTT_## flag, #flag)
2765aba8816bSmsaitoh 
2766aba8816bSmsaitoh 	printf("\tFlags=");
2767aba8816bSmsaitoh 	PRINTFLAG(processor->Flags, PHYSICAL_PACKAGE);
2768aba8816bSmsaitoh 	PRINTFLAG(processor->Flags, ACPI_PROCESSOR_ID_VALID);
2769aba8816bSmsaitoh 	PRINTFLAG_END();
2770aba8816bSmsaitoh 
2771aba8816bSmsaitoh #undef PRINTFLAG
2772aba8816bSmsaitoh 	printf("\tParent=%08x\n", processor->Parent);
2773aba8816bSmsaitoh 	printf("\tACPI Processor ID=0x%08x\n", processor->AcpiProcessorId);
2774aba8816bSmsaitoh 	printf("\tprivate resources=%d\n", processor->NumberOfPrivResources);
2775aba8816bSmsaitoh 
2776aba8816bSmsaitoh 	private = (uint32_t *)(processor + 1);
2777aba8816bSmsaitoh 	for (i = 0; i < processor->NumberOfPrivResources; i++)
2778aba8816bSmsaitoh 		printf("\tprivate resources%d=%08x\n", i, private[i]);
2779aba8816bSmsaitoh }
2780aba8816bSmsaitoh 
2781aba8816bSmsaitoh static void
acpi_print_pptt_cache(ACPI_PPTT_CACHE * cache)2782aba8816bSmsaitoh acpi_print_pptt_cache(ACPI_PPTT_CACHE *cache)
2783aba8816bSmsaitoh {
2784aba8816bSmsaitoh 
2785aba8816bSmsaitoh 	printf("\tType=cache\n");
2786aba8816bSmsaitoh 	printf("\tLength=%d\n", cache->Header.Length);
2787aba8816bSmsaitoh 
2788aba8816bSmsaitoh #define	PRINTFLAG(var, flag)	printflag((var), ACPI_PPTT_## flag, #flag)
2789aba8816bSmsaitoh 	printf("\tFlags=");
2790aba8816bSmsaitoh 	PRINTFLAG(cache->Flags, SIZE_PROPERTY_VALID);
2791aba8816bSmsaitoh 	PRINTFLAG(cache->Flags, NUMBER_OF_SETS_VALID);
2792aba8816bSmsaitoh 	PRINTFLAG(cache->Flags, ASSOCIATIVITY_VALID);
2793aba8816bSmsaitoh 	PRINTFLAG(cache->Flags, ALLOCATION_TYPE_VALID);
2794aba8816bSmsaitoh 	PRINTFLAG(cache->Flags, CACHE_TYPE_VALID);
2795aba8816bSmsaitoh 	PRINTFLAG(cache->Flags, WRITE_POLICY_VALID);
2796aba8816bSmsaitoh 	PRINTFLAG(cache->Flags, LINE_SIZE_VALID);
2797aba8816bSmsaitoh 	PRINTFLAG_END();
2798aba8816bSmsaitoh #undef PRINTFLAG
2799aba8816bSmsaitoh 
2800aba8816bSmsaitoh 	printf("\tNextLevel=0x%08x\n", cache->NextLevelOfCache);
2801aba8816bSmsaitoh 	if (cache->Flags & ACPI_PPTT_SIZE_PROPERTY_VALID)
2802aba8816bSmsaitoh 		printf("\tSize=%d\n", cache->Size);
2803aba8816bSmsaitoh 	if (cache->Flags & ACPI_PPTT_NUMBER_OF_SETS_VALID)
2804aba8816bSmsaitoh 		printf("\tSets=%d\n", cache->NumberOfSets);
2805aba8816bSmsaitoh 	if (cache->Flags & ACPI_PPTT_ASSOCIATIVITY_VALID)
2806aba8816bSmsaitoh 		printf("\tAssociativity=%d\n", cache->Associativity);
2807aba8816bSmsaitoh 	if (cache->Flags & ACPI_PPTT_ALLOCATION_TYPE_VALID) {
2808aba8816bSmsaitoh 		printf("\tAllocation type=");
2809c26b2779Smsaitoh 		switch (cache->Attributes & ACPI_PPTT_MASK_ALLOCATION_TYPE) {
2810aba8816bSmsaitoh 		case ACPI_PPTT_CACHE_READ_ALLOCATE:
2811aba8816bSmsaitoh 			printf("Read allocate\n");
2812aba8816bSmsaitoh 			break;
2813aba8816bSmsaitoh 		case ACPI_PPTT_CACHE_WRITE_ALLOCATE:
2814aba8816bSmsaitoh 			printf("Write allocate\n");
2815aba8816bSmsaitoh 			break;
2816aba8816bSmsaitoh 		case ACPI_PPTT_CACHE_RW_ALLOCATE:
2817aba8816bSmsaitoh 		case ACPI_PPTT_CACHE_RW_ALLOCATE_ALT:
2818aba8816bSmsaitoh 			printf("Read and Write allocate\n");
2819aba8816bSmsaitoh 			break;
2820aba8816bSmsaitoh 		}
2821aba8816bSmsaitoh 	}
2822aba8816bSmsaitoh 	if (cache->Flags & ACPI_PPTT_CACHE_TYPE_VALID) {
2823aba8816bSmsaitoh 		printf("\tCache type=");
2824c26b2779Smsaitoh 		switch (cache->Attributes & ACPI_PPTT_MASK_CACHE_TYPE) {
2825aba8816bSmsaitoh 		case ACPI_PPTT_CACHE_TYPE_DATA:
2826aba8816bSmsaitoh 			printf("Data\n");
2827aba8816bSmsaitoh 			break;
2828aba8816bSmsaitoh 		case ACPI_PPTT_CACHE_TYPE_INSTR:
2829aba8816bSmsaitoh 			printf("Instruction\n");
2830aba8816bSmsaitoh 			break;
2831aba8816bSmsaitoh 		case ACPI_PPTT_CACHE_TYPE_UNIFIED:
2832aba8816bSmsaitoh 		case ACPI_PPTT_CACHE_TYPE_UNIFIED_ALT:
2833aba8816bSmsaitoh 			printf("Unified\n");
2834aba8816bSmsaitoh 			break;
2835aba8816bSmsaitoh 		}
2836aba8816bSmsaitoh 	}
2837aba8816bSmsaitoh 	if (cache->Flags & ACPI_PPTT_WRITE_POLICY_VALID)
2838aba8816bSmsaitoh 		printf("\tWrite Policy=Write %s \n",
2839aba8816bSmsaitoh 		    (cache->Attributes & ACPI_PPTT_MASK_WRITE_POLICY) ?
2840aba8816bSmsaitoh 		    "through" : "back");
2841aba8816bSmsaitoh 
2842aba8816bSmsaitoh 	if (cache->Flags & ACPI_PPTT_LINE_SIZE_VALID)
2843aba8816bSmsaitoh 		printf("\tLine size=%d\n", cache->LineSize);
2844aba8816bSmsaitoh }
2845aba8816bSmsaitoh 
2846aba8816bSmsaitoh static void
acpi_print_pptt_id(ACPI_PPTT_ID * id)2847aba8816bSmsaitoh acpi_print_pptt_id(ACPI_PPTT_ID *id)
2848aba8816bSmsaitoh {
2849aba8816bSmsaitoh 
2850aba8816bSmsaitoh 	printf("\tType=id\n");
2851aba8816bSmsaitoh 	printf("\tLength=%d\n", id->Header.Length);
2852aba8816bSmsaitoh 
2853aba8816bSmsaitoh 	printf("\tVENDOR_ID=");
2854aba8816bSmsaitoh 	acpi_print_string((char *)&id->VendorId, 4);
2855aba8816bSmsaitoh 	printf("\n");
2856aba8816bSmsaitoh 
2857aba8816bSmsaitoh 	printf("\tLEVEL_1_ID=%016" PRIx64 "\n", id->Level1Id);
2858aba8816bSmsaitoh 	printf("\tLEVEL_2_ID=%016" PRIx64 "\n", id->Level2Id);
2859aba8816bSmsaitoh 	printf("\tMajor=%hu", id->MajorRev);
2860aba8816bSmsaitoh 	printf("\tMinor=%hu", id->MinorRev);
2861aba8816bSmsaitoh 	printf("\tSpin=%hu", id->SpinRev);
2862aba8816bSmsaitoh }
2863aba8816bSmsaitoh 
2864aba8816bSmsaitoh static void
acpi_print_pptt(ACPI_SUBTABLE_HEADER * hdr)2865aba8816bSmsaitoh acpi_print_pptt(ACPI_SUBTABLE_HEADER *hdr)
2866aba8816bSmsaitoh {
2867aba8816bSmsaitoh 	switch (hdr->Type) {
2868aba8816bSmsaitoh 	case ACPI_PPTT_TYPE_PROCESSOR:
2869aba8816bSmsaitoh 		acpi_print_pptt_processor((ACPI_PPTT_PROCESSOR *)hdr);
2870aba8816bSmsaitoh 		break;
2871aba8816bSmsaitoh 	case ACPI_PPTT_TYPE_CACHE:
2872aba8816bSmsaitoh 		acpi_print_pptt_cache((ACPI_PPTT_CACHE *)hdr);
2873aba8816bSmsaitoh 		break;
2874aba8816bSmsaitoh 	case ACPI_PPTT_TYPE_ID:
2875aba8816bSmsaitoh 		acpi_print_pptt_id((ACPI_PPTT_ID *)hdr);
2876aba8816bSmsaitoh 		break;
2877aba8816bSmsaitoh 	default:
2878aba8816bSmsaitoh 		printf("\tUnknown structure"
2879aba8816bSmsaitoh 		    "(type = %hhu, length = %hhu)\n",
2880aba8816bSmsaitoh 		    hdr->Type, hdr->Length);
2881aba8816bSmsaitoh 		break;
2882aba8816bSmsaitoh 	}
2883aba8816bSmsaitoh }
2884aba8816bSmsaitoh 
2885aba8816bSmsaitoh static void
acpi_handle_pptt(ACPI_TABLE_HEADER * sdp)2886aba8816bSmsaitoh acpi_handle_pptt(ACPI_TABLE_HEADER *sdp)
2887aba8816bSmsaitoh {
2888aba8816bSmsaitoh 	ACPI_TABLE_PPTT *pptt;
2889aba8816bSmsaitoh 
2890aba8816bSmsaitoh 	printf(BEGIN_COMMENT);
2891aba8816bSmsaitoh 	acpi_print_sdt(sdp);
2892aba8816bSmsaitoh 
2893aba8816bSmsaitoh 	pptt = (ACPI_TABLE_PPTT *)sdp;
2894aba8816bSmsaitoh 	acpi_walk_subtables(sdp, (pptt + 1), acpi_print_pptt);
2895aba8816bSmsaitoh 
2896aba8816bSmsaitoh 	printf(END_COMMENT);
2897aba8816bSmsaitoh }
2898aba8816bSmsaitoh 
2899aba8816bSmsaitoh static void
acpi_handle_sbst(ACPI_TABLE_HEADER * sdp)290009f2089bScegger acpi_handle_sbst(ACPI_TABLE_HEADER *sdp)
290109f2089bScegger {
290209f2089bScegger 	ACPI_TABLE_SBST *sbst;
290309f2089bScegger 
290409f2089bScegger 	printf(BEGIN_COMMENT);
290509f2089bScegger 	acpi_print_sdt(sdp);
290609f2089bScegger 	sbst = (ACPI_TABLE_SBST *)sdp;
290709f2089bScegger 
290809f2089bScegger 	printf("\tWarning Level=%d mWh\n", sbst->WarningLevel);
290909f2089bScegger 	printf("\tLow Level=%d mWh\n", sbst->LowLevel);
291009f2089bScegger 	printf("\tCritical Level=%d mWh\n", sbst->CriticalLevel);
291109f2089bScegger 
291209f2089bScegger 	printf(END_COMMENT);
291309f2089bScegger }
291409f2089bScegger 
291509f2089bScegger static void
acpi_handle_slit(ACPI_TABLE_HEADER * sdp)291609f2089bScegger acpi_handle_slit(ACPI_TABLE_HEADER *sdp)
291709f2089bScegger {
291809f2089bScegger 	ACPI_TABLE_SLIT *slit;
291909f2089bScegger 	u_int idx;
292009f2089bScegger 	uint64_t cnt;
292109f2089bScegger 
292209f2089bScegger 	printf(BEGIN_COMMENT);
292309f2089bScegger 	acpi_print_sdt(sdp);
292409f2089bScegger 	slit = (ACPI_TABLE_SLIT *)sdp;
292509f2089bScegger 
292609f2089bScegger 	cnt = slit->LocalityCount * slit->LocalityCount;
2927c359a213Smsaitoh 	printf("\tLocalityCount=%ju\n", (uintmax_t)slit->LocalityCount);
292809f2089bScegger 	printf("\tEntry=\n\t");
292909f2089bScegger 	for (idx = 0; idx < cnt; idx++) {
293009f2089bScegger 		printf("%u ", slit->Entry[idx]);
293109f2089bScegger 		if ((idx % slit->LocalityCount) == (slit->LocalityCount - 1)) {
293209f2089bScegger 			printf("\n");
293309f2089bScegger 			if (idx < cnt - 1)
293409f2089bScegger 				printf("\t");
293509f2089bScegger 		}
293609f2089bScegger 	}
293709f2089bScegger 
293809f2089bScegger 	printf(END_COMMENT);
293909f2089bScegger }
294009f2089bScegger 
294109f2089bScegger static void
acpi_handle_spcr(ACPI_TABLE_HEADER * sdp)294209f2089bScegger acpi_handle_spcr(ACPI_TABLE_HEADER *sdp)
294309f2089bScegger {
294409f2089bScegger 	ACPI_TABLE_SPCR *spcr;
294509f2089bScegger 
294609f2089bScegger 	printf(BEGIN_COMMENT);
294709f2089bScegger 	acpi_print_sdt(sdp);
294809f2089bScegger 	spcr = (ACPI_TABLE_SPCR *)sdp;
294909f2089bScegger 
2950b04bf7f2Smsaitoh 	printf("\n\tInterface Type=");
2951b04bf7f2Smsaitoh 	switch (sdp->Revision) {
2952b04bf7f2Smsaitoh 	case 1:
2953b04bf7f2Smsaitoh 		printf("full 16550%s\n",
2954b04bf7f2Smsaitoh 		    (spcr->InterfaceType == 1) ?
2955b04bf7f2Smsaitoh 		    "(must also accept writing FCR register)" : "");
2956b04bf7f2Smsaitoh 		break;
2957b04bf7f2Smsaitoh 	case 2:
2958b04bf7f2Smsaitoh 		acpi_print_dbg2_serial_subtype(spcr->InterfaceType);
2959b04bf7f2Smsaitoh 		break;
2960b04bf7f2Smsaitoh 	default:
2961b04bf7f2Smsaitoh 		printf("unknown Revision\n");
2962b04bf7f2Smsaitoh 		break;
2963b04bf7f2Smsaitoh 	}
2964b04bf7f2Smsaitoh 
296509f2089bScegger 	printf("\tSerial Port=");
296609f2089bScegger 	acpi_print_gas(&spcr->SerialPort);
296709f2089bScegger 	printf("\n\tInterrupt Type={");
296809f2089bScegger 	if (spcr->InterruptType & 0x1) {
296909f2089bScegger 		printf("\n\t\tdual-8259 IRQ=");
297009f2089bScegger 		switch (spcr->PcInterrupt) {
297109f2089bScegger 		case 2 ... 7:
297209f2089bScegger 		case 9 ... 12:
297309f2089bScegger 		case 14 ... 15:
297409f2089bScegger 			printf("%d", spcr->PcInterrupt);
297509f2089bScegger 			break;
297609f2089bScegger 		default:
297709f2089bScegger 			printf("%d (invalid entry)", spcr->PcInterrupt);
297809f2089bScegger 			break;
297909f2089bScegger 		}
298009f2089bScegger 	}
298109f2089bScegger 	if (spcr->InterruptType & 0x2) {
298209f2089bScegger 		printf("\n\t\tIO APIC={ GSI=%d }", spcr->Interrupt);
298309f2089bScegger 	}
298409f2089bScegger 	if (spcr->InterruptType & 0x4) {
298509f2089bScegger 		printf("\n\t\tIO SAPIC={ GSI=%d }", spcr->Interrupt);
298609f2089bScegger 	}
2987b04bf7f2Smsaitoh 	if (spcr->InterruptType & 0x8) {
2988b04bf7f2Smsaitoh 		printf("\n\t\tARMH GIC={ GSI=%d }", spcr->Interrupt);
2989b04bf7f2Smsaitoh 	}
299009f2089bScegger 	printf("\n\t}\n");
299109f2089bScegger 
299209f2089bScegger 	printf("\tBaud Rate=");
299309f2089bScegger 	switch (spcr->BaudRate) {
299409f2089bScegger 	case 3:
299509f2089bScegger 		printf("9600");
299609f2089bScegger 		break;
299709f2089bScegger 	case 4:
299809f2089bScegger 		printf("19200");
299909f2089bScegger 		break;
300009f2089bScegger 	case 6:
300109f2089bScegger 		printf("57600");
300209f2089bScegger 		break;
300309f2089bScegger 	case 7:
300409f2089bScegger 		printf("115200");
300509f2089bScegger 		break;
300609f2089bScegger 	default:
300709f2089bScegger 		printf("unknown speed index %d", spcr->BaudRate);
300809f2089bScegger 		break;
300909f2089bScegger 	}
301009f2089bScegger 	printf("\n\tParity={");
301109f2089bScegger 	switch (spcr->Parity) {
301209f2089bScegger 	case 0:
301309f2089bScegger 		printf("OFF");
301409f2089bScegger 		break;
301509f2089bScegger 	default:
301609f2089bScegger 		printf("ON");
301709f2089bScegger 		break;
301809f2089bScegger 	}
301909f2089bScegger 	printf("}\n");
302009f2089bScegger 
302109f2089bScegger 	printf("\tStop Bits={");
302209f2089bScegger 	switch (spcr->StopBits) {
302309f2089bScegger 	case 1:
302409f2089bScegger 		printf("ON");
302509f2089bScegger 		break;
302609f2089bScegger 	default:
302709f2089bScegger 		printf("OFF");
302809f2089bScegger 		break;
302909f2089bScegger 	}
303009f2089bScegger 	printf("}\n");
303109f2089bScegger 
303209f2089bScegger 	printf("\tFlow Control={");
303309f2089bScegger 	if (spcr->FlowControl & 0x1)
303409f2089bScegger 		printf("DCD, ");
303509f2089bScegger 	if (spcr->FlowControl & 0x2)
303609f2089bScegger 		printf("RTS/CTS hardware, ");
303709f2089bScegger 	if (spcr->FlowControl & 0x4)
303809f2089bScegger 		printf("XON/XOFF software");
303909f2089bScegger 	printf("}\n");
304009f2089bScegger 
304109f2089bScegger 	printf("\tTerminal=");
304209f2089bScegger 	switch (spcr->TerminalType) {
304309f2089bScegger 	case 0:
304409f2089bScegger 		printf("VT100");
304509f2089bScegger 		break;
304609f2089bScegger 	case 1:
304709f2089bScegger 		printf("VT100+");
304809f2089bScegger 		break;
304909f2089bScegger 	case 2:
305009f2089bScegger 		printf("VT-UTF8");
305109f2089bScegger 		break;
305209f2089bScegger 	case 3:
305309f2089bScegger 		printf("ANSI");
305409f2089bScegger 		break;
305509f2089bScegger 	default:
305609f2089bScegger 		printf("unknown type %d", spcr->TerminalType);
305709f2089bScegger 		break;
305809f2089bScegger 	}
305909f2089bScegger 	printf("\n");
306009f2089bScegger 
306109f2089bScegger 	acpi_print_pci(spcr->PciVendorId, spcr->PciDeviceId,
306209f2089bScegger 	    spcr->PciSegment, spcr->PciBus, spcr->PciDevice, spcr->PciFunction);
306309f2089bScegger 
306409f2089bScegger 	printf("\tPCI Flags={");
306509f2089bScegger 	if (spcr->PciFlags & ACPI_SPCR_DO_NOT_DISABLE)
306609f2089bScegger 		printf("DONOT_DISABLE");
306709f2089bScegger 	printf("}\n");
306809f2089bScegger 
306909f2089bScegger 	printf(END_COMMENT);
307009f2089bScegger }
307109f2089bScegger 
307209f2089bScegger static void
acpi_handle_spmi(ACPI_TABLE_HEADER * sdp)30735d527485Smsaitoh acpi_handle_spmi(ACPI_TABLE_HEADER *sdp)
30745d527485Smsaitoh {
30755d527485Smsaitoh 	ACPI_TABLE_SPMI *spmi;
30765d527485Smsaitoh 
30775d527485Smsaitoh 	printf(BEGIN_COMMENT);
30785d527485Smsaitoh 	acpi_print_sdt(sdp);
30795d527485Smsaitoh 	spmi = (ACPI_TABLE_SPMI *)sdp;
30805d527485Smsaitoh 
30815d527485Smsaitoh 	printf("\tInterface Type=");
30825d527485Smsaitoh 	switch (spmi->InterfaceType) {
30835d527485Smsaitoh 	case ACPI_SPMI_KEYBOARD:
30845d527485Smsaitoh 		printf("Keyboard Controller Stype (KCS)");
30855d527485Smsaitoh 		break;
30865d527485Smsaitoh 	case ACPI_SPMI_SMI:
30875d527485Smsaitoh 		printf("Server Management Interface Chip (SMIC)");
30885d527485Smsaitoh 		break;
30895d527485Smsaitoh 	case ACPI_SPMI_BLOCK_TRANSFER:
30905d527485Smsaitoh 		printf("Block Transfer (BT)");
30915d527485Smsaitoh 		break;
30925d527485Smsaitoh 	case ACPI_SPMI_SMBUS:
30935d527485Smsaitoh 		printf("SMBus System Interface (SSIF)");
30945d527485Smsaitoh 		break;
30955d527485Smsaitoh 	default:
30965d527485Smsaitoh 		printf("Reserved(%d)", spmi->InterfaceType);
30975d527485Smsaitoh 		break;
30985d527485Smsaitoh 	}
30998b136ef7Smsaitoh 	printf("\n\tSpecRevision=%d.%d", spmi->SpecRevision >> 8,
31005d527485Smsaitoh 		spmi->SpecRevision & 0xff);
31015d527485Smsaitoh 
31025d527485Smsaitoh 	printf("\n\tInterrupt Type={");
31035d527485Smsaitoh 	if (spmi->InterruptType & 0x1) {
31045d527485Smsaitoh 		printf("\n\t\tSCI triggered GPE=%d", spmi->GpeNumber);
31055d527485Smsaitoh 	}
31065d527485Smsaitoh 	if (spmi->InterruptType & 0x2) {
31075d527485Smsaitoh 		printf("\n\t\tIO APIC/SAPIC={ GSI=%d }", spmi->Interrupt);
31085d527485Smsaitoh 	}
31095d527485Smsaitoh 	printf("\n\t}\n");
31105d527485Smsaitoh 
31115d527485Smsaitoh 	printf("\tBase Address=");
31125d527485Smsaitoh 	acpi_print_gas(&spmi->IpmiRegister);
31135d527485Smsaitoh 	printf("\n");
31145d527485Smsaitoh 
31155d527485Smsaitoh 	if ((spmi->PciDeviceFlag & 0x01) != 0)
31165d527485Smsaitoh 		acpi_print_pci_sbdf(spmi->PciSegment, spmi->PciBus,
31175d527485Smsaitoh 		    spmi->PciDevice, spmi->PciFunction);
31185d527485Smsaitoh 
31195d527485Smsaitoh 	printf(END_COMMENT);
31205d527485Smsaitoh }
31215d527485Smsaitoh 
31225d527485Smsaitoh static void
acpi_print_srat_cpu(uint8_t type,uint32_t apic_id,uint32_t proximity_domain,uint32_t flags,uint32_t clockdomain,uint8_t sapic_eid)3123597a86a6Smsaitoh acpi_print_srat_cpu(uint8_t type, uint32_t apic_id, uint32_t proximity_domain,
3124597a86a6Smsaitoh     uint32_t flags, uint32_t clockdomain, uint8_t sapic_eid)
312509f2089bScegger {
312609f2089bScegger 
312709f2089bScegger 	printf("\tFlags={");
312809f2089bScegger 	if (flags & ACPI_SRAT_CPU_ENABLED)
312909f2089bScegger 		printf("ENABLED");
313009f2089bScegger 	else
313109f2089bScegger 		printf("DISABLED");
313209f2089bScegger 	printf("}\n");
3133597a86a6Smsaitoh 	printf("\t%s ID=%d\n",
3134597a86a6Smsaitoh 	    (type == ACPI_SRAT_TYPE_GIC_ITS_AFFINITY) ? "ITS" : "APIC",
3135597a86a6Smsaitoh 	    apic_id);
3136597a86a6Smsaitoh 	if (type == ACPI_SRAT_TYPE_CPU_AFFINITY)
3137597a86a6Smsaitoh 		printf("\tSAPIC EID=%d\n", sapic_eid);
313809f2089bScegger 	printf("\tProximity Domain=%d\n", proximity_domain);
3139597a86a6Smsaitoh 	if (type != ACPI_SRAT_TYPE_GIC_ITS_AFFINITY)
314009f2089bScegger 		printf("\tClock Domain=%d\n", clockdomain);
314109f2089bScegger }
314209f2089bScegger 
314309f2089bScegger static void
acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY * mp)314409f2089bScegger acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp)
314509f2089bScegger {
314609f2089bScegger 
314709f2089bScegger 	printf("\tFlags={");
314809f2089bScegger 	if (mp->Flags & ACPI_SRAT_MEM_ENABLED)
314909f2089bScegger 		printf("ENABLED");
315009f2089bScegger 	else
315109f2089bScegger 		printf("DISABLED");
315209f2089bScegger 	if (mp->Flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)
315309f2089bScegger 		printf(",HOT_PLUGGABLE");
315409f2089bScegger 	if (mp->Flags & ACPI_SRAT_MEM_NON_VOLATILE)
315509f2089bScegger 		printf(",NON_VOLATILE");
315609f2089bScegger 	printf("}\n");
315709f2089bScegger 	printf("\tBase Address=0x%016jx\n", (uintmax_t)mp->BaseAddress);
315809f2089bScegger 	printf("\tLength=0x%016jx\n", (uintmax_t)mp->Length);
315909f2089bScegger 	printf("\tProximity Domain=%d\n", mp->ProximityDomain);
316009f2089bScegger }
316109f2089bScegger 
3162c359a213Smsaitoh static const char *srat_types[] = {
3163c359a213Smsaitoh     [ACPI_SRAT_TYPE_CPU_AFFINITY] = "CPU",
3164c359a213Smsaitoh     [ACPI_SRAT_TYPE_MEMORY_AFFINITY] = "Memory",
3165c359a213Smsaitoh     [ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY] = "X2APIC",
3166c359a213Smsaitoh     [ACPI_SRAT_TYPE_GICC_AFFINITY] = "GICC",
3167597a86a6Smsaitoh     [ACPI_SRAT_TYPE_GIC_ITS_AFFINITY] = "GIC ITS",
3168c359a213Smsaitoh };
316909f2089bScegger 
317009f2089bScegger static void
acpi_print_srat(ACPI_SUBTABLE_HEADER * srat)317109f2089bScegger acpi_print_srat(ACPI_SUBTABLE_HEADER *srat)
317209f2089bScegger {
317309f2089bScegger 	ACPI_SRAT_CPU_AFFINITY *cpu;
317409f2089bScegger 	ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic;
3175597a86a6Smsaitoh 	ACPI_SRAT_GICC_AFFINITY *gicc;
3176597a86a6Smsaitoh 	ACPI_SRAT_GIC_ITS_AFFINITY *gici;
317709f2089bScegger 
3178c359a213Smsaitoh 	if (srat->Type < __arraycount(srat_types))
317909f2089bScegger 		printf("\tType=%s\n", srat_types[srat->Type]);
318009f2089bScegger 	else
318109f2089bScegger 		printf("\tType=%d (unknown)\n", srat->Type);
318209f2089bScegger 	switch (srat->Type) {
318309f2089bScegger 	case ACPI_SRAT_TYPE_CPU_AFFINITY:
318409f2089bScegger 		cpu = (ACPI_SRAT_CPU_AFFINITY *)srat;
3185597a86a6Smsaitoh 		acpi_print_srat_cpu(srat->Type, cpu->ApicId,
318609f2089bScegger 		    cpu->ProximityDomainHi[2] << 24 |
318709f2089bScegger 		    cpu->ProximityDomainHi[1] << 16 |
318809f2089bScegger 		    cpu->ProximityDomainHi[0] << 0 |
318909f2089bScegger 		    cpu->ProximityDomainLo,
3190597a86a6Smsaitoh 		    cpu->Flags, cpu->ClockDomain, cpu->LocalSapicEid);
319109f2089bScegger 		break;
319209f2089bScegger 	case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
319309f2089bScegger 		acpi_print_srat_memory((ACPI_SRAT_MEM_AFFINITY *)srat);
319409f2089bScegger 		break;
319509f2089bScegger 	case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
319609f2089bScegger 		x2apic = (ACPI_SRAT_X2APIC_CPU_AFFINITY *)srat;
3197597a86a6Smsaitoh 		acpi_print_srat_cpu(srat->Type, x2apic->ApicId,
3198597a86a6Smsaitoh 		    x2apic->ProximityDomain,
3199597a86a6Smsaitoh 		    x2apic->Flags, x2apic->ClockDomain, 0 /* dummy */);
320009f2089bScegger 		break;
3201c359a213Smsaitoh 	case ACPI_SRAT_TYPE_GICC_AFFINITY:
3202597a86a6Smsaitoh 		gicc = (ACPI_SRAT_GICC_AFFINITY *)srat;
3203597a86a6Smsaitoh 		acpi_print_srat_cpu(srat->Type, gicc->AcpiProcessorUid,
3204597a86a6Smsaitoh 		    gicc->ProximityDomain,
3205597a86a6Smsaitoh 		    gicc->Flags, gicc->ClockDomain, 0 /* dummy */);
3206597a86a6Smsaitoh 		break;
3207597a86a6Smsaitoh 	case ACPI_SRAT_TYPE_GIC_ITS_AFFINITY:
3208597a86a6Smsaitoh 		gici = (ACPI_SRAT_GIC_ITS_AFFINITY *)srat;
3209597a86a6Smsaitoh 		acpi_print_srat_cpu(srat->Type, gici->ItsId,
3210597a86a6Smsaitoh 		    gici->ProximityDomain,
3211597a86a6Smsaitoh 		    0 /* dummy */, 0 /* dummy */, 0 /* dummy */);
3212c359a213Smsaitoh 		break;
321309f2089bScegger 	}
321409f2089bScegger }
321509f2089bScegger 
321609f2089bScegger static void
acpi_handle_srat(ACPI_TABLE_HEADER * sdp)321709f2089bScegger acpi_handle_srat(ACPI_TABLE_HEADER *sdp)
321809f2089bScegger {
321909f2089bScegger 	ACPI_TABLE_SRAT *srat;
322009f2089bScegger 
322109f2089bScegger 	printf(BEGIN_COMMENT);
322209f2089bScegger 	acpi_print_sdt(sdp);
322309f2089bScegger 	srat = (ACPI_TABLE_SRAT *)sdp;
322409f2089bScegger 	printf("\tTable Revision=%d\n", srat->TableRevision);
322509f2089bScegger 	acpi_walk_subtables(sdp, (srat + 1), acpi_print_srat);
322609f2089bScegger 	printf(END_COMMENT);
322709f2089bScegger }
322809f2089bScegger 
3229792e611dSmsaitoh static const char *nfit_types[] = {
3230792e611dSmsaitoh     [ACPI_NFIT_TYPE_SYSTEM_ADDRESS] = "System Address",
3231792e611dSmsaitoh     [ACPI_NFIT_TYPE_MEMORY_MAP] = "Memory Map",
3232792e611dSmsaitoh     [ACPI_NFIT_TYPE_INTERLEAVE] = "Interleave",
3233792e611dSmsaitoh     [ACPI_NFIT_TYPE_SMBIOS] = "SMBIOS",
3234792e611dSmsaitoh     [ACPI_NFIT_TYPE_CONTROL_REGION] = "Control Region",
3235792e611dSmsaitoh     [ACPI_NFIT_TYPE_DATA_REGION] = "Data Region",
3236792e611dSmsaitoh     [ACPI_NFIT_TYPE_FLUSH_ADDRESS] = "Flush Address"
3237792e611dSmsaitoh };
3238792e611dSmsaitoh 
3239792e611dSmsaitoh 
3240792e611dSmsaitoh static void
acpi_print_nfit(ACPI_NFIT_HEADER * nfit)3241792e611dSmsaitoh acpi_print_nfit(ACPI_NFIT_HEADER *nfit)
3242792e611dSmsaitoh {
3243792e611dSmsaitoh 	char *uuidstr;
3244792e611dSmsaitoh 	uint32_t status;
3245792e611dSmsaitoh 
3246792e611dSmsaitoh 	ACPI_NFIT_SYSTEM_ADDRESS *sysaddr;
3247792e611dSmsaitoh 	ACPI_NFIT_MEMORY_MAP *mmap;
3248792e611dSmsaitoh 	ACPI_NFIT_INTERLEAVE *ileave;
3249792e611dSmsaitoh 	ACPI_NFIT_SMBIOS *smbios __unused;
3250792e611dSmsaitoh 	ACPI_NFIT_CONTROL_REGION *ctlreg;
3251792e611dSmsaitoh 	ACPI_NFIT_DATA_REGION *datareg;
3252792e611dSmsaitoh 	ACPI_NFIT_FLUSH_ADDRESS *fladdr;
3253792e611dSmsaitoh 
3254792e611dSmsaitoh 	if (nfit->Type < __arraycount(nfit_types))
3255792e611dSmsaitoh 		printf("\tType=%s\n", nfit_types[nfit->Type]);
3256792e611dSmsaitoh 	else
3257792e611dSmsaitoh 		printf("\tType=%u (unknown)\n", nfit->Type);
3258792e611dSmsaitoh 	switch (nfit->Type) {
3259792e611dSmsaitoh 	case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
3260792e611dSmsaitoh 		sysaddr = (ACPI_NFIT_SYSTEM_ADDRESS *)nfit;
3261792e611dSmsaitoh 		printf("\tRangeIndex=%u\n", (u_int)sysaddr->RangeIndex);
3262792e611dSmsaitoh 		printf("\tProximityDomain=%u\n",
3263792e611dSmsaitoh 		    (u_int)sysaddr->ProximityDomain);
3264792e611dSmsaitoh 		uuid_to_string((uuid_t *)(sysaddr->RangeGuid),
3265792e611dSmsaitoh 		    &uuidstr, &status);
3266792e611dSmsaitoh 		if (status != uuid_s_ok)
3267792e611dSmsaitoh 			errx(1, "uuid_to_string: status=%u", status);
3268792e611dSmsaitoh 		printf("\tRangeGuid=%s\n", uuidstr);
3269792e611dSmsaitoh 		free(uuidstr);
3270792e611dSmsaitoh 		printf("\tAddress=0x%016jx\n", (uintmax_t)sysaddr->Address);
3271792e611dSmsaitoh 		printf("\tLength=0x%016jx\n", (uintmax_t)sysaddr->Length);
3272792e611dSmsaitoh 		printf("\tMemoryMapping=0x%016jx\n",
3273792e611dSmsaitoh 		    (uintmax_t)sysaddr->MemoryMapping);
3274792e611dSmsaitoh 
3275792e611dSmsaitoh #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_## flag, #flag)
3276792e611dSmsaitoh 
3277792e611dSmsaitoh 		printf("\tFlags=");
3278792e611dSmsaitoh 		PRINTFLAG(sysaddr->Flags, ADD_ONLINE_ONLY);
3279792e611dSmsaitoh 		PRINTFLAG(sysaddr->Flags, PROXIMITY_VALID);
3280792e611dSmsaitoh 		PRINTFLAG_END();
3281792e611dSmsaitoh 
3282792e611dSmsaitoh #undef PRINTFLAG
3283792e611dSmsaitoh 
3284792e611dSmsaitoh 		break;
3285792e611dSmsaitoh 	case ACPI_NFIT_TYPE_MEMORY_MAP:
3286792e611dSmsaitoh 		mmap = (ACPI_NFIT_MEMORY_MAP *)nfit;
3287792e611dSmsaitoh 		printf("\tDeviceHandle=%u\n", (u_int)mmap->DeviceHandle);
3288792e611dSmsaitoh 		printf("\tPhysicalId=%u\n", (u_int)mmap->PhysicalId);
3289792e611dSmsaitoh 		printf("\tRegionId=%u\n", (u_int)mmap->RegionId);
3290792e611dSmsaitoh 		printf("\tRangeIndex=%u\n", (u_int)mmap->RangeIndex);
3291792e611dSmsaitoh 		printf("\tRegionIndex=%u\n", (u_int)mmap->RegionIndex);
3292792e611dSmsaitoh 		printf("\tRegionSize=0x%016jx\n", (uintmax_t)mmap->RegionSize);
3293792e611dSmsaitoh 		printf("\tRegionOffset=0x%016jx\n",
3294792e611dSmsaitoh 		    (uintmax_t)mmap->RegionOffset);
3295792e611dSmsaitoh 		printf("\tAddress=0x%016jx\n", (uintmax_t)mmap->Address);
3296792e611dSmsaitoh 		printf("\tInterleaveIndex=%u\n", (u_int)mmap->InterleaveIndex);
3297792e611dSmsaitoh 		printf("\tInterleaveWays=%u\n", (u_int)mmap->InterleaveWays);
3298792e611dSmsaitoh 
3299792e611dSmsaitoh #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_MEM_## flag, #flag)
3300792e611dSmsaitoh 
3301792e611dSmsaitoh 		printf("\tFlags=");
3302792e611dSmsaitoh 		PRINTFLAG(mmap->Flags, SAVE_FAILED);
3303792e611dSmsaitoh 		PRINTFLAG(mmap->Flags, RESTORE_FAILED);
3304792e611dSmsaitoh 		PRINTFLAG(mmap->Flags, FLUSH_FAILED);
3305792e611dSmsaitoh 		PRINTFLAG(mmap->Flags, NOT_ARMED);
3306792e611dSmsaitoh 		PRINTFLAG(mmap->Flags, HEALTH_OBSERVED);
3307792e611dSmsaitoh 		PRINTFLAG(mmap->Flags, HEALTH_ENABLED);
3308792e611dSmsaitoh 		PRINTFLAG(mmap->Flags, MAP_FAILED);
3309792e611dSmsaitoh 		PRINTFLAG_END();
3310792e611dSmsaitoh 
3311792e611dSmsaitoh #undef PRINTFLAG
3312792e611dSmsaitoh 
3313792e611dSmsaitoh 		break;
3314792e611dSmsaitoh 	case ACPI_NFIT_TYPE_INTERLEAVE:
3315792e611dSmsaitoh 		ileave = (ACPI_NFIT_INTERLEAVE *)nfit;
3316792e611dSmsaitoh 		printf("\tInterleaveIndex=%u\n",
3317792e611dSmsaitoh 		    (u_int)ileave->InterleaveIndex);
3318792e611dSmsaitoh 		printf("\tLineCount=%u\n", (u_int)ileave->LineCount);
3319792e611dSmsaitoh 		printf("\tLineSize=%u\n", (u_int)ileave->LineSize);
3320792e611dSmsaitoh 		/* XXX ileave->LineOffset[i] output is not supported */
3321792e611dSmsaitoh 		break;
3322792e611dSmsaitoh 	case ACPI_NFIT_TYPE_SMBIOS:
3323792e611dSmsaitoh 		smbios = (ACPI_NFIT_SMBIOS *)nfit;
3324792e611dSmsaitoh 		/* XXX smbios->Data[x] output is not supported */
3325792e611dSmsaitoh 		break;
3326792e611dSmsaitoh 	case ACPI_NFIT_TYPE_CONTROL_REGION:
3327792e611dSmsaitoh 		ctlreg = (ACPI_NFIT_CONTROL_REGION *)nfit;
3328792e611dSmsaitoh 		printf("\tRegionIndex=%u\n", (u_int)ctlreg->RegionIndex);
3329792e611dSmsaitoh 		printf("\tVendorId=0x%04x\n", (u_int)ctlreg->VendorId);
3330792e611dSmsaitoh 		printf("\tDeviceId=0x%04x\n", (u_int)ctlreg->DeviceId);
3331792e611dSmsaitoh 		printf("\tRevisionId=%u\n", (u_int)ctlreg->RevisionId);
3332792e611dSmsaitoh 		printf("\tSubsystemVendorId=0x%04x\n",
3333792e611dSmsaitoh 		    (u_int)ctlreg->SubsystemVendorId);
3334792e611dSmsaitoh 		printf("\tSubsystemDeviceId=0x%04x\n",
3335792e611dSmsaitoh 		    (u_int)ctlreg->SubsystemDeviceId);
3336792e611dSmsaitoh 		printf("\tSubsystemRevisionId=%u\n",
3337792e611dSmsaitoh 		    (u_int)ctlreg->SubsystemRevisionId);
33381c01428aSmsaitoh 		printf("\tValidFields=%02x\n", (u_int)ctlreg->ValidFields);
3339792e611dSmsaitoh 		printf("\tManufacturingLocation=%u\n",
3340792e611dSmsaitoh 		    (u_int)ctlreg->ManufacturingLocation);
3341792e611dSmsaitoh 		printf("\tManufacturingDate=%u\n",
3342792e611dSmsaitoh 		    (u_int)ctlreg->ManufacturingDate);
3343792e611dSmsaitoh 		printf("\tSerialNumber=%u\n",
3344792e611dSmsaitoh 		    (u_int)ctlreg->SerialNumber);
3345792e611dSmsaitoh 		printf("\tCode=0x%04x\n", (u_int)ctlreg->Code);
3346792e611dSmsaitoh 		printf("\tWindows=%u\n", (u_int)ctlreg->Windows);
3347792e611dSmsaitoh 		printf("\tWindowSize=0x%016jx\n",
3348792e611dSmsaitoh 		    (uintmax_t)ctlreg->WindowSize);
3349792e611dSmsaitoh 		printf("\tCommandOffset=0x%016jx\n",
3350792e611dSmsaitoh 		    (uintmax_t)ctlreg->CommandOffset);
3351792e611dSmsaitoh 		printf("\tCommandSize=0x%016jx\n",
3352792e611dSmsaitoh 		    (uintmax_t)ctlreg->CommandSize);
3353792e611dSmsaitoh 		printf("\tStatusOffset=0x%016jx\n",
3354792e611dSmsaitoh 		    (uintmax_t)ctlreg->StatusOffset);
3355792e611dSmsaitoh 		printf("\tStatusSize=0x%016jx\n",
3356792e611dSmsaitoh 		    (uintmax_t)ctlreg->StatusSize);
3357792e611dSmsaitoh 
3358792e611dSmsaitoh #define PRINTFLAG(var, flag)	printflag((var), ACPI_NFIT_## flag, #flag)
3359792e611dSmsaitoh 
3360792e611dSmsaitoh 		printf("\tFlags=");
33611c01428aSmsaitoh 		PRINTFLAG(ctlreg->Flags, CONTROL_BUFFERED);
3362792e611dSmsaitoh 		PRINTFLAG_END();
3363792e611dSmsaitoh 
3364792e611dSmsaitoh #undef PRINTFLAG
3365792e611dSmsaitoh 
3366792e611dSmsaitoh 		break;
3367792e611dSmsaitoh 	case ACPI_NFIT_TYPE_DATA_REGION:
3368792e611dSmsaitoh 		datareg = (ACPI_NFIT_DATA_REGION *)nfit;
3369792e611dSmsaitoh 		printf("\tRegionIndex=%u\n", (u_int)datareg->RegionIndex);
3370792e611dSmsaitoh 		printf("\tWindows=%u\n", (u_int)datareg->Windows);
3371792e611dSmsaitoh 		printf("\tOffset=0x%016jx\n", (uintmax_t)datareg->Offset);
3372792e611dSmsaitoh 		printf("\tSize=0x%016jx\n", (uintmax_t)datareg->Size);
3373792e611dSmsaitoh 		printf("\tCapacity=0x%016jx\n", (uintmax_t)datareg->Capacity);
3374792e611dSmsaitoh 		printf("\tStartAddress=0x%016jx\n",
3375792e611dSmsaitoh 		    (uintmax_t)datareg->StartAddress);
3376792e611dSmsaitoh 		break;
3377792e611dSmsaitoh 	case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
3378792e611dSmsaitoh 		fladdr = (ACPI_NFIT_FLUSH_ADDRESS *)nfit;
3379792e611dSmsaitoh 		printf("\tDeviceHandle=%u\n", (u_int)fladdr->DeviceHandle);
3380792e611dSmsaitoh 		printf("\tHintCount=%u\n", (u_int)fladdr->HintCount);
3381792e611dSmsaitoh 		/* XXX fladdr->HintAddress[i] output is not supported */
3382792e611dSmsaitoh 		break;
3383792e611dSmsaitoh 	}
3384792e611dSmsaitoh }
3385792e611dSmsaitoh 
3386792e611dSmsaitoh static void
acpi_handle_nfit(ACPI_TABLE_HEADER * sdp)3387792e611dSmsaitoh acpi_handle_nfit(ACPI_TABLE_HEADER *sdp)
3388792e611dSmsaitoh {
3389792e611dSmsaitoh 	ACPI_TABLE_NFIT *nfit;
3390792e611dSmsaitoh 
3391792e611dSmsaitoh 	printf(BEGIN_COMMENT);
3392792e611dSmsaitoh 	acpi_print_sdt(sdp);
3393792e611dSmsaitoh 	nfit = (ACPI_TABLE_NFIT *)sdp;
3394792e611dSmsaitoh 	acpi_walk_nfit(sdp, (nfit + 1), acpi_print_nfit);
3395792e611dSmsaitoh 	printf(END_COMMENT);
3396792e611dSmsaitoh }
3397792e611dSmsaitoh 
3398c359a213Smsaitoh static char *
acpi_tcpa_evname(struct TCPAevent * event)3399c359a213Smsaitoh acpi_tcpa_evname(struct TCPAevent *event)
340009f2089bScegger {
3401c359a213Smsaitoh 	struct TCPApc_event *pc_event;
3402c359a213Smsaitoh 	char *eventname = NULL;
340309f2089bScegger 
3404c359a213Smsaitoh 	pc_event = (struct TCPApc_event *)(event + 1);
3405c359a213Smsaitoh 
3406c359a213Smsaitoh 	switch (event->event_type) {
3407c359a213Smsaitoh 	case PREBOOT:
3408c359a213Smsaitoh 	case POST_CODE:
3409c359a213Smsaitoh 	case UNUSED:
3410c359a213Smsaitoh 	case NO_ACTION:
3411c359a213Smsaitoh 	case SEPARATOR:
3412c359a213Smsaitoh 	case SCRTM_CONTENTS:
3413c359a213Smsaitoh 	case SCRTM_VERSION:
3414c359a213Smsaitoh 	case CPU_MICROCODE:
3415c359a213Smsaitoh 	case PLATFORM_CONFIG_FLAGS:
3416c359a213Smsaitoh 	case TABLE_OF_DEVICES:
3417c359a213Smsaitoh 	case COMPACT_HASH:
3418c359a213Smsaitoh 	case IPL:
3419c359a213Smsaitoh 	case IPL_PARTITION_DATA:
3420c359a213Smsaitoh 	case NONHOST_CODE:
3421c359a213Smsaitoh 	case NONHOST_CONFIG:
3422c359a213Smsaitoh 	case NONHOST_INFO:
3423c359a213Smsaitoh 		asprintf(&eventname, "%s",
3424c359a213Smsaitoh 		    tcpa_event_type_strings[event->event_type]);
3425df177446Schristos 		break;
3426df177446Schristos 
3427c359a213Smsaitoh 	case ACTION:
3428c359a213Smsaitoh 		eventname = calloc(event->event_size + 1, sizeof(char));
3429c359a213Smsaitoh 		memcpy(eventname, pc_event, event->event_size);
3430c359a213Smsaitoh 		break;
3431c359a213Smsaitoh 
3432c359a213Smsaitoh 	case EVENT_TAG:
3433c359a213Smsaitoh 		switch (pc_event->event_id) {
3434c359a213Smsaitoh 		case SMBIOS:
3435c359a213Smsaitoh 		case BIS_CERT:
3436c359a213Smsaitoh 		case CMOS:
3437c359a213Smsaitoh 		case NVRAM:
3438c359a213Smsaitoh 		case OPTION_ROM_EXEC:
3439c359a213Smsaitoh 		case OPTION_ROM_CONFIG:
3440c359a213Smsaitoh 		case S_CRTM_VERSION:
3441c359a213Smsaitoh 		case POST_BIOS_ROM:
3442c359a213Smsaitoh 		case ESCD:
3443c359a213Smsaitoh 		case OPTION_ROM_MICROCODE:
3444c359a213Smsaitoh 		case S_CRTM_CONTENTS:
3445c359a213Smsaitoh 		case POST_CONTENTS:
3446c359a213Smsaitoh 			asprintf(&eventname, "%s",
3447c359a213Smsaitoh 			    TCPA_pcclient_strings[pc_event->event_id]);
3448df177446Schristos 			break;
3449df177446Schristos 
3450df177446Schristos 		default:
3451c359a213Smsaitoh 			asprintf(&eventname, "<unknown tag 0x%02x>",
3452c359a213Smsaitoh 			    pc_event->event_id);
3453df177446Schristos 			break;
3454df177446Schristos 		}
3455c359a213Smsaitoh 		break;
3456c359a213Smsaitoh 
3457c359a213Smsaitoh 	default:
3458c359a213Smsaitoh 		asprintf(&eventname, "<unknown 0x%02x>", event->event_type);
3459c359a213Smsaitoh 		break;
3460c359a213Smsaitoh 	}
3461c359a213Smsaitoh 
3462c359a213Smsaitoh 	return eventname;
3463c359a213Smsaitoh }
3464c359a213Smsaitoh 
3465c359a213Smsaitoh static void
acpi_print_tcpa(struct TCPAevent * event)3466c359a213Smsaitoh acpi_print_tcpa(struct TCPAevent *event)
3467c359a213Smsaitoh {
3468c359a213Smsaitoh 	int i;
3469c359a213Smsaitoh 	char *eventname;
3470c359a213Smsaitoh 
3471c359a213Smsaitoh 	eventname = acpi_tcpa_evname(event);
3472c359a213Smsaitoh 
3473c359a213Smsaitoh 	printf("\t%d", event->pcr_index);
3474c359a213Smsaitoh 	printf(" 0x");
3475c359a213Smsaitoh 	for (i = 0; i < 20; i++)
3476c359a213Smsaitoh 		printf("%02x", event->pcr_value[i]);
3477c359a213Smsaitoh 	printf(" [%s]\n", eventname ? eventname : "<unknown>");
3478c359a213Smsaitoh 
3479c359a213Smsaitoh 	free(eventname);
3480c359a213Smsaitoh }
3481c359a213Smsaitoh 
3482c359a213Smsaitoh static void
acpi_handle_tcpa(ACPI_TABLE_HEADER * sdp)3483c359a213Smsaitoh acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp)
3484c359a213Smsaitoh {
3485c359a213Smsaitoh 	struct TCPAbody *tcpa;
3486c359a213Smsaitoh 	struct TCPAevent *event;
3487c359a213Smsaitoh 	uintmax_t len, paddr;
3488c359a213Smsaitoh 	unsigned char *vaddr = NULL;
3489c359a213Smsaitoh 	unsigned char *vend = NULL;
3490c359a213Smsaitoh 
3491c359a213Smsaitoh 	printf(BEGIN_COMMENT);
3492c359a213Smsaitoh 	acpi_print_sdt(sdp);
3493c359a213Smsaitoh 	tcpa = (struct TCPAbody *) sdp;
3494c359a213Smsaitoh 
3495c359a213Smsaitoh 	switch (tcpa->platform_class) {
3496c359a213Smsaitoh 	case ACPI_TCPA_BIOS_CLIENT:
3497c359a213Smsaitoh 		len = tcpa->client.log_max_len;
3498c359a213Smsaitoh 		paddr = tcpa->client.log_start_addr;
3499c359a213Smsaitoh 		break;
3500c359a213Smsaitoh 
3501c359a213Smsaitoh 	case ACPI_TCPA_BIOS_SERVER:
3502c359a213Smsaitoh 		len = tcpa->server.log_max_len;
3503c359a213Smsaitoh 		paddr = tcpa->server.log_start_addr;
3504c359a213Smsaitoh 		break;
3505c359a213Smsaitoh 
3506c359a213Smsaitoh 	default:
3507c359a213Smsaitoh 		printf("XXX");
3508c359a213Smsaitoh 		printf(END_COMMENT);
3509c359a213Smsaitoh 		return;
3510c359a213Smsaitoh 	}
3511c359a213Smsaitoh 	printf("\tClass %u Base Address 0x%jx Length %ju\n\n",
3512c359a213Smsaitoh 	    tcpa->platform_class, paddr, len);
3513c359a213Smsaitoh 
3514c359a213Smsaitoh 	if (len == 0) {
3515c359a213Smsaitoh 		printf("\tEmpty TCPA table\n");
3516c359a213Smsaitoh 		printf(END_COMMENT);
3517c359a213Smsaitoh 		return;
3518c359a213Smsaitoh 	}
3519c359a213Smsaitoh 	if (sdp->Revision == 1) {
3520c359a213Smsaitoh 		printf("\tOLD TCPA spec log found. Dumping not supported.\n");
3521c359a213Smsaitoh 		printf(END_COMMENT);
3522c359a213Smsaitoh 		return;
3523c359a213Smsaitoh 	}
3524c359a213Smsaitoh 
3525c359a213Smsaitoh 	vaddr = (unsigned char *)acpi_map_physical(paddr, len);
3526c359a213Smsaitoh 	vend = vaddr + len;
3527c359a213Smsaitoh 
3528c359a213Smsaitoh 	while (vaddr != NULL) {
3529c359a213Smsaitoh 		if ((vaddr + sizeof(struct TCPAevent) >= vend)||
3530c359a213Smsaitoh 		    (vaddr + sizeof(struct TCPAevent) < vaddr))
3531c359a213Smsaitoh 			break;
3532c359a213Smsaitoh 		event = (struct TCPAevent *)(void *)vaddr;
3533c359a213Smsaitoh 		if (vaddr + event->event_size >= vend)
3534c359a213Smsaitoh 			break;
3535c359a213Smsaitoh 		if (vaddr + event->event_size < vaddr)
3536c359a213Smsaitoh 			break;
3537c359a213Smsaitoh 		if (event->event_type == 0 && event->event_size == 0)
3538c359a213Smsaitoh 			break;
3539c359a213Smsaitoh #if 0
3540c359a213Smsaitoh 		{
3541c359a213Smsaitoh 		unsigned int i, j, k;
3542c359a213Smsaitoh 
3543c359a213Smsaitoh 		printf("\n\tsize %d\n\t\t%p ", event->event_size, vaddr);
3544c359a213Smsaitoh 		for (j = 0, i = 0; i <
3545c359a213Smsaitoh 		    sizeof(struct TCPAevent) + event->event_size; i++) {
3546c359a213Smsaitoh 			printf("%02x ", vaddr[i]);
3547c359a213Smsaitoh 			if ((i+1) % 8 == 0) {
3548c359a213Smsaitoh 				for (k = 0; k < 8; k++)
3549c359a213Smsaitoh 					printf("%c", isprint(vaddr[j+k]) ?
3550c359a213Smsaitoh 					    vaddr[j+k] : '.');
3551c359a213Smsaitoh 				printf("\n\t\t%p ", &vaddr[i + 1]);
3552c359a213Smsaitoh 				j = i + 1;
3553c359a213Smsaitoh 			}
3554c359a213Smsaitoh 		}
3555c359a213Smsaitoh 		printf("\n"); }
3556c359a213Smsaitoh #endif
3557c359a213Smsaitoh 		acpi_print_tcpa(event);
3558c359a213Smsaitoh 
3559c359a213Smsaitoh 		vaddr += sizeof(struct TCPAevent) + event->event_size;
3560c359a213Smsaitoh 	}
3561c359a213Smsaitoh 
3562c359a213Smsaitoh 	printf(END_COMMENT);
3563c359a213Smsaitoh }
3564c359a213Smsaitoh 
35650e3f83efSmaxv static void
acpi_handle_tpm2(ACPI_TABLE_HEADER * sdp)35660e3f83efSmaxv acpi_handle_tpm2(ACPI_TABLE_HEADER *sdp)
35670e3f83efSmaxv {
35680e3f83efSmaxv 	ACPI_TABLE_TPM2 *tpm2;
35690e3f83efSmaxv 	const char *class;
35700e3f83efSmaxv 
35710e3f83efSmaxv 	printf(BEGIN_COMMENT);
35720e3f83efSmaxv 
35730e3f83efSmaxv 	acpi_print_sdt(sdp);
35740e3f83efSmaxv 	tpm2 = (ACPI_TABLE_TPM2 *)sdp;
35750e3f83efSmaxv 
35760e3f83efSmaxv 	if (tpm2->PlatformClass == 0) {
35770e3f83efSmaxv 		class = "Client";
35780e3f83efSmaxv 	} else if (tpm2->PlatformClass == 1) {
35790e3f83efSmaxv 		class = "Server";
35800e3f83efSmaxv 	} else {
35810e3f83efSmaxv 		class = "Unknown";
35820e3f83efSmaxv 	}
35830e3f83efSmaxv 	printf("\tClass=%s (%u)\n", class, tpm2->PlatformClass);
35840e3f83efSmaxv 	printf("\tControl Address=0x%"PRIx64"\n", tpm2->ControlAddress);
35850e3f83efSmaxv 	printf("\tStart Method=%u\n", tpm2->StartMethod);
35860e3f83efSmaxv 
35870e3f83efSmaxv 	printf(END_COMMENT);
35880e3f83efSmaxv }
35890e3f83efSmaxv 
3590c359a213Smsaitoh static const char *
devscope_type2str(int type)3591c359a213Smsaitoh devscope_type2str(int type)
3592c359a213Smsaitoh {
3593c359a213Smsaitoh 	static char typebuf[16];
3594c359a213Smsaitoh 
3595c359a213Smsaitoh 	switch (type) {
3596c359a213Smsaitoh 	case 1:
3597c359a213Smsaitoh 		return ("PCI Endpoint Device");
3598c359a213Smsaitoh 	case 2:
3599c359a213Smsaitoh 		return ("PCI Sub-Hierarchy");
3600c359a213Smsaitoh 	case 3:
3601c359a213Smsaitoh 		return ("IOAPIC");
3602c359a213Smsaitoh 	case 4:
3603c359a213Smsaitoh 		return ("HPET");
36045073389cSmsaitoh 	case 5:
36055073389cSmsaitoh 		return ("ACPI Name space");
3606c359a213Smsaitoh 	default:
3607c359a213Smsaitoh 		snprintf(typebuf, sizeof(typebuf), "%d", type);
3608c359a213Smsaitoh 		return (typebuf);
3609c359a213Smsaitoh 	}
3610c359a213Smsaitoh }
3611c359a213Smsaitoh 
3612c359a213Smsaitoh static int
acpi_handle_dmar_devscope(void * addr,int remaining)3613c359a213Smsaitoh acpi_handle_dmar_devscope(void *addr, int remaining)
3614c359a213Smsaitoh {
3615c359a213Smsaitoh 	char sep;
3616c359a213Smsaitoh 	int pathlen;
3617c359a213Smsaitoh 	ACPI_DMAR_PCI_PATH *path, *pathend;
3618c359a213Smsaitoh 	ACPI_DMAR_DEVICE_SCOPE *devscope = addr;
3619c359a213Smsaitoh 
3620c359a213Smsaitoh 	if (remaining < (int)sizeof(ACPI_DMAR_DEVICE_SCOPE))
3621c359a213Smsaitoh 		return (-1);
3622c359a213Smsaitoh 
3623c359a213Smsaitoh 	if (remaining < devscope->Length)
3624c359a213Smsaitoh 		return (-1);
3625c359a213Smsaitoh 
3626c359a213Smsaitoh 	printf("\n");
3627c359a213Smsaitoh 	printf("\t\tType=%s\n", devscope_type2str(devscope->EntryType));
3628c359a213Smsaitoh 	printf("\t\tLength=%d\n", devscope->Length);
3629c359a213Smsaitoh 	printf("\t\tEnumerationId=%d\n", devscope->EnumerationId);
3630c359a213Smsaitoh 	printf("\t\tStartBusNumber=%d\n", devscope->Bus);
3631c359a213Smsaitoh 
3632c359a213Smsaitoh 	path = (ACPI_DMAR_PCI_PATH *)(devscope + 1);
3633c359a213Smsaitoh 	pathlen = devscope->Length - sizeof(ACPI_DMAR_DEVICE_SCOPE);
3634c359a213Smsaitoh 	pathend = path + pathlen / sizeof(ACPI_DMAR_PCI_PATH);
3635c359a213Smsaitoh 	if (path < pathend) {
3636c359a213Smsaitoh 		sep = '{';
3637c359a213Smsaitoh 		printf("\t\tPath=");
3638c359a213Smsaitoh 		do {
3639c359a213Smsaitoh 			printf("%c%d:%d", sep, path->Device, path->Function);
3640c359a213Smsaitoh 			sep=',';
3641c359a213Smsaitoh 			path++;
3642c359a213Smsaitoh 		} while (path < pathend);
3643c359a213Smsaitoh 		printf("}\n");
3644c359a213Smsaitoh 	}
3645c359a213Smsaitoh 
3646c359a213Smsaitoh 	return (devscope->Length);
3647c359a213Smsaitoh }
3648c359a213Smsaitoh 
3649c359a213Smsaitoh static void
acpi_handle_dmar_drhd(ACPI_DMAR_HARDWARE_UNIT * drhd)3650c359a213Smsaitoh acpi_handle_dmar_drhd(ACPI_DMAR_HARDWARE_UNIT *drhd)
3651c359a213Smsaitoh {
3652c359a213Smsaitoh 	char *cp;
3653c359a213Smsaitoh 	int remaining, consumed;
3654c359a213Smsaitoh 
3655c359a213Smsaitoh 	printf("\n");
3656c359a213Smsaitoh 	printf("\tType=DRHD\n");
3657c359a213Smsaitoh 	printf("\tLength=%d\n", drhd->Header.Length);
3658c359a213Smsaitoh 
3659c359a213Smsaitoh #define	PRINTFLAG(var, flag)	printflag((var), ACPI_DMAR_## flag, #flag)
3660c359a213Smsaitoh 
3661c359a213Smsaitoh 	printf("\tFlags=");
3662c359a213Smsaitoh 	PRINTFLAG(drhd->Flags, INCLUDE_ALL);
3663c359a213Smsaitoh 	PRINTFLAG_END();
3664c359a213Smsaitoh 
3665c359a213Smsaitoh #undef PRINTFLAG
3666c359a213Smsaitoh 
3667c359a213Smsaitoh 	printf("\tSegment=%d\n", drhd->Segment);
3668c359a213Smsaitoh 	printf("\tAddress=0x%016jx\n", (uintmax_t)drhd->Address);
3669c359a213Smsaitoh 
3670c359a213Smsaitoh 	remaining = drhd->Header.Length - sizeof(ACPI_DMAR_HARDWARE_UNIT);
3671c359a213Smsaitoh 	if (remaining > 0)
3672c359a213Smsaitoh 		printf("\tDevice Scope:");
3673c359a213Smsaitoh 	while (remaining > 0) {
3674c359a213Smsaitoh 		cp = (char *)drhd + drhd->Header.Length - remaining;
3675c359a213Smsaitoh 		consumed = acpi_handle_dmar_devscope(cp, remaining);
3676c359a213Smsaitoh 		if (consumed <= 0)
3677c359a213Smsaitoh 			break;
3678c359a213Smsaitoh 		else
3679c359a213Smsaitoh 			remaining -= consumed;
3680c359a213Smsaitoh 	}
3681c359a213Smsaitoh }
3682c359a213Smsaitoh 
3683c359a213Smsaitoh static void
acpi_handle_dmar_rmrr(ACPI_DMAR_RESERVED_MEMORY * rmrr)3684c359a213Smsaitoh acpi_handle_dmar_rmrr(ACPI_DMAR_RESERVED_MEMORY *rmrr)
3685c359a213Smsaitoh {
3686c359a213Smsaitoh 	char *cp;
3687c359a213Smsaitoh 	int remaining, consumed;
3688c359a213Smsaitoh 
3689c359a213Smsaitoh 	printf("\n");
3690c359a213Smsaitoh 	printf("\tType=RMRR\n");
3691c359a213Smsaitoh 	printf("\tLength=%d\n", rmrr->Header.Length);
3692c359a213Smsaitoh 	printf("\tSegment=%d\n", rmrr->Segment);
3693c359a213Smsaitoh 	printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rmrr->BaseAddress);
3694c359a213Smsaitoh 	printf("\tLimitAddress=0x%016jx\n", (uintmax_t)rmrr->EndAddress);
3695c359a213Smsaitoh 
3696c359a213Smsaitoh 	remaining = rmrr->Header.Length - sizeof(ACPI_DMAR_RESERVED_MEMORY);
3697c359a213Smsaitoh 	if (remaining > 0)
3698c359a213Smsaitoh 		printf("\tDevice Scope:");
3699c359a213Smsaitoh 	while (remaining > 0) {
3700c359a213Smsaitoh 		cp = (char *)rmrr + rmrr->Header.Length - remaining;
3701c359a213Smsaitoh 		consumed = acpi_handle_dmar_devscope(cp, remaining);
3702c359a213Smsaitoh 		if (consumed <= 0)
3703c359a213Smsaitoh 			break;
3704c359a213Smsaitoh 		else
3705c359a213Smsaitoh 			remaining -= consumed;
3706c359a213Smsaitoh 	}
3707c359a213Smsaitoh }
3708c359a213Smsaitoh 
3709c359a213Smsaitoh static void
acpi_handle_dmar_atsr(ACPI_DMAR_ATSR * atsr)3710c359a213Smsaitoh acpi_handle_dmar_atsr(ACPI_DMAR_ATSR *atsr)
3711c359a213Smsaitoh {
3712c359a213Smsaitoh 	char *cp;
3713c359a213Smsaitoh 	int remaining, consumed;
3714c359a213Smsaitoh 
3715c359a213Smsaitoh 	printf("\n");
3716c359a213Smsaitoh 	printf("\tType=ATSR\n");
3717c359a213Smsaitoh 	printf("\tLength=%d\n", atsr->Header.Length);
3718c359a213Smsaitoh 
3719c359a213Smsaitoh #define	PRINTFLAG(var, flag)	printflag((var), ACPI_DMAR_## flag, #flag)
3720c359a213Smsaitoh 
3721c359a213Smsaitoh 	printf("\tFlags=");
3722c359a213Smsaitoh 	PRINTFLAG(atsr->Flags, ALL_PORTS);
3723c359a213Smsaitoh 	PRINTFLAG_END();
3724c359a213Smsaitoh 
3725c359a213Smsaitoh #undef PRINTFLAG
3726c359a213Smsaitoh 
3727c359a213Smsaitoh 	printf("\tSegment=%d\n", atsr->Segment);
3728c359a213Smsaitoh 
3729c359a213Smsaitoh 	remaining = atsr->Header.Length - sizeof(ACPI_DMAR_ATSR);
3730c359a213Smsaitoh 	if (remaining > 0)
3731c359a213Smsaitoh 		printf("\tDevice Scope:");
3732c359a213Smsaitoh 	while (remaining > 0) {
3733c359a213Smsaitoh 		cp = (char *)atsr + atsr->Header.Length - remaining;
3734c359a213Smsaitoh 		consumed = acpi_handle_dmar_devscope(cp, remaining);
3735c359a213Smsaitoh 		if (consumed <= 0)
3736c359a213Smsaitoh 			break;
3737c359a213Smsaitoh 		else
3738c359a213Smsaitoh 			remaining -= consumed;
3739c359a213Smsaitoh 	}
3740c359a213Smsaitoh }
3741c359a213Smsaitoh 
3742c359a213Smsaitoh static void
acpi_handle_dmar_rhsa(ACPI_DMAR_RHSA * rhsa)3743c359a213Smsaitoh acpi_handle_dmar_rhsa(ACPI_DMAR_RHSA *rhsa)
3744c359a213Smsaitoh {
3745c359a213Smsaitoh 
3746c359a213Smsaitoh 	printf("\n");
3747c359a213Smsaitoh 	printf("\tType=RHSA\n");
3748c359a213Smsaitoh 	printf("\tLength=%d\n", rhsa->Header.Length);
3749c359a213Smsaitoh 	printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rhsa->BaseAddress);
3750c359a213Smsaitoh 	printf("\tProximityDomain=0x%08x\n", rhsa->ProximityDomain);
3751c359a213Smsaitoh }
3752c359a213Smsaitoh 
37535073389cSmsaitoh static void
acpi_handle_dmar_andd(ACPI_DMAR_ANDD * andd)37545073389cSmsaitoh acpi_handle_dmar_andd(ACPI_DMAR_ANDD *andd)
37555073389cSmsaitoh {
37565073389cSmsaitoh 
37575073389cSmsaitoh 	printf("\n");
37585073389cSmsaitoh 	printf("\tType=ANDD\n");
37595073389cSmsaitoh 	printf("\tLength=%d\n", andd->Header.Length);
37605073389cSmsaitoh 	printf("\tDeviceNumber=%d\n", andd->DeviceNumber);
37615073389cSmsaitoh 	printf("\tDeviceName=0x%s\n", andd->DeviceName);
37625073389cSmsaitoh }
37635073389cSmsaitoh 
3764c359a213Smsaitoh static int
acpi_handle_dmar_remapping_structure(void * addr,int remaining)3765c359a213Smsaitoh acpi_handle_dmar_remapping_structure(void *addr, int remaining)
3766c359a213Smsaitoh {
3767c359a213Smsaitoh 	ACPI_DMAR_HEADER *hdr = addr;
3768c359a213Smsaitoh 
3769c359a213Smsaitoh 	if (remaining < (int)sizeof(ACPI_DMAR_HEADER))
3770c359a213Smsaitoh 		return (-1);
3771c359a213Smsaitoh 
3772c359a213Smsaitoh 	if (remaining < hdr->Length)
3773c359a213Smsaitoh 		return (-1);
3774c359a213Smsaitoh 
3775c359a213Smsaitoh 	switch (hdr->Type) {
3776c359a213Smsaitoh 	case ACPI_DMAR_TYPE_HARDWARE_UNIT:
3777c359a213Smsaitoh 		acpi_handle_dmar_drhd(addr);
3778c359a213Smsaitoh 		break;
3779c359a213Smsaitoh 	case ACPI_DMAR_TYPE_RESERVED_MEMORY:
3780c359a213Smsaitoh 		acpi_handle_dmar_rmrr(addr);
3781c359a213Smsaitoh 		break;
3782c359a213Smsaitoh 	case ACPI_DMAR_TYPE_ROOT_ATS:
3783c359a213Smsaitoh 		acpi_handle_dmar_atsr(addr);
3784c359a213Smsaitoh 		break;
3785c359a213Smsaitoh 	case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
3786c359a213Smsaitoh 		acpi_handle_dmar_rhsa(addr);
3787c359a213Smsaitoh 		break;
37885073389cSmsaitoh 	case ACPI_DMAR_TYPE_NAMESPACE:
37895073389cSmsaitoh 		acpi_handle_dmar_andd(addr);
37905073389cSmsaitoh 		break;
3791c359a213Smsaitoh 	default:
3792c359a213Smsaitoh 		printf("\n");
3793c359a213Smsaitoh 		printf("\tType=%d\n", hdr->Type);
3794c359a213Smsaitoh 		printf("\tLength=%d\n", hdr->Length);
3795c359a213Smsaitoh 		break;
3796c359a213Smsaitoh 	}
3797c359a213Smsaitoh 	return (hdr->Length);
3798c359a213Smsaitoh }
3799c359a213Smsaitoh 
3800c359a213Smsaitoh #ifndef ACPI_DMAR_X2APIC_OPT_OUT
3801c359a213Smsaitoh #define	ACPI_DMAR_X2APIC_OPT_OUT	(0x2)
3802c359a213Smsaitoh #endif
3803c359a213Smsaitoh 
3804c359a213Smsaitoh static void
acpi_handle_dmar(ACPI_TABLE_HEADER * sdp)3805c359a213Smsaitoh acpi_handle_dmar(ACPI_TABLE_HEADER *sdp)
3806c359a213Smsaitoh {
3807c359a213Smsaitoh 	char *cp;
3808c359a213Smsaitoh 	int remaining, consumed;
3809c359a213Smsaitoh 	ACPI_TABLE_DMAR *dmar;
3810c359a213Smsaitoh 
3811c359a213Smsaitoh 	printf(BEGIN_COMMENT);
3812c359a213Smsaitoh 	acpi_print_sdt(sdp);
3813c359a213Smsaitoh 	dmar = (ACPI_TABLE_DMAR *)sdp;
3814c359a213Smsaitoh 	printf("\tHost Address Width=%d\n", dmar->Width + 1);
3815c359a213Smsaitoh 
3816c359a213Smsaitoh #define PRINTFLAG(var, flag)	printflag((var), ACPI_DMAR_## flag, #flag)
3817c359a213Smsaitoh 
3818c359a213Smsaitoh 	printf("\tFlags=");
3819c359a213Smsaitoh 	PRINTFLAG(dmar->Flags, INTR_REMAP);
3820c359a213Smsaitoh 	PRINTFLAG(dmar->Flags, X2APIC_OPT_OUT);
38215073389cSmsaitoh 	PRINTFLAG(dmar->Flags, X2APIC_MODE);
3822c359a213Smsaitoh 	PRINTFLAG_END();
3823c359a213Smsaitoh 
3824c359a213Smsaitoh #undef PRINTFLAG
3825c359a213Smsaitoh 
3826c359a213Smsaitoh 	remaining = sdp->Length - sizeof(ACPI_TABLE_DMAR);
3827c359a213Smsaitoh 	while (remaining > 0) {
3828c359a213Smsaitoh 		cp = (char *)sdp + sdp->Length - remaining;
3829c359a213Smsaitoh 		consumed = acpi_handle_dmar_remapping_structure(cp, remaining);
3830c359a213Smsaitoh 		if (consumed <= 0)
3831c359a213Smsaitoh 			break;
3832c359a213Smsaitoh 		else
3833c359a213Smsaitoh 			remaining -= consumed;
3834c359a213Smsaitoh 	}
3835df177446Schristos 
383609f2089bScegger 	printf(END_COMMENT);
383709f2089bScegger }
383809f2089bScegger 
383909f2089bScegger static void
acpi_handle_uefi(ACPI_TABLE_HEADER * sdp)38405d527485Smsaitoh acpi_handle_uefi(ACPI_TABLE_HEADER *sdp)
38415d527485Smsaitoh {
38425d527485Smsaitoh 	ACPI_TABLE_UEFI *uefi;
38435d527485Smsaitoh 	char *uuidstr;
38445d527485Smsaitoh 	uint32_t status;
38455d527485Smsaitoh 
38465d527485Smsaitoh 	printf(BEGIN_COMMENT);
38475d527485Smsaitoh 	acpi_print_sdt(sdp);
38485d527485Smsaitoh 	uefi = (ACPI_TABLE_UEFI *)sdp;
38495d527485Smsaitoh 
38505d527485Smsaitoh 	uuid_to_string((uuid_t *)(uefi->Identifier),
38515d527485Smsaitoh 	    &uuidstr, &status);
38525d527485Smsaitoh 	if (status != uuid_s_ok)
38535d527485Smsaitoh 		errx(1, "uuid_to_string: status=%u", status);
38545d527485Smsaitoh 	printf("\tUUID=%s\n", uuidstr);
38555d527485Smsaitoh 	free(uuidstr);
38565d527485Smsaitoh 
38575d527485Smsaitoh 	printf("\tDataOffset=%04hx\n", uefi->DataOffset);
38585d527485Smsaitoh 	/* XXX need write */
38595d527485Smsaitoh 
38605d527485Smsaitoh 	printf(END_COMMENT);
38615d527485Smsaitoh }
38625d527485Smsaitoh 
38635d527485Smsaitoh static void
acpi_handle_waet(ACPI_TABLE_HEADER * sdp)386409f2089bScegger acpi_handle_waet(ACPI_TABLE_HEADER *sdp)
386509f2089bScegger {
386609f2089bScegger 	ACPI_TABLE_WAET *waet;
386709f2089bScegger 
386809f2089bScegger 	printf(BEGIN_COMMENT);
386909f2089bScegger 	acpi_print_sdt(sdp);
387009f2089bScegger 	waet = (ACPI_TABLE_WAET *)sdp;
387109f2089bScegger 
387209f2089bScegger 	printf("\tRTC Timer={");
387309f2089bScegger 	if (waet->Flags & ACPI_WAET_RTC_NO_ACK)
387409f2089bScegger 		printf("No ACK required");
387509f2089bScegger 	else
387609f2089bScegger 		printf("default behaviour");
387709f2089bScegger 	printf("}\n");
387809f2089bScegger 	printf("\t ACPI PM Timer={");
387909f2089bScegger 	if (waet->Flags & ACPI_WAET_TIMER_ONE_READ)
388009f2089bScegger 		printf("One Read sufficient");
388109f2089bScegger 	else
388209f2089bScegger 		printf("default behaviour");
388309f2089bScegger 	printf("}\n");
388409f2089bScegger 
388509f2089bScegger 	printf(END_COMMENT);
388609f2089bScegger }
388709f2089bScegger 
388809f2089bScegger static void
acpi_print_wdat_action(ACPI_WHEA_HEADER * whea)388909f2089bScegger acpi_print_wdat_action(ACPI_WHEA_HEADER *whea)
389009f2089bScegger {
389109f2089bScegger 	printf("\tACTION={");
389209f2089bScegger 	switch (whea->Action) {
389309f2089bScegger 	case ACPI_WDAT_RESET:
389409f2089bScegger 		printf("RESET");
389509f2089bScegger 		break;
389609f2089bScegger 	case ACPI_WDAT_GET_CURRENT_COUNTDOWN:
389709f2089bScegger 		printf("GET_CURRENT_COUNTDOWN");
389809f2089bScegger 		break;
389909f2089bScegger 	case ACPI_WDAT_GET_COUNTDOWN:
390009f2089bScegger 		printf("GET_COUNTDOWN");
390109f2089bScegger 		break;
390209f2089bScegger 	case ACPI_WDAT_SET_COUNTDOWN:
390309f2089bScegger 		printf("SET_COUNTDOWN");
390409f2089bScegger 		break;
390509f2089bScegger 	case ACPI_WDAT_GET_RUNNING_STATE:
390609f2089bScegger 		printf("GET_RUNNING_STATE");
390709f2089bScegger 		break;
390809f2089bScegger 	case ACPI_WDAT_SET_RUNNING_STATE:
390909f2089bScegger 		printf("SET_RUNNING_STATE");
391009f2089bScegger 		break;
391109f2089bScegger 	case ACPI_WDAT_GET_STOPPED_STATE:
391209f2089bScegger 		printf("GET_STOPPED_STATE");
391309f2089bScegger 		break;
391409f2089bScegger 	case ACPI_WDAT_SET_STOPPED_STATE:
391509f2089bScegger 		printf("SET_STOPPED_STATE");
391609f2089bScegger 		break;
391709f2089bScegger 	case ACPI_WDAT_GET_REBOOT:
391809f2089bScegger 		printf("GET_REBOOT");
391909f2089bScegger 		break;
392009f2089bScegger 	case ACPI_WDAT_SET_REBOOT:
392109f2089bScegger 		printf("SET_REBOOT");
392209f2089bScegger 		break;
392309f2089bScegger 	case ACPI_WDAT_GET_SHUTDOWN:
392409f2089bScegger 		printf("GET_SHUTDOWN");
392509f2089bScegger 		break;
392609f2089bScegger 	case ACPI_WDAT_SET_SHUTDOWN:
392709f2089bScegger 		printf("SET_SHUTDOWN");
392809f2089bScegger 		break;
392909f2089bScegger 	case ACPI_WDAT_GET_STATUS:
393009f2089bScegger 		printf("GET_STATUS");
393109f2089bScegger 		break;
393209f2089bScegger 	case ACPI_WDAT_SET_STATUS:
393309f2089bScegger 		printf("SET_STATUS");
393409f2089bScegger 		break;
393509f2089bScegger 	case ACPI_WDAT_ACTION_RESERVED:
393609f2089bScegger 		printf("ACTION_RESERVED");
393709f2089bScegger 		break;
393809f2089bScegger 	default:
393909f2089bScegger 		printf("%d", whea->Action);
394009f2089bScegger 		break;
394109f2089bScegger 	}
394209f2089bScegger 	printf("}\n");
394309f2089bScegger }
394409f2089bScegger 
394509f2089bScegger static void
acpi_print_wdat_instruction(ACPI_WHEA_HEADER * whea)394609f2089bScegger acpi_print_wdat_instruction(ACPI_WHEA_HEADER *whea)
394709f2089bScegger {
394809f2089bScegger 	uint32_t ins;
394909f2089bScegger 
395009f2089bScegger 	ins = whea->Instruction & ~ACPI_WDAT_PRESERVE_REGISTER;
395109f2089bScegger 
395209f2089bScegger 	printf("\tINSTRUCTION={");
395309f2089bScegger 	switch (ins) {
395409f2089bScegger 	case ACPI_WDAT_READ_VALUE:
395509f2089bScegger 		printf("READ_VALUE");
395609f2089bScegger 		break;
395709f2089bScegger 	case ACPI_WDAT_READ_COUNTDOWN:
395809f2089bScegger 		printf("READ_COUNTDOWN");
395909f2089bScegger 		break;
396009f2089bScegger 	case ACPI_WDAT_WRITE_VALUE:
396109f2089bScegger 		printf("WRITE_VALUE");
396209f2089bScegger 		break;
396309f2089bScegger 	case ACPI_WDAT_WRITE_COUNTDOWN:
396409f2089bScegger 		printf("WRITE_COUNTDOWN");
396509f2089bScegger 		break;
396609f2089bScegger 	case ACPI_WDAT_INSTRUCTION_RESERVED:
396709f2089bScegger 		printf("INSTRUCTION_RESERVED");
396809f2089bScegger 		break;
396909f2089bScegger 	default:
397009f2089bScegger 		printf("%d", ins);
397109f2089bScegger 		break;
397209f2089bScegger 	}
397309f2089bScegger 
397409f2089bScegger 	if (whea->Instruction & ACPI_WDAT_PRESERVE_REGISTER)
397509f2089bScegger 		printf(", Preserve Register");
397609f2089bScegger 
397709f2089bScegger 	printf("}\n");
397809f2089bScegger }
397909f2089bScegger 
398009f2089bScegger static void
acpi_handle_wdat(ACPI_TABLE_HEADER * sdp)398109f2089bScegger acpi_handle_wdat(ACPI_TABLE_HEADER *sdp)
398209f2089bScegger {
398309f2089bScegger 	ACPI_TABLE_WDAT *wdat;
398409f2089bScegger 	ACPI_WHEA_HEADER *whea;
39858dabdd9fSmsaitoh 	ACPI_WDAT_ENTRY *wdat_pos;
398609f2089bScegger 	u_int i;
398709f2089bScegger 
398809f2089bScegger 	printf(BEGIN_COMMENT);
398909f2089bScegger 	acpi_print_sdt(sdp);
399009f2089bScegger 	wdat = (ACPI_TABLE_WDAT *)sdp;
399109f2089bScegger 
399209f2089bScegger 	printf("\tHeader Length=%d\n", wdat->HeaderLength);
399309f2089bScegger 
39945d527485Smsaitoh 	acpi_print_pci_sbdf(wdat->PciSegment, wdat->PciBus, wdat->PciDevice,
399509f2089bScegger 	    wdat->PciFunction);
399609f2089bScegger 	printf("\n\tTimer Counter Period=%d msec\n", wdat->TimerPeriod);
399709f2089bScegger 	printf("\tTimer Maximum Counter Value=%d\n", wdat->MaxCount);
399809f2089bScegger 	printf("\tTimer Minimum Counter Value=%d\n", wdat->MinCount);
399909f2089bScegger 
400009f2089bScegger 	printf("\tFlags={");
400109f2089bScegger 	if (wdat->Flags & ACPI_WDAT_ENABLED)
400209f2089bScegger 		printf("ENABLED");
400309f2089bScegger 	if (wdat->Flags & ACPI_WDAT_STOPPED)
400409f2089bScegger 		printf(", STOPPED");
400509f2089bScegger 	printf("}\n");
400609f2089bScegger 
40078dabdd9fSmsaitoh 	wdat_pos = (ACPI_WDAT_ENTRY *)((char *)wdat + sizeof(ACPI_TABLE_WDAT));
400809f2089bScegger 
400909f2089bScegger 	for (i = 0; i < wdat->Entries; i++) {
401009f2089bScegger 		whea = (ACPI_WHEA_HEADER *)wdat_pos;
401109f2089bScegger 		acpi_print_whea(whea,
401209f2089bScegger 		    acpi_print_wdat_action, acpi_print_wdat_instruction,
401309f2089bScegger 		    NULL);
40148dabdd9fSmsaitoh 		wdat_pos++;
401509f2089bScegger 	}
401609f2089bScegger 	printf(END_COMMENT);
401709f2089bScegger }
401809f2089bScegger 
401909f2089bScegger static void
acpi_handle_wddt(ACPI_TABLE_HEADER * sdp)40205d527485Smsaitoh acpi_handle_wddt(ACPI_TABLE_HEADER *sdp)
40215d527485Smsaitoh {
40225d527485Smsaitoh 	ACPI_TABLE_WDDT *wddt;
40235d527485Smsaitoh 
40245d527485Smsaitoh 	printf(BEGIN_COMMENT);
40255d527485Smsaitoh 	acpi_print_sdt(sdp);
40265d527485Smsaitoh 	wddt = (ACPI_TABLE_WDDT *)sdp;
40275d527485Smsaitoh 
40285d527485Smsaitoh 	printf("\tSpecVersion=%04hx\n", wddt->SpecVersion);
40295d527485Smsaitoh 	printf("\tTableVersion=%04hx\n", wddt->TableVersion);
40305d527485Smsaitoh 	printf("\tPciVendorID=%04hx\n", wddt->PciVendorId);
40315d527485Smsaitoh 	printf("\tAddress=");
40325d527485Smsaitoh 	acpi_print_gas(&wddt->Address);
40335d527485Smsaitoh 	printf("\n\tTimer Maximum Counter Value=%d\n", wddt->MaxCount);
40345d527485Smsaitoh 	printf("\tTimer Minimum Counter Value=%d\n", wddt->MinCount);
40355d527485Smsaitoh 	printf("\tTimer Counter Period=%d\n", wddt->Period);
40365d527485Smsaitoh 
40375d527485Smsaitoh #define PRINTFLAG(var, flag)	printflag((var), ACPI_WDDT_## flag, #flag)
40385d527485Smsaitoh 
40395d527485Smsaitoh 	printf("\tStatus=");
40405d527485Smsaitoh 	PRINTFLAG(wddt->Status, AVAILABLE);
40415d527485Smsaitoh 	PRINTFLAG(wddt->Status, ACTIVE);
40425d527485Smsaitoh 	PRINTFLAG(wddt->Status, TCO_OS_OWNED);
40435d527485Smsaitoh 	PRINTFLAG(wddt->Status, USER_RESET);
40445d527485Smsaitoh 	PRINTFLAG(wddt->Status, WDT_RESET);
40455d527485Smsaitoh 	PRINTFLAG(wddt->Status, POWER_FAIL);
40465d527485Smsaitoh 	PRINTFLAG(wddt->Status, UNKNOWN_RESET);
40475d527485Smsaitoh 	PRINTFLAG_END();
40485d527485Smsaitoh 
40495d527485Smsaitoh 	printf("\tCapability=");
40505d527485Smsaitoh 	PRINTFLAG(wddt->Capability, AUTO_RESET);
40515d527485Smsaitoh 	PRINTFLAG(wddt->Capability, ALERT_SUPPORT);
40525d527485Smsaitoh 	PRINTFLAG_END();
40535d527485Smsaitoh 
40545d527485Smsaitoh #undef PRINTFLAG
40555d527485Smsaitoh 
40565d527485Smsaitoh 	printf(END_COMMENT);
40575d527485Smsaitoh }
40585d527485Smsaitoh 
40595d527485Smsaitoh static void
acpi_handle_wdrt(ACPI_TABLE_HEADER * sdp)406009f2089bScegger acpi_handle_wdrt(ACPI_TABLE_HEADER *sdp)
406109f2089bScegger {
406209f2089bScegger 	ACPI_TABLE_WDRT *wdrt;
406309f2089bScegger 
406409f2089bScegger 	printf(BEGIN_COMMENT);
406509f2089bScegger 	acpi_print_sdt(sdp);
406609f2089bScegger 	wdrt = (ACPI_TABLE_WDRT *)sdp;
406709f2089bScegger 
406809f2089bScegger 	printf("\tControl Register=");
406909f2089bScegger 	acpi_print_gas(&wdrt->ControlRegister);
4070800ead4eSmsaitoh 	printf("\n\tCount Register=");
407109f2089bScegger 	acpi_print_gas(&wdrt->CountRegister);
4072800ead4eSmsaitoh 	printf("\n");
407309f2089bScegger 	acpi_print_pci(wdrt->PciVendorId, wdrt->PciDeviceId,
407409f2089bScegger 	    wdrt->PciSegment, wdrt->PciBus, wdrt->PciDevice, wdrt->PciFunction);
407509f2089bScegger 
407609f2089bScegger 	/* Value must be >= 511 and < 65535 */
407709f2089bScegger 	printf("\tMaxCount=%d", wdrt->MaxCount);
407809f2089bScegger 	if (wdrt->MaxCount < 511)
407909f2089bScegger 		printf(" (Out of Range. Valid range: 511 <= maxcount < 65535)");
408009f2089bScegger 	printf("\n");
408109f2089bScegger 
408209f2089bScegger 	printf("\tUnit={");
408309f2089bScegger 	switch (wdrt->Units) {
408409f2089bScegger 	case 0:
408509f2089bScegger 		printf("1 seconds/count");
408609f2089bScegger 		break;
408709f2089bScegger 	case 1:
408809f2089bScegger 		printf("100 milliseconds/count");
408909f2089bScegger 		break;
409009f2089bScegger 	case 2:
409109f2089bScegger 		printf("10 milliseconds/count");
409209f2089bScegger 		break;
409309f2089bScegger 	default:
409409f2089bScegger 		printf("%d", wdrt->Units);
409509f2089bScegger 		break;
409609f2089bScegger 	}
409709f2089bScegger 	printf("}\n");
409809f2089bScegger 
409909f2089bScegger 	printf(END_COMMENT);
410009f2089bScegger }
410109f2089bScegger 
410209f2089bScegger static void
acpi_print_sdt(ACPI_TABLE_HEADER * sdp)410309f2089bScegger acpi_print_sdt(ACPI_TABLE_HEADER *sdp)
410409f2089bScegger {
410509f2089bScegger 	printf("  ");
41068ffd671aSdogcow 	acpi_print_string(sdp->Signature, ACPI_NAMESEG_SIZE);
4107d34a996fSjmcneill 	printf(": Length=%d, Revision=%d, Checksum=%d",
410809f2089bScegger 	       sdp->Length, sdp->Revision, sdp->Checksum);
4109d34a996fSjmcneill 	if (acpi_checksum(sdp, sdp->Length))
4110d34a996fSjmcneill 		printf(" (Incorrect)");
4111d34a996fSjmcneill 	printf(",\n\tOEMID=");
411209f2089bScegger 	acpi_print_string(sdp->OemId, ACPI_OEM_ID_SIZE);
411309f2089bScegger 	printf(", OEM Table ID=");
411409f2089bScegger 	acpi_print_string(sdp->OemTableId, ACPI_OEM_TABLE_ID_SIZE);
411509f2089bScegger 	printf(", OEM Revision=0x%x,\n", sdp->OemRevision);
411609f2089bScegger 	printf("\tCreator ID=");
41178ffd671aSdogcow 	acpi_print_string(sdp->AslCompilerId, ACPI_NAMESEG_SIZE);
411809f2089bScegger 	printf(", Creator Revision=0x%x\n", sdp->AslCompilerRevision);
411909f2089bScegger }
412009f2089bScegger 
4121055f8b85Smsaitoh void
acpi_print_tabs(unsigned int n)4122055f8b85Smsaitoh acpi_print_tabs(unsigned int n)
4123055f8b85Smsaitoh {
4124055f8b85Smsaitoh 
4125055f8b85Smsaitoh 	while (n-- > 0)
4126055f8b85Smsaitoh 		printf("\t");
4127055f8b85Smsaitoh }
4128055f8b85Smsaitoh 
412909f2089bScegger static void
acpi_dump_bytes(uint8_t * p,uint32_t len,unsigned int ntabs)4130055f8b85Smsaitoh acpi_dump_bytes(uint8_t *p, uint32_t len, unsigned int ntabs)
4131d91f7d52Sjmcneill {
4132d91f7d52Sjmcneill 	unsigned int i;
4133d91f7d52Sjmcneill 
4134055f8b85Smsaitoh 	acpi_print_tabs(ntabs);
4135055f8b85Smsaitoh 	printf("Data={");
4136055f8b85Smsaitoh 	for (i = 0; i < len; i++) {
4137d91f7d52Sjmcneill 		if (cflag) {
4138055f8b85Smsaitoh 			if (i % 64 == 0) {
4139055f8b85Smsaitoh 				printf("\n");
4140055f8b85Smsaitoh 				acpi_print_tabs(ntabs);
4141055f8b85Smsaitoh 				printf(" ");
4142055f8b85Smsaitoh 			}else if (i % 16 == 0)
4143d91f7d52Sjmcneill 				printf(" ");
4144d91f7d52Sjmcneill 			printf("%c", (p[i] >= ' ' && p[i] <= '~') ? p[i] : '.');
4145d91f7d52Sjmcneill 		} else {
4146055f8b85Smsaitoh 			if (i % 16 == 0) {
4147055f8b85Smsaitoh 				printf("\n");
4148055f8b85Smsaitoh 				acpi_print_tabs(ntabs + 1);
4149055f8b85Smsaitoh 			} else if (i % 8 == 0)
4150d91f7d52Sjmcneill 				printf("   ");
4151d91f7d52Sjmcneill 			printf(" %02x", p[i]);
4152d91f7d52Sjmcneill 		}
4153d91f7d52Sjmcneill 	}
4154055f8b85Smsaitoh 	printf("\n");
4155055f8b85Smsaitoh 	acpi_print_tabs(ntabs);
4156055f8b85Smsaitoh 	printf("}\n");
4157055f8b85Smsaitoh }
4158055f8b85Smsaitoh 
4159055f8b85Smsaitoh /* Dump data which has ACPI_TABLE_HEADER */
4160055f8b85Smsaitoh static void
acpi_dump_table(ACPI_TABLE_HEADER * sdp)4161055f8b85Smsaitoh acpi_dump_table(ACPI_TABLE_HEADER *sdp)
4162055f8b85Smsaitoh {
4163055f8b85Smsaitoh 
4164055f8b85Smsaitoh 	acpi_dump_bytes((uint8_t *)sdp, sdp->Length, 1);
4165d91f7d52Sjmcneill }
4166d91f7d52Sjmcneill 
4167d91f7d52Sjmcneill static void
acpi_print_rsdt(ACPI_TABLE_HEADER * rsdp)416809f2089bScegger acpi_print_rsdt(ACPI_TABLE_HEADER *rsdp)
416909f2089bScegger {
417009f2089bScegger 	ACPI_TABLE_RSDT *rsdt;
417109f2089bScegger 	ACPI_TABLE_XSDT *xsdt;
417209f2089bScegger 	int	i, entries;
417309f2089bScegger 
417409f2089bScegger 	rsdt = (ACPI_TABLE_RSDT *)rsdp;
417509f2089bScegger 	xsdt = (ACPI_TABLE_XSDT *)rsdp;
417609f2089bScegger 	printf(BEGIN_COMMENT);
417709f2089bScegger 	acpi_print_sdt(rsdp);
417809f2089bScegger 	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
417953e202c1Schristos 	printf("\tEntries={ ");
418053e202c1Schristos 	for (i = 0; i < entries; i++) {
418153e202c1Schristos 		if (i > 0)
418253e202c1Schristos 			printf(", ");
4183c359a213Smsaitoh 		if (addr_size == 4)
4184c359a213Smsaitoh 			printf("0x%08x", le32toh(rsdt->TableOffsetEntry[i]));
4185c359a213Smsaitoh 		else
4186c359a213Smsaitoh 			printf("0x%016jx",
4187c359a213Smsaitoh 			    (uintmax_t)le64toh(xsdt->TableOffsetEntry[i]));
418853e202c1Schristos 	}
418953e202c1Schristos 	printf(" }\n");
419053e202c1Schristos 	printf(END_COMMENT);
419153e202c1Schristos }
419253e202c1Schristos 
419309f2089bScegger static const char *acpi_pm_profiles[] = {
419409f2089bScegger 	"Unspecified", "Desktop", "Mobile", "Workstation",
4195ff98ea46Smsaitoh 	"Enterprise Server", "SOHO Server", "Appliance PC",
4196ff98ea46Smsaitoh 	"Performance Server", "Tablet"
419709f2089bScegger };
419809f2089bScegger 
419909f2089bScegger static void
acpi_print_fadt(ACPI_TABLE_HEADER * sdp)420009f2089bScegger acpi_print_fadt(ACPI_TABLE_HEADER *sdp)
420153e202c1Schristos {
420209f2089bScegger 	ACPI_TABLE_FADT *fadt;
420309f2089bScegger 	const char *pm;
420453e202c1Schristos 
420509f2089bScegger 	fadt = (ACPI_TABLE_FADT *)sdp;
420653e202c1Schristos 	printf(BEGIN_COMMENT);
420709f2089bScegger 	acpi_print_sdt(sdp);
420809f2089bScegger 	printf(" \tFACS=0x%x, DSDT=0x%x\n", fadt->Facs,
420909f2089bScegger 	       fadt->Dsdt);
4210ff98ea46Smsaitoh 	/* XXX ACPI 2.0 eliminated this */
421109f2089bScegger 	printf("\tINT_MODEL=%s\n", fadt->Model ? "APIC" : "PIC");
421209f2089bScegger 	if (fadt->PreferredProfile >= sizeof(acpi_pm_profiles) / sizeof(char *))
421309f2089bScegger 		pm = "Reserved";
421409f2089bScegger 	else
421509f2089bScegger 		pm = acpi_pm_profiles[fadt->PreferredProfile];
421609f2089bScegger 	printf("\tPreferred_PM_Profile=%s (%d)\n", pm, fadt->PreferredProfile);
421709f2089bScegger 	printf("\tSCI_INT=%d\n", fadt->SciInterrupt);
421809f2089bScegger 	printf("\tSMI_CMD=0x%x, ", fadt->SmiCommand);
421909f2089bScegger 	printf("ACPI_ENABLE=0x%x, ", fadt->AcpiEnable);
422009f2089bScegger 	printf("ACPI_DISABLE=0x%x, ", fadt->AcpiDisable);
422109f2089bScegger 	printf("S4BIOS_REQ=0x%x\n", fadt->S4BiosRequest);
422209f2089bScegger 	printf("\tPSTATE_CNT=0x%x\n", fadt->PstateControl);
422353e202c1Schristos 	printf("\tPM1a_EVT_BLK=0x%x-0x%x\n",
422409f2089bScegger 	       fadt->Pm1aEventBlock,
422509f2089bScegger 	       fadt->Pm1aEventBlock + fadt->Pm1EventLength - 1);
422609f2089bScegger 	if (fadt->Pm1bEventBlock != 0)
422753e202c1Schristos 		printf("\tPM1b_EVT_BLK=0x%x-0x%x\n",
422809f2089bScegger 		       fadt->Pm1bEventBlock,
422909f2089bScegger 		       fadt->Pm1bEventBlock + fadt->Pm1EventLength - 1);
423053e202c1Schristos 	printf("\tPM1a_CNT_BLK=0x%x-0x%x\n",
423109f2089bScegger 	       fadt->Pm1aControlBlock,
423209f2089bScegger 	       fadt->Pm1aControlBlock + fadt->Pm1ControlLength - 1);
423309f2089bScegger 	if (fadt->Pm1bControlBlock != 0)
423453e202c1Schristos 		printf("\tPM1b_CNT_BLK=0x%x-0x%x\n",
423509f2089bScegger 		       fadt->Pm1bControlBlock,
423609f2089bScegger 		       fadt->Pm1bControlBlock + fadt->Pm1ControlLength - 1);
423709f2089bScegger 	if (fadt->Pm2ControlBlock != 0)
423853e202c1Schristos 		printf("\tPM2_CNT_BLK=0x%x-0x%x\n",
423909f2089bScegger 		       fadt->Pm2ControlBlock,
424009f2089bScegger 		       fadt->Pm2ControlBlock + fadt->Pm2ControlLength - 1);
424127cdf6cfSmsaitoh 	if (fadt->PmTimerBlock != 0)
424209f2089bScegger 		printf("\tPM_TMR_BLK=0x%x-0x%x\n",
424309f2089bScegger 		    fadt->PmTimerBlock,
424409f2089bScegger 		    fadt->PmTimerBlock + fadt->PmTimerLength - 1);
424509f2089bScegger 	if (fadt->Gpe0Block != 0)
424609f2089bScegger 		printf("\tGPE0_BLK=0x%x-0x%x\n",
424709f2089bScegger 		       fadt->Gpe0Block,
424809f2089bScegger 		       fadt->Gpe0Block + fadt->Gpe0BlockLength - 1);
424909f2089bScegger 	if (fadt->Gpe1Block != 0)
425009f2089bScegger 		printf("\tGPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n",
425109f2089bScegger 		       fadt->Gpe1Block,
425209f2089bScegger 		       fadt->Gpe1Block + fadt->Gpe1BlockLength - 1,
425309f2089bScegger 		       fadt->Gpe1Base);
425409f2089bScegger 	if (fadt->CstControl != 0)
425509f2089bScegger 		printf("\tCST_CNT=0x%x\n", fadt->CstControl);
425609f2089bScegger 	printf("\tP_LVL2_LAT=%d us, P_LVL3_LAT=%d us\n",
425709f2089bScegger 	       fadt->C2Latency, fadt->C3Latency);
425853e202c1Schristos 	printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n",
425909f2089bScegger 	       fadt->FlushSize, fadt->FlushStride);
426053e202c1Schristos 	printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n",
426109f2089bScegger 	       fadt->DutyOffset, fadt->DutyWidth);
426253e202c1Schristos 	printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n",
426309f2089bScegger 	       fadt->DayAlarm, fadt->MonthAlarm, fadt->Century);
426453e202c1Schristos 
4265c359a213Smsaitoh #define PRINTFLAG(var, flag)	printflag((var), ACPI_FADT_## flag, #flag)
426653e202c1Schristos 
426709f2089bScegger 	printf("\tIAPC_BOOT_ARCH=");
426809f2089bScegger 	PRINTFLAG(fadt->BootFlags, LEGACY_DEVICES);
426909f2089bScegger 	PRINTFLAG(fadt->BootFlags, 8042);
427009f2089bScegger 	PRINTFLAG(fadt->BootFlags, NO_VGA);
427109f2089bScegger 	PRINTFLAG(fadt->BootFlags, NO_MSI);
427209f2089bScegger 	PRINTFLAG(fadt->BootFlags, NO_ASPM);
4273c359a213Smsaitoh 	PRINTFLAG(fadt->BootFlags, NO_CMOS_RTC);
4274c359a213Smsaitoh 	PRINTFLAG_END();
427509f2089bScegger 
427609f2089bScegger 	printf("\tFlags=");
427709f2089bScegger 	PRINTFLAG(fadt->Flags, WBINVD);
427809f2089bScegger 	PRINTFLAG(fadt->Flags, WBINVD_FLUSH);
427909f2089bScegger 	PRINTFLAG(fadt->Flags, C1_SUPPORTED);
428009f2089bScegger 	PRINTFLAG(fadt->Flags, C2_MP_SUPPORTED);
428109f2089bScegger 	PRINTFLAG(fadt->Flags, POWER_BUTTON);
428209f2089bScegger 	PRINTFLAG(fadt->Flags, SLEEP_BUTTON);
428309f2089bScegger 	PRINTFLAG(fadt->Flags, FIXED_RTC);
428409f2089bScegger 	PRINTFLAG(fadt->Flags, S4_RTC_WAKE);
428509f2089bScegger 	PRINTFLAG(fadt->Flags, 32BIT_TIMER);
428609f2089bScegger 	PRINTFLAG(fadt->Flags, DOCKING_SUPPORTED);
428709f2089bScegger 	PRINTFLAG(fadt->Flags, RESET_REGISTER);
428809f2089bScegger 	PRINTFLAG(fadt->Flags, SEALED_CASE);
428909f2089bScegger 	PRINTFLAG(fadt->Flags, HEADLESS);
429009f2089bScegger 	PRINTFLAG(fadt->Flags, SLEEP_TYPE);
429109f2089bScegger 	PRINTFLAG(fadt->Flags, PCI_EXPRESS_WAKE);
429209f2089bScegger 	PRINTFLAG(fadt->Flags, PLATFORM_CLOCK);
429309f2089bScegger 	PRINTFLAG(fadt->Flags, S4_RTC_VALID);
429409f2089bScegger 	PRINTFLAG(fadt->Flags, REMOTE_POWER_ON);
429509f2089bScegger 	PRINTFLAG(fadt->Flags, APIC_CLUSTER);
429609f2089bScegger 	PRINTFLAG(fadt->Flags, APIC_PHYSICAL);
4297c359a213Smsaitoh 	PRINTFLAG(fadt->Flags, HW_REDUCED);
4298c359a213Smsaitoh 	PRINTFLAG(fadt->Flags, LOW_POWER_S0);
4299c359a213Smsaitoh 	PRINTFLAG_END();
430053e202c1Schristos 
4301ff98ea46Smsaitoh 	if (sdp->Length < ACPI_FADT_V2_SIZE)
4302ff98ea46Smsaitoh 		goto out;
430353e202c1Schristos 
430409f2089bScegger 	if (fadt->Flags & ACPI_FADT_RESET_REGISTER) {
430509f2089bScegger 		printf("\tRESET_REG=");
430609f2089bScegger 		acpi_print_gas(&fadt->ResetRegister);
430709f2089bScegger 		printf(", RESET_VALUE=%#x\n", fadt->ResetValue);
430809f2089bScegger 	}
4309ff98ea46Smsaitoh 
4310ff98ea46Smsaitoh 	printf("\tArmBootFlags=");
4311ff98ea46Smsaitoh 	PRINTFLAG(fadt->ArmBootFlags, PSCI_COMPLIANT);
4312ff98ea46Smsaitoh 	PRINTFLAG(fadt->ArmBootFlags, PSCI_USE_HVC);
4313ff98ea46Smsaitoh 	PRINTFLAG_END();
4314ff98ea46Smsaitoh 
4315ff98ea46Smsaitoh #undef PRINTFLAG
4316ff98ea46Smsaitoh 
4317ff98ea46Smsaitoh 	printf("\tMinorRevision=%u\n", fadt->MinorRevision);
4318ff98ea46Smsaitoh 
4319ff98ea46Smsaitoh 	if (sdp->Length < ACPI_FADT_V3_SIZE)
4320ff98ea46Smsaitoh 		goto out;
4321ff98ea46Smsaitoh 
4322c359a213Smsaitoh 	printf("\tX_FACS=0x%016jx, ", (uintmax_t)fadt->XFacs);
4323c359a213Smsaitoh 	printf("X_DSDT=0x%016jx\n", (uintmax_t)fadt->XDsdt);
432409f2089bScegger 	printf("\tX_PM1a_EVT_BLK=");
432509f2089bScegger 	acpi_print_gas(&fadt->XPm1aEventBlock);
432609f2089bScegger 	if (fadt->XPm1bEventBlock.Address != 0) {
432709f2089bScegger 		printf("\n\tX_PM1b_EVT_BLK=");
432809f2089bScegger 		acpi_print_gas(&fadt->XPm1bEventBlock);
432909f2089bScegger 	}
433009f2089bScegger 	printf("\n\tX_PM1a_CNT_BLK=");
433109f2089bScegger 	acpi_print_gas(&fadt->XPm1aControlBlock);
433209f2089bScegger 	if (fadt->XPm1bControlBlock.Address != 0) {
433309f2089bScegger 		printf("\n\tX_PM1b_CNT_BLK=");
433409f2089bScegger 		acpi_print_gas(&fadt->XPm1bControlBlock);
433509f2089bScegger 	}
433609f2089bScegger 	if (fadt->XPm2ControlBlock.Address != 0) {
433709f2089bScegger 		printf("\n\tX_PM2_CNT_BLK=");
433809f2089bScegger 		acpi_print_gas(&fadt->XPm2ControlBlock);
433909f2089bScegger 	}
4340bf819d34Smsaitoh 	if (fadt->XPmTimerBlock.Address != 0) {
434109f2089bScegger 		printf("\n\tX_PM_TMR_BLK=");
434209f2089bScegger 		acpi_print_gas(&fadt->XPmTimerBlock);
4343bf819d34Smsaitoh 	}
434409f2089bScegger 	if (fadt->XGpe0Block.Address != 0) {
434509f2089bScegger 		printf("\n\tX_GPE0_BLK=");
434609f2089bScegger 		acpi_print_gas(&fadt->XGpe0Block);
434709f2089bScegger 	}
434809f2089bScegger 	if (fadt->XGpe1Block.Address != 0) {
434909f2089bScegger 		printf("\n\tX_GPE1_BLK=");
435009f2089bScegger 		acpi_print_gas(&fadt->XGpe1Block);
435109f2089bScegger 	}
435209f2089bScegger 	printf("\n");
4353ff98ea46Smsaitoh 
4354ff98ea46Smsaitoh 	if (sdp->Length < ACPI_FADT_V5_SIZE)
4355ff98ea46Smsaitoh 		goto out;
4356ff98ea46Smsaitoh 
4357ff98ea46Smsaitoh 	if (fadt->SleepControl.Address != 0) {
4358ff98ea46Smsaitoh 		printf("\tSleepControl=");
4359ff98ea46Smsaitoh 		acpi_print_gas(&fadt->SleepControl);
4360ff98ea46Smsaitoh 		printf("\n");
4361ff98ea46Smsaitoh 	}
4362ff98ea46Smsaitoh 	if (fadt->SleepStatus.Address != 0) {
4363ff98ea46Smsaitoh 		printf("\n\tSleepStatus=");
4364ff98ea46Smsaitoh 		acpi_print_gas(&fadt->SleepStatus);
4365ff98ea46Smsaitoh 		printf("\n");
436609f2089bScegger 	}
436709f2089bScegger 
4368ff98ea46Smsaitoh 	if (sdp->Length < ACPI_FADT_V6_SIZE)
4369ff98ea46Smsaitoh 		goto out;
4370ff98ea46Smsaitoh 
4371ff98ea46Smsaitoh 	printf("\tHypervisorId=0x%016"PRIx64"\n", fadt->HypervisorId);
4372ff98ea46Smsaitoh 
4373ff98ea46Smsaitoh out:
437453e202c1Schristos 	printf(END_COMMENT);
437553e202c1Schristos }
437653e202c1Schristos 
437709f2089bScegger static void
acpi_print_facs(ACPI_TABLE_FACS * facs)437809f2089bScegger acpi_print_facs(ACPI_TABLE_FACS *facs)
437953e202c1Schristos {
438009f2089bScegger 	printf(BEGIN_COMMENT);
438109f2089bScegger 	printf("  FACS:\tLength=%u, ", facs->Length);
438209f2089bScegger 	printf("HwSig=0x%08x, ", facs->HardwareSignature);
438309f2089bScegger 	printf("Firm_Wake_Vec=0x%08x\n", facs->FirmwareWakingVector);
438453e202c1Schristos 
4385ff98ea46Smsaitoh #define PRINTFLAG(var, flag)	printflag((var), ACPI_GLOCK_## flag, #flag)
4386ff98ea46Smsaitoh 
438709f2089bScegger 	printf("\tGlobal_Lock=");
4388ff98ea46Smsaitoh 	PRINTFLAG(facs->GlobalLock, PENDING);
4389ff98ea46Smsaitoh 	PRINTFLAG(facs->GlobalLock, OWNED);
4390ff98ea46Smsaitoh 	PRINTFLAG_END();
4391ff98ea46Smsaitoh 
4392ff98ea46Smsaitoh #undef PRINTFLAG
4393ff98ea46Smsaitoh 
4394ff98ea46Smsaitoh #define PRINTFLAG(var, flag)	printflag((var), ACPI_FACS_## flag, #flag)
439509f2089bScegger 
439609f2089bScegger 	printf("\tFlags=");
4397ff98ea46Smsaitoh 	PRINTFLAG(facs->Flags, S4_BIOS_PRESENT);
4398ff98ea46Smsaitoh 	PRINTFLAG(facs->Flags, 64BIT_WAKE);
4399ff98ea46Smsaitoh 	PRINTFLAG_END();
4400ff98ea46Smsaitoh 
4401ff98ea46Smsaitoh #undef PRINTFLAG
440209f2089bScegger 
4403c359a213Smsaitoh 	if (facs->XFirmwareWakingVector != 0)
4404c359a213Smsaitoh 		printf("\tX_Firm_Wake_Vec=%016jx\n",
4405c359a213Smsaitoh 		    (uintmax_t)facs->XFirmwareWakingVector);
440609f2089bScegger 	printf("\tVersion=%u\n", facs->Version);
440709f2089bScegger 
4408ff98ea46Smsaitoh 	printf("\tOspmFlags={");
4409ff98ea46Smsaitoh 	if (facs->OspmFlags & ACPI_FACS_64BIT_ENVIRONMENT)
4410ff98ea46Smsaitoh 		printf("64BIT_WAKE");
4411ff98ea46Smsaitoh 	printf("}\n");
4412ff98ea46Smsaitoh 
441309f2089bScegger 	printf(END_COMMENT);
441409f2089bScegger }
441509f2089bScegger 
441609f2089bScegger static void
acpi_print_dsdt(ACPI_TABLE_HEADER * dsdp)441709f2089bScegger acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp)
441809f2089bScegger {
441909f2089bScegger 	printf(BEGIN_COMMENT);
442053e202c1Schristos 	acpi_print_sdt(dsdp);
442109f2089bScegger 	printf(END_COMMENT);
442253e202c1Schristos }
442353e202c1Schristos 
442453e202c1Schristos int
acpi_checksum(void * p,size_t length)442553e202c1Schristos acpi_checksum(void *p, size_t length)
442653e202c1Schristos {
442709f2089bScegger 	uint8_t *bp;
442809f2089bScegger 	uint8_t sum;
442953e202c1Schristos 
443053e202c1Schristos 	bp = p;
443153e202c1Schristos 	sum = 0;
443253e202c1Schristos 	while (length--)
443353e202c1Schristos 		sum += *bp++;
443453e202c1Schristos 
443553e202c1Schristos 	return (sum);
443653e202c1Schristos }
443753e202c1Schristos 
443809f2089bScegger static ACPI_TABLE_HEADER *
acpi_map_sdt(vm_offset_t pa)443953e202c1Schristos acpi_map_sdt(vm_offset_t pa)
444053e202c1Schristos {
444109f2089bScegger 	ACPI_TABLE_HEADER *sp;
444253e202c1Schristos 
444309f2089bScegger 	sp = acpi_map_physical(pa, sizeof(ACPI_TABLE_HEADER));
444409f2089bScegger 	sp = acpi_map_physical(pa, sp->Length);
444553e202c1Schristos 	return (sp);
444653e202c1Schristos }
444753e202c1Schristos 
444809f2089bScegger static void
acpi_print_rsd_ptr(ACPI_TABLE_RSDP * rp)444909f2089bScegger acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp)
445053e202c1Schristos {
445153e202c1Schristos 	printf(BEGIN_COMMENT);
445209f2089bScegger 	printf("  RSD PTR: OEM=");
445309f2089bScegger 	acpi_print_string(rp->OemId, ACPI_OEM_ID_SIZE);
445409f2089bScegger 	printf(", ACPI_Rev=%s (%d)\n", rp->Revision < 2 ? "1.0x" : "2.0x",
445509f2089bScegger 	       rp->Revision);
445609f2089bScegger 	if (rp->Revision < 2) {
445709f2089bScegger 		printf("\tRSDT=0x%08x, cksum=%u\n", rp->RsdtPhysicalAddress,
445809f2089bScegger 		    rp->Checksum);
445909f2089bScegger 	} else {
4460c359a213Smsaitoh 		printf("\tXSDT=0x%016jx, length=%u, cksum=%u\n",
4461c359a213Smsaitoh 		    (uintmax_t)rp->XsdtPhysicalAddress, rp->Length,
446209f2089bScegger 		    rp->ExtendedChecksum);
446309f2089bScegger 	}
446453e202c1Schristos 	printf(END_COMMENT);
446553e202c1Schristos }
446653e202c1Schristos 
446709f2089bScegger static void
acpi_handle_rsdt(ACPI_TABLE_HEADER * rsdp)446809f2089bScegger acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp)
446953e202c1Schristos {
447009f2089bScegger 	ACPI_TABLE_HEADER *sdp;
447109f2089bScegger 	ACPI_TABLE_RSDT *rsdt;
447209f2089bScegger 	ACPI_TABLE_XSDT *xsdt;
4473bdb04d1cSchristos 	vm_offset_t addr = 0;
447409f2089bScegger 	int entries, i;
447553e202c1Schristos 
447653e202c1Schristos 	acpi_print_rsdt(rsdp);
447709f2089bScegger 	rsdt = (ACPI_TABLE_RSDT *)rsdp;
447809f2089bScegger 	xsdt = (ACPI_TABLE_XSDT *)rsdp;
447909f2089bScegger 	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
448053e202c1Schristos 	for (i = 0; i < entries; i++) {
4481c359a213Smsaitoh 		if (addr_size == 4)
448209f2089bScegger 			addr = le32toh(rsdt->TableOffsetEntry[i]);
4483c359a213Smsaitoh 		else
448409f2089bScegger 			addr = le64toh(xsdt->TableOffsetEntry[i]);
4485c359a213Smsaitoh 		if (addr == 0)
4486c359a213Smsaitoh 			continue;
448709f2089bScegger 		sdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
448809f2089bScegger 		if (acpi_checksum(sdp, sdp->Length)) {
448909f2089bScegger 			warnx("RSDT entry %d (sig %.4s) is corrupt", i,
449009f2089bScegger 			    sdp->Signature);
4491d34a996fSjmcneill 			if (sflag)
4492e6c80518Sdrochner 				continue;
4493e6c80518Sdrochner 		}
449409f2089bScegger 		if (!memcmp(sdp->Signature, ACPI_SIG_FADT, 4))
449509f2089bScegger 			acpi_handle_fadt(sdp);
449609f2089bScegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_BERT, 4))
449709f2089bScegger 			acpi_handle_bert(sdp);
4498755dd632Smsaitoh 		else if (!memcmp(sdp->Signature, ACPI_SIG_BGRT, 4))
4499755dd632Smsaitoh 			acpi_handle_bgrt(sdp);
450009f2089bScegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_BOOT, 4))
450109f2089bScegger 			acpi_handle_boot(sdp);
450209f2089bScegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_CPEP, 4))
450309f2089bScegger 			acpi_handle_cpep(sdp);
4504055f8b85Smsaitoh 		else if (!memcmp(sdp->Signature, ACPI_SIG_CSRT, 4))
4505055f8b85Smsaitoh 			acpi_handle_csrt(sdp);
450609f2089bScegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_DBGP, 4))
450709f2089bScegger 			acpi_handle_dbgp(sdp);
45085d527485Smsaitoh 		else if (!memcmp(sdp->Signature, ACPI_SIG_DBG2, 4))
45095d527485Smsaitoh 			acpi_handle_dbg2(sdp);
4510c359a213Smsaitoh 		else if (!memcmp(sdp->Signature, ACPI_SIG_DMAR, 4))
4511c359a213Smsaitoh 			acpi_handle_dmar(sdp);
451209f2089bScegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_EINJ, 4))
451309f2089bScegger 			acpi_handle_einj(sdp);
451409f2089bScegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_ERST, 4))
451509f2089bScegger 			acpi_handle_erst(sdp);
4516aba8816bSmsaitoh 		else if (!memcmp(sdp->Signature, ACPI_SIG_GTDT, 4))
4517aba8816bSmsaitoh 			acpi_handle_gtdt(sdp);
451809f2089bScegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_MADT, 4))
451909f2089bScegger 			acpi_handle_madt(sdp);
452009f2089bScegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_MSCT, 4))
452109f2089bScegger 			acpi_handle_msct(sdp);
452209f2089bScegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_HEST, 4))
452309f2089bScegger 			acpi_handle_hest(sdp);
452409f2089bScegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_HPET, 4))
452509f2089bScegger 			acpi_handle_hpet(sdp);
4526c0f969c5Smsaitoh 		else if (!memcmp(sdp->Signature, ACPI_SIG_IORT, 4))
4527c0f969c5Smsaitoh 			acpi_handle_iort(sdp);
452809f2089bScegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_ECDT, 4))
452909f2089bScegger 			acpi_handle_ecdt(sdp);
45303de33cabSmsaitoh 		else if (!memcmp(sdp->Signature, ACPI_SIG_LPIT, 4))
45313de33cabSmsaitoh 			acpi_handle_lpit(sdp);
453209f2089bScegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_MCFG, 4))
453309f2089bScegger 			acpi_handle_mcfg(sdp);
45340eb6f089Sjmcneill 		else if (!memcmp(sdp->Signature, ACPI_SIG_PCCT, 4))
45350eb6f089Sjmcneill 			acpi_handle_pcct(sdp);
4536aba8816bSmsaitoh 		else if (!memcmp(sdp->Signature, ACPI_SIG_PPTT, 4))
4537aba8816bSmsaitoh 			acpi_handle_pptt(sdp);
453809f2089bScegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_SBST, 4))
453909f2089bScegger 			acpi_handle_sbst(sdp);
454009f2089bScegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_SLIT, 4))
454109f2089bScegger 			acpi_handle_slit(sdp);
454209f2089bScegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_SPCR, 4))
454309f2089bScegger 			acpi_handle_spcr(sdp);
45445d527485Smsaitoh 		else if (!memcmp(sdp->Signature, ACPI_SIG_SPMI, 4))
45455d527485Smsaitoh 			acpi_handle_spmi(sdp);
454609f2089bScegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_SRAT, 4))
454709f2089bScegger 			acpi_handle_srat(sdp);
454809f2089bScegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_TCPA, 4))
454909f2089bScegger 			acpi_handle_tcpa(sdp);
45500e3f83efSmaxv 		else if (!memcmp(sdp->Signature, ACPI_SIG_TPM2, 4))
45510e3f83efSmaxv 			acpi_handle_tpm2(sdp);
4552792e611dSmsaitoh 		else if (!memcmp(sdp->Signature, ACPI_SIG_NFIT, 4))
4553792e611dSmsaitoh 			acpi_handle_nfit(sdp);
45545d527485Smsaitoh 		else if (!memcmp(sdp->Signature, ACPI_SIG_UEFI, 4))
45555d527485Smsaitoh 			acpi_handle_uefi(sdp);
455609f2089bScegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_WAET, 4))
455709f2089bScegger 			acpi_handle_waet(sdp);
455809f2089bScegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_WDAT, 4))
455909f2089bScegger 			acpi_handle_wdat(sdp);
45605d527485Smsaitoh 		else if (!memcmp(sdp->Signature, ACPI_SIG_WDDT, 4))
45615d527485Smsaitoh 			acpi_handle_wddt(sdp);
456209f2089bScegger 		else if (!memcmp(sdp->Signature, ACPI_SIG_WDRT, 4))
456309f2089bScegger 			acpi_handle_wdrt(sdp);
456409f2089bScegger 		else {
456509f2089bScegger 			printf(BEGIN_COMMENT);
456653e202c1Schristos 			acpi_print_sdt(sdp);
4567055f8b85Smsaitoh 			printf("\n");
4568055f8b85Smsaitoh 			acpi_dump_table(sdp);
456909f2089bScegger 			printf(END_COMMENT);
457053e202c1Schristos 		}
457153e202c1Schristos 	}
457253e202c1Schristos }
457353e202c1Schristos 
457409f2089bScegger ACPI_TABLE_HEADER *
sdt_load_devmem(void)457509f2089bScegger sdt_load_devmem(void)
457609f2089bScegger {
457709f2089bScegger 	ACPI_TABLE_RSDP *rp;
457809f2089bScegger 	ACPI_TABLE_HEADER *rsdp;
457909f2089bScegger 
458009f2089bScegger 	rp = acpi_find_rsd_ptr();
458109f2089bScegger 	if (!rp)
458209f2089bScegger 		errx(EXIT_FAILURE, "Can't find ACPI information");
458309f2089bScegger 
458409f2089bScegger 	if (tflag)
458509f2089bScegger 		acpi_print_rsd_ptr(rp);
458609f2089bScegger 	if (rp->Revision < 2) {
458709f2089bScegger 		rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->RsdtPhysicalAddress);
458809f2089bScegger 		if (memcmp(rsdp->Signature, "RSDT", 4) != 0 ||
458909f2089bScegger 		    acpi_checksum(rsdp, rsdp->Length) != 0)
459009f2089bScegger 			errx(EXIT_FAILURE, "RSDT is corrupted");
459109f2089bScegger 		addr_size = sizeof(uint32_t);
459209f2089bScegger 	} else {
459309f2089bScegger 		rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->XsdtPhysicalAddress);
459409f2089bScegger 		if (memcmp(rsdp->Signature, "XSDT", 4) != 0 ||
459509f2089bScegger 		    acpi_checksum(rsdp, rsdp->Length) != 0)
459609f2089bScegger 			errx(EXIT_FAILURE, "XSDT is corrupted");
459709f2089bScegger 		addr_size = sizeof(uint64_t);
459809f2089bScegger 	}
459909f2089bScegger 	return (rsdp);
460009f2089bScegger }
460109f2089bScegger 
460209f2089bScegger /* Write the DSDT to a file, concatenating any SSDTs (if present). */
460309f2089bScegger static int
write_dsdt(int fd,ACPI_TABLE_HEADER * rsdt,ACPI_TABLE_HEADER * dsdt)460409f2089bScegger write_dsdt(int fd, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdt)
460509f2089bScegger {
460609f2089bScegger 	ACPI_TABLE_HEADER sdt;
460709f2089bScegger 	ACPI_TABLE_HEADER *ssdt;
460809f2089bScegger 	uint8_t sum;
460909f2089bScegger 
461009f2089bScegger 	/* Create a new checksum to account for the DSDT and any SSDTs. */
461109f2089bScegger 	sdt = *dsdt;
461209f2089bScegger 	if (rsdt != NULL) {
461309f2089bScegger 		sdt.Checksum = 0;
461409f2089bScegger 		sum = acpi_checksum(dsdt + 1, dsdt->Length -
461509f2089bScegger 		    sizeof(ACPI_TABLE_HEADER));
461609f2089bScegger 		ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, NULL);
461709f2089bScegger 		while (ssdt != NULL) {
461809f2089bScegger 			sdt.Length += ssdt->Length - sizeof(ACPI_TABLE_HEADER);
461909f2089bScegger 			sum += acpi_checksum(ssdt + 1,
462009f2089bScegger 			    ssdt->Length - sizeof(ACPI_TABLE_HEADER));
462109f2089bScegger 			ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, ssdt);
462209f2089bScegger 		}
462309f2089bScegger 		sum += acpi_checksum(&sdt, sizeof(ACPI_TABLE_HEADER));
462409f2089bScegger 		sdt.Checksum -= sum;
462509f2089bScegger 	}
462609f2089bScegger 
462709f2089bScegger 	/* Write out the DSDT header and body. */
462809f2089bScegger 	write(fd, &sdt, sizeof(ACPI_TABLE_HEADER));
462909f2089bScegger 	write(fd, dsdt + 1, dsdt->Length - sizeof(ACPI_TABLE_HEADER));
463009f2089bScegger 
463109f2089bScegger 	/* Write out any SSDTs (if present.) */
463209f2089bScegger 	if (rsdt != NULL) {
463391ad7c9eSskrll 		ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, NULL);
463409f2089bScegger 		while (ssdt != NULL) {
463509f2089bScegger 			write(fd, ssdt + 1, ssdt->Length -
463609f2089bScegger 			    sizeof(ACPI_TABLE_HEADER));
463791ad7c9eSskrll 			ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, ssdt);
463809f2089bScegger 		}
463909f2089bScegger 	}
464009f2089bScegger 	return (0);
464109f2089bScegger }
464253e202c1Schristos 
464353e202c1Schristos void
dsdt_save_file(char * outfile,ACPI_TABLE_HEADER * rsdt,ACPI_TABLE_HEADER * dsdp)464409f2089bScegger dsdt_save_file(char *outfile, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
464553e202c1Schristos {
464609f2089bScegger 	int	fd;
464709f2089bScegger 	mode_t	mode;
464809f2089bScegger 
464909f2089bScegger 	assert(outfile != NULL);
465009f2089bScegger 	mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
465109f2089bScegger 	fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, mode);
465209f2089bScegger 	if (fd == -1) {
465309f2089bScegger 		perror("dsdt_save_file");
465409f2089bScegger 		return;
465509f2089bScegger 	}
465609f2089bScegger 	write_dsdt(fd, rsdt, dsdp);
465709f2089bScegger 	close(fd);
465853e202c1Schristos }
465953e202c1Schristos 
466009f2089bScegger void
aml_disassemble(ACPI_TABLE_HEADER * rsdt,ACPI_TABLE_HEADER * dsdp)466109f2089bScegger aml_disassemble(ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
466253e202c1Schristos {
4663c359a213Smsaitoh 	char buf[MAXPATHLEN], tmpstr[MAXPATHLEN], wrkdir[MAXPATHLEN];
4664c359a213Smsaitoh 	const char *iname = "/acpdump.din";
4665c359a213Smsaitoh 	const char *oname = "/acpdump.dsl";
466609f2089bScegger 	const char *tmpdir;
466709f2089bScegger 	FILE *fp;
466809f2089bScegger 	size_t len;
4669c359a213Smsaitoh 	int fd, status;
4670c359a213Smsaitoh 	pid_t pid;
467109f2089bScegger 
467209f2089bScegger 	if (rsdt == NULL)
467309f2089bScegger 		errx(EXIT_FAILURE, "aml_disassemble: invalid rsdt");
467409f2089bScegger 	if (dsdp == NULL)
467509f2089bScegger 		errx(EXIT_FAILURE, "aml_disassemble: invalid dsdp");
467609f2089bScegger 
467709f2089bScegger 	tmpdir = getenv("TMPDIR");
467809f2089bScegger 	if (tmpdir == NULL)
467909f2089bScegger 		tmpdir = _PATH_TMP;
4680c359a213Smsaitoh 	if (realpath(tmpdir, buf) == NULL) {
4681c359a213Smsaitoh 		perror("realpath tmp dir");
468209f2089bScegger 		return;
468309f2089bScegger 	}
4684c359a213Smsaitoh 	len = sizeof(wrkdir) - strlen(iname);
4685c359a213Smsaitoh 	if ((size_t)snprintf(wrkdir, len, "%s/acpidump.XXXXXX", buf) > len-1 ) {
4686c359a213Smsaitoh 		fprintf(stderr, "$TMPDIR too long\n");
4687c359a213Smsaitoh 		return;
4688c359a213Smsaitoh 	}
4689c359a213Smsaitoh 	if  (mkdtemp(wrkdir) == NULL) {
4690c359a213Smsaitoh 		perror("mkdtemp tmp working dir");
4691c359a213Smsaitoh 		return;
4692c359a213Smsaitoh 	}
4693c359a213Smsaitoh 	len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, iname);
4694c359a213Smsaitoh 	assert(len <= sizeof(tmpstr) - 1);
4695c359a213Smsaitoh 	fd = open(tmpstr, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
469609f2089bScegger 	if (fd < 0) {
469709f2089bScegger 		perror("iasl tmp file");
469809f2089bScegger 		return;
469909f2089bScegger 	}
470009f2089bScegger 	write_dsdt(fd, rsdt, dsdp);
470109f2089bScegger 	close(fd);
470209f2089bScegger 
470309f2089bScegger 	/* Run iasl -d on the temp file */
4704c359a213Smsaitoh 	if ((pid = fork()) == 0) {
470509f2089bScegger 		close(STDOUT_FILENO);
470609f2089bScegger 		if (vflag == 0)
470709f2089bScegger 			close(STDERR_FILENO);
470809f2089bScegger 		execl("/usr/bin/iasl", "iasl", "-d", tmpstr, NULL);
470909f2089bScegger 		err(EXIT_FAILURE, "exec");
471053e202c1Schristos 	}
4711c359a213Smsaitoh 	if (pid > 0)
4712c359a213Smsaitoh 		wait(&status);
4713c359a213Smsaitoh 	if (unlink(tmpstr) < 0) {
4714c359a213Smsaitoh 		perror("unlink");
4715c359a213Smsaitoh 		goto out;
4716c359a213Smsaitoh 	}
4717c359a213Smsaitoh 	if (pid < 0) {
4718c359a213Smsaitoh 		perror("fork");
4719c359a213Smsaitoh 		goto out;
4720c359a213Smsaitoh 	}
4721c359a213Smsaitoh 	if (status != 0) {
4722*636c2f2bSmsaitoh 		fprintf(stderr, "iasl exit status = %d\n", status);
4723c359a213Smsaitoh 	}
472409f2089bScegger 
472509f2089bScegger 	/* Dump iasl's output to stdout */
4726c359a213Smsaitoh 	len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, oname);
4727c359a213Smsaitoh 	assert(len <= sizeof(tmpstr) - 1);
472809f2089bScegger 	fp = fopen(tmpstr, "r");
4729c359a213Smsaitoh 	if (unlink(tmpstr) < 0) {
4730c359a213Smsaitoh 		perror("unlink");
4731c359a213Smsaitoh 		goto out;
4732c359a213Smsaitoh 	}
473309f2089bScegger 	if (fp == NULL) {
473409f2089bScegger 		perror("iasl tmp file (read)");
4735c359a213Smsaitoh 		goto out;
473609f2089bScegger 	}
473709f2089bScegger 	while ((len = fread(buf, 1, sizeof(buf), fp)) > 0)
473809f2089bScegger 		fwrite(buf, 1, len, stdout);
473909f2089bScegger 	fclose(fp);
4740c359a213Smsaitoh 
4741c359a213Smsaitoh     out:
4742c359a213Smsaitoh 	if (rmdir(wrkdir) < 0)
4743c359a213Smsaitoh 		perror("rmdir");
474453e202c1Schristos }
474553e202c1Schristos 
474609f2089bScegger void
sdt_print_all(ACPI_TABLE_HEADER * rsdp)474709f2089bScegger sdt_print_all(ACPI_TABLE_HEADER *rsdp)
474853e202c1Schristos {
474909f2089bScegger 	acpi_handle_rsdt(rsdp);
475053e202c1Schristos }
475153e202c1Schristos 
475209f2089bScegger /* Fetch a table matching the given signature via the RSDT. */
475309f2089bScegger ACPI_TABLE_HEADER *
sdt_from_rsdt(ACPI_TABLE_HEADER * rsdp,const char * sig,ACPI_TABLE_HEADER * last)475409f2089bScegger sdt_from_rsdt(ACPI_TABLE_HEADER *rsdp, const char *sig, ACPI_TABLE_HEADER *last)
475553e202c1Schristos {
475609f2089bScegger 	ACPI_TABLE_HEADER *sdt;
475709f2089bScegger 	ACPI_TABLE_RSDT *rsdt;
475809f2089bScegger 	ACPI_TABLE_XSDT *xsdt;
4759bdb04d1cSchristos 	vm_offset_t addr = 0;
476009f2089bScegger 	int entries, i;
476109f2089bScegger 
476209f2089bScegger 	rsdt = (ACPI_TABLE_RSDT *)rsdp;
476309f2089bScegger 	xsdt = (ACPI_TABLE_XSDT *)rsdp;
476409f2089bScegger 	entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
476509f2089bScegger 	for (i = 0; i < entries; i++) {
4766c359a213Smsaitoh 		if (addr_size == 4)
476709f2089bScegger 			addr = le32toh(rsdt->TableOffsetEntry[i]);
4768c359a213Smsaitoh 		else
476909f2089bScegger 			addr = le64toh(xsdt->TableOffsetEntry[i]);
4770c359a213Smsaitoh 		if (addr == 0)
4771c359a213Smsaitoh 			continue;
477209f2089bScegger 		sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
477309f2089bScegger 		if (last != NULL) {
477409f2089bScegger 			if (sdt == last)
477509f2089bScegger 				last = NULL;
477609f2089bScegger 			continue;
477709f2089bScegger 		}
477809f2089bScegger 		if (memcmp(sdt->Signature, sig, strlen(sig)))
477909f2089bScegger 			continue;
478009f2089bScegger 		if (acpi_checksum(sdt, sdt->Length))
478109f2089bScegger 			errx(EXIT_FAILURE, "RSDT entry %d is corrupt", i);
478209f2089bScegger 		return (sdt);
478353e202c1Schristos 	}
478453e202c1Schristos 
478509f2089bScegger 	return (NULL);
478653e202c1Schristos }
478753e202c1Schristos 
478809f2089bScegger ACPI_TABLE_HEADER *
dsdt_from_fadt(ACPI_TABLE_FADT * fadt)478909f2089bScegger dsdt_from_fadt(ACPI_TABLE_FADT *fadt)
479053e202c1Schristos {
479109f2089bScegger 	ACPI_TABLE_HEADER	*sdt;
479253e202c1Schristos 
479309f2089bScegger 	/* Use the DSDT address if it is version 1, otherwise use XDSDT. */
47948f0f46f9Smsaitoh 	sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(
47958f0f46f9Smsaitoh 		acpi_select_address(fadt->Dsdt, fadt->XDsdt));
479609f2089bScegger 	if (acpi_checksum(sdt, sdt->Length))
47978ee626c9Schristos 		errx(EXIT_FAILURE, "DSDT is corrupt");
479809f2089bScegger 	return (sdt);
479953e202c1Schristos }
4800