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