1/*	$NetBSD: acpi_verbose.c,v 1.22 2022/06/02 00:12:20 rin Exp $ */
2
3/*-
4 * Copyright (c) 2003, 2007, 2010 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Charles M. Hannum of By Noon Software, Inc, and Jukka Ruohonen.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32/*
33 * Copyright 2001, 2003 Wasabi Systems, Inc.
34 * All rights reserved.
35 *
36 * Written by Jason R. Thorpe for Wasabi Systems, Inc.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
40 * are met:
41 * 1. Redistributions of source code must retain the above copyright
42 *    notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 *    notice, this list of conditions and the following disclaimer in the
45 *    documentation and/or other materials provided with the distribution.
46 * 3. All advertising materials mentioning features or use of this software
47 *    must display the following acknowledgement:
48 *	This product includes software developed for the NetBSD Project by
49 *	Wasabi Systems, Inc.
50 * 4. The name of Wasabi Systems, Inc. may not be used to endorse
51 *    or promote products derived from this software without specific prior
52 *    written permission.
53 *
54 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
55 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
56 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
57 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
58 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
59 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
60 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
61 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
62 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
63 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
64 * POSSIBILITY OF SUCH DAMAGE.
65 */
66
67#include <sys/cdefs.h>
68__KERNEL_RCSID(0, "$NetBSD: acpi_verbose.c,v 1.22 2022/06/02 00:12:20 rin Exp $");
69
70#include "pci.h"
71
72#include <sys/param.h>
73#include <sys/device.h>
74#include <sys/kernel.h>
75#include <sys/systm.h>
76#include <sys/module.h>
77
78#include <dev/acpi/acpireg.h>
79#include <dev/acpi/acpivar.h>
80#include <dev/acpi/acpidevs_data.h>
81#include <dev/acpi/acpi_pci.h>
82
83#include <prop/proplib.h>
84
85#define _COMPONENT ACPI_UTILITIES
86ACPI_MODULE_NAME   ("acpi_verbose")
87
88static bool	   acpiverbose_modcmd_prop(prop_dictionary_t);
89
90void		   acpi_print_verbose_real(struct acpi_softc *);
91void		   acpi_print_dev_real(const char *);
92static void	   acpi_print_madt(struct acpi_softc *);
93static ACPI_STATUS acpi_print_madt_callback(ACPI_SUBTABLE_HEADER *, void *);
94static void	   acpi_print_fadt(struct acpi_softc *);
95static void	   acpi_print_devnodes(struct acpi_softc *);
96static void	   acpi_print_tree(struct acpi_devnode *, uint32_t);
97
98extern ACPI_TABLE_HEADER *madt_header;
99
100MODULE(MODULE_CLASS_MISC, acpiverbose, NULL);
101
102static int
103acpiverbose_modcmd(modcmd_t cmd, void *arg)
104{
105	static void (*saved_print_verbose)(struct acpi_softc *);
106	static void (*saved_print_dev)(const char *);
107	bool dump;
108
109	dump = false;
110
111	switch (cmd) {
112
113	case MODULE_CMD_INIT:
114		saved_print_verbose = acpi_print_verbose;
115		saved_print_dev = acpi_print_dev;
116		acpi_print_verbose = acpi_print_verbose_real;
117		acpi_print_dev = acpi_print_dev_real;
118		acpi_verbose_loaded = 1;
119
120		if (arg != NULL)
121			dump = acpiverbose_modcmd_prop(arg);
122
123		if (dump != false)
124			acpi_print_verbose_real(acpi_softc);
125
126		return 0;
127
128	case MODULE_CMD_FINI:
129		acpi_print_verbose = saved_print_verbose;
130		acpi_print_dev = saved_print_dev;
131		acpi_verbose_loaded = 0;
132		return 0;
133
134	default:
135		return ENOTTY;
136	}
137}
138
139static bool
140acpiverbose_modcmd_prop(prop_dictionary_t dict)
141{
142	prop_object_t obj;
143
144	obj = prop_dictionary_get(dict, "dump");
145
146	if (obj == NULL || prop_object_type(obj) != PROP_TYPE_BOOL)
147		return false;
148
149	return prop_bool_true(obj);
150}
151
152void
153acpi_print_verbose_real(struct acpi_softc *sc)
154{
155
156	acpi_print_madt(sc);
157	acpi_print_fadt(sc);
158	acpi_print_devnodes(sc);
159	acpi_print_tree(sc->sc_root, 0);
160}
161
162void
163acpi_print_dev_real(const char *pnpstr)
164{
165	int i;
166
167	for (i = 0; i < __arraycount(acpi_knowndevs); i++) {
168
169		if (strcmp(acpi_knowndevs[i].pnp, pnpstr) == 0)
170			aprint_normal("[%s] ", acpi_knowndevs[i].str);
171	}
172}
173
174static void
175acpi_print_madt(struct acpi_softc *sc)
176{
177	ACPI_STATUS rv;
178
179	rv = acpi_madt_map();
180
181	if (ACPI_FAILURE(rv) && rv != AE_ALREADY_EXISTS)
182		return;
183
184	if (madt_header == NULL)
185		return;
186
187	acpi_madt_walk(acpi_print_madt_callback, sc);
188}
189
190static ACPI_STATUS
191acpi_print_madt_callback(ACPI_SUBTABLE_HEADER *hdr, void *aux)
192{
193	struct acpi_softc *sc = aux;
194	device_t self = sc->sc_dev;
195
196	/*
197	 * See ACPI 4.0, section 5.2.12.
198	 */
199	switch (hdr->Type) {
200
201	case ACPI_MADT_TYPE_LOCAL_APIC:
202
203		aprint_normal_dev(self, "[MADT] %-15s: "
204		    "CPU ID %u, LAPIC ID %u, FLAGS 0x%02X", "LAPIC",
205		    ((ACPI_MADT_LOCAL_APIC *)hdr)->ProcessorId,
206		    ((ACPI_MADT_LOCAL_APIC *)hdr)->Id,
207		    ((ACPI_MADT_LOCAL_APIC *)hdr)->LapicFlags);
208
209		break;
210
211	case ACPI_MADT_TYPE_IO_APIC:
212
213		aprint_normal_dev(self, "[MADT] %-15s: "
214		    "ID %u, GSI %u, ADDR 0x%04X", "I/O APIC",
215		    ((ACPI_MADT_IO_APIC *)hdr)->Id,
216		    ((ACPI_MADT_IO_APIC *)hdr)->GlobalIrqBase,
217		    ((ACPI_MADT_IO_APIC *)hdr)->Address);
218
219		break;
220
221	case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
222
223		aprint_normal_dev(self, "[MADT] %-15s: "
224		    "BUS %u, IRQ %u, GSI %u, FLAGS 0x%02X", "INTR OVERRIDE",
225		    ((ACPI_MADT_INTERRUPT_OVERRIDE *)hdr)->Bus,
226		    ((ACPI_MADT_INTERRUPT_OVERRIDE *)hdr)->SourceIrq,
227		    ((ACPI_MADT_INTERRUPT_OVERRIDE *)hdr)->GlobalIrq,
228		    ((ACPI_MADT_INTERRUPT_OVERRIDE *)hdr)->IntiFlags);
229
230		break;
231
232	case ACPI_MADT_TYPE_NMI_SOURCE:
233
234		aprint_normal_dev(self, "[MADT] %-15s: "
235		    "GSI %u, FLAGS 0x%02X", "NMI SOURCE",
236		    ((ACPI_MADT_NMI_SOURCE *)hdr)->GlobalIrq,
237		    ((ACPI_MADT_NMI_SOURCE *)hdr)->IntiFlags);
238
239		break;
240
241	case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
242
243		aprint_normal_dev(self, "[MADT] %-15s: "
244		    "CPU ID %u, LINT %u, FLAGS 0x%02X", "LAPIC NMI",
245		    ((ACPI_MADT_LOCAL_APIC_NMI *)hdr)->ProcessorId,
246		    ((ACPI_MADT_LOCAL_APIC_NMI *)hdr)->Lint,
247		    ((ACPI_MADT_LOCAL_APIC_NMI *)hdr)->IntiFlags);
248
249		break;
250
251	case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
252
253		aprint_normal_dev(self, "[MADT] %-15s: "
254		    "ADDR 0x%016" PRIX64"", "APIC OVERRIDE",
255		    ((ACPI_MADT_LOCAL_APIC_OVERRIDE *)hdr)->Address);
256
257		break;
258
259	case ACPI_MADT_TYPE_IO_SAPIC:
260
261		aprint_normal_dev(self, "[MADT] %-15s: "
262		    "ID %u, GSI %u, ADDR 0x%016" PRIX64"", "I/O SAPIC",
263		    ((ACPI_MADT_IO_SAPIC *)hdr)->Id,
264		    ((ACPI_MADT_IO_SAPIC *)hdr)->GlobalIrqBase,
265		    ((ACPI_MADT_IO_SAPIC *)hdr)->Address);
266
267		break;
268
269	case ACPI_MADT_TYPE_LOCAL_SAPIC:
270
271		aprint_normal_dev(self, "[MADT] %-15s: "
272		    "CPU ID %u, ID %u, EID %u, UID %u, FLAGS 0x%02X", "LSAPIC",
273		    ((ACPI_MADT_LOCAL_SAPIC*)hdr)->ProcessorId,
274		    ((ACPI_MADT_LOCAL_SAPIC*)hdr)->Id,
275		    ((ACPI_MADT_LOCAL_SAPIC*)hdr)->Eid,
276		    ((ACPI_MADT_LOCAL_SAPIC*)hdr)->Uid,
277		    ((ACPI_MADT_LOCAL_SAPIC*)hdr)->LapicFlags);
278
279		break;
280
281	case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
282
283		aprint_normal_dev(self, "[MADT] %-15s: ID %u, EID %u, "
284		    "TYPE %u, PMI %u, GSI %u, FLAGS 0x%02X", "INTR SOURCE",
285		    ((ACPI_MADT_INTERRUPT_SOURCE *)hdr)->Id,
286		    ((ACPI_MADT_INTERRUPT_SOURCE *)hdr)->Eid,
287		    ((ACPI_MADT_INTERRUPT_SOURCE *)hdr)->Type,
288		    ((ACPI_MADT_INTERRUPT_SOURCE *)hdr)->IoSapicVector,
289		    ((ACPI_MADT_INTERRUPT_SOURCE *)hdr)->GlobalIrq,
290		    ((ACPI_MADT_INTERRUPT_SOURCE *)hdr)->Flags);
291
292		break;
293
294	case ACPI_MADT_TYPE_LOCAL_X2APIC:
295
296		aprint_normal_dev(self, "[MADT] %-15s: "
297		    "ID %u, UID %u, FLAGS 0x%02X", "X2APIC",
298		    ((ACPI_MADT_LOCAL_X2APIC *)hdr)->LocalApicId,
299		    ((ACPI_MADT_LOCAL_X2APIC *)hdr)->Uid,
300		    ((ACPI_MADT_LOCAL_X2APIC *)hdr)->LapicFlags);
301
302		break;
303
304	case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
305
306		aprint_normal_dev(self, "[MADT] %-15s: "
307		    "UID %u, LINT %u, FLAGS 0x%02X", "X2APIC NMI",
308		    ((ACPI_MADT_LOCAL_X2APIC_NMI *)hdr)->Uid,
309		    ((ACPI_MADT_LOCAL_X2APIC_NMI *)hdr)->Lint,
310		    ((ACPI_MADT_LOCAL_X2APIC_NMI *)hdr)->IntiFlags);
311
312		break;
313
314	default:
315		aprint_normal_dev(self, "[MADT] %-15s", "UNKNOWN");
316		break;
317	}
318
319	aprint_normal("\n");
320
321	return AE_OK;
322}
323
324static void
325acpi_print_fadt(struct acpi_softc *sc)
326{
327	uint32_t i;
328
329	/*
330	 * See ACPI 4.0, section 5.2.9.
331	 */
332	struct acpi_fadt {
333		uint32_t	 fadt_offset;
334		const char	*fadt_name;
335		uint64_t	 fadt_value;
336	};
337
338	struct acpi_fadt_genaddr {
339		uint32_t		 fadt_offset;
340		const char		*fadt_name;
341		ACPI_GENERIC_ADDRESS	 fadt_value;
342	};
343
344	const struct acpi_fadt acpi_fadt_table[] = {
345
346		{ 36,	"FACS",		 AcpiGbl_FADT.Facs		},
347		{ 40,	"DSDT",		 AcpiGbl_FADT.Dsdt		},
348		{ 44,	"INT_MODEL",	 AcpiGbl_FADT.Model		},
349		{ 45,	"PM_PROFILE",	 AcpiGbl_FADT.PreferredProfile	},
350		{ 46,	"SCI_INT",	 AcpiGbl_FADT.SciInterrupt	},
351		{ 48,	"SMI_CMD",	 AcpiGbl_FADT.SmiCommand	},
352		{ 52,	"ACPI_ENABLE",	 AcpiGbl_FADT.AcpiEnable	},
353		{ 53,	"ACPI_DISABLE",	 AcpiGbl_FADT.AcpiDisable	},
354		{ 54,	"S4BIOS_REQ",	 AcpiGbl_FADT.S4BiosRequest	},
355		{ 55,	"PSTATE_CNT",	 AcpiGbl_FADT.PstateControl	},
356		{ 56,	"PM1a_EVT_BLK",	 AcpiGbl_FADT.Pm1aEventBlock	},
357		{ 60,	"PM1b_EVT_BLK",	 AcpiGbl_FADT.Pm1bEventBlock	},
358		{ 64,	"PM1a_CNT_BLK",	 AcpiGbl_FADT.Pm1aControlBlock	},
359		{ 68,	"PM1b_CNT_BLK",	 AcpiGbl_FADT.Pm1bControlBlock	},
360		{ 72,	"PM2_CNT_BLK",	 AcpiGbl_FADT.Pm2ControlBlock	},
361		{ 76,	"PM_TMR_BLK",	 AcpiGbl_FADT.PmTimerBlock	},
362		{ 80,	"GPE0_BLK",	 AcpiGbl_FADT.Gpe0Block		},
363		{ 84,	"GPE1_BLK",	 AcpiGbl_FADT.Gpe1Block		},
364		{ 88,	"PM1_EVT_LEN",	 AcpiGbl_FADT.Pm1EventLength	},
365		{ 89,	"PM1_CNT_LEN",	 AcpiGbl_FADT.Pm1ControlLength	},
366		{ 90,	"PM2_CNT_LEN",	 AcpiGbl_FADT.Pm2ControlLength	},
367		{ 91,	"PM_TMR_LEN",	 AcpiGbl_FADT.PmTimerLength	},
368		{ 92,	"GPE0_BLK_LEN",	 AcpiGbl_FADT.Gpe0BlockLength	},
369		{ 93,	"GPE1_BLK_LEN",	 AcpiGbl_FADT.Gpe1BlockLength	},
370		{ 94,	"GPE1_BASE",	 AcpiGbl_FADT.Gpe1Base		},
371		{ 95,	"CST_CNT",	 AcpiGbl_FADT.CstControl	},
372		{ 96,	"P_LVL2_LAT",	 AcpiGbl_FADT.C2Latency		},
373		{ 98,	"P_LVL3_LAT",	 AcpiGbl_FADT.C3Latency		},
374		{ 100,	"FLUSH_SIZE",	 AcpiGbl_FADT.FlushSize		},
375		{ 102,	"FLUSH_STRIDE",	 AcpiGbl_FADT.FlushStride	},
376		{ 104,	"DUTY_OFFSET",	 AcpiGbl_FADT.DutyOffset	},
377		{ 105,	"DUTY_WIDTH",	 AcpiGbl_FADT.DutyWidth		},
378		{ 106,	"DAY_ALRM",	 AcpiGbl_FADT.DayAlarm		},
379		{ 107,	"MON_ALRM",	 AcpiGbl_FADT.MonthAlarm	},
380		{ 108,	"CENTURY",	 AcpiGbl_FADT.Century		},
381		{ 109,	"IAPC_BOOT_ARCH",AcpiGbl_FADT.BootFlags		},
382		{ 128,	"RESET_VALUE",	 AcpiGbl_FADT.ResetValue	},
383		{ 129,	"ARM_BOOT_ARCH", AcpiGbl_FADT.ArmBootFlags	},
384		{ 132,	"X_FACS",	 AcpiGbl_FADT.XFacs  		},
385		{ 140,	"X_DSDT",	 AcpiGbl_FADT.XDsdt  		},
386	};
387
388	const struct acpi_fadt_genaddr acpi_fadt_genaddr_table[] = {
389
390		{ 116,	"RESET_REG",	 AcpiGbl_FADT.ResetRegister  	},
391		{ 148,	"X_PM1a_EVT_BLK",AcpiGbl_FADT.XPm1aEventBlock	},
392		{ 160,	"X_PM1b_EVT_BLK",AcpiGbl_FADT.XPm1bEventBlock	},
393		{ 172,	"X_PM1a_CNT_BLK",AcpiGbl_FADT.XPm1aControlBlock	},
394		{ 184,	"X_PM1b_CNT_BLK",AcpiGbl_FADT.XPm1bControlBlock	},
395		{ 196,	"X_PM2_CNT_BLK", AcpiGbl_FADT.XPm2ControlBlock	},
396		{ 208,	"X_PM_TMR_BLK",	 AcpiGbl_FADT.XPmTimerBlock	},
397		{ 220,	"X_GPE0_BLK",	 AcpiGbl_FADT.XGpe0Block	},
398		{ 232,	"X_GPE1_BLK",	 AcpiGbl_FADT.XGpe1Block	},
399		{ 244,	"SLEEP_CTRL_REG",AcpiGbl_FADT.SleepControl	},
400		{ 256,	"SLEEP_STAT_REG",AcpiGbl_FADT.SleepStatus	},
401	};
402
403	const struct acpi_fadt acpi_fadt_flags[] = {
404
405		{ 0,	"WBINVD",	ACPI_FADT_WBINVD		},
406		{ 1,	"WBINVD_FLUSH",	ACPI_FADT_WBINVD_FLUSH		},
407		{ 2,	"PROC_C1",	ACPI_FADT_C1_SUPPORTED		},
408		{ 3,	"P_LVL2_UP",	ACPI_FADT_C2_MP_SUPPORTED	},
409		{ 4,	"PWR_BUTTON",	ACPI_FADT_POWER_BUTTON		},
410		{ 5,	"SLP_BUTTON",	ACPI_FADT_SLEEP_BUTTON		},
411		{ 6,	"FIX_RTC",	ACPI_FADT_FIXED_RTC		},
412		{ 7,	"RTC_S4",	ACPI_FADT_S4_RTC_WAKE		},
413		{ 8,	"TMR_VAL_EXT",	ACPI_FADT_32BIT_TIMER		},
414		{ 9,	"DCK_CAP",	ACPI_FADT_DOCKING_SUPPORTED	},
415		{ 10,	"RESET_REG_SUP",ACPI_FADT_RESET_REGISTER	},
416		{ 11,	"SEALED_CASE",	ACPI_FADT_SEALED_CASE		},
417		{ 12,	"HEADLESS",	ACPI_FADT_HEADLESS		},
418		{ 13,	"CPU_SW_SLP",	ACPI_FADT_SLEEP_TYPE		},
419		{ 14,	"PCI_EXP_WAK",	ACPI_FADT_PCI_EXPRESS_WAKE	},
420		{ 15,	"PLATFORM_CLK", ACPI_FADT_PLATFORM_CLOCK	},
421		{ 16,	"S4_RTC_STS",	ACPI_FADT_S4_RTC_VALID		},
422		{ 17,	"REMOTE_POWER", ACPI_FADT_REMOTE_POWER_ON	},
423		{ 18,	"APIC_CLUSTER",	ACPI_FADT_APIC_CLUSTER		},
424		{ 19,	"APIC_PHYSICAL",ACPI_FADT_APIC_PHYSICAL		},
425		{ 20,	"HW_REDUCED",	ACPI_FADT_HW_REDUCED		},
426		{ 21,	"LOW_POWER_S0",	ACPI_FADT_LOW_POWER_S0		},
427	};
428
429	for (i = 0; i < __arraycount(acpi_fadt_table); i++) {
430
431		aprint_normal_dev(sc->sc_dev,
432		    "[FADT] %-15s: 0x%016" PRIX64"\n",
433		    acpi_fadt_table[i].fadt_name,
434		    acpi_fadt_table[i].fadt_value);
435	}
436
437	for (i = 0; i < __arraycount(acpi_fadt_genaddr_table); i++) {
438
439		aprint_normal_dev(sc->sc_dev,
440		    "[FADT] %-15s: 0x%016" PRIX64", "
441		    "SPACE ID %u, BIT WIDTH %u, BIT OFFSET %u, "
442		    "ACCESS WIDTH %u\n",
443		    acpi_fadt_genaddr_table[i].fadt_name,
444		    acpi_fadt_genaddr_table[i].fadt_value.Address,
445		    acpi_fadt_genaddr_table[i].fadt_value.SpaceId,
446		    acpi_fadt_genaddr_table[i].fadt_value.BitWidth,
447		    acpi_fadt_genaddr_table[i].fadt_value.BitOffset,
448		    acpi_fadt_genaddr_table[i].fadt_value.AccessWidth);
449	}
450
451	for (i = 0; i < __arraycount(acpi_fadt_flags); i++) {
452
453		aprint_normal_dev(sc->sc_dev,
454		    "[FADT] %-15s: 0x%016" PRIX64"\n",
455		    acpi_fadt_flags[i].fadt_name, AcpiGbl_FADT.Flags &
456		    acpi_fadt_flags[i].fadt_value);
457
458		KASSERT(i ==  acpi_fadt_flags[i].fadt_offset);
459		KASSERT(__BIT(acpi_fadt_flags[i].fadt_offset) ==
460		              acpi_fadt_flags[i].fadt_value);
461	}
462}
463
464static void
465acpi_print_devnodes(struct acpi_softc *sc)
466{
467	struct acpi_devnode *ad;
468	ACPI_DEVICE_INFO *di;
469
470	SIMPLEQ_FOREACH(ad, &sc->sc_head, ad_list) {
471
472		di = ad->ad_devinfo;
473		aprint_normal_dev(sc->sc_dev, "[%-4s] ", ad->ad_name);
474
475		aprint_normal("HID %-10s ",
476		    ((di->Valid & ACPI_VALID_HID) != 0) ?
477		    di->HardwareId.String: "-");
478
479		aprint_normal("UID %-4s ",
480		    ((di->Valid & ACPI_VALID_UID) != 0) ?
481		    di->UniqueId.String : "-");
482
483		if ((di->Valid & ACPI_VALID_ADR) != 0)
484			aprint_normal("ADR 0x%016" PRIX64"", di->Address);
485		else
486			aprint_normal("ADR -");
487
488		aprint_normal("\n");
489	}
490	aprint_normal("\n");
491}
492
493static void
494acpi_print_tree(struct acpi_devnode *ad, uint32_t level)
495{
496	struct acpi_devnode *child;
497	char buf[5];
498	uint32_t i;
499
500	for (i = 0; i < level; i++)
501		aprint_normal("    ");
502
503	buf[0] = '\0';
504
505	if ((ad->ad_flags & ACPI_DEVICE_POWER) != 0)
506		(void)strlcat(buf, "P", sizeof(buf));
507
508	if ((ad->ad_flags & ACPI_DEVICE_WAKEUP) != 0)
509		(void)strlcat(buf, "W", sizeof(buf));
510
511	if ((ad->ad_flags & ACPI_DEVICE_EJECT) != 0)
512		(void)strlcat(buf, "E", sizeof(buf));
513
514	aprint_normal("%-5s [%02u] [%s]", ad->ad_name, ad->ad_type, buf);
515
516	if (ad->ad_device != NULL)
517		aprint_normal(" <%s>", device_xname(ad->ad_device));
518
519#if NPCI > 0
520	if (ad->ad_pciinfo != NULL) {
521
522		aprint_normal(" (PCI)");
523
524		if ((ad->ad_pciinfo->ap_flags & ACPI_PCI_INFO_DEVICE) != 0)
525			aprint_normal(" @ 0x%02X:0x%02X:0x%02X:0x%02X",
526			    ad->ad_pciinfo->ap_segment,
527			    ad->ad_pciinfo->ap_bus,
528			    ad->ad_pciinfo->ap_device,
529			    ad->ad_pciinfo->ap_function);
530
531		if ((ad->ad_devinfo->Flags & ACPI_PCI_ROOT_BRIDGE) != 0)
532			aprint_normal(" [R]");
533
534		if ((ad->ad_pciinfo->ap_flags & ACPI_PCI_INFO_BRIDGE) != 0)
535			aprint_normal(" [B] -> 0x%02X:0x%02X",
536			    ad->ad_pciinfo->ap_segment,
537			    ad->ad_pciinfo->ap_downbus);
538
539		device_t dev = acpi_pcidev_find_dev(ad);
540
541		if (dev != NULL)
542			aprint_normal(" <%s>", device_xname(dev));
543	}
544#endif
545
546	aprint_normal("\n");
547
548	SIMPLEQ_FOREACH(child, &ad->ad_child_head, ad_child_list)
549	    acpi_print_tree(child, level + 1);
550}
551