1e1e9a4bfSMitsuru IWASAKI /*-
24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
31de7b4b8SPedro F. Giffuni *
4e1e9a4bfSMitsuru IWASAKI * Copyright (c) 1998 Doug Rabson
5e1e9a4bfSMitsuru IWASAKI * Copyright (c) 2000 Mitsuru IWASAKI <iwasaki@FreeBSD.org>
6ebc22d04SAlexander Motin * Copyright (c) 2020 Alexander Motin <mav@FreeBSD.org>
7f1519a82SKonstantin Belousov * Copyright (c) 2024 The FreeBSD Foundation
8e1e9a4bfSMitsuru IWASAKI * All rights reserved.
9e1e9a4bfSMitsuru IWASAKI *
10f1519a82SKonstantin Belousov * Portions of this software were developed by Konstantin Belousov
11f1519a82SKonstantin Belousov * under sponsorship from the FreeBSD Foundation.
12f1519a82SKonstantin Belousov *
13e1e9a4bfSMitsuru IWASAKI * Redistribution and use in source and binary forms, with or without
14e1e9a4bfSMitsuru IWASAKI * modification, are permitted provided that the following conditions
15e1e9a4bfSMitsuru IWASAKI * are met:
16e1e9a4bfSMitsuru IWASAKI * 1. Redistributions of source code must retain the above copyright
17e1e9a4bfSMitsuru IWASAKI * notice, this list of conditions and the following disclaimer.
18e1e9a4bfSMitsuru IWASAKI * 2. Redistributions in binary form must reproduce the above copyright
19e1e9a4bfSMitsuru IWASAKI * notice, this list of conditions and the following disclaimer in the
20e1e9a4bfSMitsuru IWASAKI * documentation and/or other materials provided with the distribution.
21e1e9a4bfSMitsuru IWASAKI *
22e1e9a4bfSMitsuru IWASAKI * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
23e1e9a4bfSMitsuru IWASAKI * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24e1e9a4bfSMitsuru IWASAKI * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25e1e9a4bfSMitsuru IWASAKI * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
26e1e9a4bfSMitsuru IWASAKI * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27e1e9a4bfSMitsuru IWASAKI * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28e1e9a4bfSMitsuru IWASAKI * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29e1e9a4bfSMitsuru IWASAKI * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30e1e9a4bfSMitsuru IWASAKI * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31e1e9a4bfSMitsuru IWASAKI * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32e1e9a4bfSMitsuru IWASAKI * SUCH DAMAGE.
33e1e9a4bfSMitsuru IWASAKI */
34e1e9a4bfSMitsuru IWASAKI
35e1e9a4bfSMitsuru IWASAKI #include <sys/param.h>
36a74172abSNate Lawson #include <sys/endian.h>
37e1e9a4bfSMitsuru IWASAKI #include <sys/stat.h>
38945137d9SNate Lawson #include <sys/wait.h>
39e1e9a4bfSMitsuru IWASAKI #include <assert.h>
40e1e9a4bfSMitsuru IWASAKI #include <err.h>
41e1e9a4bfSMitsuru IWASAKI #include <fcntl.h>
4299065116SJung-uk Kim #include <paths.h>
436d789b61SKonstantin Belousov #include <stdbool.h>
44e1e9a4bfSMitsuru IWASAKI #include <stdio.h>
45a0333ad1SJohn Baldwin #include <stdint.h>
4699065116SJung-uk Kim #include <stdlib.h>
47945137d9SNate Lawson #include <string.h>
48e1e9a4bfSMitsuru IWASAKI #include <unistd.h>
49340c0022SEd Maste #include <uuid.h>
50e1e9a4bfSMitsuru IWASAKI
51e1e9a4bfSMitsuru IWASAKI #include "acpidump.h"
52e1e9a4bfSMitsuru IWASAKI
53c62f1cccSMitsuru IWASAKI #define BEGIN_COMMENT "/*\n"
54c62f1cccSMitsuru IWASAKI #define END_COMMENT " */\n"
55c62f1cccSMitsuru IWASAKI
56945137d9SNate Lawson static void acpi_print_string(char *s, size_t length);
57986dffafSJohn Baldwin static void acpi_print_gas(ACPI_GENERIC_ADDRESS *gas);
58986dffafSJohn Baldwin static int acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt);
59986dffafSJohn Baldwin static void acpi_handle_fadt(ACPI_TABLE_HEADER *fadt);
60945137d9SNate Lawson static void acpi_print_cpu(u_char cpu_id);
61986dffafSJohn Baldwin static void acpi_print_cpu_uid(uint32_t uid, char *uid_string);
62986dffafSJohn Baldwin static void acpi_print_local_apic(uint32_t apic_id, uint32_t flags);
63986dffafSJohn Baldwin static void acpi_print_io_apic(uint32_t apic_id, uint32_t int_base,
64986dffafSJohn Baldwin uint64_t apic_addr);
65986dffafSJohn Baldwin static void acpi_print_mps_flags(uint16_t flags);
66986dffafSJohn Baldwin static void acpi_print_intr(uint32_t intr, uint16_t mps_flags);
67986dffafSJohn Baldwin static void acpi_print_local_nmi(u_int lint, uint16_t mps_flags);
68986dffafSJohn Baldwin static void acpi_print_madt(ACPI_SUBTABLE_HEADER *mp);
69986dffafSJohn Baldwin static void acpi_handle_madt(ACPI_TABLE_HEADER *sdp);
70986dffafSJohn Baldwin static void acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp);
71986dffafSJohn Baldwin static void acpi_handle_hpet(ACPI_TABLE_HEADER *sdp);
72986dffafSJohn Baldwin static void acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp);
7333866658SJohn Baldwin static void acpi_handle_slit(ACPI_TABLE_HEADER *sdp);
74ed26c389SScott Long static void acpi_handle_wddt(ACPI_TABLE_HEADER *sdp);
755857fba5SBen Widawsky static void acpi_handle_lpit(ACPI_TABLE_HEADER *sdp);
76a0333ad1SJohn Baldwin static void acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain,
77a0333ad1SJohn Baldwin uint32_t flags);
78986dffafSJohn Baldwin static void acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp);
79986dffafSJohn Baldwin static void acpi_print_srat(ACPI_SUBTABLE_HEADER *srat);
80986dffafSJohn Baldwin static void acpi_handle_srat(ACPI_TABLE_HEADER *sdp);
81c031c93bSTakanori Watanabe static void acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp);
82340c0022SEd Maste static void acpi_print_nfit(ACPI_NFIT_HEADER *nfit);
83340c0022SEd Maste static void acpi_handle_nfit(ACPI_TABLE_HEADER *sdp);
84986dffafSJohn Baldwin static void acpi_print_sdt(ACPI_TABLE_HEADER *sdp);
85986dffafSJohn Baldwin static void acpi_print_fadt(ACPI_TABLE_HEADER *sdp);
86986dffafSJohn Baldwin static void acpi_print_facs(ACPI_TABLE_FACS *facs);
87986dffafSJohn Baldwin static void acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp);
88986dffafSJohn Baldwin static ACPI_TABLE_HEADER *acpi_map_sdt(vm_offset_t pa);
89986dffafSJohn Baldwin static void acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp);
903ff9ea7dSWarner Losh static void acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp, const char *elm);
91986dffafSJohn Baldwin static void acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
92986dffafSJohn Baldwin void (*action)(ACPI_SUBTABLE_HEADER *));
93340c0022SEd Maste static void acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first,
94340c0022SEd Maste void (*action)(ACPI_NFIT_HEADER *));
95c62f1cccSMitsuru IWASAKI
96773b6454SNate Lawson /* Size of an address. 32-bit for ACPI 1.0, 64-bit for ACPI 2.0 and up. */
97a74172abSNate Lawson static int addr_size;
98a74172abSNate Lawson
99c031c93bSTakanori Watanabe /* Strings used in the TCPA table */
100c031c93bSTakanori Watanabe static const char *tcpa_event_type_strings[] = {
101c031c93bSTakanori Watanabe "PREBOOT Certificate",
102c031c93bSTakanori Watanabe "POST Code",
103c031c93bSTakanori Watanabe "Unused",
104c031c93bSTakanori Watanabe "No Action",
105c031c93bSTakanori Watanabe "Separator",
106c031c93bSTakanori Watanabe "Action",
107c031c93bSTakanori Watanabe "Event Tag",
108c031c93bSTakanori Watanabe "S-CRTM Contents",
109c031c93bSTakanori Watanabe "S-CRTM Version",
110c031c93bSTakanori Watanabe "CPU Microcode",
111c031c93bSTakanori Watanabe "Platform Config Flags",
112c031c93bSTakanori Watanabe "Table of Devices",
113c031c93bSTakanori Watanabe "Compact Hash",
114c031c93bSTakanori Watanabe "IPL",
115c031c93bSTakanori Watanabe "IPL Partition Data",
116c031c93bSTakanori Watanabe "Non-Host Code",
117c031c93bSTakanori Watanabe "Non-Host Config",
118c031c93bSTakanori Watanabe "Non-Host Info"
119c031c93bSTakanori Watanabe };
120c031c93bSTakanori Watanabe
121c031c93bSTakanori Watanabe static const char *TCPA_pcclient_strings[] = {
122c031c93bSTakanori Watanabe "<undefined>",
123c031c93bSTakanori Watanabe "SMBIOS",
124c031c93bSTakanori Watanabe "BIS Certificate",
125c031c93bSTakanori Watanabe "POST BIOS ROM Strings",
126c031c93bSTakanori Watanabe "ESCD",
127c031c93bSTakanori Watanabe "CMOS",
128c031c93bSTakanori Watanabe "NVRAM",
129c031c93bSTakanori Watanabe "Option ROM Execute",
130c031c93bSTakanori Watanabe "Option ROM Configurateion",
131c031c93bSTakanori Watanabe "<undefined>",
132c031c93bSTakanori Watanabe "Option ROM Microcode Update ",
133c031c93bSTakanori Watanabe "S-CRTM Version String",
134c031c93bSTakanori Watanabe "S-CRTM Contents",
135c031c93bSTakanori Watanabe "POST Contents",
136c031c93bSTakanori Watanabe "Table of Devices",
137c031c93bSTakanori Watanabe };
138c031c93bSTakanori Watanabe
139ec650989SNeel Natu #define PRINTFLAG_END() printflag_end()
140ec650989SNeel Natu
141ec650989SNeel Natu static char pf_sep = '{';
142ec650989SNeel Natu
143ec650989SNeel Natu static void
printflag_end(void)144ec650989SNeel Natu printflag_end(void)
145ec650989SNeel Natu {
146ec650989SNeel Natu
147ec650989SNeel Natu if (pf_sep != '{') {
148ec650989SNeel Natu printf("}");
149ec650989SNeel Natu pf_sep = '{';
150ec650989SNeel Natu }
151ec650989SNeel Natu printf("\n");
152ec650989SNeel Natu }
153ec650989SNeel Natu
154ec650989SNeel Natu static void
printflag(uint64_t var,uint64_t mask,const char * name)155ec650989SNeel Natu printflag(uint64_t var, uint64_t mask, const char *name)
156ec650989SNeel Natu {
157ec650989SNeel Natu
158ec650989SNeel Natu if (var & mask) {
159ec650989SNeel Natu printf("%c%s", pf_sep, name);
160ec650989SNeel Natu pf_sep = ',';
161ec650989SNeel Natu }
162ec650989SNeel Natu }
163ec650989SNeel Natu
164e1e9a4bfSMitsuru IWASAKI static void
printfield(uint64_t var,int lbit,int hbit,const char * name)165969a4b8bSKonstantin Belousov printfield(uint64_t var, int lbit, int hbit, const char *name)
166969a4b8bSKonstantin Belousov {
167969a4b8bSKonstantin Belousov uint64_t mask;
168969a4b8bSKonstantin Belousov int len;
169969a4b8bSKonstantin Belousov
170969a4b8bSKonstantin Belousov len = hbit - lbit + 1;
171969a4b8bSKonstantin Belousov mask = ((1 << (len + 1)) - 1) << lbit;
172969a4b8bSKonstantin Belousov printf("%c%s=%#jx", pf_sep, name, (uintmax_t)((var & mask) >> lbit));
173969a4b8bSKonstantin Belousov pf_sep = ',';
174969a4b8bSKonstantin Belousov }
175969a4b8bSKonstantin Belousov
176969a4b8bSKonstantin Belousov static void
acpi_print_string(char * s,size_t length)177e1e9a4bfSMitsuru IWASAKI acpi_print_string(char *s, size_t length)
178e1e9a4bfSMitsuru IWASAKI {
179e1e9a4bfSMitsuru IWASAKI int c;
180e1e9a4bfSMitsuru IWASAKI
181e1e9a4bfSMitsuru IWASAKI /* Trim trailing spaces and NULLs */
182e1e9a4bfSMitsuru IWASAKI while (length > 0 && (s[length - 1] == ' ' || s[length - 1] == '\0'))
183e1e9a4bfSMitsuru IWASAKI length--;
184e1e9a4bfSMitsuru IWASAKI
185e1e9a4bfSMitsuru IWASAKI while (length--) {
186e1e9a4bfSMitsuru IWASAKI c = *s++;
187e1e9a4bfSMitsuru IWASAKI putchar(c);
188e1e9a4bfSMitsuru IWASAKI }
189e1e9a4bfSMitsuru IWASAKI }
190e1e9a4bfSMitsuru IWASAKI
191e1e9a4bfSMitsuru IWASAKI static void
acpi_print_gas(ACPI_GENERIC_ADDRESS * gas)192986dffafSJohn Baldwin acpi_print_gas(ACPI_GENERIC_ADDRESS *gas)
1938e6a8737SNate Lawson {
194986dffafSJohn Baldwin switch(gas->SpaceId) {
1958e6a8737SNate Lawson case ACPI_GAS_MEMORY:
196ebc22d04SAlexander Motin printf("0x%016jx:%u[%u] (Memory)", (uintmax_t)gas->Address,
197ebc22d04SAlexander Motin gas->BitOffset, gas->BitWidth);
1988e6a8737SNate Lawson break;
1998e6a8737SNate Lawson case ACPI_GAS_IO:
200ebc22d04SAlexander Motin printf("0x%02jx:%u[%u] (IO)", (uintmax_t)gas->Address,
201986dffafSJohn Baldwin gas->BitOffset, gas->BitWidth);
2028e6a8737SNate Lawson break;
2038e6a8737SNate Lawson case ACPI_GAS_PCI:
204ebc22d04SAlexander Motin printf("%x:%x+0x%x:%u[%u] (PCI)", (uint16_t)(gas->Address >> 32),
205986dffafSJohn Baldwin (uint16_t)((gas->Address >> 16) & 0xffff),
206ebc22d04SAlexander Motin (uint16_t)gas->Address, gas->BitOffset, gas->BitWidth);
2078e6a8737SNate Lawson break;
2088e6a8737SNate Lawson /* XXX How to handle these below? */
2098e6a8737SNate Lawson case ACPI_GAS_EMBEDDED:
210986dffafSJohn Baldwin printf("0x%x:%u[%u] (EC)", (uint16_t)gas->Address,
211986dffafSJohn Baldwin gas->BitOffset, gas->BitWidth);
2128e6a8737SNate Lawson break;
2138e6a8737SNate Lawson case ACPI_GAS_SMBUS:
214986dffafSJohn Baldwin printf("0x%x:%u[%u] (SMBus)", (uint16_t)gas->Address,
215986dffafSJohn Baldwin gas->BitOffset, gas->BitWidth);
2168e6a8737SNate Lawson break;
217986dffafSJohn Baldwin case ACPI_GAS_CMOS:
218986dffafSJohn Baldwin case ACPI_GAS_PCIBAR:
219986dffafSJohn Baldwin case ACPI_GAS_DATATABLE:
2208e6a8737SNate Lawson case ACPI_GAS_FIXED:
2218e6a8737SNate Lawson default:
2227d369c6eSJung-uk Kim printf("0x%016jx (?)", (uintmax_t)gas->Address);
2238e6a8737SNate Lawson break;
2248e6a8737SNate Lawson }
2258e6a8737SNate Lawson }
2268e6a8737SNate Lawson
227c2962974SNate Lawson /* The FADT revision indicates whether we use the DSDT or X_DSDT addresses. */
228c2962974SNate Lawson static int
acpi_get_fadt_revision(ACPI_TABLE_FADT * fadt __unused)2294262ad56SKonstantin Belousov acpi_get_fadt_revision(ACPI_TABLE_FADT *fadt __unused)
230e1e9a4bfSMitsuru IWASAKI {
231c2962974SNate Lawson int fadt_revision;
232e1e9a4bfSMitsuru IWASAKI
233c83f0f99SNate Lawson /* Set the FADT revision separately from the RSDP version. */
234c83f0f99SNate Lawson if (addr_size == 8) {
235c83f0f99SNate Lawson fadt_revision = 2;
2368e6a8737SNate Lawson
23701593a0fSAndrew Turner #if defined(__i386__)
238773b6454SNate Lawson /*
239c83f0f99SNate Lawson * A few systems (e.g., IBM T23) have an RSDP that claims
240c83f0f99SNate Lawson * revision 2 but the 64 bit addresses are invalid. If
241c83f0f99SNate Lawson * revision 2 and the 32 bit address is non-zero but the
242c83f0f99SNate Lawson * 32 and 64 bit versions don't match, prefer the 32 bit
243c83f0f99SNate Lawson * version for all subsequent tables.
24401593a0fSAndrew Turner *
24501593a0fSAndrew Turner * The only known ACPI systems this affects are early
24601593a0fSAndrew Turner * implementations on 32-bit x86. Because of this limit the
24701593a0fSAndrew Turner * workaround to i386.
248773b6454SNate Lawson */
249986dffafSJohn Baldwin if (fadt->Facs != 0 &&
250986dffafSJohn Baldwin (fadt->XFacs & 0xffffffff) != fadt->Facs)
251c83f0f99SNate Lawson fadt_revision = 1;
25201593a0fSAndrew Turner #endif
253c2962974SNate Lawson } else
254c83f0f99SNate Lawson fadt_revision = 1;
255c2962974SNate Lawson return (fadt_revision);
256c83f0f99SNate Lawson }
257c2962974SNate Lawson
258c2962974SNate Lawson static void
acpi_handle_fadt(ACPI_TABLE_HEADER * sdp)259986dffafSJohn Baldwin acpi_handle_fadt(ACPI_TABLE_HEADER *sdp)
260c2962974SNate Lawson {
261986dffafSJohn Baldwin ACPI_TABLE_HEADER *dsdp;
262986dffafSJohn Baldwin ACPI_TABLE_FACS *facs;
263986dffafSJohn Baldwin ACPI_TABLE_FADT *fadt;
264bc711181SAndrew Turner vm_offset_t addr;
265c2962974SNate Lawson int fadt_revision;
266c2962974SNate Lawson
267986dffafSJohn Baldwin fadt = (ACPI_TABLE_FADT *)sdp;
2682177d4e6SNate Lawson acpi_print_fadt(sdp);
269c83f0f99SNate Lawson
270c2962974SNate Lawson fadt_revision = acpi_get_fadt_revision(fadt);
271c83f0f99SNate Lawson if (fadt_revision == 1)
272bc711181SAndrew Turner addr = fadt->Facs;
273773b6454SNate Lawson else
274bc711181SAndrew Turner addr = fadt->XFacs;
275bc711181SAndrew Turner if (addr != 0) {
276bc711181SAndrew Turner facs = (ACPI_TABLE_FACS *)acpi_map_sdt(addr);
277bc711181SAndrew Turner
2783ff9ea7dSWarner Losh if (memcmp(facs->Signature, ACPI_SIG_FACS, ACPI_NAMESEG_SIZE) != 0 ||
279bc711181SAndrew Turner facs->Length < 64)
2808e6a8737SNate Lawson errx(1, "FACS is corrupt");
2818e6a8737SNate Lawson acpi_print_facs(facs);
282bc711181SAndrew Turner }
2838e6a8737SNate Lawson
284c83f0f99SNate Lawson if (fadt_revision == 1)
285986dffafSJohn Baldwin dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt);
286773b6454SNate Lawson else
287986dffafSJohn Baldwin dsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt);
288986dffafSJohn Baldwin if (acpi_checksum(dsdp, dsdp->Length))
289945137d9SNate Lawson errx(1, "DSDT is corrupt");
290945137d9SNate Lawson acpi_print_dsdt(dsdp);
291c62f1cccSMitsuru IWASAKI }
292c62f1cccSMitsuru IWASAKI
293c62f1cccSMitsuru IWASAKI static void
acpi_walk_subtables(ACPI_TABLE_HEADER * table,void * first,void (* action)(ACPI_SUBTABLE_HEADER *))294986dffafSJohn Baldwin acpi_walk_subtables(ACPI_TABLE_HEADER *table, void *first,
295986dffafSJohn Baldwin void (*action)(ACPI_SUBTABLE_HEADER *))
296986dffafSJohn Baldwin {
297986dffafSJohn Baldwin ACPI_SUBTABLE_HEADER *subtable;
298986dffafSJohn Baldwin char *end;
299986dffafSJohn Baldwin
300986dffafSJohn Baldwin subtable = first;
301986dffafSJohn Baldwin end = (char *)table + table->Length;
302986dffafSJohn Baldwin while ((char *)subtable < end) {
303986dffafSJohn Baldwin printf("\n");
304f5d0a8f7SEd Maste if (subtable->Length < sizeof(ACPI_SUBTABLE_HEADER)) {
305f5d0a8f7SEd Maste warnx("invalid subtable length %u", subtable->Length);
306f5d0a8f7SEd Maste return;
307f5d0a8f7SEd Maste }
308986dffafSJohn Baldwin action(subtable);
309986dffafSJohn Baldwin subtable = (ACPI_SUBTABLE_HEADER *)((char *)subtable +
310986dffafSJohn Baldwin subtable->Length);
311986dffafSJohn Baldwin }
312986dffafSJohn Baldwin }
313986dffafSJohn Baldwin
314986dffafSJohn Baldwin static void
acpi_walk_nfit(ACPI_TABLE_HEADER * table,void * first,void (* action)(ACPI_NFIT_HEADER *))315340c0022SEd Maste acpi_walk_nfit(ACPI_TABLE_HEADER *table, void *first,
316340c0022SEd Maste void (*action)(ACPI_NFIT_HEADER *))
317340c0022SEd Maste {
318340c0022SEd Maste ACPI_NFIT_HEADER *subtable;
319340c0022SEd Maste char *end;
320340c0022SEd Maste
321340c0022SEd Maste subtable = first;
322340c0022SEd Maste end = (char *)table + table->Length;
323340c0022SEd Maste while ((char *)subtable < end) {
324340c0022SEd Maste printf("\n");
325340c0022SEd Maste if (subtable->Length < sizeof(ACPI_NFIT_HEADER)) {
326340c0022SEd Maste warnx("invalid subtable length %u", subtable->Length);
327340c0022SEd Maste return;
328340c0022SEd Maste }
329340c0022SEd Maste action(subtable);
330340c0022SEd Maste subtable = (ACPI_NFIT_HEADER *)((char *)subtable +
331340c0022SEd Maste subtable->Length);
332340c0022SEd Maste }
333340c0022SEd Maste }
334340c0022SEd Maste
335340c0022SEd Maste static void
acpi_print_cpu(u_char cpu_id)3360a473124SJohn Baldwin acpi_print_cpu(u_char cpu_id)
3370a473124SJohn Baldwin {
3380a473124SJohn Baldwin
3390a473124SJohn Baldwin printf("\tACPI CPU=");
3400a473124SJohn Baldwin if (cpu_id == 0xff)
3410a473124SJohn Baldwin printf("ALL\n");
3420a473124SJohn Baldwin else
3430a473124SJohn Baldwin printf("%d\n", (u_int)cpu_id);
3440a473124SJohn Baldwin }
3450a473124SJohn Baldwin
3460a473124SJohn Baldwin static void
acpi_print_cpu_uid(uint32_t uid,char * uid_string)347986dffafSJohn Baldwin acpi_print_cpu_uid(uint32_t uid, char *uid_string)
3480a473124SJohn Baldwin {
349986dffafSJohn Baldwin
350986dffafSJohn Baldwin printf("\tUID=%d", uid);
351986dffafSJohn Baldwin if (uid_string != NULL)
352986dffafSJohn Baldwin printf(" (%s)", uid_string);
353986dffafSJohn Baldwin printf("\n");
354986dffafSJohn Baldwin }
355986dffafSJohn Baldwin
356986dffafSJohn Baldwin static void
acpi_print_local_apic(uint32_t apic_id,uint32_t flags)357986dffafSJohn Baldwin acpi_print_local_apic(uint32_t apic_id, uint32_t flags)
358986dffafSJohn Baldwin {
359986dffafSJohn Baldwin
3600a473124SJohn Baldwin printf("\tFlags={");
361986dffafSJohn Baldwin if (flags & ACPI_MADT_ENABLED)
3620a473124SJohn Baldwin printf("ENABLED");
3630a473124SJohn Baldwin else
3640a473124SJohn Baldwin printf("DISABLED");
3650a473124SJohn Baldwin printf("}\n");
366986dffafSJohn Baldwin printf("\tAPIC ID=%d\n", apic_id);
3670a473124SJohn Baldwin }
3680a473124SJohn Baldwin
3690a473124SJohn Baldwin static void
acpi_print_io_apic(uint32_t apic_id,uint32_t int_base,uint64_t apic_addr)370986dffafSJohn Baldwin acpi_print_io_apic(uint32_t apic_id, uint32_t int_base, uint64_t apic_addr)
3710a473124SJohn Baldwin {
372986dffafSJohn Baldwin
373986dffafSJohn Baldwin printf("\tAPIC ID=%d\n", apic_id);
3740a473124SJohn Baldwin printf("\tINT BASE=%d\n", int_base);
375986dffafSJohn Baldwin printf("\tADDR=0x%016jx\n", (uintmax_t)apic_addr);
3760a473124SJohn Baldwin }
3770a473124SJohn Baldwin
3780a473124SJohn Baldwin static void
acpi_print_mps_flags(uint16_t flags)379986dffafSJohn Baldwin acpi_print_mps_flags(uint16_t flags)
3800a473124SJohn Baldwin {
3810a473124SJohn Baldwin
3820a473124SJohn Baldwin printf("\tFlags={Polarity=");
383986dffafSJohn Baldwin switch (flags & ACPI_MADT_POLARITY_MASK) {
384986dffafSJohn Baldwin case ACPI_MADT_POLARITY_CONFORMS:
3850a473124SJohn Baldwin printf("conforming");
3860a473124SJohn Baldwin break;
387986dffafSJohn Baldwin case ACPI_MADT_POLARITY_ACTIVE_HIGH:
3880a473124SJohn Baldwin printf("active-hi");
3890a473124SJohn Baldwin break;
390986dffafSJohn Baldwin case ACPI_MADT_POLARITY_ACTIVE_LOW:
3910a473124SJohn Baldwin printf("active-lo");
3920a473124SJohn Baldwin break;
3930a473124SJohn Baldwin default:
394986dffafSJohn Baldwin printf("0x%x", flags & ACPI_MADT_POLARITY_MASK);
3950a473124SJohn Baldwin break;
3960a473124SJohn Baldwin }
3970a473124SJohn Baldwin printf(", Trigger=");
398986dffafSJohn Baldwin switch (flags & ACPI_MADT_TRIGGER_MASK) {
399986dffafSJohn Baldwin case ACPI_MADT_TRIGGER_CONFORMS:
4000a473124SJohn Baldwin printf("conforming");
4010a473124SJohn Baldwin break;
402986dffafSJohn Baldwin case ACPI_MADT_TRIGGER_EDGE:
4030a473124SJohn Baldwin printf("edge");
4040a473124SJohn Baldwin break;
405986dffafSJohn Baldwin case ACPI_MADT_TRIGGER_LEVEL:
4060a473124SJohn Baldwin printf("level");
4070a473124SJohn Baldwin break;
4080a473124SJohn Baldwin default:
409986dffafSJohn Baldwin printf("0x%x", (flags & ACPI_MADT_TRIGGER_MASK) >> 2);
4100a473124SJohn Baldwin }
4110a473124SJohn Baldwin printf("}\n");
4120a473124SJohn Baldwin }
4130a473124SJohn Baldwin
4140a473124SJohn Baldwin static void
acpi_print_gicc_flags(uint32_t flags)4152b2b1f42SAndrew Turner acpi_print_gicc_flags(uint32_t flags)
4162b2b1f42SAndrew Turner {
4172b2b1f42SAndrew Turner
4182b2b1f42SAndrew Turner printf("\tFlags={Performance intr=");
4192b2b1f42SAndrew Turner if (flags & ACPI_MADT_PERFORMANCE_IRQ_MODE)
4202b2b1f42SAndrew Turner printf("edge");
4212b2b1f42SAndrew Turner else
4222b2b1f42SAndrew Turner printf("level");
4232b2b1f42SAndrew Turner printf(", VGIC intr=");
4242b2b1f42SAndrew Turner if (flags & ACPI_MADT_VGIC_IRQ_MODE)
4252b2b1f42SAndrew Turner printf("edge");
4262b2b1f42SAndrew Turner else
4272b2b1f42SAndrew Turner printf("level");
4282b2b1f42SAndrew Turner printf("}\n");
4292b2b1f42SAndrew Turner }
4302b2b1f42SAndrew Turner
4312b2b1f42SAndrew Turner static void
acpi_print_intr(uint32_t intr,uint16_t mps_flags)432986dffafSJohn Baldwin acpi_print_intr(uint32_t intr, uint16_t mps_flags)
4330a473124SJohn Baldwin {
4340a473124SJohn Baldwin
435986dffafSJohn Baldwin printf("\tINTR=%d\n", intr);
436986dffafSJohn Baldwin acpi_print_mps_flags(mps_flags);
437986dffafSJohn Baldwin }
438986dffafSJohn Baldwin
439986dffafSJohn Baldwin static void
acpi_print_local_nmi(u_int lint,uint16_t mps_flags)440986dffafSJohn Baldwin acpi_print_local_nmi(u_int lint, uint16_t mps_flags)
441986dffafSJohn Baldwin {
442986dffafSJohn Baldwin
443986dffafSJohn Baldwin printf("\tLINT Pin=%d\n", lint);
4440a473124SJohn Baldwin acpi_print_mps_flags(mps_flags);
4450a473124SJohn Baldwin }
4460a473124SJohn Baldwin
44727941afaSEd Maste static const char *apic_types[] = {
44827941afaSEd Maste [ACPI_MADT_TYPE_LOCAL_APIC] = "Local APIC",
44927941afaSEd Maste [ACPI_MADT_TYPE_IO_APIC] = "IO APIC",
45027941afaSEd Maste [ACPI_MADT_TYPE_INTERRUPT_OVERRIDE] = "INT Override",
45127941afaSEd Maste [ACPI_MADT_TYPE_NMI_SOURCE] = "NMI",
45227941afaSEd Maste [ACPI_MADT_TYPE_LOCAL_APIC_NMI] = "Local APIC NMI",
45327941afaSEd Maste [ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE] = "Local APIC Override",
45427941afaSEd Maste [ACPI_MADT_TYPE_IO_SAPIC] = "IO SAPIC",
45527941afaSEd Maste [ACPI_MADT_TYPE_LOCAL_SAPIC] = "Local SAPIC",
45627941afaSEd Maste [ACPI_MADT_TYPE_INTERRUPT_SOURCE] = "Platform Interrupt",
45727941afaSEd Maste [ACPI_MADT_TYPE_LOCAL_X2APIC] = "Local X2APIC",
45827941afaSEd Maste [ACPI_MADT_TYPE_LOCAL_X2APIC_NMI] = "Local X2APIC NMI",
45927941afaSEd Maste [ACPI_MADT_TYPE_GENERIC_INTERRUPT] = "GIC CPU Interface Structure",
46027941afaSEd Maste [ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR] = "GIC Distributor Structure",
46127941afaSEd Maste [ACPI_MADT_TYPE_GENERIC_MSI_FRAME] = "GICv2m MSI Frame",
46227941afaSEd Maste [ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR] = "GIC Redistributor Structure",
46327941afaSEd Maste [ACPI_MADT_TYPE_GENERIC_TRANSLATOR] = "GIC ITS Structure"
46427941afaSEd Maste };
46527941afaSEd Maste
466bf70beceSEd Schouten static const char *platform_int_types[] = { "0 (unknown)", "PMI", "INIT",
4670a473124SJohn Baldwin "Corrected Platform Error" };
4680a473124SJohn Baldwin
4690a473124SJohn Baldwin static void
acpi_print_madt(ACPI_SUBTABLE_HEADER * mp)470986dffafSJohn Baldwin acpi_print_madt(ACPI_SUBTABLE_HEADER *mp)
4710a473124SJohn Baldwin {
472986dffafSJohn Baldwin ACPI_MADT_LOCAL_APIC *lapic;
473986dffafSJohn Baldwin ACPI_MADT_IO_APIC *ioapic;
474986dffafSJohn Baldwin ACPI_MADT_INTERRUPT_OVERRIDE *over;
475986dffafSJohn Baldwin ACPI_MADT_NMI_SOURCE *nmi;
476986dffafSJohn Baldwin ACPI_MADT_LOCAL_APIC_NMI *lapic_nmi;
477986dffafSJohn Baldwin ACPI_MADT_LOCAL_APIC_OVERRIDE *lapic_over;
478986dffafSJohn Baldwin ACPI_MADT_IO_SAPIC *iosapic;
479986dffafSJohn Baldwin ACPI_MADT_LOCAL_SAPIC *lsapic;
480986dffafSJohn Baldwin ACPI_MADT_INTERRUPT_SOURCE *isrc;
481986dffafSJohn Baldwin ACPI_MADT_LOCAL_X2APIC *x2apic;
482986dffafSJohn Baldwin ACPI_MADT_LOCAL_X2APIC_NMI *x2apic_nmi;
4832b2b1f42SAndrew Turner ACPI_MADT_GENERIC_INTERRUPT *gicc;
4842b2b1f42SAndrew Turner ACPI_MADT_GENERIC_DISTRIBUTOR *gicd;
4852b2b1f42SAndrew Turner ACPI_MADT_GENERIC_REDISTRIBUTOR *gicr;
4862b2b1f42SAndrew Turner ACPI_MADT_GENERIC_TRANSLATOR *gict;
4870a473124SJohn Baldwin
488c86932b6SMarcelo Araujo if (mp->Type < nitems(apic_types))
489986dffafSJohn Baldwin printf("\tType=%s\n", apic_types[mp->Type]);
490a0333ad1SJohn Baldwin else
491986dffafSJohn Baldwin printf("\tType=%d (unknown)\n", mp->Type);
492986dffafSJohn Baldwin switch (mp->Type) {
493986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_APIC:
494986dffafSJohn Baldwin lapic = (ACPI_MADT_LOCAL_APIC *)mp;
495986dffafSJohn Baldwin acpi_print_cpu(lapic->ProcessorId);
496986dffafSJohn Baldwin acpi_print_local_apic(lapic->Id, lapic->LapicFlags);
4970a473124SJohn Baldwin break;
498986dffafSJohn Baldwin case ACPI_MADT_TYPE_IO_APIC:
499986dffafSJohn Baldwin ioapic = (ACPI_MADT_IO_APIC *)mp;
500986dffafSJohn Baldwin acpi_print_io_apic(ioapic->Id, ioapic->GlobalIrqBase,
501986dffafSJohn Baldwin ioapic->Address);
5020a473124SJohn Baldwin break;
503986dffafSJohn Baldwin case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
504986dffafSJohn Baldwin over = (ACPI_MADT_INTERRUPT_OVERRIDE *)mp;
505986dffafSJohn Baldwin printf("\tBUS=%d\n", (u_int)over->Bus);
506986dffafSJohn Baldwin printf("\tIRQ=%d\n", (u_int)over->SourceIrq);
507986dffafSJohn Baldwin acpi_print_intr(over->GlobalIrq, over->IntiFlags);
5080a473124SJohn Baldwin break;
509986dffafSJohn Baldwin case ACPI_MADT_TYPE_NMI_SOURCE:
510986dffafSJohn Baldwin nmi = (ACPI_MADT_NMI_SOURCE *)mp;
511986dffafSJohn Baldwin acpi_print_intr(nmi->GlobalIrq, nmi->IntiFlags);
5120a473124SJohn Baldwin break;
513986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
514986dffafSJohn Baldwin lapic_nmi = (ACPI_MADT_LOCAL_APIC_NMI *)mp;
515986dffafSJohn Baldwin acpi_print_cpu(lapic_nmi->ProcessorId);
516986dffafSJohn Baldwin acpi_print_local_nmi(lapic_nmi->Lint, lapic_nmi->IntiFlags);
5170a473124SJohn Baldwin break;
518986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
519986dffafSJohn Baldwin lapic_over = (ACPI_MADT_LOCAL_APIC_OVERRIDE *)mp;
520945137d9SNate Lawson printf("\tLocal APIC ADDR=0x%016jx\n",
521986dffafSJohn Baldwin (uintmax_t)lapic_over->Address);
5220a473124SJohn Baldwin break;
523986dffafSJohn Baldwin case ACPI_MADT_TYPE_IO_SAPIC:
524986dffafSJohn Baldwin iosapic = (ACPI_MADT_IO_SAPIC *)mp;
525986dffafSJohn Baldwin acpi_print_io_apic(iosapic->Id, iosapic->GlobalIrqBase,
526986dffafSJohn Baldwin iosapic->Address);
5270a473124SJohn Baldwin break;
528986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_SAPIC:
529986dffafSJohn Baldwin lsapic = (ACPI_MADT_LOCAL_SAPIC *)mp;
530986dffafSJohn Baldwin acpi_print_cpu(lsapic->ProcessorId);
531986dffafSJohn Baldwin acpi_print_local_apic(lsapic->Id, lsapic->LapicFlags);
532986dffafSJohn Baldwin printf("\tAPIC EID=%d\n", (u_int)lsapic->Eid);
533986dffafSJohn Baldwin if (mp->Length > __offsetof(ACPI_MADT_LOCAL_SAPIC, Uid))
534986dffafSJohn Baldwin acpi_print_cpu_uid(lsapic->Uid, lsapic->UidString);
5350a473124SJohn Baldwin break;
536986dffafSJohn Baldwin case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
537986dffafSJohn Baldwin isrc = (ACPI_MADT_INTERRUPT_SOURCE *)mp;
538c86932b6SMarcelo Araujo if (isrc->Type < nitems(platform_int_types))
539986dffafSJohn Baldwin printf("\tType=%s\n", platform_int_types[isrc->Type]);
540986dffafSJohn Baldwin else
541986dffafSJohn Baldwin printf("\tType=%d (unknown)\n", isrc->Type);
542986dffafSJohn Baldwin printf("\tAPIC ID=%d\n", (u_int)isrc->Id);
543986dffafSJohn Baldwin printf("\tAPIC EID=%d\n", (u_int)isrc->Eid);
544986dffafSJohn Baldwin printf("\tSAPIC Vector=%d\n", (u_int)isrc->IoSapicVector);
545986dffafSJohn Baldwin acpi_print_intr(isrc->GlobalIrq, isrc->IntiFlags);
546986dffafSJohn Baldwin break;
547986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_X2APIC:
548986dffafSJohn Baldwin x2apic = (ACPI_MADT_LOCAL_X2APIC *)mp;
549986dffafSJohn Baldwin acpi_print_cpu_uid(x2apic->Uid, NULL);
550986dffafSJohn Baldwin acpi_print_local_apic(x2apic->LocalApicId, x2apic->LapicFlags);
551986dffafSJohn Baldwin break;
552986dffafSJohn Baldwin case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
553986dffafSJohn Baldwin x2apic_nmi = (ACPI_MADT_LOCAL_X2APIC_NMI *)mp;
554986dffafSJohn Baldwin acpi_print_cpu_uid(x2apic_nmi->Uid, NULL);
555986dffafSJohn Baldwin acpi_print_local_nmi(x2apic_nmi->Lint, x2apic_nmi->IntiFlags);
5560a473124SJohn Baldwin break;
5572b2b1f42SAndrew Turner case ACPI_MADT_TYPE_GENERIC_INTERRUPT:
5582b2b1f42SAndrew Turner gicc = (ACPI_MADT_GENERIC_INTERRUPT *)mp;
5592b2b1f42SAndrew Turner acpi_print_cpu_uid(gicc->Uid, NULL);
5602b2b1f42SAndrew Turner printf("\tCPU INTERFACE=%x\n", gicc->CpuInterfaceNumber);
5612b2b1f42SAndrew Turner acpi_print_gicc_flags(gicc->Flags);
5622b2b1f42SAndrew Turner printf("\tParking Protocol Version=%x\n", gicc->ParkingVersion);
5632b2b1f42SAndrew Turner printf("\tPERF INTR=%d\n", gicc->PerformanceInterrupt);
5642b2b1f42SAndrew Turner printf("\tParked ADDR=%016jx\n",
5652b2b1f42SAndrew Turner (uintmax_t)gicc->ParkedAddress);
5662b2b1f42SAndrew Turner printf("\tBase ADDR=%016jx\n", (uintmax_t)gicc->BaseAddress);
5672b2b1f42SAndrew Turner printf("\tGICV=%016jx\n", (uintmax_t)gicc->GicvBaseAddress);
5682b2b1f42SAndrew Turner printf("\tGICH=%016jx\n", (uintmax_t)gicc->GichBaseAddress);
5692b2b1f42SAndrew Turner printf("\tVGIC INTR=%d\n", gicc->VgicInterrupt);
5702b2b1f42SAndrew Turner printf("\tGICR ADDR=%016jx\n",
5712b2b1f42SAndrew Turner (uintmax_t)gicc->GicrBaseAddress);
5722b2b1f42SAndrew Turner printf("\tMPIDR=%jx\n", (uintmax_t)gicc->ArmMpidr);
5730b4302aaSGordon Bergling printf("\tEfficiency Class=%d\n", (u_int)gicc->EfficiencyClass);
574c363da4aSAndrew Turner printf("\tSPE INTR=%d\n", gicc->SpeInterrupt);
5752b2b1f42SAndrew Turner break;
5762b2b1f42SAndrew Turner case ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR:
5772b2b1f42SAndrew Turner gicd = (ACPI_MADT_GENERIC_DISTRIBUTOR *)mp;
5782b2b1f42SAndrew Turner printf("\tGIC ID=%d\n", (u_int)gicd->GicId);
5792b2b1f42SAndrew Turner printf("\tBase ADDR=%016jx\n", (uintmax_t)gicd->BaseAddress);
5802b2b1f42SAndrew Turner printf("\tVector Base=%d\n", gicd->GlobalIrqBase);
5812b2b1f42SAndrew Turner printf("\tGIC VERSION=%d\n", (u_int)gicd->Version);
5822b2b1f42SAndrew Turner break;
5832b2b1f42SAndrew Turner case ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR:
5842b2b1f42SAndrew Turner gicr = (ACPI_MADT_GENERIC_REDISTRIBUTOR *)mp;
5852b2b1f42SAndrew Turner printf("\tBase ADDR=%016jx\n", (uintmax_t)gicr->BaseAddress);
5862b2b1f42SAndrew Turner printf("\tLength=%08x\n", gicr->Length);
5872b2b1f42SAndrew Turner break;
5882b2b1f42SAndrew Turner case ACPI_MADT_TYPE_GENERIC_TRANSLATOR:
5892b2b1f42SAndrew Turner gict = (ACPI_MADT_GENERIC_TRANSLATOR *)mp;
5902b2b1f42SAndrew Turner printf("\tGIC ITS ID=%d\n", gict->TranslationId);
5912b2b1f42SAndrew Turner printf("\tBase ADDR=%016jx\n", (uintmax_t)gict->BaseAddress);
5922b2b1f42SAndrew Turner break;
5930a473124SJohn Baldwin }
5940a473124SJohn Baldwin }
5950a473124SJohn Baldwin
5960a473124SJohn Baldwin static void
acpi_handle_madt(ACPI_TABLE_HEADER * sdp)597986dffafSJohn Baldwin acpi_handle_madt(ACPI_TABLE_HEADER *sdp)
5980a473124SJohn Baldwin {
599986dffafSJohn Baldwin ACPI_TABLE_MADT *madt;
6000a473124SJohn Baldwin
601773b6454SNate Lawson printf(BEGIN_COMMENT);
602773b6454SNate Lawson acpi_print_sdt(sdp);
603986dffafSJohn Baldwin madt = (ACPI_TABLE_MADT *)sdp;
604986dffafSJohn Baldwin printf("\tLocal APIC ADDR=0x%08x\n", madt->Address);
6050a473124SJohn Baldwin printf("\tFlags={");
606986dffafSJohn Baldwin if (madt->Flags & ACPI_MADT_PCAT_COMPAT)
6070a473124SJohn Baldwin printf("PC-AT");
6080a473124SJohn Baldwin printf("}\n");
609986dffafSJohn Baldwin acpi_walk_subtables(sdp, (madt + 1), acpi_print_madt);
6100a473124SJohn Baldwin printf(END_COMMENT);
6110a473124SJohn Baldwin }
6120a473124SJohn Baldwin
6130a473124SJohn Baldwin static void
acpi_handle_bert(ACPI_TABLE_HEADER * sdp)614ebc22d04SAlexander Motin acpi_handle_bert(ACPI_TABLE_HEADER *sdp)
615ebc22d04SAlexander Motin {
616ebc22d04SAlexander Motin ACPI_TABLE_BERT *bert;
617ebc22d04SAlexander Motin
618ebc22d04SAlexander Motin printf(BEGIN_COMMENT);
619ebc22d04SAlexander Motin acpi_print_sdt(sdp);
620ebc22d04SAlexander Motin bert = (ACPI_TABLE_BERT *)sdp;
621ebc22d04SAlexander Motin printf("\tRegionLength=%d\n", bert->RegionLength);
622ebc22d04SAlexander Motin printf("\tAddress=0x%016jx\n", bert->Address);
623ebc22d04SAlexander Motin printf(END_COMMENT);
624ebc22d04SAlexander Motin }
625ebc22d04SAlexander Motin
626ebc22d04SAlexander Motin static void
acpi_print_whea(ACPI_WHEA_HEADER * w)627ebc22d04SAlexander Motin acpi_print_whea(ACPI_WHEA_HEADER *w)
628ebc22d04SAlexander Motin {
629ebc22d04SAlexander Motin
630ebc22d04SAlexander Motin printf("\n\tAction=%d\n", w->Action);
631ebc22d04SAlexander Motin printf("\tInstruction=%d\n", w->Instruction);
632ebc22d04SAlexander Motin printf("\tFlags=%02x\n", w->Flags);
633ebc22d04SAlexander Motin printf("\tRegisterRegion=");
634ebc22d04SAlexander Motin acpi_print_gas(&w->RegisterRegion);
635ebc22d04SAlexander Motin printf("\n\tValue=0x%016jx\n", w->Value);
636ebc22d04SAlexander Motin printf("\tMask=0x%016jx\n", w->Mask);
637ebc22d04SAlexander Motin }
638ebc22d04SAlexander Motin
639ebc22d04SAlexander Motin static void
acpi_handle_einj(ACPI_TABLE_HEADER * sdp)640ebc22d04SAlexander Motin acpi_handle_einj(ACPI_TABLE_HEADER *sdp)
641ebc22d04SAlexander Motin {
642ebc22d04SAlexander Motin ACPI_TABLE_EINJ *einj;
643ebc22d04SAlexander Motin ACPI_WHEA_HEADER *w;
644ebc22d04SAlexander Motin u_int i;
645ebc22d04SAlexander Motin
646ebc22d04SAlexander Motin printf(BEGIN_COMMENT);
647ebc22d04SAlexander Motin acpi_print_sdt(sdp);
648ebc22d04SAlexander Motin einj = (ACPI_TABLE_EINJ *)sdp;
649ebc22d04SAlexander Motin printf("\tHeaderLength=%d\n", einj->HeaderLength);
650ebc22d04SAlexander Motin printf("\tFlags=0x%02x\n", einj->Flags);
651ebc22d04SAlexander Motin printf("\tEntries=%d\n", einj->Entries);
652ebc22d04SAlexander Motin w = (ACPI_WHEA_HEADER *)(einj + 1);
653ebc22d04SAlexander Motin for (i = 0; i < MIN(einj->Entries, (sdp->Length -
654ebc22d04SAlexander Motin sizeof(ACPI_TABLE_EINJ)) / sizeof(ACPI_WHEA_HEADER)); i++)
655ebc22d04SAlexander Motin acpi_print_whea(w + i);
656ebc22d04SAlexander Motin printf(END_COMMENT);
657ebc22d04SAlexander Motin }
658ebc22d04SAlexander Motin
659ebc22d04SAlexander Motin static void
acpi_handle_erst(ACPI_TABLE_HEADER * sdp)660ebc22d04SAlexander Motin acpi_handle_erst(ACPI_TABLE_HEADER *sdp)
661ebc22d04SAlexander Motin {
662ebc22d04SAlexander Motin ACPI_TABLE_ERST *erst;
663ebc22d04SAlexander Motin ACPI_WHEA_HEADER *w;
664ebc22d04SAlexander Motin u_int i;
665ebc22d04SAlexander Motin
666ebc22d04SAlexander Motin printf(BEGIN_COMMENT);
667ebc22d04SAlexander Motin acpi_print_sdt(sdp);
668ebc22d04SAlexander Motin erst = (ACPI_TABLE_ERST *)sdp;
669ebc22d04SAlexander Motin printf("\tHeaderLength=%d\n", erst->HeaderLength);
670ebc22d04SAlexander Motin printf("\tEntries=%d\n", erst->Entries);
671ebc22d04SAlexander Motin w = (ACPI_WHEA_HEADER *)(erst + 1);
672ebc22d04SAlexander Motin for (i = 0; i < MIN(erst->Entries, (sdp->Length -
673ebc22d04SAlexander Motin sizeof(ACPI_TABLE_ERST)) / sizeof(ACPI_WHEA_HEADER)); i++)
674ebc22d04SAlexander Motin acpi_print_whea(w + i);
675ebc22d04SAlexander Motin printf(END_COMMENT);
676ebc22d04SAlexander Motin }
677ebc22d04SAlexander Motin
678ebc22d04SAlexander Motin static void
acpi_print_hest_bank(ACPI_HEST_IA_ERROR_BANK * b)679ebc22d04SAlexander Motin acpi_print_hest_bank(ACPI_HEST_IA_ERROR_BANK *b)
680ebc22d04SAlexander Motin {
681ebc22d04SAlexander Motin
682ebc22d04SAlexander Motin printf("\tBank:\n");
683ebc22d04SAlexander Motin printf("\t\tBankNumber=%d\n", b->BankNumber);
684ebc22d04SAlexander Motin printf("\t\tClearStatusOnInit=%d\n", b->ClearStatusOnInit);
685ebc22d04SAlexander Motin printf("\t\tStatusFormat=%d\n", b->StatusFormat);
686ebc22d04SAlexander Motin printf("\t\tControlRegister=%x\n", b->ControlRegister);
687ebc22d04SAlexander Motin printf("\t\tControlData=%jx\n", b->ControlData);
688ebc22d04SAlexander Motin printf("\t\tStatusRegister=%x\n", b->StatusRegister);
689ebc22d04SAlexander Motin printf("\t\tAddressRegister=%x\n", b->AddressRegister);
690ebc22d04SAlexander Motin printf("\t\tMiscRegister=%x\n", b->MiscRegister);
691ebc22d04SAlexander Motin }
692ebc22d04SAlexander Motin
693ebc22d04SAlexander Motin static void
acpi_print_hest_notify(ACPI_HEST_NOTIFY * n)694ebc22d04SAlexander Motin acpi_print_hest_notify(ACPI_HEST_NOTIFY *n)
695ebc22d04SAlexander Motin {
696ebc22d04SAlexander Motin
697ebc22d04SAlexander Motin printf("\t\tType=%d\n", n->Type);
698ebc22d04SAlexander Motin printf("\t\tLength=%d\n", n->Length);
699ebc22d04SAlexander Motin printf("\t\tConfigWriteEnable=%04x\n", n->ConfigWriteEnable);
700ebc22d04SAlexander Motin printf("\t\tPollInterval=%d\n", n->PollInterval);
701ebc22d04SAlexander Motin printf("\t\tVector=%d\n", n->Vector);
702ebc22d04SAlexander Motin printf("\t\tPollingThresholdValue=%d\n", n->PollingThresholdValue);
703ebc22d04SAlexander Motin printf("\t\tPollingThresholdWindow=%d\n", n->PollingThresholdWindow);
704ebc22d04SAlexander Motin printf("\t\tErrorThresholdValue=%d\n", n->ErrorThresholdValue);
705ebc22d04SAlexander Motin printf("\t\tErrorThresholdWindow=%d\n", n->ErrorThresholdWindow);
706ebc22d04SAlexander Motin }
707ebc22d04SAlexander Motin
708ebc22d04SAlexander Motin static void
acpi_print_hest_aer(ACPI_HEST_AER_COMMON * a)709ebc22d04SAlexander Motin acpi_print_hest_aer(ACPI_HEST_AER_COMMON *a)
710ebc22d04SAlexander Motin {
711ebc22d04SAlexander Motin
712ebc22d04SAlexander Motin printf("\tFlags=%02x\n", a->Flags);
713ebc22d04SAlexander Motin printf("\tEnabled=%d\n", a->Enabled);
714ebc22d04SAlexander Motin printf("\tRecordsToPreallocate=%d\n", a->RecordsToPreallocate);
715ebc22d04SAlexander Motin printf("\tMaxSectionsPerRecord=%d\n", a->MaxSectionsPerRecord);
716ebc22d04SAlexander Motin printf("\tBus=%d\n", a->Bus);
717ebc22d04SAlexander Motin printf("\tDevice=%d\n", a->Device);
718ebc22d04SAlexander Motin printf("\tFunction=%d\n", a->Function);
719ebc22d04SAlexander Motin printf("\tDeviceControl=%d\n", a->DeviceControl);
720ebc22d04SAlexander Motin printf("\tUncorrectableMask=%d\n", a->UncorrectableMask);
721ebc22d04SAlexander Motin printf("\tUncorrectableSeverity=%d\n", a->UncorrectableSeverity);
722ebc22d04SAlexander Motin printf("\tCorrectableMask=%d\n", a->CorrectableMask);
723ebc22d04SAlexander Motin printf("\tAdvancedCapabilities=%d\n", a->AdvancedCapabilities);
724ebc22d04SAlexander Motin }
725ebc22d04SAlexander Motin
726ebc22d04SAlexander Motin static int
acpi_handle_hest_structure(void * addr,int remaining)727ebc22d04SAlexander Motin acpi_handle_hest_structure(void *addr, int remaining)
728ebc22d04SAlexander Motin {
729ebc22d04SAlexander Motin ACPI_HEST_HEADER *hdr = addr;
730ebc22d04SAlexander Motin int i;
731ebc22d04SAlexander Motin
732ebc22d04SAlexander Motin if (remaining < (int)sizeof(ACPI_HEST_HEADER))
733ebc22d04SAlexander Motin return (-1);
734ebc22d04SAlexander Motin
735ebc22d04SAlexander Motin printf("\n\tType=%d\n", hdr->Type);
736ebc22d04SAlexander Motin printf("\tSourceId=%d\n", hdr->SourceId);
737ebc22d04SAlexander Motin switch (hdr->Type) {
738ebc22d04SAlexander Motin case ACPI_HEST_TYPE_IA32_CHECK: {
739ebc22d04SAlexander Motin ACPI_HEST_IA_MACHINE_CHECK *s = addr;
740ebc22d04SAlexander Motin printf("\tFlags=%02x\n", s->Flags);
741ebc22d04SAlexander Motin printf("\tEnabled=%d\n", s->Enabled);
742ebc22d04SAlexander Motin printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
743ebc22d04SAlexander Motin printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
744ebc22d04SAlexander Motin printf("\tGlobalCapabilityData=%jd\n", s->GlobalCapabilityData);
745ebc22d04SAlexander Motin printf("\tGlobalControlData=%jd\n", s->GlobalControlData);
746ebc22d04SAlexander Motin printf("\tNumHardwareBanks=%d\n", s->NumHardwareBanks);
747ebc22d04SAlexander Motin for (i = 0; i < s->NumHardwareBanks; i++) {
748ebc22d04SAlexander Motin acpi_print_hest_bank((ACPI_HEST_IA_ERROR_BANK *)
749ebc22d04SAlexander Motin (s + 1) + i);
750ebc22d04SAlexander Motin }
751ebc22d04SAlexander Motin return (sizeof(*s) + s->NumHardwareBanks *
752ebc22d04SAlexander Motin sizeof(ACPI_HEST_IA_ERROR_BANK));
753ebc22d04SAlexander Motin }
754ebc22d04SAlexander Motin case ACPI_HEST_TYPE_IA32_CORRECTED_CHECK: {
755ebc22d04SAlexander Motin ACPI_HEST_IA_CORRECTED *s = addr;
756ebc22d04SAlexander Motin printf("\tFlags=%02x\n", s->Flags);
757ebc22d04SAlexander Motin printf("\tEnabled=%d\n", s->Enabled);
758ebc22d04SAlexander Motin printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
759ebc22d04SAlexander Motin printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
760ebc22d04SAlexander Motin printf("\tNotify:\n");
761ebc22d04SAlexander Motin acpi_print_hest_notify(&s->Notify);
762ebc22d04SAlexander Motin printf("\tNumHardwareBanks=%d\n", s->NumHardwareBanks);
763ebc22d04SAlexander Motin for (i = 0; i < s->NumHardwareBanks; i++) {
764ebc22d04SAlexander Motin acpi_print_hest_bank((ACPI_HEST_IA_ERROR_BANK *)
765ebc22d04SAlexander Motin (s + 1) + i);
766ebc22d04SAlexander Motin }
767ebc22d04SAlexander Motin return (sizeof(*s) + s->NumHardwareBanks *
768ebc22d04SAlexander Motin sizeof(ACPI_HEST_IA_ERROR_BANK));
769ebc22d04SAlexander Motin }
770ebc22d04SAlexander Motin case ACPI_HEST_TYPE_IA32_NMI: {
771ebc22d04SAlexander Motin ACPI_HEST_IA_NMI *s = addr;
772ebc22d04SAlexander Motin printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
773ebc22d04SAlexander Motin printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
774ebc22d04SAlexander Motin printf("\tMaxRawDataLength=%d\n", s->MaxRawDataLength);
775ebc22d04SAlexander Motin return (sizeof(*s));
776ebc22d04SAlexander Motin }
777ebc22d04SAlexander Motin case ACPI_HEST_TYPE_AER_ROOT_PORT: {
778ebc22d04SAlexander Motin ACPI_HEST_AER_ROOT *s = addr;
779ebc22d04SAlexander Motin acpi_print_hest_aer(&s->Aer);
780ebc22d04SAlexander Motin printf("\tRootErrorCommand=%d\n", s->RootErrorCommand);
781ebc22d04SAlexander Motin return (sizeof(*s));
782ebc22d04SAlexander Motin }
783ebc22d04SAlexander Motin case ACPI_HEST_TYPE_AER_ENDPOINT: {
784ebc22d04SAlexander Motin ACPI_HEST_AER *s = addr;
785ebc22d04SAlexander Motin acpi_print_hest_aer(&s->Aer);
786ebc22d04SAlexander Motin return (sizeof(*s));
787ebc22d04SAlexander Motin }
788ebc22d04SAlexander Motin case ACPI_HEST_TYPE_AER_BRIDGE: {
789ebc22d04SAlexander Motin ACPI_HEST_AER_BRIDGE *s = addr;
790ebc22d04SAlexander Motin acpi_print_hest_aer(&s->Aer);
791ebc22d04SAlexander Motin printf("\tUncorrectableMask2=%d\n", s->UncorrectableMask2);
792ebc22d04SAlexander Motin printf("\tUncorrectableSeverity2=%d\n", s->UncorrectableSeverity2);
793ebc22d04SAlexander Motin printf("\tAdvancedCapabilities2=%d\n", s->AdvancedCapabilities2);
794ebc22d04SAlexander Motin return (sizeof(*s));
795ebc22d04SAlexander Motin }
796ebc22d04SAlexander Motin case ACPI_HEST_TYPE_GENERIC_ERROR: {
797ebc22d04SAlexander Motin ACPI_HEST_GENERIC *s = addr;
798ebc22d04SAlexander Motin printf("\tRelatedSourceId=%d\n", s->RelatedSourceId);
799ebc22d04SAlexander Motin printf("\tEnabled=%d\n", s->Enabled);
800ebc22d04SAlexander Motin printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
801ebc22d04SAlexander Motin printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
802ebc22d04SAlexander Motin printf("\tMaxRawDataLength=%d\n", s->MaxRawDataLength);
803ebc22d04SAlexander Motin printf("\tErrorStatusAddress=");
804ebc22d04SAlexander Motin acpi_print_gas(&s->ErrorStatusAddress);
805ebc22d04SAlexander Motin printf("\n");
806ebc22d04SAlexander Motin printf("\tNotify:\n");
807ebc22d04SAlexander Motin acpi_print_hest_notify(&s->Notify);
808ebc22d04SAlexander Motin printf("\tErrorBlockLength=%d\n", s->ErrorBlockLength);
809ebc22d04SAlexander Motin return (sizeof(*s));
810ebc22d04SAlexander Motin }
811ebc22d04SAlexander Motin case ACPI_HEST_TYPE_GENERIC_ERROR_V2: {
812ebc22d04SAlexander Motin ACPI_HEST_GENERIC_V2 *s = addr;
813ebc22d04SAlexander Motin printf("\tRelatedSourceId=%d\n", s->RelatedSourceId);
814ebc22d04SAlexander Motin printf("\tEnabled=%d\n", s->Enabled);
815ebc22d04SAlexander Motin printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
816ebc22d04SAlexander Motin printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
817ebc22d04SAlexander Motin printf("\tMaxRawDataLength=%d\n", s->MaxRawDataLength);
818ebc22d04SAlexander Motin printf("\tErrorStatusAddress=");
819ebc22d04SAlexander Motin acpi_print_gas(&s->ErrorStatusAddress);
820ebc22d04SAlexander Motin printf("\n");
821ebc22d04SAlexander Motin printf("\tNotify:\n");
822ebc22d04SAlexander Motin acpi_print_hest_notify(&s->Notify);
823ebc22d04SAlexander Motin printf("\tErrorBlockLength=%d\n", s->ErrorBlockLength);
824ebc22d04SAlexander Motin printf("\tReadAckRegister=");
825ebc22d04SAlexander Motin acpi_print_gas(&s->ReadAckRegister);
826ebc22d04SAlexander Motin printf("\n");
827ebc22d04SAlexander Motin printf("\tReadAckPreserve=%jd\n", s->ReadAckPreserve);
828ebc22d04SAlexander Motin printf("\tReadAckWrite=%jd\n", s->ReadAckWrite);
829ebc22d04SAlexander Motin return (sizeof(*s));
830ebc22d04SAlexander Motin }
831ebc22d04SAlexander Motin case ACPI_HEST_TYPE_IA32_DEFERRED_CHECK: {
832ebc22d04SAlexander Motin ACPI_HEST_IA_DEFERRED_CHECK *s = addr;
833ebc22d04SAlexander Motin printf("\tFlags=%02x\n", s->Flags);
834ebc22d04SAlexander Motin printf("\tEnabled=%d\n", s->Enabled);
835ebc22d04SAlexander Motin printf("\tRecordsToPreallocate=%d\n", s->RecordsToPreallocate);
836ebc22d04SAlexander Motin printf("\tMaxSectionsPerRecord=%d\n", s->MaxSectionsPerRecord);
837ebc22d04SAlexander Motin printf("\tNotify:\n");
838ebc22d04SAlexander Motin acpi_print_hest_notify(&s->Notify);
839ebc22d04SAlexander Motin printf("\tNumHardwareBanks=%d\n", s->NumHardwareBanks);
840ebc22d04SAlexander Motin for (i = 0; i < s->NumHardwareBanks; i++) {
841ebc22d04SAlexander Motin acpi_print_hest_bank((ACPI_HEST_IA_ERROR_BANK *)
842ebc22d04SAlexander Motin (s + 1) + i);
843ebc22d04SAlexander Motin }
844ebc22d04SAlexander Motin return (sizeof(*s) + s->NumHardwareBanks *
845ebc22d04SAlexander Motin sizeof(ACPI_HEST_IA_ERROR_BANK));
846ebc22d04SAlexander Motin }
847ebc22d04SAlexander Motin default:
848ebc22d04SAlexander Motin return (-1);
849ebc22d04SAlexander Motin }
850ebc22d04SAlexander Motin }
851ebc22d04SAlexander Motin
852ebc22d04SAlexander Motin static void
acpi_handle_hest(ACPI_TABLE_HEADER * sdp)853ebc22d04SAlexander Motin acpi_handle_hest(ACPI_TABLE_HEADER *sdp)
854ebc22d04SAlexander Motin {
855ebc22d04SAlexander Motin char *cp;
856ebc22d04SAlexander Motin int remaining, consumed;
857ebc22d04SAlexander Motin ACPI_TABLE_HEST *hest;
858ebc22d04SAlexander Motin
859ebc22d04SAlexander Motin printf(BEGIN_COMMENT);
860ebc22d04SAlexander Motin acpi_print_sdt(sdp);
861ebc22d04SAlexander Motin hest = (ACPI_TABLE_HEST *)sdp;
862ebc22d04SAlexander Motin printf("\tErrorSourceCount=%d\n", hest->ErrorSourceCount);
863ebc22d04SAlexander Motin
864ebc22d04SAlexander Motin remaining = sdp->Length - sizeof(ACPI_TABLE_HEST);
865ebc22d04SAlexander Motin while (remaining > 0) {
866ebc22d04SAlexander Motin cp = (char *)sdp + sdp->Length - remaining;
867ebc22d04SAlexander Motin consumed = acpi_handle_hest_structure(cp, remaining);
868ebc22d04SAlexander Motin if (consumed <= 0)
869ebc22d04SAlexander Motin break;
870ebc22d04SAlexander Motin else
871ebc22d04SAlexander Motin remaining -= consumed;
872ebc22d04SAlexander Motin }
873ebc22d04SAlexander Motin printf(END_COMMENT);
874ebc22d04SAlexander Motin }
875ebc22d04SAlexander Motin
876ebc22d04SAlexander Motin static void
acpi_handle_hpet(ACPI_TABLE_HEADER * sdp)877986dffafSJohn Baldwin acpi_handle_hpet(ACPI_TABLE_HEADER *sdp)
87879d7565cSPeter Wemm {
879986dffafSJohn Baldwin ACPI_TABLE_HPET *hpet;
88079d7565cSPeter Wemm
881773b6454SNate Lawson printf(BEGIN_COMMENT);
882773b6454SNate Lawson acpi_print_sdt(sdp);
883986dffafSJohn Baldwin hpet = (ACPI_TABLE_HPET *)sdp;
884986dffafSJohn Baldwin printf("\tHPET Number=%d\n", hpet->Sequence);
88587f9f09aSTakanori Watanabe printf("\tADDR=");
886986dffafSJohn Baldwin acpi_print_gas(&hpet->Address);
887ebc22d04SAlexander Motin printf("\n\tHW Rev=0x%x\n", hpet->Id & ACPI_HPET_ID_HARDWARE_REV_ID);
888986dffafSJohn Baldwin printf("\tComparators=%d\n", (hpet->Id & ACPI_HPET_ID_COMPARATORS) >>
889986dffafSJohn Baldwin 8);
890986dffafSJohn Baldwin printf("\tCounter Size=%d\n", hpet->Id & ACPI_HPET_ID_COUNT_SIZE_CAP ?
891986dffafSJohn Baldwin 1 : 0);
89279d7565cSPeter Wemm printf("\tLegacy IRQ routing capable={");
893986dffafSJohn Baldwin if (hpet->Id & ACPI_HPET_ID_LEGACY_CAPABLE)
89479d7565cSPeter Wemm printf("TRUE}\n");
89579d7565cSPeter Wemm else
89679d7565cSPeter Wemm printf("FALSE}\n");
897986dffafSJohn Baldwin printf("\tPCI Vendor ID=0x%04x\n", hpet->Id >> 16);
898986dffafSJohn Baldwin printf("\tMinimal Tick=%d\n", hpet->MinimumTick);
8999785e979SNeel Natu printf("\tFlags=0x%02x\n", hpet->Flags);
90079d7565cSPeter Wemm printf(END_COMMENT);
90179d7565cSPeter Wemm }
90279d7565cSPeter Wemm
90379d7565cSPeter Wemm static void
acpi_handle_ecdt(ACPI_TABLE_HEADER * sdp)904986dffafSJohn Baldwin acpi_handle_ecdt(ACPI_TABLE_HEADER *sdp)
90555d7ff9eSNate Lawson {
906986dffafSJohn Baldwin ACPI_TABLE_ECDT *ecdt;
90755d7ff9eSNate Lawson
90855d7ff9eSNate Lawson printf(BEGIN_COMMENT);
90955d7ff9eSNate Lawson acpi_print_sdt(sdp);
910986dffafSJohn Baldwin ecdt = (ACPI_TABLE_ECDT *)sdp;
91155d7ff9eSNate Lawson printf("\tEC_CONTROL=");
912986dffafSJohn Baldwin acpi_print_gas(&ecdt->Control);
91355d7ff9eSNate Lawson printf("\n\tEC_DATA=");
914986dffafSJohn Baldwin acpi_print_gas(&ecdt->Data);
915986dffafSJohn Baldwin printf("\n\tUID=%#x, ", ecdt->Uid);
916986dffafSJohn Baldwin printf("GPE_BIT=%#x\n", ecdt->Gpe);
917986dffafSJohn Baldwin printf("\tEC_ID=%s\n", ecdt->Id);
91855d7ff9eSNate Lawson printf(END_COMMENT);
91955d7ff9eSNate Lawson }
92055d7ff9eSNate Lawson
92155d7ff9eSNate Lawson static void
acpi_handle_mcfg(ACPI_TABLE_HEADER * sdp)922986dffafSJohn Baldwin acpi_handle_mcfg(ACPI_TABLE_HEADER *sdp)
923a47e681bSScott Long {
924986dffafSJohn Baldwin ACPI_TABLE_MCFG *mcfg;
925986dffafSJohn Baldwin ACPI_MCFG_ALLOCATION *alloc;
926986dffafSJohn Baldwin u_int i, entries;
927a47e681bSScott Long
928a47e681bSScott Long printf(BEGIN_COMMENT);
929a47e681bSScott Long acpi_print_sdt(sdp);
930986dffafSJohn Baldwin mcfg = (ACPI_TABLE_MCFG *)sdp;
931986dffafSJohn Baldwin entries = (sdp->Length - sizeof(ACPI_TABLE_MCFG)) /
932986dffafSJohn Baldwin sizeof(ACPI_MCFG_ALLOCATION);
933986dffafSJohn Baldwin alloc = (ACPI_MCFG_ALLOCATION *)(mcfg + 1);
934986dffafSJohn Baldwin for (i = 0; i < entries; i++, alloc++) {
935a47e681bSScott Long printf("\n");
9360c10b85aSJung-uk Kim printf("\tBase Address=0x%016jx\n", (uintmax_t)alloc->Address);
937986dffafSJohn Baldwin printf("\tSegment Group=0x%04x\n", alloc->PciSegment);
938986dffafSJohn Baldwin printf("\tStart Bus=%d\n", alloc->StartBusNumber);
939986dffafSJohn Baldwin printf("\tEnd Bus=%d\n", alloc->EndBusNumber);
940a47e681bSScott Long }
941a47e681bSScott Long printf(END_COMMENT);
942a47e681bSScott Long }
943a47e681bSScott Long
944a47e681bSScott Long static void
acpi_handle_slit(ACPI_TABLE_HEADER * sdp)94533866658SJohn Baldwin acpi_handle_slit(ACPI_TABLE_HEADER *sdp)
94633866658SJohn Baldwin {
94733866658SJohn Baldwin ACPI_TABLE_SLIT *slit;
94833866658SJohn Baldwin UINT64 i, j;
94933866658SJohn Baldwin
95033866658SJohn Baldwin printf(BEGIN_COMMENT);
95133866658SJohn Baldwin acpi_print_sdt(sdp);
95233866658SJohn Baldwin slit = (ACPI_TABLE_SLIT *)sdp;
9530c10b85aSJung-uk Kim printf("\tLocality Count=%ju\n", (uintmax_t)slit->LocalityCount);
95433866658SJohn Baldwin printf("\n\t ");
95533866658SJohn Baldwin for (i = 0; i < slit->LocalityCount; i++)
9560c10b85aSJung-uk Kim printf(" %3ju", (uintmax_t)i);
95733866658SJohn Baldwin printf("\n\t +");
95833866658SJohn Baldwin for (i = 0; i < slit->LocalityCount; i++)
95933866658SJohn Baldwin printf("----");
96033866658SJohn Baldwin printf("\n");
96133866658SJohn Baldwin for (i = 0; i < slit->LocalityCount; i++) {
9620c10b85aSJung-uk Kim printf("\t %3ju |", (uintmax_t)i);
96333866658SJohn Baldwin for (j = 0; j < slit->LocalityCount; j++)
96433866658SJohn Baldwin printf(" %3d",
96533866658SJohn Baldwin slit->Entry[i * slit->LocalityCount + j]);
96633866658SJohn Baldwin printf("\n");
96733866658SJohn Baldwin }
96833866658SJohn Baldwin printf(END_COMMENT);
96933866658SJohn Baldwin }
97033866658SJohn Baldwin
97133866658SJohn Baldwin static void
acpi_handle_wddt(ACPI_TABLE_HEADER * sdp)972ed26c389SScott Long acpi_handle_wddt(ACPI_TABLE_HEADER *sdp)
973ed26c389SScott Long {
974ed26c389SScott Long ACPI_TABLE_WDDT *wddt;
975ed26c389SScott Long
976ed26c389SScott Long printf(BEGIN_COMMENT);
977ed26c389SScott Long acpi_print_sdt(sdp);
978ed26c389SScott Long wddt = (ACPI_TABLE_WDDT *)sdp;
979ed26c389SScott Long printf("\tSpecVersion=0x%04x, TableVersion=0x%04x\n",
980ed26c389SScott Long wddt->SpecVersion, wddt->TableVersion);
981ed26c389SScott Long printf("\tPciVendorId=0x%04x, Address=", wddt->PciVendorId);
982ed26c389SScott Long acpi_print_gas(&wddt->Address);
983ed26c389SScott Long printf("\n\tMaxCount=%u, MinCount=%u, Period=%ums\n",
984ed26c389SScott Long wddt->MaxCount, wddt->MinCount, wddt->Period);
985ed26c389SScott Long
986ed26c389SScott Long #define PRINTFLAG(var, flag) printflag((var), ACPI_WDDT_## flag, #flag)
987ed26c389SScott Long printf("\tStatus=");
988ed26c389SScott Long PRINTFLAG(wddt->Status, AVAILABLE);
989ed26c389SScott Long PRINTFLAG(wddt->Status, ACTIVE);
990ed26c389SScott Long PRINTFLAG(wddt->Status, TCO_OS_OWNED);
991ed26c389SScott Long PRINTFLAG(wddt->Status, USER_RESET);
992ed26c389SScott Long PRINTFLAG(wddt->Status, WDT_RESET);
993ed26c389SScott Long PRINTFLAG(wddt->Status, POWER_FAIL);
994ed26c389SScott Long PRINTFLAG(wddt->Status, UNKNOWN_RESET);
995ed26c389SScott Long PRINTFLAG_END();
996ed26c389SScott Long printf("\tCapability=");
997ed26c389SScott Long PRINTFLAG(wddt->Capability, AUTO_RESET);
998ed26c389SScott Long PRINTFLAG(wddt->Capability, ALERT_SUPPORT);
999ed26c389SScott Long PRINTFLAG_END();
1000ed26c389SScott Long #undef PRINTFLAG
1001ed26c389SScott Long
1002ed26c389SScott Long printf(END_COMMENT);
1003ed26c389SScott Long }
1004ed26c389SScott Long
1005ed26c389SScott Long static void
acpi_print_native_lpit(ACPI_LPIT_NATIVE * nl)10065857fba5SBen Widawsky acpi_print_native_lpit(ACPI_LPIT_NATIVE *nl)
10075857fba5SBen Widawsky {
10085857fba5SBen Widawsky printf("\tEntryTrigger=");
10095857fba5SBen Widawsky acpi_print_gas(&nl->EntryTrigger);
1010ebc22d04SAlexander Motin printf("\n\tResidency=%u\n", nl->Residency);
10115857fba5SBen Widawsky printf("\tLatency=%u\n", nl->Latency);
10125857fba5SBen Widawsky if (nl->Header.Flags & ACPI_LPIT_NO_COUNTER)
10135857fba5SBen Widawsky printf("\tResidencyCounter=Not Present");
10145857fba5SBen Widawsky else {
10155857fba5SBen Widawsky printf("\tResidencyCounter=");
10165857fba5SBen Widawsky acpi_print_gas(&nl->ResidencyCounter);
1017ebc22d04SAlexander Motin printf("\n");
10185857fba5SBen Widawsky }
10195857fba5SBen Widawsky if (nl->CounterFrequency)
10205857fba5SBen Widawsky printf("\tCounterFrequency=%ju\n", nl->CounterFrequency);
10215857fba5SBen Widawsky else
10225857fba5SBen Widawsky printf("\tCounterFrequency=TSC\n");
10235857fba5SBen Widawsky }
10245857fba5SBen Widawsky
10255857fba5SBen Widawsky static void
acpi_print_lpit(ACPI_LPIT_HEADER * lpit)10265857fba5SBen Widawsky acpi_print_lpit(ACPI_LPIT_HEADER *lpit)
10275857fba5SBen Widawsky {
10285857fba5SBen Widawsky if (lpit->Type == ACPI_LPIT_TYPE_NATIVE_CSTATE)
10295857fba5SBen Widawsky printf("\tType=ACPI_LPIT_TYPE_NATIVE_CSTATE\n");
10305857fba5SBen Widawsky else
10315857fba5SBen Widawsky warnx("unknown LPIT type %u", lpit->Type);
10325857fba5SBen Widawsky
10335857fba5SBen Widawsky printf("\tLength=%u\n", lpit->Length);
10345857fba5SBen Widawsky printf("\tUniqueId=0x%04x\n", lpit->UniqueId);
10355857fba5SBen Widawsky #define PRINTFLAG(var, flag) printflag((var), ACPI_LPIT_## flag, #flag)
10365857fba5SBen Widawsky printf("\tFlags=");
10375857fba5SBen Widawsky PRINTFLAG(lpit->Flags, STATE_DISABLED);
10385857fba5SBen Widawsky PRINTFLAG_END();
10395857fba5SBen Widawsky #undef PRINTFLAG
10405857fba5SBen Widawsky
10415857fba5SBen Widawsky if (lpit->Type == ACPI_LPIT_TYPE_NATIVE_CSTATE)
10425857fba5SBen Widawsky return acpi_print_native_lpit((ACPI_LPIT_NATIVE *)lpit);
10435857fba5SBen Widawsky }
10445857fba5SBen Widawsky
10455857fba5SBen Widawsky static void
acpi_walk_lpit(ACPI_TABLE_HEADER * table,void * first,void (* action)(ACPI_LPIT_HEADER *))10465857fba5SBen Widawsky acpi_walk_lpit(ACPI_TABLE_HEADER *table, void *first,
10475857fba5SBen Widawsky void (*action)(ACPI_LPIT_HEADER *))
10485857fba5SBen Widawsky {
10495857fba5SBen Widawsky ACPI_LPIT_HEADER *subtable;
10505857fba5SBen Widawsky char *end;
10515857fba5SBen Widawsky
10525857fba5SBen Widawsky subtable = first;
10535857fba5SBen Widawsky end = (char *)table + table->Length;
10545857fba5SBen Widawsky while ((char *)subtable < end) {
10555857fba5SBen Widawsky printf("\n");
10565857fba5SBen Widawsky if (subtable->Length < sizeof(ACPI_LPIT_HEADER)) {
10575857fba5SBen Widawsky warnx("invalid subtable length %u", subtable->Length);
10585857fba5SBen Widawsky return;
10595857fba5SBen Widawsky }
10605857fba5SBen Widawsky action(subtable);
10615857fba5SBen Widawsky subtable = (ACPI_LPIT_HEADER *)((char *)subtable +
10625857fba5SBen Widawsky subtable->Length);
10635857fba5SBen Widawsky }
10645857fba5SBen Widawsky }
10655857fba5SBen Widawsky
10665857fba5SBen Widawsky static void
acpi_handle_lpit(ACPI_TABLE_HEADER * sdp)10675857fba5SBen Widawsky acpi_handle_lpit(ACPI_TABLE_HEADER *sdp)
10685857fba5SBen Widawsky {
10695857fba5SBen Widawsky ACPI_TABLE_LPIT *lpit;
10705857fba5SBen Widawsky
10715857fba5SBen Widawsky printf(BEGIN_COMMENT);
10725857fba5SBen Widawsky acpi_print_sdt(sdp);
10735857fba5SBen Widawsky lpit = (ACPI_TABLE_LPIT *)sdp;
10745857fba5SBen Widawsky acpi_walk_lpit(sdp, (lpit + 1), acpi_print_lpit);
10755857fba5SBen Widawsky
10765857fba5SBen Widawsky printf(END_COMMENT);
10775857fba5SBen Widawsky }
10785857fba5SBen Widawsky
10795857fba5SBen Widawsky static void
acpi_print_srat_cpu(uint32_t apic_id,uint32_t proximity_domain,uint32_t flags)1080a0333ad1SJohn Baldwin acpi_print_srat_cpu(uint32_t apic_id, uint32_t proximity_domain,
1081a0333ad1SJohn Baldwin uint32_t flags)
1082a0333ad1SJohn Baldwin {
1083a0333ad1SJohn Baldwin
1084a0333ad1SJohn Baldwin printf("\tFlags={");
1085a0333ad1SJohn Baldwin if (flags & ACPI_SRAT_CPU_ENABLED)
1086a0333ad1SJohn Baldwin printf("ENABLED");
1087a0333ad1SJohn Baldwin else
1088a0333ad1SJohn Baldwin printf("DISABLED");
1089a0333ad1SJohn Baldwin printf("}\n");
1090a0333ad1SJohn Baldwin printf("\tAPIC ID=%d\n", apic_id);
1091a0333ad1SJohn Baldwin printf("\tProximity Domain=%d\n", proximity_domain);
1092a0333ad1SJohn Baldwin }
1093a0333ad1SJohn Baldwin
1094c031c93bSTakanori Watanabe static char *
acpi_tcpa_evname(struct TCPAevent * event)1095c031c93bSTakanori Watanabe acpi_tcpa_evname(struct TCPAevent *event)
1096c031c93bSTakanori Watanabe {
1097c031c93bSTakanori Watanabe struct TCPApc_event *pc_event;
1098c031c93bSTakanori Watanabe char *eventname = NULL;
1099c031c93bSTakanori Watanabe
1100c031c93bSTakanori Watanabe pc_event = (struct TCPApc_event *)(event + 1);
1101c031c93bSTakanori Watanabe
1102c031c93bSTakanori Watanabe switch(event->event_type) {
1103c031c93bSTakanori Watanabe case PREBOOT:
1104c031c93bSTakanori Watanabe case POST_CODE:
1105c031c93bSTakanori Watanabe case UNUSED:
1106c031c93bSTakanori Watanabe case NO_ACTION:
1107c031c93bSTakanori Watanabe case SEPARATOR:
1108c031c93bSTakanori Watanabe case SCRTM_CONTENTS:
1109c031c93bSTakanori Watanabe case SCRTM_VERSION:
1110c031c93bSTakanori Watanabe case CPU_MICROCODE:
1111c031c93bSTakanori Watanabe case PLATFORM_CONFIG_FLAGS:
1112c031c93bSTakanori Watanabe case TABLE_OF_DEVICES:
1113c031c93bSTakanori Watanabe case COMPACT_HASH:
1114c031c93bSTakanori Watanabe case IPL:
1115c031c93bSTakanori Watanabe case IPL_PARTITION_DATA:
1116c031c93bSTakanori Watanabe case NONHOST_CODE:
1117c031c93bSTakanori Watanabe case NONHOST_CONFIG:
1118c031c93bSTakanori Watanabe case NONHOST_INFO:
1119c031c93bSTakanori Watanabe asprintf(&eventname, "%s",
1120c031c93bSTakanori Watanabe tcpa_event_type_strings[event->event_type]);
1121c031c93bSTakanori Watanabe break;
1122c031c93bSTakanori Watanabe
1123c031c93bSTakanori Watanabe case ACTION:
1124c031c93bSTakanori Watanabe eventname = calloc(event->event_size + 1, sizeof(char));
1125c031c93bSTakanori Watanabe memcpy(eventname, pc_event, event->event_size);
1126c031c93bSTakanori Watanabe break;
1127c031c93bSTakanori Watanabe
1128c031c93bSTakanori Watanabe case EVENT_TAG:
1129c031c93bSTakanori Watanabe switch (pc_event->event_id) {
1130c031c93bSTakanori Watanabe case SMBIOS:
1131c031c93bSTakanori Watanabe case BIS_CERT:
1132c031c93bSTakanori Watanabe case CMOS:
1133c031c93bSTakanori Watanabe case NVRAM:
1134c031c93bSTakanori Watanabe case OPTION_ROM_EXEC:
1135c031c93bSTakanori Watanabe case OPTION_ROM_CONFIG:
1136c031c93bSTakanori Watanabe case S_CRTM_VERSION:
1137c031c93bSTakanori Watanabe case POST_BIOS_ROM:
1138c031c93bSTakanori Watanabe case ESCD:
1139c031c93bSTakanori Watanabe case OPTION_ROM_MICROCODE:
1140c031c93bSTakanori Watanabe case S_CRTM_CONTENTS:
1141c031c93bSTakanori Watanabe case POST_CONTENTS:
1142c031c93bSTakanori Watanabe asprintf(&eventname, "%s",
1143c031c93bSTakanori Watanabe TCPA_pcclient_strings[pc_event->event_id]);
1144c031c93bSTakanori Watanabe break;
1145c031c93bSTakanori Watanabe
1146c031c93bSTakanori Watanabe default:
1147c031c93bSTakanori Watanabe asprintf(&eventname, "<unknown tag 0x%02x>",
1148c031c93bSTakanori Watanabe pc_event->event_id);
1149c031c93bSTakanori Watanabe break;
1150c031c93bSTakanori Watanabe }
1151c031c93bSTakanori Watanabe break;
1152c031c93bSTakanori Watanabe
1153c031c93bSTakanori Watanabe default:
1154c031c93bSTakanori Watanabe asprintf(&eventname, "<unknown 0x%02x>", event->event_type);
1155c031c93bSTakanori Watanabe break;
1156c031c93bSTakanori Watanabe }
1157c031c93bSTakanori Watanabe
1158c031c93bSTakanori Watanabe return eventname;
1159c031c93bSTakanori Watanabe }
1160c031c93bSTakanori Watanabe
1161c031c93bSTakanori Watanabe static void
acpi_print_tcpa(struct TCPAevent * event)1162c031c93bSTakanori Watanabe acpi_print_tcpa(struct TCPAevent *event)
1163c031c93bSTakanori Watanabe {
1164c031c93bSTakanori Watanabe int i;
1165c031c93bSTakanori Watanabe char *eventname;
1166c031c93bSTakanori Watanabe
1167c031c93bSTakanori Watanabe eventname = acpi_tcpa_evname(event);
1168c031c93bSTakanori Watanabe
1169c031c93bSTakanori Watanabe printf("\t%d", event->pcr_index);
1170c031c93bSTakanori Watanabe printf(" 0x");
1171c031c93bSTakanori Watanabe for (i = 0; i < 20; i++)
1172c031c93bSTakanori Watanabe printf("%02x", event->pcr_value[i]);
1173c031c93bSTakanori Watanabe printf(" [%s]\n", eventname ? eventname : "<unknown>");
1174c031c93bSTakanori Watanabe
1175c031c93bSTakanori Watanabe free(eventname);
1176c031c93bSTakanori Watanabe }
1177c031c93bSTakanori Watanabe
1178c031c93bSTakanori Watanabe static void
acpi_handle_tcpa(ACPI_TABLE_HEADER * sdp)1179c031c93bSTakanori Watanabe acpi_handle_tcpa(ACPI_TABLE_HEADER *sdp)
1180c031c93bSTakanori Watanabe {
1181c031c93bSTakanori Watanabe struct TCPAbody *tcpa;
1182c031c93bSTakanori Watanabe struct TCPAevent *event;
1183977fd9daSTakanori Watanabe uintmax_t len, paddr;
1184c031c93bSTakanori Watanabe unsigned char *vaddr = NULL;
1185c031c93bSTakanori Watanabe unsigned char *vend = NULL;
1186c031c93bSTakanori Watanabe
1187c031c93bSTakanori Watanabe printf(BEGIN_COMMENT);
1188c031c93bSTakanori Watanabe acpi_print_sdt(sdp);
1189c031c93bSTakanori Watanabe tcpa = (struct TCPAbody *) sdp;
1190c031c93bSTakanori Watanabe
1191c031c93bSTakanori Watanabe switch (tcpa->platform_class) {
1192c031c93bSTakanori Watanabe case ACPI_TCPA_BIOS_CLIENT:
1193c031c93bSTakanori Watanabe len = tcpa->client.log_max_len;
1194c031c93bSTakanori Watanabe paddr = tcpa->client.log_start_addr;
1195c031c93bSTakanori Watanabe break;
1196c031c93bSTakanori Watanabe
1197c031c93bSTakanori Watanabe case ACPI_TCPA_BIOS_SERVER:
1198c031c93bSTakanori Watanabe len = tcpa->server.log_max_len;
1199c031c93bSTakanori Watanabe paddr = tcpa->server.log_start_addr;
1200c031c93bSTakanori Watanabe break;
1201c031c93bSTakanori Watanabe
1202c031c93bSTakanori Watanabe default:
1203c031c93bSTakanori Watanabe printf("XXX");
1204c031c93bSTakanori Watanabe printf(END_COMMENT);
1205c031c93bSTakanori Watanabe return;
1206c031c93bSTakanori Watanabe }
12070e1982f4STakanori Watanabe printf("\tClass %u Base Address 0x%jx Length %ju\n\n",
1208c031c93bSTakanori Watanabe tcpa->platform_class, paddr, len);
1209c031c93bSTakanori Watanabe
1210c031c93bSTakanori Watanabe if (len == 0) {
1211c031c93bSTakanori Watanabe printf("\tEmpty TCPA table\n");
1212c031c93bSTakanori Watanabe printf(END_COMMENT);
1213c031c93bSTakanori Watanabe return;
1214c031c93bSTakanori Watanabe }
12152ef23c6dSTakanori Watanabe if(sdp->Revision == 1){
12162ef23c6dSTakanori Watanabe printf("\tOLD TCPA spec log found. Dumping not supported.\n");
12172ef23c6dSTakanori Watanabe printf(END_COMMENT);
12182ef23c6dSTakanori Watanabe return;
12192ef23c6dSTakanori Watanabe }
1220c031c93bSTakanori Watanabe
1221c031c93bSTakanori Watanabe vaddr = (unsigned char *)acpi_map_physical(paddr, len);
1222c031c93bSTakanori Watanabe vend = vaddr + len;
1223c031c93bSTakanori Watanabe
1224c031c93bSTakanori Watanabe while (vaddr != NULL) {
1225*8c108dccSKonstantin Belousov if ((uintptr_t)vaddr + sizeof(struct TCPAevent) >=
1226*8c108dccSKonstantin Belousov (uintptr_t)vend || (uintptr_t)vaddr + sizeof(
1227*8c108dccSKonstantin Belousov struct TCPAevent) < (uintptr_t)vaddr)
1228c031c93bSTakanori Watanabe break;
12290e1982f4STakanori Watanabe event = (struct TCPAevent *)(void *)vaddr;
1230*8c108dccSKonstantin Belousov if ((uintptr_t)vaddr + event->event_size >= (uintptr_t)vend)
1231c031c93bSTakanori Watanabe break;
1232*8c108dccSKonstantin Belousov if ((uintptr_t)vaddr + event->event_size < (uintptr_t)vaddr)
12332ef23c6dSTakanori Watanabe break;
1234c031c93bSTakanori Watanabe if (event->event_type == 0 && event->event_size == 0)
1235c031c93bSTakanori Watanabe break;
1236c031c93bSTakanori Watanabe #if 0
1237c031c93bSTakanori Watanabe {
1238c031c93bSTakanori Watanabe unsigned int i, j, k;
1239c031c93bSTakanori Watanabe
1240c031c93bSTakanori Watanabe printf("\n\tsize %d\n\t\t%p ", event->event_size, vaddr);
1241c031c93bSTakanori Watanabe for (j = 0, i = 0; i <
1242c031c93bSTakanori Watanabe sizeof(struct TCPAevent) + event->event_size; i++) {
1243c031c93bSTakanori Watanabe printf("%02x ", vaddr[i]);
1244c031c93bSTakanori Watanabe if ((i+1) % 8 == 0) {
1245c031c93bSTakanori Watanabe for (k = 0; k < 8; k++)
1246c031c93bSTakanori Watanabe printf("%c", isprint(vaddr[j+k]) ?
1247c031c93bSTakanori Watanabe vaddr[j+k] : '.');
1248c031c93bSTakanori Watanabe printf("\n\t\t%p ", &vaddr[i + 1]);
1249c031c93bSTakanori Watanabe j = i + 1;
1250c031c93bSTakanori Watanabe }
1251c031c93bSTakanori Watanabe }
1252c031c93bSTakanori Watanabe printf("\n"); }
1253c031c93bSTakanori Watanabe #endif
1254c031c93bSTakanori Watanabe acpi_print_tcpa(event);
1255c031c93bSTakanori Watanabe
1256c031c93bSTakanori Watanabe vaddr += sizeof(struct TCPAevent) + event->event_size;
1257c031c93bSTakanori Watanabe }
1258c031c93bSTakanori Watanabe
1259c031c93bSTakanori Watanabe printf(END_COMMENT);
1260c031c93bSTakanori Watanabe }
12615d57fad8SWarner Losh
acpi_handle_tpm2(ACPI_TABLE_HEADER * sdp)1262877fc2e3STakanori Watanabe static void acpi_handle_tpm2(ACPI_TABLE_HEADER *sdp)
1263877fc2e3STakanori Watanabe {
1264877fc2e3STakanori Watanabe ACPI_TABLE_TPM2 *tpm2;
1265877fc2e3STakanori Watanabe
1266877fc2e3STakanori Watanabe printf (BEGIN_COMMENT);
1267877fc2e3STakanori Watanabe acpi_print_sdt(sdp);
1268877fc2e3STakanori Watanabe tpm2 = (ACPI_TABLE_TPM2 *) sdp;
12697aef7138SCy Schubert printf ("\t\tControlArea=%jx\n", tpm2->ControlAddress);
1270877fc2e3STakanori Watanabe printf ("\t\tStartMethod=%x\n", tpm2->StartMethod);
1271877fc2e3STakanori Watanabe printf (END_COMMENT);
1272877fc2e3STakanori Watanabe }
1273c031c93bSTakanori Watanabe
spcr_xlate_baud(uint8_t r)12745d57fad8SWarner Losh static int spcr_xlate_baud(uint8_t r)
12755d57fad8SWarner Losh {
12765d57fad8SWarner Losh static int rates[] = { 9600, 19200, -1, 57600, 115200 };
12775d57fad8SWarner Losh _Static_assert(nitems(rates) == 7 - 3 + 1, "rates array size incorrect");
12785d57fad8SWarner Losh
12795d57fad8SWarner Losh if (r == 0)
12805d57fad8SWarner Losh return (0);
12815d57fad8SWarner Losh
12825d57fad8SWarner Losh if (r < 3 || r > 7)
12835d57fad8SWarner Losh return (-1);
12845d57fad8SWarner Losh
12855d57fad8SWarner Losh return (rates[r - 3]);
12865d57fad8SWarner Losh }
12875d57fad8SWarner Losh
spcr_interface_type(int ift)12885d57fad8SWarner Losh static const char *spcr_interface_type(int ift)
12895d57fad8SWarner Losh {
12905d57fad8SWarner Losh static const char *if_names[] = {
12915d57fad8SWarner Losh [0x00] = "Fully 16550-compatible",
12925d57fad8SWarner Losh [0x01] = "16550 subset compatible with DBGP Revision 1",
12935d57fad8SWarner Losh [0x02] = "MAX311xE SPI UART",
12945d57fad8SWarner Losh [0x03] = "Arm PL011 UART",
12955d57fad8SWarner Losh [0x04] = "MSM8x60 (e.g. 8960)",
12965d57fad8SWarner Losh [0x05] = "Nvidia 16550",
12975d57fad8SWarner Losh [0x06] = "TI OMAP",
12985d57fad8SWarner Losh [0x07] = "Reserved (Do Not Use)",
12995d57fad8SWarner Losh [0x08] = "APM88xxxx",
13005d57fad8SWarner Losh [0x09] = "MSM8974",
13015d57fad8SWarner Losh [0x0a] = "SAM5250",
13025d57fad8SWarner Losh [0x0b] = "Intel USIF",
13035d57fad8SWarner Losh [0x0c] = "i.MX 6",
13045d57fad8SWarner Losh [0x0d] = "(deprecated) Arm SBSA (2.x only) Generic UART supporting only 32-bit accesses",
13055d57fad8SWarner Losh [0x0e] = "Arm SBSA Generic UART",
13065d57fad8SWarner Losh [0x0f] = "Arm DCC",
13075d57fad8SWarner Losh [0x10] = "BCM2835",
13085d57fad8SWarner Losh [0x11] = "SDM845 with clock rate of 1.8432 MHz",
13095d57fad8SWarner Losh [0x12] = "16550-compatible with parameters defined in Generic Address Structure",
13105d57fad8SWarner Losh [0x13] = "SDM845 with clock rate of 7.372 MHz",
13115d57fad8SWarner Losh [0x14] = "Intel LPSS",
13125d57fad8SWarner Losh [0x15] = "RISC-V SBI console (any supported SBI mechanism)",
13135d57fad8SWarner Losh };
13145d57fad8SWarner Losh
13155d57fad8SWarner Losh if (ift >= (int)nitems(if_names) || if_names[ift] == NULL)
13165d57fad8SWarner Losh return ("Reserved");
13175d57fad8SWarner Losh return (if_names[ift]);
13185d57fad8SWarner Losh }
13195d57fad8SWarner Losh
spcr_interrupt_type(int ift)13205d57fad8SWarner Losh static const char *spcr_interrupt_type(int ift)
13215d57fad8SWarner Losh {
13225d57fad8SWarner Losh static char buf[100];
13235d57fad8SWarner Losh
13245d57fad8SWarner Losh #define APPEND(b,s) \
13255d57fad8SWarner Losh if ((ift & (b)) != 0) { \
13265d57fad8SWarner Losh if (strlen(buf) > 0) \
13275d57fad8SWarner Losh strlcat(buf, ",", sizeof(buf)); \
13285d57fad8SWarner Losh strlcat(buf, s, sizeof(buf)); \
13295d57fad8SWarner Losh }
13305d57fad8SWarner Losh
13315d57fad8SWarner Losh *buf = '\0';
13325d57fad8SWarner Losh APPEND(0x01, "PC/AT IRQ");
13335d57fad8SWarner Losh APPEND(0x02, "I/O APIC");
13345d57fad8SWarner Losh APPEND(0x04, "I/O SAPIC");
13355d57fad8SWarner Losh APPEND(0x08, "ARMH GIC");
13365d57fad8SWarner Losh APPEND(0x10, "RISC-V PLIC/APLIC");
13375d57fad8SWarner Losh
13385d57fad8SWarner Losh #undef APPEND
13395d57fad8SWarner Losh
13405d57fad8SWarner Losh return (buf);
13415d57fad8SWarner Losh }
13425d57fad8SWarner Losh
spcr_terminal_type(int type)13435d57fad8SWarner Losh static const char *spcr_terminal_type(int type)
13445d57fad8SWarner Losh {
13455d57fad8SWarner Losh static const char *term_names[] = {
13465d57fad8SWarner Losh [0] = "VT100",
13475d57fad8SWarner Losh [1] = "Extended VT100",
13485d57fad8SWarner Losh [2] = "VT-UTF8",
13495d57fad8SWarner Losh [3] = "ANSI",
13505d57fad8SWarner Losh };
13515d57fad8SWarner Losh
13525d57fad8SWarner Losh if (type >= (int)nitems(term_names) || term_names[type] == NULL)
13535d57fad8SWarner Losh return ("Reserved");
13545d57fad8SWarner Losh return (term_names[type]);
13555d57fad8SWarner Losh }
13565d57fad8SWarner Losh
acpi_handle_spcr(ACPI_TABLE_HEADER * sdp)13575d57fad8SWarner Losh static void acpi_handle_spcr(ACPI_TABLE_HEADER *sdp)
13585d57fad8SWarner Losh {
13595d57fad8SWarner Losh ACPI_TABLE_SPCR *spcr;
13605d57fad8SWarner Losh
13615d57fad8SWarner Losh printf (BEGIN_COMMENT);
13625d57fad8SWarner Losh acpi_print_sdt(sdp);
13635d57fad8SWarner Losh
13645d57fad8SWarner Losh /* Rev 1 and 2 are the same size */
13655d57fad8SWarner Losh spcr = (ACPI_TABLE_SPCR *) sdp;
13665d57fad8SWarner Losh printf ("\tInterfaceType=%d (%s)\n", spcr->InterfaceType,
13675d57fad8SWarner Losh spcr_interface_type(spcr->InterfaceType));
13685d57fad8SWarner Losh printf ("\tSerialPort=");
13695d57fad8SWarner Losh acpi_print_gas(&spcr->SerialPort);
13705d57fad8SWarner Losh printf ("\n\tInterruptType=%#x (%s)\n", spcr->InterruptType,
13715d57fad8SWarner Losh spcr_interrupt_type(spcr->InterruptType));
13725d57fad8SWarner Losh printf ("\tPcInterrupt=%d (%s)\n", spcr->PcInterrupt,
13735d57fad8SWarner Losh (spcr->InterruptType & 0x1) ? "Valid" : "Invalid");
13745d57fad8SWarner Losh printf ("\tInterrupt=%d\n", spcr->Interrupt);
13755d57fad8SWarner Losh printf ("\tBaudRate=%d (%d)\n", spcr_xlate_baud(spcr->BaudRate), spcr->BaudRate);
13765d57fad8SWarner Losh printf ("\tParity=%d\n", spcr->Parity);
13775d57fad8SWarner Losh printf ("\tStopBits=%d\n", spcr->StopBits);
13785d57fad8SWarner Losh printf ("\tFlowControl=%d\n", spcr->FlowControl);
13795d57fad8SWarner Losh printf ("\tTerminalType=%d (%s)\n", spcr->TerminalType,
13805d57fad8SWarner Losh spcr_terminal_type(spcr->TerminalType));
13815d57fad8SWarner Losh printf ("\tPciDeviceId=%#04x\n", spcr->PciDeviceId);
13825d57fad8SWarner Losh printf ("\tPciVendorId=%#04x\n", spcr->PciVendorId);
13835d57fad8SWarner Losh printf ("\tPciBus=%d\n", spcr->PciBus);
13845d57fad8SWarner Losh printf ("\tPciDevice=%d\n", spcr->PciDevice);
13855d57fad8SWarner Losh printf ("\tPciFunction=%d\n", spcr->PciFunction);
13865d57fad8SWarner Losh printf ("\tPciFlags=%d\n", spcr->PciFlags);
13875d57fad8SWarner Losh printf ("\tPciSegment=%d\n", spcr->PciSegment);
13885d57fad8SWarner Losh
13895d57fad8SWarner Losh /* Rev 3 added UartClkFrequency */
13905d57fad8SWarner Losh if (sdp->Revision >= 3) {
13915d57fad8SWarner Losh printf("\tLanguage=%d\n", spcr->Language);
13925d57fad8SWarner Losh printf("\tUartClkFreq=%jd",
13935d57fad8SWarner Losh (uintmax_t)spcr->UartClkFreq);
13945d57fad8SWarner Losh }
13955d57fad8SWarner Losh
13965d57fad8SWarner Losh /* Rev 4 added PreciseBaudrate and NameSpace* */
13975d57fad8SWarner Losh if (sdp->Revision >= 4) {
13985d57fad8SWarner Losh printf("\tPreciseBaudrate=%jd",
13995d57fad8SWarner Losh (uintmax_t)spcr->PreciseBaudrate);
14005d57fad8SWarner Losh if (spcr->NameSpaceStringLength > 0 &&
14015d57fad8SWarner Losh spcr->NameSpaceStringOffset >= sizeof(*spcr) &&
14025d57fad8SWarner Losh sdp->Length >= spcr->NameSpaceStringOffset +
14035d57fad8SWarner Losh spcr->NameSpaceStringLength) {
14045d57fad8SWarner Losh printf ("\tNameSpaceString='%s'\n",
14055d57fad8SWarner Losh (char *)sdp + spcr->NameSpaceStringOffset);
14065d57fad8SWarner Losh }
14075d57fad8SWarner Losh }
14085d57fad8SWarner Losh
14095d57fad8SWarner Losh printf (END_COMMENT);
14105d57fad8SWarner Losh }
14115d57fad8SWarner Losh
1412ec650989SNeel Natu static const char *
devscope_type2str(int type)1413ec650989SNeel Natu devscope_type2str(int type)
1414ec650989SNeel Natu {
1415ec650989SNeel Natu static char typebuf[16];
1416ec650989SNeel Natu
1417ec650989SNeel Natu switch (type) {
14185a6e19caSKonstantin Belousov case ACPI_DMAR_SCOPE_TYPE_ENDPOINT:
1419ec650989SNeel Natu return ("PCI Endpoint Device");
14205a6e19caSKonstantin Belousov case ACPI_DMAR_SCOPE_TYPE_BRIDGE:
1421ec650989SNeel Natu return ("PCI Sub-Hierarchy");
14225a6e19caSKonstantin Belousov case ACPI_DMAR_SCOPE_TYPE_IOAPIC:
1423ec650989SNeel Natu return ("IOAPIC");
14245a6e19caSKonstantin Belousov case ACPI_DMAR_SCOPE_TYPE_HPET:
1425ec650989SNeel Natu return ("HPET");
14265a6e19caSKonstantin Belousov case ACPI_DMAR_SCOPE_TYPE_NAMESPACE:
14275a6e19caSKonstantin Belousov return ("ACPI NS DEV");
1428ec650989SNeel Natu default:
1429ec650989SNeel Natu snprintf(typebuf, sizeof(typebuf), "%d", type);
1430ec650989SNeel Natu return (typebuf);
1431ec650989SNeel Natu }
1432ec650989SNeel Natu }
1433ec650989SNeel Natu
1434ec650989SNeel Natu static int
acpi_handle_dmar_devscope(void * addr,int remaining)1435ec650989SNeel Natu acpi_handle_dmar_devscope(void *addr, int remaining)
1436ec650989SNeel Natu {
1437ec650989SNeel Natu char sep;
1438ec650989SNeel Natu int pathlen;
1439ec650989SNeel Natu ACPI_DMAR_PCI_PATH *path, *pathend;
1440ec650989SNeel Natu ACPI_DMAR_DEVICE_SCOPE *devscope = addr;
1441ec650989SNeel Natu
1442ec650989SNeel Natu if (remaining < (int)sizeof(ACPI_DMAR_DEVICE_SCOPE))
1443ec650989SNeel Natu return (-1);
1444ec650989SNeel Natu
1445ec650989SNeel Natu if (remaining < devscope->Length)
1446ec650989SNeel Natu return (-1);
1447ec650989SNeel Natu
1448ec650989SNeel Natu printf("\n");
1449ec650989SNeel Natu printf("\t\tType=%s\n", devscope_type2str(devscope->EntryType));
1450ec650989SNeel Natu printf("\t\tLength=%d\n", devscope->Length);
1451ec650989SNeel Natu printf("\t\tEnumerationId=%d\n", devscope->EnumerationId);
1452ec650989SNeel Natu printf("\t\tStartBusNumber=%d\n", devscope->Bus);
1453ec650989SNeel Natu
1454ec650989SNeel Natu path = (ACPI_DMAR_PCI_PATH *)(devscope + 1);
1455ec650989SNeel Natu pathlen = devscope->Length - sizeof(ACPI_DMAR_DEVICE_SCOPE);
1456ec650989SNeel Natu pathend = path + pathlen / sizeof(ACPI_DMAR_PCI_PATH);
1457ec650989SNeel Natu if (path < pathend) {
1458ec650989SNeel Natu sep = '{';
1459ec650989SNeel Natu printf("\t\tPath=");
1460ec650989SNeel Natu do {
1461ec650989SNeel Natu printf("%c%d:%d", sep, path->Device, path->Function);
1462ec650989SNeel Natu sep=',';
1463ec650989SNeel Natu path++;
1464ec650989SNeel Natu } while (path < pathend);
1465ec650989SNeel Natu printf("}\n");
1466ec650989SNeel Natu }
1467ec650989SNeel Natu
1468ec650989SNeel Natu return (devscope->Length);
1469ec650989SNeel Natu }
1470ec650989SNeel Natu
1471ec650989SNeel Natu static void
acpi_handle_dmar_drhd(ACPI_DMAR_HARDWARE_UNIT * drhd)1472ec650989SNeel Natu acpi_handle_dmar_drhd(ACPI_DMAR_HARDWARE_UNIT *drhd)
1473ec650989SNeel Natu {
1474ec650989SNeel Natu char *cp;
1475ec650989SNeel Natu int remaining, consumed;
1476ec650989SNeel Natu
1477ec650989SNeel Natu printf("\n");
1478ec650989SNeel Natu printf("\tType=DRHD\n");
1479ec650989SNeel Natu printf("\tLength=%d\n", drhd->Header.Length);
1480ec650989SNeel Natu
1481ec650989SNeel Natu #define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag)
1482ec650989SNeel Natu
1483ec650989SNeel Natu printf("\tFlags=");
1484ec650989SNeel Natu PRINTFLAG(drhd->Flags, INCLUDE_ALL);
1485ec650989SNeel Natu PRINTFLAG_END();
1486ec650989SNeel Natu
1487ec650989SNeel Natu #undef PRINTFLAG
1488ec650989SNeel Natu
1489ec650989SNeel Natu printf("\tSegment=%d\n", drhd->Segment);
14907d369c6eSJung-uk Kim printf("\tAddress=0x%016jx\n", (uintmax_t)drhd->Address);
1491ec650989SNeel Natu
1492ec650989SNeel Natu remaining = drhd->Header.Length - sizeof(ACPI_DMAR_HARDWARE_UNIT);
1493ec650989SNeel Natu if (remaining > 0)
1494ec650989SNeel Natu printf("\tDevice Scope:");
1495ec650989SNeel Natu while (remaining > 0) {
1496ec650989SNeel Natu cp = (char *)drhd + drhd->Header.Length - remaining;
1497ec650989SNeel Natu consumed = acpi_handle_dmar_devscope(cp, remaining);
1498ec650989SNeel Natu if (consumed <= 0)
1499ec650989SNeel Natu break;
1500ec650989SNeel Natu else
1501ec650989SNeel Natu remaining -= consumed;
1502ec650989SNeel Natu }
1503ec650989SNeel Natu }
1504ec650989SNeel Natu
1505ec650989SNeel Natu static void
acpi_handle_dmar_rmrr(ACPI_DMAR_RESERVED_MEMORY * rmrr)1506ec650989SNeel Natu acpi_handle_dmar_rmrr(ACPI_DMAR_RESERVED_MEMORY *rmrr)
1507ec650989SNeel Natu {
1508ec650989SNeel Natu char *cp;
1509ec650989SNeel Natu int remaining, consumed;
1510ec650989SNeel Natu
1511ec650989SNeel Natu printf("\n");
1512ec650989SNeel Natu printf("\tType=RMRR\n");
1513ec650989SNeel Natu printf("\tLength=%d\n", rmrr->Header.Length);
1514ec650989SNeel Natu printf("\tSegment=%d\n", rmrr->Segment);
15157d369c6eSJung-uk Kim printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rmrr->BaseAddress);
15167d369c6eSJung-uk Kim printf("\tLimitAddress=0x%016jx\n", (uintmax_t)rmrr->EndAddress);
1517ec650989SNeel Natu
1518ec650989SNeel Natu remaining = rmrr->Header.Length - sizeof(ACPI_DMAR_RESERVED_MEMORY);
1519ec650989SNeel Natu if (remaining > 0)
1520ec650989SNeel Natu printf("\tDevice Scope:");
1521ec650989SNeel Natu while (remaining > 0) {
1522ec650989SNeel Natu cp = (char *)rmrr + rmrr->Header.Length - remaining;
1523ec650989SNeel Natu consumed = acpi_handle_dmar_devscope(cp, remaining);
1524ec650989SNeel Natu if (consumed <= 0)
1525ec650989SNeel Natu break;
1526ec650989SNeel Natu else
1527ec650989SNeel Natu remaining -= consumed;
1528ec650989SNeel Natu }
1529ec650989SNeel Natu }
1530ec650989SNeel Natu
1531ec650989SNeel Natu static void
acpi_handle_dmar_atsr(ACPI_DMAR_ATSR * atsr)1532ec650989SNeel Natu acpi_handle_dmar_atsr(ACPI_DMAR_ATSR *atsr)
1533ec650989SNeel Natu {
1534ec650989SNeel Natu char *cp;
1535ec650989SNeel Natu int remaining, consumed;
1536ec650989SNeel Natu
1537ec650989SNeel Natu printf("\n");
1538ec650989SNeel Natu printf("\tType=ATSR\n");
1539ec650989SNeel Natu printf("\tLength=%d\n", atsr->Header.Length);
1540ec650989SNeel Natu
1541ec650989SNeel Natu #define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag)
1542ec650989SNeel Natu
1543ec650989SNeel Natu printf("\tFlags=");
1544ec650989SNeel Natu PRINTFLAG(atsr->Flags, ALL_PORTS);
1545ec650989SNeel Natu PRINTFLAG_END();
1546ec650989SNeel Natu
1547ec650989SNeel Natu #undef PRINTFLAG
1548ec650989SNeel Natu
1549ec650989SNeel Natu printf("\tSegment=%d\n", atsr->Segment);
1550ec650989SNeel Natu
1551ec650989SNeel Natu remaining = atsr->Header.Length - sizeof(ACPI_DMAR_ATSR);
1552ec650989SNeel Natu if (remaining > 0)
1553ec650989SNeel Natu printf("\tDevice Scope:");
1554ec650989SNeel Natu while (remaining > 0) {
1555ec650989SNeel Natu cp = (char *)atsr + atsr->Header.Length - remaining;
1556ec650989SNeel Natu consumed = acpi_handle_dmar_devscope(cp, remaining);
1557ec650989SNeel Natu if (consumed <= 0)
1558ec650989SNeel Natu break;
1559ec650989SNeel Natu else
1560ec650989SNeel Natu remaining -= consumed;
1561ec650989SNeel Natu }
1562ec650989SNeel Natu }
1563ec650989SNeel Natu
1564ec650989SNeel Natu static void
acpi_handle_dmar_rhsa(ACPI_DMAR_RHSA * rhsa)1565ec650989SNeel Natu acpi_handle_dmar_rhsa(ACPI_DMAR_RHSA *rhsa)
1566ec650989SNeel Natu {
1567ec650989SNeel Natu
1568ec650989SNeel Natu printf("\n");
1569ec650989SNeel Natu printf("\tType=RHSA\n");
1570ec650989SNeel Natu printf("\tLength=%d\n", rhsa->Header.Length);
15717d369c6eSJung-uk Kim printf("\tBaseAddress=0x%016jx\n", (uintmax_t)rhsa->BaseAddress);
1572ec650989SNeel Natu printf("\tProximityDomain=0x%08x\n", rhsa->ProximityDomain);
1573ec650989SNeel Natu }
1574ec650989SNeel Natu
1575ec650989SNeel Natu static int
acpi_handle_dmar_remapping_structure(void * addr,int remaining)1576ec650989SNeel Natu acpi_handle_dmar_remapping_structure(void *addr, int remaining)
1577ec650989SNeel Natu {
1578ec650989SNeel Natu ACPI_DMAR_HEADER *hdr = addr;
1579ec650989SNeel Natu
1580ec650989SNeel Natu if (remaining < (int)sizeof(ACPI_DMAR_HEADER))
1581ec650989SNeel Natu return (-1);
1582ec650989SNeel Natu
1583ec650989SNeel Natu if (remaining < hdr->Length)
1584ec650989SNeel Natu return (-1);
1585ec650989SNeel Natu
1586ec650989SNeel Natu switch (hdr->Type) {
1587ec650989SNeel Natu case ACPI_DMAR_TYPE_HARDWARE_UNIT:
1588ec650989SNeel Natu acpi_handle_dmar_drhd(addr);
1589ec650989SNeel Natu break;
1590ec650989SNeel Natu case ACPI_DMAR_TYPE_RESERVED_MEMORY:
1591ec650989SNeel Natu acpi_handle_dmar_rmrr(addr);
1592ec650989SNeel Natu break;
1593313a0c13SJung-uk Kim case ACPI_DMAR_TYPE_ROOT_ATS:
1594ec650989SNeel Natu acpi_handle_dmar_atsr(addr);
1595ec650989SNeel Natu break;
1596313a0c13SJung-uk Kim case ACPI_DMAR_TYPE_HARDWARE_AFFINITY:
1597ec650989SNeel Natu acpi_handle_dmar_rhsa(addr);
1598ec650989SNeel Natu break;
1599ec650989SNeel Natu default:
1600ec650989SNeel Natu printf("\n");
1601ec650989SNeel Natu printf("\tType=%d\n", hdr->Type);
1602ec650989SNeel Natu printf("\tLength=%d\n", hdr->Length);
1603ec650989SNeel Natu break;
1604ec650989SNeel Natu }
1605ec650989SNeel Natu return (hdr->Length);
1606ec650989SNeel Natu }
1607ec650989SNeel Natu
1608ec650989SNeel Natu #ifndef ACPI_DMAR_X2APIC_OPT_OUT
1609ec650989SNeel Natu #define ACPI_DMAR_X2APIC_OPT_OUT (0x2)
1610ec650989SNeel Natu #endif
1611ec650989SNeel Natu
1612ec650989SNeel Natu static void
acpi_handle_dmar(ACPI_TABLE_HEADER * sdp)1613ec650989SNeel Natu acpi_handle_dmar(ACPI_TABLE_HEADER *sdp)
1614ec650989SNeel Natu {
1615ec650989SNeel Natu char *cp;
1616ec650989SNeel Natu int remaining, consumed;
1617ec650989SNeel Natu ACPI_TABLE_DMAR *dmar;
1618ec650989SNeel Natu
1619ec650989SNeel Natu printf(BEGIN_COMMENT);
1620ec650989SNeel Natu acpi_print_sdt(sdp);
1621ec650989SNeel Natu dmar = (ACPI_TABLE_DMAR *)sdp;
1622ec650989SNeel Natu printf("\tHost Address Width=%d\n", dmar->Width + 1);
1623ec650989SNeel Natu
1624ec650989SNeel Natu #define PRINTFLAG(var, flag) printflag((var), ACPI_DMAR_## flag, #flag)
1625ec650989SNeel Natu
1626ec650989SNeel Natu printf("\tFlags=");
1627ec650989SNeel Natu PRINTFLAG(dmar->Flags, INTR_REMAP);
1628ec650989SNeel Natu PRINTFLAG(dmar->Flags, X2APIC_OPT_OUT);
1629ec650989SNeel Natu PRINTFLAG_END();
1630ec650989SNeel Natu
1631ec650989SNeel Natu #undef PRINTFLAG
1632ec650989SNeel Natu
1633ec650989SNeel Natu remaining = sdp->Length - sizeof(ACPI_TABLE_DMAR);
1634ec650989SNeel Natu while (remaining > 0) {
1635ec650989SNeel Natu cp = (char *)sdp + sdp->Length - remaining;
1636ec650989SNeel Natu consumed = acpi_handle_dmar_remapping_structure(cp, remaining);
1637ec650989SNeel Natu if (consumed <= 0)
1638ec650989SNeel Natu break;
1639ec650989SNeel Natu else
1640ec650989SNeel Natu remaining -= consumed;
1641ec650989SNeel Natu }
1642ec650989SNeel Natu
1643ec650989SNeel Natu printf(END_COMMENT);
1644ec650989SNeel Natu }
1645ec650989SNeel Natu
1646a0333ad1SJohn Baldwin static void
acpi_handle_ivrs_ivhd_header(ACPI_IVRS_HEADER * addr)16476d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_header(ACPI_IVRS_HEADER *addr)
16486d789b61SKonstantin Belousov {
16496cba29c0SKonstantin Belousov printf("\n\tIVHD Type=%#x IOMMU DeviceId=%#06x\n\tFlags=",
16506d789b61SKonstantin Belousov addr->Type, addr->DeviceId);
16516d789b61SKonstantin Belousov #define PRINTFLAG(flag, name) printflag(addr->Flags, flag, #name)
16526d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVHD_TT_ENABLE, HtTunEn);
16536d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVHD_ISOC, PassPW);
16546d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVHD_RES_PASS_PW, ResPassPW);
16556d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVHD_ISOC, Isoc);
16566d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVHD_TT_ENABLE, IotlbSup);
16576d789b61SKonstantin Belousov PRINTFLAG((1 << 5), Coherent);
16586d789b61SKonstantin Belousov PRINTFLAG((1 << 6), PreFSup);
16596d789b61SKonstantin Belousov PRINTFLAG((1 << 7), PPRSup);
16606d789b61SKonstantin Belousov #undef PRINTFLAG
16616d789b61SKonstantin Belousov PRINTFLAG_END();
16626d789b61SKonstantin Belousov }
16636d789b61SKonstantin Belousov
16646d789b61SKonstantin Belousov static void
acpi_handle_ivrs_ivhd_dte(UINT8 dte)16656d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_dte(UINT8 dte)
16666d789b61SKonstantin Belousov {
16676d789b61SKonstantin Belousov if (dte == 0) {
16686d789b61SKonstantin Belousov printf("\n");
16696d789b61SKonstantin Belousov return;
16706d789b61SKonstantin Belousov }
16716d789b61SKonstantin Belousov printf(" DTE=");
16726d789b61SKonstantin Belousov #define PRINTFLAG(flag, name) printflag(dte, flag, #name)
16736d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVHD_INIT_PASS, INITPass);
16746d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVHD_EINT_PASS, EIntPass);
16756d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVHD_NMI_PASS, NMIPass);
16766d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVHD_SYSTEM_MGMT, SysMgtPass);
16776d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVHD_LINT0_PASS, Lint0Pass);
16786d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVHD_LINT1_PASS, Lint1Pass);
16796d789b61SKonstantin Belousov #undef PRINTFLAG
16806d789b61SKonstantin Belousov PRINTFLAG_END();
16816d789b61SKonstantin Belousov }
16826d789b61SKonstantin Belousov
16836d789b61SKonstantin Belousov static void
acpi_handle_ivrs_ivhd_edte(UINT32 edte)16846d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_edte(UINT32 edte)
16856d789b61SKonstantin Belousov {
16866d789b61SKonstantin Belousov if (edte == 0)
16876d789b61SKonstantin Belousov return;
16886d789b61SKonstantin Belousov printf("\t\t ExtDTE=");
16896d789b61SKonstantin Belousov #define PRINTFLAG(flag, name) printflag(edte, flag, #name)
16906d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVHD_ATS_DISABLED, AtsDisabled);
16916d789b61SKonstantin Belousov #undef PRINTFLAG
16926d789b61SKonstantin Belousov PRINTFLAG_END();
16936d789b61SKonstantin Belousov }
16946d789b61SKonstantin Belousov
16956d789b61SKonstantin Belousov static const char *
acpi_handle_ivrs_ivhd_variety(UINT8 v)16966d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_variety(UINT8 v)
16976d789b61SKonstantin Belousov {
16986d789b61SKonstantin Belousov switch (v) {
16996d789b61SKonstantin Belousov case ACPI_IVHD_IOAPIC:
17006d789b61SKonstantin Belousov return ("IOAPIC");
17016d789b61SKonstantin Belousov case ACPI_IVHD_HPET:
17026d789b61SKonstantin Belousov return ("HPET");
17036d789b61SKonstantin Belousov default:
17046d789b61SKonstantin Belousov return ("UNKNOWN");
17056d789b61SKonstantin Belousov }
17066d789b61SKonstantin Belousov }
17076d789b61SKonstantin Belousov
17086d789b61SKonstantin Belousov static void
acpi_handle_ivrs_ivhd_devs(ACPI_IVRS_DE_HEADER * d,char * de)17096d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_devs(ACPI_IVRS_DE_HEADER *d, char *de)
17106d789b61SKonstantin Belousov {
17116d789b61SKonstantin Belousov char *db;
17126d789b61SKonstantin Belousov ACPI_IVRS_DEVICE4 *d4;
17136d789b61SKonstantin Belousov ACPI_IVRS_DEVICE8A *d8a;
17146d789b61SKonstantin Belousov ACPI_IVRS_DEVICE8B *d8b;
17156d789b61SKonstantin Belousov ACPI_IVRS_DEVICE8C *d8c;
17166d789b61SKonstantin Belousov ACPI_IVRS_DEVICE_HID *dh;
17176d789b61SKonstantin Belousov size_t len;
17186d789b61SKonstantin Belousov UINT32 x32;
17196d789b61SKonstantin Belousov
17206d789b61SKonstantin Belousov for (; (char *)d < de; d = (ACPI_IVRS_DE_HEADER *)(db + len)) {
17216d789b61SKonstantin Belousov db = (char *)d;
17226d789b61SKonstantin Belousov if (d->Type == ACPI_IVRS_TYPE_PAD4) {
17236d789b61SKonstantin Belousov len = sizeof(*d4);
17246d789b61SKonstantin Belousov } else if (d->Type == ACPI_IVRS_TYPE_ALL) {
17256d789b61SKonstantin Belousov d4 = (ACPI_IVRS_DEVICE4 *)db;
17266d789b61SKonstantin Belousov len = sizeof(*d4);
17276d789b61SKonstantin Belousov printf("\t\tDev Type=%#x Id=ALL", d4->Header.Type);
17286d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_dte(d4->Header.DataSetting);
17296d789b61SKonstantin Belousov } else if (d->Type == ACPI_IVRS_TYPE_SELECT) {
17306d789b61SKonstantin Belousov d4 = (ACPI_IVRS_DEVICE4 *)db;
17316d789b61SKonstantin Belousov len = sizeof(*d4);
17326d789b61SKonstantin Belousov printf("\t\tDev Type=%#x Id=%#06x", d4->Header.Type,
17336d789b61SKonstantin Belousov d4->Header.Id);
17346d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_dte(d4->Header.DataSetting);
17356d789b61SKonstantin Belousov } else if (d->Type == ACPI_IVRS_TYPE_START) {
17366d789b61SKonstantin Belousov d4 = (ACPI_IVRS_DEVICE4 *)db;
17376d789b61SKonstantin Belousov len = 2 * sizeof(*d4);
17386d789b61SKonstantin Belousov printf("\t\tDev Type=%#x Id=%#06x-%#06x",
17396d789b61SKonstantin Belousov d4->Header.Type,
17406d789b61SKonstantin Belousov d4->Header.Id, (d4 + 1)->Header.Id);
17416d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_dte(d4->Header.DataSetting);
17426d789b61SKonstantin Belousov } else if (d->Type == ACPI_IVRS_TYPE_END) {
17436d789b61SKonstantin Belousov d4 = (ACPI_IVRS_DEVICE4 *)db;
17446d789b61SKonstantin Belousov len = 2 * sizeof(*d4);
17456d789b61SKonstantin Belousov printf("\t\tDev Type=%#x Id=%#06x BIOS BUG\n",
17466d789b61SKonstantin Belousov d4->Header.Type, d4->Header.Id);
17476d789b61SKonstantin Belousov } else if (d->Type == ACPI_IVRS_TYPE_PAD8) {
17486d789b61SKonstantin Belousov len = sizeof(*d8a);
17496d789b61SKonstantin Belousov } else if (d->Type == ACPI_IVRS_TYPE_ALIAS_SELECT) {
17506d789b61SKonstantin Belousov d8a = (ACPI_IVRS_DEVICE8A *)db;
17516d789b61SKonstantin Belousov len = sizeof(*d8a);
17526d789b61SKonstantin Belousov printf("\t\tDev Type=%#x Id=%#06x AliasId=%#06x",
17536d789b61SKonstantin Belousov d8a->Header.Type, d8a->Header.Id, d8a->UsedId);
17546d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_dte(d8a->Header.DataSetting);
17556d789b61SKonstantin Belousov } else if (d->Type == ACPI_IVRS_TYPE_ALIAS_START) {
17566d789b61SKonstantin Belousov d8a = (ACPI_IVRS_DEVICE8A *)db;
17576d789b61SKonstantin Belousov d4 = (ACPI_IVRS_DEVICE4 *)(db + sizeof(*d8a));
17586d789b61SKonstantin Belousov len = sizeof(*d8a) + sizeof(*d4);
17596d789b61SKonstantin Belousov printf("\t\tDev Type=%#x Id=%#06x-%#06x AliasId=%#06x",
17606d789b61SKonstantin Belousov d8a->Header.Type, d8a->Header.Id, d4->Header.Id,
17616d789b61SKonstantin Belousov d8a->UsedId);
17626d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_dte(d8a->Header.DataSetting);
17636d789b61SKonstantin Belousov } else if (d->Type == ACPI_IVRS_TYPE_EXT_SELECT) {
17646d789b61SKonstantin Belousov d8b = (ACPI_IVRS_DEVICE8B *)db;
17656d789b61SKonstantin Belousov len = sizeof(*d8b);
17666d789b61SKonstantin Belousov printf("\t\tDev Type=%#x Id=%#06x",
17676d789b61SKonstantin Belousov d8a->Header.Type, d8a->Header.Id);
17686d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_dte(d8b->Header.DataSetting);
17696d789b61SKonstantin Belousov printf("\t\t");
17706d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_edte(d8b->ExtendedData);
17716d789b61SKonstantin Belousov } else if (d->Type == ACPI_IVRS_TYPE_EXT_START) {
17726d789b61SKonstantin Belousov d8b = (ACPI_IVRS_DEVICE8B *)db;
17736d789b61SKonstantin Belousov len = sizeof(*d8b);
17741eb7099eSKonstantin Belousov d4 = (ACPI_IVRS_DEVICE4 *)(db + sizeof(*d8b));
17751eb7099eSKonstantin Belousov len = sizeof(*d8b) + sizeof(*d4);
17766d789b61SKonstantin Belousov printf("\t\tDev Type=%#x Id=%#06x-%#06x",
17776d789b61SKonstantin Belousov d8a->Header.Type, d8a->Header.Id, d4->Header.Id);
17786d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_dte(d8b->Header.DataSetting);
17796d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_edte(d8b->ExtendedData);
17806d789b61SKonstantin Belousov } else if (d->Type == ACPI_IVRS_TYPE_SPECIAL) {
17816d789b61SKonstantin Belousov d8c = (ACPI_IVRS_DEVICE8C *)db;
17826d789b61SKonstantin Belousov len = sizeof(*d8c);
17836d789b61SKonstantin Belousov printf("\t\tDev Type=%#x Id=%#06x Handle=%#x "
17846d789b61SKonstantin Belousov "Variety=%d(%s)",
17856d789b61SKonstantin Belousov d8c->Header.Type, d8c->UsedId, d8c->Handle,
17866d789b61SKonstantin Belousov d8c->Variety,
17876d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_variety(d8c->Variety));
17886d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_dte(d8c->Header.DataSetting);
17896d789b61SKonstantin Belousov } else if (d->Type == ACPI_IVRS_TYPE_HID) {
17906d789b61SKonstantin Belousov dh = (ACPI_IVRS_DEVICE_HID *)db;
17916d789b61SKonstantin Belousov len = sizeof(*dh) + dh->UidLength;
17926d789b61SKonstantin Belousov printf("\t\tDev Type=%#x Id=%#06x HID=",
17936d789b61SKonstantin Belousov dh->Header.Type, dh->Header.Id);
17946d789b61SKonstantin Belousov acpi_print_string((char *)&dh->AcpiHid,
17956d789b61SKonstantin Belousov sizeof(dh->AcpiHid));
17966d789b61SKonstantin Belousov printf(" CID=");
17976d789b61SKonstantin Belousov acpi_print_string((char *)&dh->AcpiCid,
17986d789b61SKonstantin Belousov sizeof(dh->AcpiCid));
17996d789b61SKonstantin Belousov printf(" UID=");
18006d789b61SKonstantin Belousov switch (dh->UidType) {
18016d789b61SKonstantin Belousov case ACPI_IVRS_UID_NOT_PRESENT:
18026d789b61SKonstantin Belousov default:
18036d789b61SKonstantin Belousov printf("none");
18046d789b61SKonstantin Belousov break;
18056d789b61SKonstantin Belousov case ACPI_IVRS_UID_IS_INTEGER:
18066d789b61SKonstantin Belousov memcpy(&x32, dh + 1, sizeof(x32));
18076d789b61SKonstantin Belousov printf("%#x", x32);
18086d789b61SKonstantin Belousov break;
18096d789b61SKonstantin Belousov case ACPI_IVRS_UID_IS_STRING:
18106d789b61SKonstantin Belousov acpi_print_string((char *)(dh + 1),
18116d789b61SKonstantin Belousov dh->UidLength);
18126d789b61SKonstantin Belousov break;
18136d789b61SKonstantin Belousov }
18146d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_dte(dh->Header.DataSetting);
18156d789b61SKonstantin Belousov } else {
18166d789b61SKonstantin Belousov printf("\t\tDev Type=%#x Unknown\n", d->Type);
18176d789b61SKonstantin Belousov if (d->Type <= 63)
18186d789b61SKonstantin Belousov len = sizeof(*d4);
18196d789b61SKonstantin Belousov else if (d->Type <= 127)
18206d789b61SKonstantin Belousov len = sizeof(*d8a);
18216d789b61SKonstantin Belousov else {
18226d789b61SKonstantin Belousov printf("Abort, cannot advance iterator.\n");
18236d789b61SKonstantin Belousov return;
18246d789b61SKonstantin Belousov }
18256d789b61SKonstantin Belousov }
18266d789b61SKonstantin Belousov }
18276d789b61SKonstantin Belousov }
18286d789b61SKonstantin Belousov
18296d789b61SKonstantin Belousov static void
acpi_handle_ivrs_ivhd_10(ACPI_IVRS_HARDWARE1 * addr,bool efrsup)18306d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_10(ACPI_IVRS_HARDWARE1 *addr, bool efrsup)
18316d789b61SKonstantin Belousov {
18326d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_header(&addr->Header);
18336d789b61SKonstantin Belousov printf("\tCapOffset=%#x Base=%#jx PCISeg=%#x Unit=%#x MSIlog=%d\n",
18346d789b61SKonstantin Belousov addr->CapabilityOffset, (uintmax_t)addr->BaseAddress,
18356d789b61SKonstantin Belousov addr->PciSegmentGroup, (addr->Info & ACPI_IVHD_UNIT_ID_MASK) >> 8,
18366d789b61SKonstantin Belousov addr->Info & ACPI_IVHD_MSI_NUMBER_MASK);
18376d789b61SKonstantin Belousov if (efrsup) {
18386d789b61SKonstantin Belousov #define PRINTFLAG(flag, name) printflag(addr->FeatureReporting, flag, #name)
18396d789b61SKonstantin Belousov #define PRINTFIELD(lbit, hbit, name) \
18406d789b61SKonstantin Belousov printfield(addr->FeatureReporting, lbit, hbit, #name)
18416d789b61SKonstantin Belousov PRINTFIELD(30, 31, HATS);
18426d789b61SKonstantin Belousov PRINTFIELD(28, 29, GATS);
18436d789b61SKonstantin Belousov PRINTFIELD(23, 27, MsiNumPPR);
18446d789b61SKonstantin Belousov PRINTFIELD(17, 22, PNBanks);
18456d789b61SKonstantin Belousov PRINTFIELD(13, 16, PNCounters);
18466d789b61SKonstantin Belousov PRINTFIELD(8, 12, PASmax);
18476d789b61SKonstantin Belousov PRINTFLAG(1 << 7, HESup);
18486d789b61SKonstantin Belousov PRINTFLAG(1 << 6, GASup);
18496d789b61SKonstantin Belousov PRINTFLAG(1 << 5, UASup);
18506d789b61SKonstantin Belousov PRINTFIELD(3, 2, GLXSup);
18516d789b61SKonstantin Belousov PRINTFLAG(1 << 1, NXSup);
18526d789b61SKonstantin Belousov PRINTFLAG(1 << 0, XTSup);
18536d789b61SKonstantin Belousov #undef PRINTFLAG
18546d789b61SKonstantin Belousov #undef PRINTFIELD
18556d789b61SKonstantin Belousov PRINTFLAG_END();
18566d789b61SKonstantin Belousov }
18576d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_devs((ACPI_IVRS_DE_HEADER *)(addr + 1),
18586d789b61SKonstantin Belousov (char *)addr + addr->Header.Length);
18596d789b61SKonstantin Belousov }
18606d789b61SKonstantin Belousov
18616d789b61SKonstantin Belousov static void
acpi_handle_ivrs_ivhd_info_11(ACPI_IVRS_HARDWARE2 * addr)18626d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_info_11(ACPI_IVRS_HARDWARE2 *addr)
18636d789b61SKonstantin Belousov {
18646d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_header(&addr->Header);
18656d789b61SKonstantin Belousov printf("\tCapOffset=%#x Base=%#jx PCISeg=%#x Unit=%#x MSIlog=%d\n",
18666d789b61SKonstantin Belousov addr->CapabilityOffset, (uintmax_t)addr->BaseAddress,
18676d789b61SKonstantin Belousov addr->PciSegmentGroup, (addr->Info >> 8) & 0x1f,
18686d789b61SKonstantin Belousov addr->Info & 0x5);
18696d789b61SKonstantin Belousov printf("\tAttr=");
18706d789b61SKonstantin Belousov #define PRINTFIELD(lbit, hbit, name) \
18716d789b61SKonstantin Belousov printfield(addr->Attributes, lbit, hbit, #name)
18726d789b61SKonstantin Belousov PRINTFIELD(23, 27, MsiNumPPR);
18736d789b61SKonstantin Belousov PRINTFIELD(17, 22, PNBanks);
18746d789b61SKonstantin Belousov PRINTFIELD(13, 16, PNCounters);
18756d789b61SKonstantin Belousov #undef PRINTFIELD
18766d789b61SKonstantin Belousov PRINTFLAG_END();
18776d789b61SKonstantin Belousov }
18786d789b61SKonstantin Belousov
18796d789b61SKonstantin Belousov static void
acpi_handle_ivrs_ivhd_11(ACPI_IVRS_HARDWARE2 * addr)18806d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_11(ACPI_IVRS_HARDWARE2 *addr)
18816d789b61SKonstantin Belousov {
18826d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_info_11(addr);
18836d789b61SKonstantin Belousov printf("\tEFRreg=%#018jx\n", (uintmax_t)addr->EfrRegisterImage);
18846d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_devs((ACPI_IVRS_DE_HEADER *)(addr + 1),
18856d789b61SKonstantin Belousov (char *)addr + addr->Header.Length);
18866d789b61SKonstantin Belousov }
18876d789b61SKonstantin Belousov
18886d789b61SKonstantin Belousov static void
acpi_handle_ivrs_ivhd_40(ACPI_IVRS_HARDWARE2 * addr)18896d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_40(ACPI_IVRS_HARDWARE2 *addr)
18906d789b61SKonstantin Belousov {
18916d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_info_11(addr);
18926d789b61SKonstantin Belousov printf("\tEFRreg=%#018jx EFR2reg=%#018jx\n",
18936d789b61SKonstantin Belousov (uintmax_t)addr->EfrRegisterImage, (uintmax_t)addr->Reserved);
18946d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_devs((ACPI_IVRS_DE_HEADER *)(addr + 1),
18956d789b61SKonstantin Belousov (char *)addr + addr->Header.Length);
18966d789b61SKonstantin Belousov }
18976d789b61SKonstantin Belousov
18986d789b61SKonstantin Belousov static const char *
acpi_handle_ivrs_ivmd_type(ACPI_IVRS_MEMORY * addr)18996d789b61SKonstantin Belousov acpi_handle_ivrs_ivmd_type(ACPI_IVRS_MEMORY *addr)
19006d789b61SKonstantin Belousov {
19016d789b61SKonstantin Belousov switch (addr->Header.Type) {
19026d789b61SKonstantin Belousov case ACPI_IVRS_TYPE_MEMORY1:
19036d789b61SKonstantin Belousov return ("ALL");
19046d789b61SKonstantin Belousov case ACPI_IVRS_TYPE_MEMORY2:
19056d789b61SKonstantin Belousov return ("specified");
19066d789b61SKonstantin Belousov case ACPI_IVRS_TYPE_MEMORY3:
19076d789b61SKonstantin Belousov return ("range");
19086d789b61SKonstantin Belousov default:
19096d789b61SKonstantin Belousov return ("unknown");
19106d789b61SKonstantin Belousov }
19116d789b61SKonstantin Belousov }
19126d789b61SKonstantin Belousov
19136d789b61SKonstantin Belousov static void
acpi_handle_ivrs_ivmd(ACPI_IVRS_MEMORY * addr)19146d789b61SKonstantin Belousov acpi_handle_ivrs_ivmd(ACPI_IVRS_MEMORY *addr)
19156d789b61SKonstantin Belousov {
19166d789b61SKonstantin Belousov printf("\tMem Type=%#x(%s) ",
19176d789b61SKonstantin Belousov addr->Header.Type, acpi_handle_ivrs_ivmd_type(addr));
19186d789b61SKonstantin Belousov switch (addr->Header.Type) {
19196d789b61SKonstantin Belousov case ACPI_IVRS_TYPE_MEMORY2:
19206d789b61SKonstantin Belousov printf("Id=%#06x PCISeg=%#x ", addr->Header.DeviceId,
19216d789b61SKonstantin Belousov *(UINT16 *)&addr->Reserved);
19226d789b61SKonstantin Belousov break;
19236d789b61SKonstantin Belousov case ACPI_IVRS_TYPE_MEMORY3:
19246d789b61SKonstantin Belousov printf("Id=%#06x-%#06x PCISeg=%#x", addr->Header.DeviceId,
19256d789b61SKonstantin Belousov addr->AuxData, *(UINT16 *)&addr->Reserved);
19266d789b61SKonstantin Belousov break;
19276d789b61SKonstantin Belousov }
19286d789b61SKonstantin Belousov printf("Start=%#18jx Length=%#jx Flags=",
19296d789b61SKonstantin Belousov (uintmax_t)addr->StartAddress, (uintmax_t)addr->MemoryLength);
19306d789b61SKonstantin Belousov #define PRINTFLAG(flag, name) printflag(addr->Header.Flags, flag, #name)
19316d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVMD_EXCLUSION_RANGE, ExclusionRange);
19326d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVMD_WRITE, IW);
19336d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVMD_READ, IR);
19346d789b61SKonstantin Belousov PRINTFLAG(ACPI_IVMD_UNITY, Unity);
19356d789b61SKonstantin Belousov #undef PRINTFLAG
19366d789b61SKonstantin Belousov PRINTFLAG_END();
19376d789b61SKonstantin Belousov }
19386d789b61SKonstantin Belousov
19396d789b61SKonstantin Belousov static int
acpi_handle_ivrs_blocks(void * addr,int remaining,bool efrsup)19406d789b61SKonstantin Belousov acpi_handle_ivrs_blocks(void *addr, int remaining, bool efrsup)
19416d789b61SKonstantin Belousov {
19426d789b61SKonstantin Belousov ACPI_IVRS_HEADER *hdr = addr;
19436d789b61SKonstantin Belousov
19446d789b61SKonstantin Belousov if (remaining < (int)sizeof(ACPI_IVRS_HEADER))
19456d789b61SKonstantin Belousov return (-1);
19466d789b61SKonstantin Belousov
19476d789b61SKonstantin Belousov if (remaining < hdr->Length)
19486d789b61SKonstantin Belousov return (-1);
19496d789b61SKonstantin Belousov
19506d789b61SKonstantin Belousov switch (hdr->Type) {
19516d789b61SKonstantin Belousov case ACPI_IVRS_TYPE_HARDWARE1:
19526d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_10(addr, efrsup);
19536d789b61SKonstantin Belousov break;
19546d789b61SKonstantin Belousov case ACPI_IVRS_TYPE_HARDWARE2:
19556d789b61SKonstantin Belousov if (!efrsup)
19566d789b61SKonstantin Belousov printf("\t!! Found IVHD block 0x11 but !EFRsup\n");
19576d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_11(addr);
19586d789b61SKonstantin Belousov break;
19596d789b61SKonstantin Belousov case ACPI_IVRS_TYPE_HARDWARE3:
19606d789b61SKonstantin Belousov if (!efrsup)
19616d789b61SKonstantin Belousov printf("\t!! Found IVHD block 0x40 but !EFRsup\n");
19626d789b61SKonstantin Belousov acpi_handle_ivrs_ivhd_40(addr);
19636d789b61SKonstantin Belousov break;
19646d789b61SKonstantin Belousov case ACPI_IVRS_TYPE_MEMORY1:
19656d789b61SKonstantin Belousov case ACPI_IVRS_TYPE_MEMORY2:
19666d789b61SKonstantin Belousov case ACPI_IVRS_TYPE_MEMORY3:
19676d789b61SKonstantin Belousov acpi_handle_ivrs_ivmd(addr);
19686d789b61SKonstantin Belousov break;
19696d789b61SKonstantin Belousov default:
19706d789b61SKonstantin Belousov printf("\n");
19716d789b61SKonstantin Belousov printf("\tType=%d\n", hdr->Type);
19726d789b61SKonstantin Belousov printf("\tLength=%d\n", hdr->Length);
19736d789b61SKonstantin Belousov break;
19746d789b61SKonstantin Belousov }
19756d789b61SKonstantin Belousov return (hdr->Length);
19766d789b61SKonstantin Belousov }
19776d789b61SKonstantin Belousov
19786d789b61SKonstantin Belousov #define ACPI_IVRS_DMAREMAP 0x00000002
19796d789b61SKonstantin Belousov #define ACPI_IVRS_EFRSUP 0x00000001
19806d789b61SKonstantin Belousov #define ACPI_IVRS_GVA_SIZE 0x000000e0
19816d789b61SKonstantin Belousov
19826d789b61SKonstantin Belousov static void
acpi_handle_ivrs(ACPI_TABLE_HEADER * sdp)19836d789b61SKonstantin Belousov acpi_handle_ivrs(ACPI_TABLE_HEADER *sdp)
19846d789b61SKonstantin Belousov {
19856d789b61SKonstantin Belousov ACPI_TABLE_IVRS *ivrs;
19866d789b61SKonstantin Belousov char *cp;
19876d789b61SKonstantin Belousov int remaining, consumed;
19886d789b61SKonstantin Belousov bool efrsup;
19896d789b61SKonstantin Belousov
19906d789b61SKonstantin Belousov printf(BEGIN_COMMENT);
19916d789b61SKonstantin Belousov acpi_print_sdt(sdp);
19926d789b61SKonstantin Belousov ivrs = (ACPI_TABLE_IVRS *)sdp;
19936d789b61SKonstantin Belousov efrsup = (ivrs->Info & ACPI_IVRS_EFRSUP) != 0;
19946d789b61SKonstantin Belousov printf("\tVAsize=%d PAsize=%d GVAsize=%d\n",
19956d789b61SKonstantin Belousov (ivrs->Info & ACPI_IVRS_VIRTUAL_SIZE) >> 15,
19966d789b61SKonstantin Belousov (ivrs->Info & ACPI_IVRS_PHYSICAL_SIZE) >> 8,
19976d789b61SKonstantin Belousov (ivrs->Info & ACPI_IVRS_GVA_SIZE) >> 5);
19986d789b61SKonstantin Belousov printf("\tATS_resp_res=%d DMA_preboot_remap=%d EFRsup=%d\n",
19996d789b61SKonstantin Belousov (ivrs->Info & ACPI_IVRS_ATS_RESERVED) != 0,
20006d789b61SKonstantin Belousov (ivrs->Info & ACPI_IVRS_DMAREMAP) != 0, efrsup);
20016d789b61SKonstantin Belousov
20026d789b61SKonstantin Belousov remaining = sdp->Length - sizeof(ACPI_TABLE_IVRS);
20036d789b61SKonstantin Belousov while (remaining > 0) {
20046d789b61SKonstantin Belousov cp = (char *)sdp + sdp->Length - remaining;
20056d789b61SKonstantin Belousov consumed = acpi_handle_ivrs_blocks(cp, remaining, efrsup);
20066d789b61SKonstantin Belousov if (consumed <= 0)
20076d789b61SKonstantin Belousov break;
20086d789b61SKonstantin Belousov else
20096d789b61SKonstantin Belousov remaining -= consumed;
20106d789b61SKonstantin Belousov }
20116d789b61SKonstantin Belousov
20126d789b61SKonstantin Belousov printf(END_COMMENT);
20136d789b61SKonstantin Belousov }
20146d789b61SKonstantin Belousov
20156d789b61SKonstantin Belousov static void
acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY * mp)2016986dffafSJohn Baldwin acpi_print_srat_memory(ACPI_SRAT_MEM_AFFINITY *mp)
2017a0333ad1SJohn Baldwin {
2018a0333ad1SJohn Baldwin
2019a0333ad1SJohn Baldwin printf("\tFlags={");
2020986dffafSJohn Baldwin if (mp->Flags & ACPI_SRAT_MEM_ENABLED)
2021a0333ad1SJohn Baldwin printf("ENABLED");
2022a0333ad1SJohn Baldwin else
2023a0333ad1SJohn Baldwin printf("DISABLED");
2024986dffafSJohn Baldwin if (mp->Flags & ACPI_SRAT_MEM_HOT_PLUGGABLE)
2025a0333ad1SJohn Baldwin printf(",HOT_PLUGGABLE");
2026986dffafSJohn Baldwin if (mp->Flags & ACPI_SRAT_MEM_NON_VOLATILE)
2027a0333ad1SJohn Baldwin printf(",NON_VOLATILE");
2028a0333ad1SJohn Baldwin printf("}\n");
2029986dffafSJohn Baldwin printf("\tBase Address=0x%016jx\n", (uintmax_t)mp->BaseAddress);
2030986dffafSJohn Baldwin printf("\tLength=0x%016jx\n", (uintmax_t)mp->Length);
2031986dffafSJohn Baldwin printf("\tProximity Domain=%d\n", mp->ProximityDomain);
2032a0333ad1SJohn Baldwin }
2033a0333ad1SJohn Baldwin
203427941afaSEd Maste static const char *srat_types[] = {
203527941afaSEd Maste [ACPI_SRAT_TYPE_CPU_AFFINITY] = "CPU",
203627941afaSEd Maste [ACPI_SRAT_TYPE_MEMORY_AFFINITY] = "Memory",
203727941afaSEd Maste [ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY] = "X2APIC",
2038cebb7b19SEd Maste [ACPI_SRAT_TYPE_GICC_AFFINITY] = "GICC",
2039cebb7b19SEd Maste [ACPI_SRAT_TYPE_GIC_ITS_AFFINITY] = "GIC ITS",
204027941afaSEd Maste };
2041a0333ad1SJohn Baldwin
2042a0333ad1SJohn Baldwin static void
acpi_print_srat(ACPI_SUBTABLE_HEADER * srat)2043986dffafSJohn Baldwin acpi_print_srat(ACPI_SUBTABLE_HEADER *srat)
2044a0333ad1SJohn Baldwin {
2045986dffafSJohn Baldwin ACPI_SRAT_CPU_AFFINITY *cpu;
2046986dffafSJohn Baldwin ACPI_SRAT_X2APIC_CPU_AFFINITY *x2apic;
20472b2b1f42SAndrew Turner ACPI_SRAT_GICC_AFFINITY *gic;
2048a0333ad1SJohn Baldwin
2049c86932b6SMarcelo Araujo if (srat->Type < nitems(srat_types))
2050986dffafSJohn Baldwin printf("\tType=%s\n", srat_types[srat->Type]);
2051a0333ad1SJohn Baldwin else
2052986dffafSJohn Baldwin printf("\tType=%d (unknown)\n", srat->Type);
2053986dffafSJohn Baldwin switch (srat->Type) {
2054a0333ad1SJohn Baldwin case ACPI_SRAT_TYPE_CPU_AFFINITY:
2055986dffafSJohn Baldwin cpu = (ACPI_SRAT_CPU_AFFINITY *)srat;
2056986dffafSJohn Baldwin acpi_print_srat_cpu(cpu->ApicId,
2057986dffafSJohn Baldwin cpu->ProximityDomainHi[2] << 24 |
2058986dffafSJohn Baldwin cpu->ProximityDomainHi[1] << 16 |
2059986dffafSJohn Baldwin cpu->ProximityDomainHi[0] << 0 |
2060986dffafSJohn Baldwin cpu->ProximityDomainLo, cpu->Flags);
2061a0333ad1SJohn Baldwin break;
2062a0333ad1SJohn Baldwin case ACPI_SRAT_TYPE_MEMORY_AFFINITY:
2063986dffafSJohn Baldwin acpi_print_srat_memory((ACPI_SRAT_MEM_AFFINITY *)srat);
2064a0333ad1SJohn Baldwin break;
2065a0333ad1SJohn Baldwin case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
2066986dffafSJohn Baldwin x2apic = (ACPI_SRAT_X2APIC_CPU_AFFINITY *)srat;
2067986dffafSJohn Baldwin acpi_print_srat_cpu(x2apic->ApicId, x2apic->ProximityDomain,
2068986dffafSJohn Baldwin x2apic->Flags);
2069a0333ad1SJohn Baldwin break;
20702b2b1f42SAndrew Turner case ACPI_SRAT_TYPE_GICC_AFFINITY:
20712b2b1f42SAndrew Turner gic = (ACPI_SRAT_GICC_AFFINITY *)srat;
20722b2b1f42SAndrew Turner acpi_print_srat_cpu(gic->AcpiProcessorUid, gic->ProximityDomain,
20732b2b1f42SAndrew Turner gic->Flags);
20742b2b1f42SAndrew Turner break;
2075a0333ad1SJohn Baldwin }
2076a0333ad1SJohn Baldwin }
2077a0333ad1SJohn Baldwin
2078a0333ad1SJohn Baldwin static void
acpi_handle_srat(ACPI_TABLE_HEADER * sdp)2079986dffafSJohn Baldwin acpi_handle_srat(ACPI_TABLE_HEADER *sdp)
2080a0333ad1SJohn Baldwin {
2081986dffafSJohn Baldwin ACPI_TABLE_SRAT *srat;
2082a0333ad1SJohn Baldwin
2083a0333ad1SJohn Baldwin printf(BEGIN_COMMENT);
2084a0333ad1SJohn Baldwin acpi_print_sdt(sdp);
2085986dffafSJohn Baldwin srat = (ACPI_TABLE_SRAT *)sdp;
2086986dffafSJohn Baldwin printf("\tTable Revision=%d\n", srat->TableRevision);
2087986dffafSJohn Baldwin acpi_walk_subtables(sdp, (srat + 1), acpi_print_srat);
2088a0333ad1SJohn Baldwin printf(END_COMMENT);
2089a0333ad1SJohn Baldwin }
2090a0333ad1SJohn Baldwin
2091340c0022SEd Maste static const char *nfit_types[] = {
2092340c0022SEd Maste [ACPI_NFIT_TYPE_SYSTEM_ADDRESS] = "System Address",
2093340c0022SEd Maste [ACPI_NFIT_TYPE_MEMORY_MAP] = "Memory Map",
2094340c0022SEd Maste [ACPI_NFIT_TYPE_INTERLEAVE] = "Interleave",
2095340c0022SEd Maste [ACPI_NFIT_TYPE_SMBIOS] = "SMBIOS",
2096340c0022SEd Maste [ACPI_NFIT_TYPE_CONTROL_REGION] = "Control Region",
2097340c0022SEd Maste [ACPI_NFIT_TYPE_DATA_REGION] = "Data Region",
20981b109c69SAlexander Motin [ACPI_NFIT_TYPE_FLUSH_ADDRESS] = "Flush Address",
20991b109c69SAlexander Motin [ACPI_NFIT_TYPE_CAPABILITIES] = "Platform Capabilities"
2100340c0022SEd Maste };
2101340c0022SEd Maste
2102340c0022SEd Maste
2103340c0022SEd Maste static void
acpi_print_nfit(ACPI_NFIT_HEADER * nfit)2104340c0022SEd Maste acpi_print_nfit(ACPI_NFIT_HEADER *nfit)
2105340c0022SEd Maste {
2106340c0022SEd Maste char *uuidstr;
21073b7935f3SAlexander Motin uint32_t m, status;
2108340c0022SEd Maste
2109340c0022SEd Maste ACPI_NFIT_SYSTEM_ADDRESS *sysaddr;
2110340c0022SEd Maste ACPI_NFIT_MEMORY_MAP *mmap;
2111340c0022SEd Maste ACPI_NFIT_INTERLEAVE *ileave;
2112340c0022SEd Maste ACPI_NFIT_CONTROL_REGION *ctlreg;
2113340c0022SEd Maste ACPI_NFIT_DATA_REGION *datareg;
2114340c0022SEd Maste ACPI_NFIT_FLUSH_ADDRESS *fladdr;
21151b109c69SAlexander Motin ACPI_NFIT_CAPABILITIES *caps;
2116340c0022SEd Maste
2117340c0022SEd Maste if (nfit->Type < nitems(nfit_types))
2118340c0022SEd Maste printf("\tType=%s\n", nfit_types[nfit->Type]);
2119340c0022SEd Maste else
2120340c0022SEd Maste printf("\tType=%u (unknown)\n", nfit->Type);
2121340c0022SEd Maste switch (nfit->Type) {
2122340c0022SEd Maste case ACPI_NFIT_TYPE_SYSTEM_ADDRESS:
2123340c0022SEd Maste sysaddr = (ACPI_NFIT_SYSTEM_ADDRESS *)nfit;
2124340c0022SEd Maste printf("\tRangeIndex=%u\n", (u_int)sysaddr->RangeIndex);
2125340c0022SEd Maste printf("\tProximityDomain=%u\n",
2126340c0022SEd Maste (u_int)sysaddr->ProximityDomain);
2127de937ecbSKonstantin Belousov uuid_to_string((uuid_t *)(uintptr_t)(sysaddr->RangeGuid),
2128340c0022SEd Maste &uuidstr, &status);
2129340c0022SEd Maste if (status != uuid_s_ok)
2130340c0022SEd Maste errx(1, "uuid_to_string: status=%u", status);
2131340c0022SEd Maste printf("\tRangeGuid=%s\n", uuidstr);
2132340c0022SEd Maste free(uuidstr);
2133340c0022SEd Maste printf("\tAddress=0x%016jx\n", (uintmax_t)sysaddr->Address);
2134340c0022SEd Maste printf("\tLength=0x%016jx\n", (uintmax_t)sysaddr->Length);
2135340c0022SEd Maste printf("\tMemoryMapping=0x%016jx\n",
2136340c0022SEd Maste (uintmax_t)sysaddr->MemoryMapping);
2137340c0022SEd Maste
2138340c0022SEd Maste #define PRINTFLAG(var, flag) printflag((var), ACPI_NFIT_## flag, #flag)
2139340c0022SEd Maste
2140340c0022SEd Maste printf("\tFlags=");
2141340c0022SEd Maste PRINTFLAG(sysaddr->Flags, ADD_ONLINE_ONLY);
2142340c0022SEd Maste PRINTFLAG(sysaddr->Flags, PROXIMITY_VALID);
2143340c0022SEd Maste PRINTFLAG_END();
2144340c0022SEd Maste
2145340c0022SEd Maste #undef PRINTFLAG
2146340c0022SEd Maste
2147340c0022SEd Maste break;
2148340c0022SEd Maste case ACPI_NFIT_TYPE_MEMORY_MAP:
2149340c0022SEd Maste mmap = (ACPI_NFIT_MEMORY_MAP *)nfit;
215092d0d6bbSAlexander Motin printf("\tDeviceHandle=0x%x\n", (u_int)mmap->DeviceHandle);
215192d0d6bbSAlexander Motin printf("\tPhysicalId=0x%04x\n", (u_int)mmap->PhysicalId);
2152340c0022SEd Maste printf("\tRegionId=%u\n", (u_int)mmap->RegionId);
2153340c0022SEd Maste printf("\tRangeIndex=%u\n", (u_int)mmap->RangeIndex);
2154340c0022SEd Maste printf("\tRegionIndex=%u\n", (u_int)mmap->RegionIndex);
2155340c0022SEd Maste printf("\tRegionSize=0x%016jx\n", (uintmax_t)mmap->RegionSize);
2156340c0022SEd Maste printf("\tRegionOffset=0x%016jx\n",
2157340c0022SEd Maste (uintmax_t)mmap->RegionOffset);
2158340c0022SEd Maste printf("\tAddress=0x%016jx\n", (uintmax_t)mmap->Address);
2159340c0022SEd Maste printf("\tInterleaveIndex=%u\n", (u_int)mmap->InterleaveIndex);
2160fb1cf2a9SAlexander Motin printf("\tInterleaveWays=%u\n", (u_int)mmap->InterleaveWays);
2161340c0022SEd Maste
2162340c0022SEd Maste #define PRINTFLAG(var, flag) printflag((var), ACPI_NFIT_MEM_## flag, #flag)
2163340c0022SEd Maste
2164340c0022SEd Maste printf("\tFlags=");
2165340c0022SEd Maste PRINTFLAG(mmap->Flags, SAVE_FAILED);
2166340c0022SEd Maste PRINTFLAG(mmap->Flags, RESTORE_FAILED);
2167340c0022SEd Maste PRINTFLAG(mmap->Flags, FLUSH_FAILED);
2168340c0022SEd Maste PRINTFLAG(mmap->Flags, NOT_ARMED);
2169340c0022SEd Maste PRINTFLAG(mmap->Flags, HEALTH_OBSERVED);
2170340c0022SEd Maste PRINTFLAG(mmap->Flags, HEALTH_ENABLED);
2171340c0022SEd Maste PRINTFLAG(mmap->Flags, MAP_FAILED);
2172340c0022SEd Maste PRINTFLAG_END();
2173340c0022SEd Maste
2174340c0022SEd Maste #undef PRINTFLAG
2175340c0022SEd Maste
2176340c0022SEd Maste break;
2177340c0022SEd Maste case ACPI_NFIT_TYPE_INTERLEAVE:
2178340c0022SEd Maste ileave = (ACPI_NFIT_INTERLEAVE *)nfit;
2179340c0022SEd Maste printf("\tInterleaveIndex=%u\n",
2180340c0022SEd Maste (u_int)ileave->InterleaveIndex);
2181340c0022SEd Maste printf("\tLineCount=%u\n", (u_int)ileave->LineCount);
2182340c0022SEd Maste printf("\tLineSize=%u\n", (u_int)ileave->LineSize);
21833b7935f3SAlexander Motin for (m = 0; m < ileave->LineCount; m++) {
21843b7935f3SAlexander Motin printf("\tLine%uOffset=0x%08x\n", (u_int)m + 1,
21853b7935f3SAlexander Motin (u_int)ileave->LineOffset[m]);
21863b7935f3SAlexander Motin }
2187340c0022SEd Maste break;
2188340c0022SEd Maste case ACPI_NFIT_TYPE_SMBIOS:
2189340c0022SEd Maste /* XXX smbios->Data[x] output is not supported */
2190340c0022SEd Maste break;
2191340c0022SEd Maste case ACPI_NFIT_TYPE_CONTROL_REGION:
2192340c0022SEd Maste ctlreg = (ACPI_NFIT_CONTROL_REGION *)nfit;
2193340c0022SEd Maste printf("\tRegionIndex=%u\n", (u_int)ctlreg->RegionIndex);
2194340c0022SEd Maste printf("\tVendorId=0x%04x\n", (u_int)ctlreg->VendorId);
2195340c0022SEd Maste printf("\tDeviceId=0x%04x\n", (u_int)ctlreg->DeviceId);
219635e39fd9SAlexander Motin printf("\tRevisionId=0x%02x\n", (u_int)ctlreg->RevisionId);
2197340c0022SEd Maste printf("\tSubsystemVendorId=0x%04x\n",
2198340c0022SEd Maste (u_int)ctlreg->SubsystemVendorId);
2199340c0022SEd Maste printf("\tSubsystemDeviceId=0x%04x\n",
2200340c0022SEd Maste (u_int)ctlreg->SubsystemDeviceId);
220135e39fd9SAlexander Motin printf("\tSubsystemRevisionId=0x%02x\n",
2202340c0022SEd Maste (u_int)ctlreg->SubsystemRevisionId);
2203d4c2de2eSAlexander Motin printf("\tValidFields=0x%02x\n", (u_int)ctlreg->ValidFields);
220435e39fd9SAlexander Motin printf("\tManufacturingLocation=0x%02x\n",
2205340c0022SEd Maste (u_int)ctlreg->ManufacturingLocation);
220635e39fd9SAlexander Motin printf("\tManufacturingDate=%04x\n",
220735e39fd9SAlexander Motin (u_int)be16toh(ctlreg->ManufacturingDate));
220835e39fd9SAlexander Motin printf("\tSerialNumber=%08X\n",
220935e39fd9SAlexander Motin (u_int)be32toh(ctlreg->SerialNumber));
2210fb1cf2a9SAlexander Motin printf("\tCode=0x%04x\n", (u_int)ctlreg->Code);
2211340c0022SEd Maste printf("\tWindows=%u\n", (u_int)ctlreg->Windows);
2212340c0022SEd Maste printf("\tWindowSize=0x%016jx\n",
2213340c0022SEd Maste (uintmax_t)ctlreg->WindowSize);
2214340c0022SEd Maste printf("\tCommandOffset=0x%016jx\n",
2215340c0022SEd Maste (uintmax_t)ctlreg->CommandOffset);
2216340c0022SEd Maste printf("\tCommandSize=0x%016jx\n",
2217340c0022SEd Maste (uintmax_t)ctlreg->CommandSize);
2218340c0022SEd Maste printf("\tStatusOffset=0x%016jx\n",
2219340c0022SEd Maste (uintmax_t)ctlreg->StatusOffset);
2220340c0022SEd Maste printf("\tStatusSize=0x%016jx\n",
2221340c0022SEd Maste (uintmax_t)ctlreg->StatusSize);
2222340c0022SEd Maste
2223340c0022SEd Maste #define PRINTFLAG(var, flag) printflag((var), ACPI_NFIT_## flag, #flag)
2224340c0022SEd Maste
2225340c0022SEd Maste printf("\tFlags=");
2226d4c2de2eSAlexander Motin PRINTFLAG(ctlreg->Flags, CONTROL_BUFFERED);
2227340c0022SEd Maste PRINTFLAG_END();
2228340c0022SEd Maste
2229340c0022SEd Maste #undef PRINTFLAG
2230340c0022SEd Maste
2231340c0022SEd Maste break;
2232340c0022SEd Maste case ACPI_NFIT_TYPE_DATA_REGION:
2233340c0022SEd Maste datareg = (ACPI_NFIT_DATA_REGION *)nfit;
2234340c0022SEd Maste printf("\tRegionIndex=%u\n", (u_int)datareg->RegionIndex);
2235340c0022SEd Maste printf("\tWindows=%u\n", (u_int)datareg->Windows);
2236340c0022SEd Maste printf("\tOffset=0x%016jx\n", (uintmax_t)datareg->Offset);
2237340c0022SEd Maste printf("\tSize=0x%016jx\n", (uintmax_t)datareg->Size);
2238340c0022SEd Maste printf("\tCapacity=0x%016jx\n", (uintmax_t)datareg->Capacity);
2239340c0022SEd Maste printf("\tStartAddress=0x%016jx\n",
2240340c0022SEd Maste (uintmax_t)datareg->StartAddress);
2241340c0022SEd Maste break;
2242340c0022SEd Maste case ACPI_NFIT_TYPE_FLUSH_ADDRESS:
2243340c0022SEd Maste fladdr = (ACPI_NFIT_FLUSH_ADDRESS *)nfit;
2244340c0022SEd Maste printf("\tDeviceHandle=%u\n", (u_int)fladdr->DeviceHandle);
2245340c0022SEd Maste printf("\tHintCount=%u\n", (u_int)fladdr->HintCount);
22463b7935f3SAlexander Motin for (m = 0; m < fladdr->HintCount; m++) {
22473b7935f3SAlexander Motin printf("\tHintAddress%u=0x%016jx\n", (u_int)m + 1,
22483b7935f3SAlexander Motin (uintmax_t)fladdr->HintAddress[m]);
22493b7935f3SAlexander Motin }
2250340c0022SEd Maste break;
22511b109c69SAlexander Motin case ACPI_NFIT_TYPE_CAPABILITIES:
22521b109c69SAlexander Motin caps = (ACPI_NFIT_CAPABILITIES *)nfit;
22531b109c69SAlexander Motin printf("\tHighestCapability=%u\n", (u_int)caps->HighestCapability);
22541b109c69SAlexander Motin
22551b109c69SAlexander Motin #define PRINTFLAG(var, flag) printflag((var), ACPI_NFIT_CAPABILITY_## flag, #flag)
22561b109c69SAlexander Motin
22571b109c69SAlexander Motin printf("\tCapabilities=");
22581b109c69SAlexander Motin PRINTFLAG(caps->Capabilities, CACHE_FLUSH);
22591b109c69SAlexander Motin PRINTFLAG(caps->Capabilities, MEM_FLUSH);
22601b109c69SAlexander Motin PRINTFLAG(caps->Capabilities, MEM_MIRRORING);
22611b109c69SAlexander Motin PRINTFLAG_END();
22621b109c69SAlexander Motin
22631b109c69SAlexander Motin #undef PRINTFLAG
22641b109c69SAlexander Motin break;
2265340c0022SEd Maste }
2266340c0022SEd Maste }
2267340c0022SEd Maste
2268340c0022SEd Maste static void
acpi_handle_nfit(ACPI_TABLE_HEADER * sdp)2269340c0022SEd Maste acpi_handle_nfit(ACPI_TABLE_HEADER *sdp)
2270340c0022SEd Maste {
2271340c0022SEd Maste ACPI_TABLE_NFIT *nfit;
2272340c0022SEd Maste
2273340c0022SEd Maste printf(BEGIN_COMMENT);
2274340c0022SEd Maste acpi_print_sdt(sdp);
2275340c0022SEd Maste nfit = (ACPI_TABLE_NFIT *)sdp;
2276340c0022SEd Maste acpi_walk_nfit(sdp, (nfit + 1), acpi_print_nfit);
2277340c0022SEd Maste printf(END_COMMENT);
2278340c0022SEd Maste }
2279340c0022SEd Maste
2280a0333ad1SJohn Baldwin static void
acpi_print_sdt(ACPI_TABLE_HEADER * sdp)2281986dffafSJohn Baldwin acpi_print_sdt(ACPI_TABLE_HEADER *sdp)
2282c62f1cccSMitsuru IWASAKI {
2283773b6454SNate Lawson printf(" ");
2284278f0de6SJung-uk Kim acpi_print_string(sdp->Signature, ACPI_NAMESEG_SIZE);
2285c62f1cccSMitsuru IWASAKI printf(": Length=%d, Revision=%d, Checksum=%d,\n",
2286986dffafSJohn Baldwin sdp->Length, sdp->Revision, sdp->Checksum);
2287e1e9a4bfSMitsuru IWASAKI printf("\tOEMID=");
2288986dffafSJohn Baldwin acpi_print_string(sdp->OemId, ACPI_OEM_ID_SIZE);
2289e1e9a4bfSMitsuru IWASAKI printf(", OEM Table ID=");
2290986dffafSJohn Baldwin acpi_print_string(sdp->OemTableId, ACPI_OEM_TABLE_ID_SIZE);
2291986dffafSJohn Baldwin printf(", OEM Revision=0x%x,\n", sdp->OemRevision);
2292e1e9a4bfSMitsuru IWASAKI printf("\tCreator ID=");
2293278f0de6SJung-uk Kim acpi_print_string(sdp->AslCompilerId, ACPI_NAMESEG_SIZE);
2294986dffafSJohn Baldwin printf(", Creator Revision=0x%x\n", sdp->AslCompilerRevision);
2295e1e9a4bfSMitsuru IWASAKI }
2296e1e9a4bfSMitsuru IWASAKI
2297945137d9SNate Lawson static void
acpi_print_rsdt(ACPI_TABLE_HEADER * rsdp)2298986dffafSJohn Baldwin acpi_print_rsdt(ACPI_TABLE_HEADER *rsdp)
2299e1e9a4bfSMitsuru IWASAKI {
2300986dffafSJohn Baldwin ACPI_TABLE_RSDT *rsdt;
2301986dffafSJohn Baldwin ACPI_TABLE_XSDT *xsdt;
2302e1e9a4bfSMitsuru IWASAKI int i, entries;
2303e1e9a4bfSMitsuru IWASAKI
2304986dffafSJohn Baldwin rsdt = (ACPI_TABLE_RSDT *)rsdp;
2305986dffafSJohn Baldwin xsdt = (ACPI_TABLE_XSDT *)rsdp;
2306773b6454SNate Lawson printf(BEGIN_COMMENT);
2307773b6454SNate Lawson acpi_print_sdt(rsdp);
2308986dffafSJohn Baldwin entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
2309e1e9a4bfSMitsuru IWASAKI printf("\tEntries={ ");
2310e1e9a4bfSMitsuru IWASAKI for (i = 0; i < entries; i++) {
2311e1e9a4bfSMitsuru IWASAKI if (i > 0)
2312e1e9a4bfSMitsuru IWASAKI printf(", ");
2313fe1d0c2dSJung-uk Kim if (addr_size == 4)
23147d369c6eSJung-uk Kim printf("0x%08x", le32toh(rsdt->TableOffsetEntry[i]));
2315fe1d0c2dSJung-uk Kim else
23167d369c6eSJung-uk Kim printf("0x%016jx",
23177d369c6eSJung-uk Kim (uintmax_t)le64toh(xsdt->TableOffsetEntry[i]));
2318e1e9a4bfSMitsuru IWASAKI }
2319e1e9a4bfSMitsuru IWASAKI printf(" }\n");
2320c62f1cccSMitsuru IWASAKI printf(END_COMMENT);
2321e1e9a4bfSMitsuru IWASAKI }
2322e1e9a4bfSMitsuru IWASAKI
23238e6a8737SNate Lawson static const char *acpi_pm_profiles[] = {
23248e6a8737SNate Lawson "Unspecified", "Desktop", "Mobile", "Workstation",
23258e6a8737SNate Lawson "Enterprise Server", "SOHO Server", "Appliance PC"
23268e6a8737SNate Lawson };
23278e6a8737SNate Lawson
2328945137d9SNate Lawson static void
acpi_print_fadt(ACPI_TABLE_HEADER * sdp)2329986dffafSJohn Baldwin acpi_print_fadt(ACPI_TABLE_HEADER *sdp)
2330e1e9a4bfSMitsuru IWASAKI {
2331986dffafSJohn Baldwin ACPI_TABLE_FADT *fadt;
23328e6a8737SNate Lawson const char *pm;
2333e1e9a4bfSMitsuru IWASAKI
2334986dffafSJohn Baldwin fadt = (ACPI_TABLE_FADT *)sdp;
2335c62f1cccSMitsuru IWASAKI printf(BEGIN_COMMENT);
23362177d4e6SNate Lawson acpi_print_sdt(sdp);
2337986dffafSJohn Baldwin printf(" \tFACS=0x%x, DSDT=0x%x\n", fadt->Facs,
2338986dffafSJohn Baldwin fadt->Dsdt);
2339986dffafSJohn Baldwin printf("\tINT_MODEL=%s\n", fadt->Model ? "APIC" : "PIC");
2340986dffafSJohn Baldwin if (fadt->PreferredProfile >= sizeof(acpi_pm_profiles) / sizeof(char *))
23418e6a8737SNate Lawson pm = "Reserved";
23428e6a8737SNate Lawson else
2343986dffafSJohn Baldwin pm = acpi_pm_profiles[fadt->PreferredProfile];
2344986dffafSJohn Baldwin printf("\tPreferred_PM_Profile=%s (%d)\n", pm, fadt->PreferredProfile);
2345986dffafSJohn Baldwin printf("\tSCI_INT=%d\n", fadt->SciInterrupt);
2346986dffafSJohn Baldwin printf("\tSMI_CMD=0x%x, ", fadt->SmiCommand);
2347986dffafSJohn Baldwin printf("ACPI_ENABLE=0x%x, ", fadt->AcpiEnable);
2348986dffafSJohn Baldwin printf("ACPI_DISABLE=0x%x, ", fadt->AcpiDisable);
2349986dffafSJohn Baldwin printf("S4BIOS_REQ=0x%x\n", fadt->S4BiosRequest);
2350986dffafSJohn Baldwin printf("\tPSTATE_CNT=0x%x\n", fadt->PstateControl);
2351e1e9a4bfSMitsuru IWASAKI printf("\tPM1a_EVT_BLK=0x%x-0x%x\n",
2352986dffafSJohn Baldwin fadt->Pm1aEventBlock,
2353986dffafSJohn Baldwin fadt->Pm1aEventBlock + fadt->Pm1EventLength - 1);
2354986dffafSJohn Baldwin if (fadt->Pm1bEventBlock != 0)
2355e1e9a4bfSMitsuru IWASAKI printf("\tPM1b_EVT_BLK=0x%x-0x%x\n",
2356986dffafSJohn Baldwin fadt->Pm1bEventBlock,
2357986dffafSJohn Baldwin fadt->Pm1bEventBlock + fadt->Pm1EventLength - 1);
2358e1e9a4bfSMitsuru IWASAKI printf("\tPM1a_CNT_BLK=0x%x-0x%x\n",
2359986dffafSJohn Baldwin fadt->Pm1aControlBlock,
2360986dffafSJohn Baldwin fadt->Pm1aControlBlock + fadt->Pm1ControlLength - 1);
2361986dffafSJohn Baldwin if (fadt->Pm1bControlBlock != 0)
2362e1e9a4bfSMitsuru IWASAKI printf("\tPM1b_CNT_BLK=0x%x-0x%x\n",
2363986dffafSJohn Baldwin fadt->Pm1bControlBlock,
2364986dffafSJohn Baldwin fadt->Pm1bControlBlock + fadt->Pm1ControlLength - 1);
2365986dffafSJohn Baldwin if (fadt->Pm2ControlBlock != 0)
2366e1e9a4bfSMitsuru IWASAKI printf("\tPM2_CNT_BLK=0x%x-0x%x\n",
2367986dffafSJohn Baldwin fadt->Pm2ControlBlock,
2368986dffafSJohn Baldwin fadt->Pm2ControlBlock + fadt->Pm2ControlLength - 1);
2369c08c4e81SNate Lawson printf("\tPM_TMR_BLK=0x%x-0x%x\n",
2370986dffafSJohn Baldwin fadt->PmTimerBlock,
2371986dffafSJohn Baldwin fadt->PmTimerBlock + fadt->PmTimerLength - 1);
2372986dffafSJohn Baldwin if (fadt->Gpe0Block != 0)
23738e6a8737SNate Lawson printf("\tGPE0_BLK=0x%x-0x%x\n",
2374986dffafSJohn Baldwin fadt->Gpe0Block,
2375986dffafSJohn Baldwin fadt->Gpe0Block + fadt->Gpe0BlockLength - 1);
2376986dffafSJohn Baldwin if (fadt->Gpe1Block != 0)
23778e6a8737SNate Lawson printf("\tGPE1_BLK=0x%x-0x%x, GPE1_BASE=%d\n",
2378986dffafSJohn Baldwin fadt->Gpe1Block,
2379986dffafSJohn Baldwin fadt->Gpe1Block + fadt->Gpe1BlockLength - 1,
2380986dffafSJohn Baldwin fadt->Gpe1Base);
2381986dffafSJohn Baldwin if (fadt->CstControl != 0)
2382986dffafSJohn Baldwin printf("\tCST_CNT=0x%x\n", fadt->CstControl);
238351c1824fSNate Lawson printf("\tP_LVL2_LAT=%d us, P_LVL3_LAT=%d us\n",
2384986dffafSJohn Baldwin fadt->C2Latency, fadt->C3Latency);
2385e1e9a4bfSMitsuru IWASAKI printf("\tFLUSH_SIZE=%d, FLUSH_STRIDE=%d\n",
2386986dffafSJohn Baldwin fadt->FlushSize, fadt->FlushStride);
2387e1e9a4bfSMitsuru IWASAKI printf("\tDUTY_OFFSET=%d, DUTY_WIDTH=%d\n",
2388986dffafSJohn Baldwin fadt->DutyOffset, fadt->DutyWidth);
2389e1e9a4bfSMitsuru IWASAKI printf("\tDAY_ALRM=%d, MON_ALRM=%d, CENTURY=%d\n",
2390986dffafSJohn Baldwin fadt->DayAlarm, fadt->MonthAlarm, fadt->Century);
2391e1e9a4bfSMitsuru IWASAKI
2392ec650989SNeel Natu #define PRINTFLAG(var, flag) printflag((var), ACPI_FADT_## flag, #flag)
2393e1e9a4bfSMitsuru IWASAKI
23948e6a8737SNate Lawson printf("\tIAPC_BOOT_ARCH=");
2395986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, LEGACY_DEVICES);
2396986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, 8042);
2397986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, NO_VGA);
2398986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, NO_MSI);
2399986dffafSJohn Baldwin PRINTFLAG(fadt->BootFlags, NO_ASPM);
2400f6469ce1SAndrew Turner PRINTFLAG(fadt->BootFlags, NO_CMOS_RTC);
2401ec650989SNeel Natu PRINTFLAG_END();
24028e6a8737SNate Lawson
24038e6a8737SNate Lawson printf("\tFlags=");
2404986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, WBINVD);
2405986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, WBINVD_FLUSH);
2406986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, C1_SUPPORTED);
2407986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, C2_MP_SUPPORTED);
2408986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, POWER_BUTTON);
2409986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, SLEEP_BUTTON);
2410986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, FIXED_RTC);
2411986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, S4_RTC_WAKE);
2412986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, 32BIT_TIMER);
2413986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, DOCKING_SUPPORTED);
2414986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, RESET_REGISTER);
2415986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, SEALED_CASE);
2416986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, HEADLESS);
2417986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, SLEEP_TYPE);
2418986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, PCI_EXPRESS_WAKE);
2419986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, PLATFORM_CLOCK);
2420986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, S4_RTC_VALID);
2421986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, REMOTE_POWER_ON);
2422986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, APIC_CLUSTER);
2423986dffafSJohn Baldwin PRINTFLAG(fadt->Flags, APIC_PHYSICAL);
2424f6469ce1SAndrew Turner PRINTFLAG(fadt->Flags, HW_REDUCED);
2425f6469ce1SAndrew Turner PRINTFLAG(fadt->Flags, LOW_POWER_S0);
2426ec650989SNeel Natu PRINTFLAG_END();
2427e1e9a4bfSMitsuru IWASAKI
2428e1e9a4bfSMitsuru IWASAKI #undef PRINTFLAG
2429e1e9a4bfSMitsuru IWASAKI
2430986dffafSJohn Baldwin if (fadt->Flags & ACPI_FADT_RESET_REGISTER) {
24318e6a8737SNate Lawson printf("\tRESET_REG=");
2432986dffafSJohn Baldwin acpi_print_gas(&fadt->ResetRegister);
2433986dffafSJohn Baldwin printf(", RESET_VALUE=%#x\n", fadt->ResetValue);
24348e6a8737SNate Lawson }
2435c2962974SNate Lawson if (acpi_get_fadt_revision(fadt) > 1) {
24367d369c6eSJung-uk Kim printf("\tX_FACS=0x%016jx, ", (uintmax_t)fadt->XFacs);
24377d369c6eSJung-uk Kim printf("X_DSDT=0x%016jx\n", (uintmax_t)fadt->XDsdt);
2438c08c4e81SNate Lawson printf("\tX_PM1a_EVT_BLK=");
2439986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1aEventBlock);
2440986dffafSJohn Baldwin if (fadt->XPm1bEventBlock.Address != 0) {
2441c08c4e81SNate Lawson printf("\n\tX_PM1b_EVT_BLK=");
2442986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1bEventBlock);
2443c08c4e81SNate Lawson }
2444c08c4e81SNate Lawson printf("\n\tX_PM1a_CNT_BLK=");
2445986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1aControlBlock);
2446986dffafSJohn Baldwin if (fadt->XPm1bControlBlock.Address != 0) {
2447c08c4e81SNate Lawson printf("\n\tX_PM1b_CNT_BLK=");
2448986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm1bControlBlock);
2449c08c4e81SNate Lawson }
2450986dffafSJohn Baldwin if (fadt->XPm2ControlBlock.Address != 0) {
2451773b6454SNate Lawson printf("\n\tX_PM2_CNT_BLK=");
2452986dffafSJohn Baldwin acpi_print_gas(&fadt->XPm2ControlBlock);
2453c08c4e81SNate Lawson }
2454773b6454SNate Lawson printf("\n\tX_PM_TMR_BLK=");
2455986dffafSJohn Baldwin acpi_print_gas(&fadt->XPmTimerBlock);
2456986dffafSJohn Baldwin if (fadt->XGpe0Block.Address != 0) {
2457773b6454SNate Lawson printf("\n\tX_GPE0_BLK=");
2458986dffafSJohn Baldwin acpi_print_gas(&fadt->XGpe0Block);
2459c08c4e81SNate Lawson }
2460986dffafSJohn Baldwin if (fadt->XGpe1Block.Address != 0) {
2461773b6454SNate Lawson printf("\n\tX_GPE1_BLK=");
2462986dffafSJohn Baldwin acpi_print_gas(&fadt->XGpe1Block);
2463c08c4e81SNate Lawson }
2464773b6454SNate Lawson printf("\n");
2465773b6454SNate Lawson }
24668e6a8737SNate Lawson
24678e6a8737SNate Lawson printf(END_COMMENT);
24688e6a8737SNate Lawson }
24698e6a8737SNate Lawson
24708e6a8737SNate Lawson static void
acpi_print_facs(ACPI_TABLE_FACS * facs)2471986dffafSJohn Baldwin acpi_print_facs(ACPI_TABLE_FACS *facs)
24728e6a8737SNate Lawson {
24738e6a8737SNate Lawson printf(BEGIN_COMMENT);
2474986dffafSJohn Baldwin printf(" FACS:\tLength=%u, ", facs->Length);
2475986dffafSJohn Baldwin printf("HwSig=0x%08x, ", facs->HardwareSignature);
2476986dffafSJohn Baldwin printf("Firm_Wake_Vec=0x%08x\n", facs->FirmwareWakingVector);
24778e6a8737SNate Lawson
2478773b6454SNate Lawson printf("\tGlobal_Lock=");
2479986dffafSJohn Baldwin if (facs->GlobalLock != 0) {
2480986dffafSJohn Baldwin if (facs->GlobalLock & ACPI_GLOCK_PENDING)
24818e6a8737SNate Lawson printf("PENDING,");
2482986dffafSJohn Baldwin if (facs->GlobalLock & ACPI_GLOCK_OWNED)
24838e6a8737SNate Lawson printf("OWNED");
24848e6a8737SNate Lawson }
2485773b6454SNate Lawson printf("\n");
24868e6a8737SNate Lawson
2487773b6454SNate Lawson printf("\tFlags=");
2488986dffafSJohn Baldwin if (facs->Flags & ACPI_FACS_S4_BIOS_PRESENT)
24898e6a8737SNate Lawson printf("S4BIOS");
2490773b6454SNate Lawson printf("\n");
24918e6a8737SNate Lawson
24927d369c6eSJung-uk Kim if (facs->XFirmwareWakingVector != 0)
24937d369c6eSJung-uk Kim printf("\tX_Firm_Wake_Vec=%016jx\n",
24947d369c6eSJung-uk Kim (uintmax_t)facs->XFirmwareWakingVector);
2495986dffafSJohn Baldwin printf("\tVersion=%u\n", facs->Version);
24968e6a8737SNate Lawson
2497c62f1cccSMitsuru IWASAKI printf(END_COMMENT);
2498e1e9a4bfSMitsuru IWASAKI }
2499e1e9a4bfSMitsuru IWASAKI
2500945137d9SNate Lawson static void
acpi_print_dsdt(ACPI_TABLE_HEADER * dsdp)2501986dffafSJohn Baldwin acpi_print_dsdt(ACPI_TABLE_HEADER *dsdp)
2502e1e9a4bfSMitsuru IWASAKI {
2503773b6454SNate Lawson printf(BEGIN_COMMENT);
2504773b6454SNate Lawson acpi_print_sdt(dsdp);
2505773b6454SNate Lawson printf(END_COMMENT);
2506e1e9a4bfSMitsuru IWASAKI }
2507e1e9a4bfSMitsuru IWASAKI
2508e1e9a4bfSMitsuru IWASAKI int
acpi_checksum(void * p,size_t length)2509e1e9a4bfSMitsuru IWASAKI acpi_checksum(void *p, size_t length)
2510e1e9a4bfSMitsuru IWASAKI {
2511986dffafSJohn Baldwin uint8_t *bp;
2512986dffafSJohn Baldwin uint8_t sum;
2513e1e9a4bfSMitsuru IWASAKI
2514e1e9a4bfSMitsuru IWASAKI bp = p;
2515e1e9a4bfSMitsuru IWASAKI sum = 0;
2516e1e9a4bfSMitsuru IWASAKI while (length--)
2517e1e9a4bfSMitsuru IWASAKI sum += *bp++;
2518e1e9a4bfSMitsuru IWASAKI
2519e1e9a4bfSMitsuru IWASAKI return (sum);
2520e1e9a4bfSMitsuru IWASAKI }
2521e1e9a4bfSMitsuru IWASAKI
2522986dffafSJohn Baldwin static ACPI_TABLE_HEADER *
acpi_map_sdt(vm_offset_t pa)2523e1e9a4bfSMitsuru IWASAKI acpi_map_sdt(vm_offset_t pa)
2524e1e9a4bfSMitsuru IWASAKI {
2525986dffafSJohn Baldwin ACPI_TABLE_HEADER *sp;
2526e1e9a4bfSMitsuru IWASAKI
2527986dffafSJohn Baldwin sp = acpi_map_physical(pa, sizeof(ACPI_TABLE_HEADER));
2528986dffafSJohn Baldwin sp = acpi_map_physical(pa, sp->Length);
2529e1e9a4bfSMitsuru IWASAKI return (sp);
2530e1e9a4bfSMitsuru IWASAKI }
2531e1e9a4bfSMitsuru IWASAKI
2532945137d9SNate Lawson static void
acpi_print_rsd_ptr(ACPI_TABLE_RSDP * rp)2533986dffafSJohn Baldwin acpi_print_rsd_ptr(ACPI_TABLE_RSDP *rp)
2534e1e9a4bfSMitsuru IWASAKI {
2535c62f1cccSMitsuru IWASAKI printf(BEGIN_COMMENT);
2536a74172abSNate Lawson printf(" RSD PTR: OEM=");
2537986dffafSJohn Baldwin acpi_print_string(rp->OemId, ACPI_OEM_ID_SIZE);
2538986dffafSJohn Baldwin printf(", ACPI_Rev=%s (%d)\n", rp->Revision < 2 ? "1.0x" : "2.0x",
2539986dffafSJohn Baldwin rp->Revision);
2540986dffafSJohn Baldwin if (rp->Revision < 2) {
2541986dffafSJohn Baldwin printf("\tRSDT=0x%08x, cksum=%u\n", rp->RsdtPhysicalAddress,
2542986dffafSJohn Baldwin rp->Checksum);
2543a74172abSNate Lawson } else {
25447d369c6eSJung-uk Kim printf("\tXSDT=0x%016jx, length=%u, cksum=%u\n",
25457d369c6eSJung-uk Kim (uintmax_t)rp->XsdtPhysicalAddress, rp->Length,
2546986dffafSJohn Baldwin rp->ExtendedChecksum);
2547a74172abSNate Lawson }
2548c62f1cccSMitsuru IWASAKI printf(END_COMMENT);
2549e1e9a4bfSMitsuru IWASAKI }
2550e1e9a4bfSMitsuru IWASAKI
255141b95006SKonstantin Belousov static const struct {
2552e9ab827dSWarner Losh const char *sig;
2553e9ab827dSWarner Losh void (*fnp)(ACPI_TABLE_HEADER *);
2554e9ab827dSWarner Losh } known[] = {
2555e9ab827dSWarner Losh { ACPI_SIG_BERT, acpi_handle_bert },
2556e9ab827dSWarner Losh { ACPI_SIG_DMAR, acpi_handle_dmar },
2557e9ab827dSWarner Losh { ACPI_SIG_ECDT, acpi_handle_ecdt },
2558e9ab827dSWarner Losh { ACPI_SIG_EINJ, acpi_handle_einj },
2559e9ab827dSWarner Losh { ACPI_SIG_ERST, acpi_handle_erst },
2560e9ab827dSWarner Losh { ACPI_SIG_FADT, acpi_handle_fadt },
2561e9ab827dSWarner Losh { ACPI_SIG_HEST, acpi_handle_hest },
2562e9ab827dSWarner Losh { ACPI_SIG_HPET, acpi_handle_hpet },
2563e9ab827dSWarner Losh { ACPI_SIG_IVRS, acpi_handle_ivrs },
2564e9ab827dSWarner Losh { ACPI_SIG_LPIT, acpi_handle_lpit },
2565e9ab827dSWarner Losh { ACPI_SIG_MADT, acpi_handle_madt },
2566e9ab827dSWarner Losh { ACPI_SIG_MCFG, acpi_handle_mcfg },
2567e9ab827dSWarner Losh { ACPI_SIG_NFIT, acpi_handle_nfit },
2568e9ab827dSWarner Losh { ACPI_SIG_SLIT, acpi_handle_slit },
2569e9ab827dSWarner Losh { ACPI_SIG_SPCR, acpi_handle_spcr },
2570e9ab827dSWarner Losh { ACPI_SIG_SRAT, acpi_handle_srat },
2571e9ab827dSWarner Losh { ACPI_SIG_TCPA, acpi_handle_tcpa },
2572e9ab827dSWarner Losh { ACPI_SIG_TPM2, acpi_handle_tpm2 },
2573e9ab827dSWarner Losh { ACPI_SIG_WDDT, acpi_handle_wddt },
2574e9ab827dSWarner Losh };
2575e9ab827dSWarner Losh
2576e9ab827dSWarner Losh static void
acpi_report_sdp(ACPI_TABLE_HEADER * sdp)2577e9ab827dSWarner Losh acpi_report_sdp(ACPI_TABLE_HEADER *sdp)
2578e9ab827dSWarner Losh {
2579e9ab827dSWarner Losh for (u_int i = 0; i < nitems(known); i++) {
25808f553746SKonstantin Belousov if (memcmp(sdp->Signature, known[i].sig, ACPI_NAMESEG_SIZE)
25818f553746SKonstantin Belousov == 0) {
2582e9ab827dSWarner Losh known[i].fnp(sdp);
2583e9ab827dSWarner Losh return;
2584e9ab827dSWarner Losh }
2585e9ab827dSWarner Losh }
2586e9ab827dSWarner Losh
2587e9ab827dSWarner Losh /*
2588e9ab827dSWarner Losh * Otherwise, do a generic thing.
2589e9ab827dSWarner Losh */
2590e9ab827dSWarner Losh printf(BEGIN_COMMENT);
2591e9ab827dSWarner Losh acpi_print_sdt(sdp);
2592e9ab827dSWarner Losh printf(END_COMMENT);
2593e9ab827dSWarner Losh }
2594e9ab827dSWarner Losh
2595945137d9SNate Lawson static void
acpi_handle_rsdt(ACPI_TABLE_HEADER * rsdp,const char * tbl)25963ff9ea7dSWarner Losh acpi_handle_rsdt(ACPI_TABLE_HEADER *rsdp, const char *tbl)
2597e1e9a4bfSMitsuru IWASAKI {
2598986dffafSJohn Baldwin ACPI_TABLE_HEADER *sdp;
2599986dffafSJohn Baldwin ACPI_TABLE_RSDT *rsdt;
2600986dffafSJohn Baldwin ACPI_TABLE_XSDT *xsdt;
2601a74172abSNate Lawson vm_offset_t addr;
2602a74172abSNate Lawson int entries, i;
2603e1e9a4bfSMitsuru IWASAKI
26043ff9ea7dSWarner Losh if (tbl == NULL) {
2605e1e9a4bfSMitsuru IWASAKI acpi_print_rsdt(rsdp);
26063ff9ea7dSWarner Losh } else {
26073ff9ea7dSWarner Losh if (memcmp(tbl, rsdp->Signature, ACPI_NAMESEG_SIZE) == 0) {
26083ff9ea7dSWarner Losh acpi_print_rsdt(rsdp);
26093ff9ea7dSWarner Losh return;
26103ff9ea7dSWarner Losh }
26113ff9ea7dSWarner Losh }
2612986dffafSJohn Baldwin rsdt = (ACPI_TABLE_RSDT *)rsdp;
2613986dffafSJohn Baldwin xsdt = (ACPI_TABLE_XSDT *)rsdp;
2614986dffafSJohn Baldwin entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
2615e1e9a4bfSMitsuru IWASAKI for (i = 0; i < entries; i++) {
2616fe1d0c2dSJung-uk Kim if (addr_size == 4)
2617986dffafSJohn Baldwin addr = le32toh(rsdt->TableOffsetEntry[i]);
2618fe1d0c2dSJung-uk Kim else
2619986dffafSJohn Baldwin addr = le64toh(xsdt->TableOffsetEntry[i]);
2620fe1d0c2dSJung-uk Kim if (addr == 0)
2621fe1d0c2dSJung-uk Kim continue;
2622986dffafSJohn Baldwin sdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
2623986dffafSJohn Baldwin if (acpi_checksum(sdp, sdp->Length)) {
26245cf6d493SNate Lawson warnx("RSDT entry %d (sig %.4s) is corrupt", i,
2625986dffafSJohn Baldwin sdp->Signature);
26265cf6d493SNate Lawson continue;
26275cf6d493SNate Lawson }
26283ff9ea7dSWarner Losh if (tbl != NULL && memcmp(sdp->Signature, tbl, ACPI_NAMESEG_SIZE) != 0)
26293ff9ea7dSWarner Losh continue;
2630e9ab827dSWarner Losh acpi_report_sdp(sdp);
2631e1e9a4bfSMitsuru IWASAKI }
2632e1e9a4bfSMitsuru IWASAKI }
2633c62f1cccSMitsuru IWASAKI
2634986dffafSJohn Baldwin ACPI_TABLE_HEADER *
sdt_load_devmem(void)2635476daaecSDag-Erling Smørgrav sdt_load_devmem(void)
2636945137d9SNate Lawson {
2637986dffafSJohn Baldwin ACPI_TABLE_RSDP *rp;
2638986dffafSJohn Baldwin ACPI_TABLE_HEADER *rsdp;
2639945137d9SNate Lawson
2640945137d9SNate Lawson rp = acpi_find_rsd_ptr();
2641945137d9SNate Lawson if (!rp)
2642945137d9SNate Lawson errx(1, "Can't find ACPI information");
2643945137d9SNate Lawson
2644945137d9SNate Lawson if (tflag)
2645945137d9SNate Lawson acpi_print_rsd_ptr(rp);
2646986dffafSJohn Baldwin if (rp->Revision < 2) {
2647986dffafSJohn Baldwin rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->RsdtPhysicalAddress);
264819dd8811SWarner Losh if (memcmp(rsdp->Signature, "RSDT", ACPI_NAMESEG_SIZE) != 0 ||
2649986dffafSJohn Baldwin acpi_checksum(rsdp, rsdp->Length) != 0)
2650945137d9SNate Lawson errx(1, "RSDT is corrupted");
2651a74172abSNate Lawson addr_size = sizeof(uint32_t);
2652a74172abSNate Lawson } else {
2653986dffafSJohn Baldwin rsdp = (ACPI_TABLE_HEADER *)acpi_map_sdt(rp->XsdtPhysicalAddress);
265419dd8811SWarner Losh if (memcmp(rsdp->Signature, "XSDT", ACPI_NAMESEG_SIZE) != 0 ||
2655986dffafSJohn Baldwin acpi_checksum(rsdp, rsdp->Length) != 0)
2656a74172abSNate Lawson errx(1, "XSDT is corrupted");
2657a74172abSNate Lawson addr_size = sizeof(uint64_t);
2658a74172abSNate Lawson }
2659945137d9SNate Lawson return (rsdp);
2660945137d9SNate Lawson }
2661c62f1cccSMitsuru IWASAKI
266262c7bde1SNate Lawson /* Write the DSDT to a file, concatenating any SSDTs (if present). */
2663bfa3f012SMarcel Moolenaar static int
write_dsdt(int fd,ACPI_TABLE_HEADER * rsdt,ACPI_TABLE_HEADER * dsdt)2664986dffafSJohn Baldwin write_dsdt(int fd, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdt)
2665bfa3f012SMarcel Moolenaar {
2666986dffafSJohn Baldwin ACPI_TABLE_HEADER sdt;
2667986dffafSJohn Baldwin ACPI_TABLE_HEADER *ssdt;
2668bfa3f012SMarcel Moolenaar uint8_t sum;
2669bfa3f012SMarcel Moolenaar
267062c7bde1SNate Lawson /* Create a new checksum to account for the DSDT and any SSDTs. */
2671bfa3f012SMarcel Moolenaar sdt = *dsdt;
2672bfa3f012SMarcel Moolenaar if (rsdt != NULL) {
2673986dffafSJohn Baldwin sdt.Checksum = 0;
2674986dffafSJohn Baldwin sum = acpi_checksum(dsdt + 1, dsdt->Length -
2675986dffafSJohn Baldwin sizeof(ACPI_TABLE_HEADER));
2676986dffafSJohn Baldwin ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, NULL);
2677f7675a56SNate Lawson while (ssdt != NULL) {
2678986dffafSJohn Baldwin sdt.Length += ssdt->Length - sizeof(ACPI_TABLE_HEADER);
2679986dffafSJohn Baldwin sum += acpi_checksum(ssdt + 1,
2680986dffafSJohn Baldwin ssdt->Length - sizeof(ACPI_TABLE_HEADER));
2681986dffafSJohn Baldwin ssdt = sdt_from_rsdt(rsdt, ACPI_SIG_SSDT, ssdt);
2682bfa3f012SMarcel Moolenaar }
2683986dffafSJohn Baldwin sum += acpi_checksum(&sdt, sizeof(ACPI_TABLE_HEADER));
2684986dffafSJohn Baldwin sdt.Checksum -= sum;
2685bfa3f012SMarcel Moolenaar }
268662c7bde1SNate Lawson
268762c7bde1SNate Lawson /* Write out the DSDT header and body. */
2688986dffafSJohn Baldwin write(fd, &sdt, sizeof(ACPI_TABLE_HEADER));
2689986dffafSJohn Baldwin write(fd, dsdt + 1, dsdt->Length - sizeof(ACPI_TABLE_HEADER));
269062c7bde1SNate Lawson
2691b64e1b67SNate Lawson /* Write out any SSDTs (if present.) */
2692f7675a56SNate Lawson if (rsdt != NULL) {
2693bfa3f012SMarcel Moolenaar ssdt = sdt_from_rsdt(rsdt, "SSDT", NULL);
2694bfa3f012SMarcel Moolenaar while (ssdt != NULL) {
2695986dffafSJohn Baldwin write(fd, ssdt + 1, ssdt->Length -
2696986dffafSJohn Baldwin sizeof(ACPI_TABLE_HEADER));
2697bfa3f012SMarcel Moolenaar ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt);
2698bfa3f012SMarcel Moolenaar }
2699bfa3f012SMarcel Moolenaar }
2700bfa3f012SMarcel Moolenaar return (0);
2701bfa3f012SMarcel Moolenaar }
2702bfa3f012SMarcel Moolenaar
2703c62f1cccSMitsuru IWASAKI void
dsdt_save_file(char * outfile,ACPI_TABLE_HEADER * rsdt,ACPI_TABLE_HEADER * dsdp)2704986dffafSJohn Baldwin dsdt_save_file(char *outfile, ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
2705c62f1cccSMitsuru IWASAKI {
2706945137d9SNate Lawson int fd;
2707945137d9SNate Lawson mode_t mode;
2708945137d9SNate Lawson
2709945137d9SNate Lawson assert(outfile != NULL);
2710945137d9SNate Lawson mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
2711945137d9SNate Lawson fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, mode);
2712945137d9SNate Lawson if (fd == -1) {
2713945137d9SNate Lawson perror("dsdt_save_file");
2714945137d9SNate Lawson return;
2715945137d9SNate Lawson }
2716bfa3f012SMarcel Moolenaar write_dsdt(fd, rsdt, dsdp);
2717945137d9SNate Lawson close(fd);
2718c62f1cccSMitsuru IWASAKI }
2719c62f1cccSMitsuru IWASAKI
2720945137d9SNate Lawson void
aml_disassemble(ACPI_TABLE_HEADER * rsdt,ACPI_TABLE_HEADER * dsdp)2721986dffafSJohn Baldwin aml_disassemble(ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
2722c62f1cccSMitsuru IWASAKI {
27237e2cc014SDon Lewis char buf[PATH_MAX], tmpstr[PATH_MAX], wrkdir[PATH_MAX];
27247e2cc014SDon Lewis const char *iname = "/acpdump.din";
27257e2cc014SDon Lewis const char *oname = "/acpdump.dsl";
272699065116SJung-uk Kim const char *tmpdir;
2727945137d9SNate Lawson FILE *fp;
272899065116SJung-uk Kim size_t len;
27297e2cc014SDon Lewis int fd, status;
27307e2cc014SDon Lewis pid_t pid;
2731945137d9SNate Lawson
273299065116SJung-uk Kim tmpdir = getenv("TMPDIR");
273399065116SJung-uk Kim if (tmpdir == NULL)
273499065116SJung-uk Kim tmpdir = _PATH_TMP;
27357e2cc014SDon Lewis if (realpath(tmpdir, buf) == NULL) {
2736d6a6e590SJung-uk Kim perror("realpath tmp dir");
273799065116SJung-uk Kim return;
273899065116SJung-uk Kim }
27397e2cc014SDon Lewis len = sizeof(wrkdir) - strlen(iname);
27407e2cc014SDon Lewis if ((size_t)snprintf(wrkdir, len, "%s/acpidump.XXXXXX", buf) > len-1 ) {
27417e2cc014SDon Lewis fprintf(stderr, "$TMPDIR too long\n");
27427e2cc014SDon Lewis return;
27437e2cc014SDon Lewis }
27447e2cc014SDon Lewis if (mkdtemp(wrkdir) == NULL) {
27457e2cc014SDon Lewis perror("mkdtemp tmp working dir");
27467e2cc014SDon Lewis return;
27477e2cc014SDon Lewis }
274830bebccaSMaxim Konovalov len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, iname);
274930bebccaSMaxim Konovalov assert(len <= sizeof(tmpstr) - 1);
27507e2cc014SDon Lewis fd = open(tmpstr, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
2751945137d9SNate Lawson if (fd < 0) {
2752945137d9SNate Lawson perror("iasl tmp file");
2753945137d9SNate Lawson return;
2754c62f1cccSMitsuru IWASAKI }
2755bfa3f012SMarcel Moolenaar write_dsdt(fd, rsdt, dsdp);
2756945137d9SNate Lawson close(fd);
2757945137d9SNate Lawson
2758945137d9SNate Lawson /* Run iasl -d on the temp file */
27597e2cc014SDon Lewis if ((pid = fork()) == 0) {
2760945137d9SNate Lawson close(STDOUT_FILENO);
2761945137d9SNate Lawson if (vflag == 0)
2762945137d9SNate Lawson close(STDERR_FILENO);
276399065116SJung-uk Kim execl("/usr/sbin/iasl", "iasl", "-d", tmpstr, NULL);
2764945137d9SNate Lawson err(1, "exec");
2765c62f1cccSMitsuru IWASAKI }
27667e2cc014SDon Lewis if (pid > 0)
27677e2cc014SDon Lewis wait(&status);
27687e2cc014SDon Lewis if (unlink(tmpstr) < 0) {
27697e2cc014SDon Lewis perror("unlink");
27707e2cc014SDon Lewis goto out;
27717e2cc014SDon Lewis }
27727e2cc014SDon Lewis if (pid < 0) {
27737e2cc014SDon Lewis perror("fork");
27747e2cc014SDon Lewis goto out;
27757e2cc014SDon Lewis }
27767e2cc014SDon Lewis if (status != 0) {
2777861f5b95SSHENG-YI HONG fprintf(stderr, "iasl exit status = %d\n", status);
27787e2cc014SDon Lewis }
2779945137d9SNate Lawson
2780945137d9SNate Lawson /* Dump iasl's output to stdout */
278130bebccaSMaxim Konovalov len = (size_t)snprintf(tmpstr, sizeof(tmpstr), "%s%s", wrkdir, oname);
278230bebccaSMaxim Konovalov assert(len <= sizeof(tmpstr) - 1);
278399065116SJung-uk Kim fp = fopen(tmpstr, "r");
27847e2cc014SDon Lewis if (unlink(tmpstr) < 0) {
27857e2cc014SDon Lewis perror("unlink");
27867e2cc014SDon Lewis goto out;
27877e2cc014SDon Lewis }
2788945137d9SNate Lawson if (fp == NULL) {
2789945137d9SNate Lawson perror("iasl tmp file (read)");
27907e2cc014SDon Lewis goto out;
2791945137d9SNate Lawson }
2792945137d9SNate Lawson while ((len = fread(buf, 1, sizeof(buf), fp)) > 0)
2793945137d9SNate Lawson fwrite(buf, 1, len, stdout);
2794945137d9SNate Lawson fclose(fp);
27957e2cc014SDon Lewis
27967e2cc014SDon Lewis out:
27977e2cc014SDon Lewis if (rmdir(wrkdir) < 0)
27987e2cc014SDon Lewis perror("rmdir");
2799c62f1cccSMitsuru IWASAKI }
2800c62f1cccSMitsuru IWASAKI
2801945137d9SNate Lawson void
aml_disassemble_separate(ACPI_TABLE_HEADER * rsdt,ACPI_TABLE_HEADER * dsdp)2802f5a04b16STakanori Watanabe aml_disassemble_separate(ACPI_TABLE_HEADER *rsdt, ACPI_TABLE_HEADER *dsdp)
2803f5a04b16STakanori Watanabe {
2804f5a04b16STakanori Watanabe ACPI_TABLE_HEADER *ssdt = NULL;
2805f5a04b16STakanori Watanabe
2806f5a04b16STakanori Watanabe aml_disassemble(NULL, dsdp);
2807f5a04b16STakanori Watanabe if (rsdt != NULL) {
2808f5a04b16STakanori Watanabe for (;;) {
2809f5a04b16STakanori Watanabe ssdt = sdt_from_rsdt(rsdt, "SSDT", ssdt);
2810f5a04b16STakanori Watanabe if (ssdt == NULL)
2811f5a04b16STakanori Watanabe break;
2812f5a04b16STakanori Watanabe aml_disassemble(NULL, ssdt);
2813f5a04b16STakanori Watanabe }
2814f5a04b16STakanori Watanabe }
2815f5a04b16STakanori Watanabe }
2816f5a04b16STakanori Watanabe
2817f5a04b16STakanori Watanabe void
sdt_print_all(ACPI_TABLE_HEADER * rsdp,const char * tbl)28183ff9ea7dSWarner Losh sdt_print_all(ACPI_TABLE_HEADER *rsdp, const char *tbl)
2819c62f1cccSMitsuru IWASAKI {
28203ff9ea7dSWarner Losh acpi_handle_rsdt(rsdp, tbl);
2821c62f1cccSMitsuru IWASAKI }
2822c62f1cccSMitsuru IWASAKI
2823bfa3f012SMarcel Moolenaar /* Fetch a table matching the given signature via the RSDT. */
2824986dffafSJohn Baldwin ACPI_TABLE_HEADER *
sdt_from_rsdt(ACPI_TABLE_HEADER * rsdp,const char * sig,ACPI_TABLE_HEADER * last)2825986dffafSJohn Baldwin sdt_from_rsdt(ACPI_TABLE_HEADER *rsdp, const char *sig, ACPI_TABLE_HEADER *last)
2826c62f1cccSMitsuru IWASAKI {
2827986dffafSJohn Baldwin ACPI_TABLE_HEADER *sdt;
2828986dffafSJohn Baldwin ACPI_TABLE_RSDT *rsdt;
2829986dffafSJohn Baldwin ACPI_TABLE_XSDT *xsdt;
2830a74172abSNate Lawson vm_offset_t addr;
2831a74172abSNate Lawson int entries, i;
2832945137d9SNate Lawson
2833986dffafSJohn Baldwin rsdt = (ACPI_TABLE_RSDT *)rsdp;
2834986dffafSJohn Baldwin xsdt = (ACPI_TABLE_XSDT *)rsdp;
2835986dffafSJohn Baldwin entries = (rsdp->Length - sizeof(ACPI_TABLE_HEADER)) / addr_size;
2836945137d9SNate Lawson for (i = 0; i < entries; i++) {
2837fe1d0c2dSJung-uk Kim if (addr_size == 4)
2838986dffafSJohn Baldwin addr = le32toh(rsdt->TableOffsetEntry[i]);
2839fe1d0c2dSJung-uk Kim else
2840986dffafSJohn Baldwin addr = le64toh(xsdt->TableOffsetEntry[i]);
2841fe1d0c2dSJung-uk Kim if (addr == 0)
2842fe1d0c2dSJung-uk Kim continue;
2843986dffafSJohn Baldwin sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(addr);
2844bfa3f012SMarcel Moolenaar if (last != NULL) {
2845bfa3f012SMarcel Moolenaar if (sdt == last)
2846bfa3f012SMarcel Moolenaar last = NULL;
2847bfa3f012SMarcel Moolenaar continue;
2848bfa3f012SMarcel Moolenaar }
2849986dffafSJohn Baldwin if (memcmp(sdt->Signature, sig, strlen(sig)))
2850a74172abSNate Lawson continue;
2851986dffafSJohn Baldwin if (acpi_checksum(sdt, sdt->Length))
2852945137d9SNate Lawson errx(1, "RSDT entry %d is corrupt", i);
2853945137d9SNate Lawson return (sdt);
2854c62f1cccSMitsuru IWASAKI }
2855c62f1cccSMitsuru IWASAKI
2856945137d9SNate Lawson return (NULL);
2857c62f1cccSMitsuru IWASAKI }
2858c62f1cccSMitsuru IWASAKI
2859986dffafSJohn Baldwin ACPI_TABLE_HEADER *
dsdt_from_fadt(ACPI_TABLE_FADT * fadt)2860986dffafSJohn Baldwin dsdt_from_fadt(ACPI_TABLE_FADT *fadt)
2861c62f1cccSMitsuru IWASAKI {
2862986dffafSJohn Baldwin ACPI_TABLE_HEADER *sdt;
2863c62f1cccSMitsuru IWASAKI
2864986dffafSJohn Baldwin /* Use the DSDT address if it is version 1, otherwise use XDSDT. */
2865c2962974SNate Lawson if (acpi_get_fadt_revision(fadt) == 1)
2866986dffafSJohn Baldwin sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->Dsdt);
28672e71eb12SNate Lawson else
2868986dffafSJohn Baldwin sdt = (ACPI_TABLE_HEADER *)acpi_map_sdt(fadt->XDsdt);
2869986dffafSJohn Baldwin if (acpi_checksum(sdt, sdt->Length))
2870945137d9SNate Lawson errx(1, "DSDT is corrupt\n");
2871945137d9SNate Lawson return (sdt);
2872c62f1cccSMitsuru IWASAKI }
2873