acpi_verbose.c revision 1.8
1/*	$NetBSD: acpi_verbose.c,v 1.8 2010/08/07 14:17:21 jruoho 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.8 2010/08/07 14:17:21 jruoho 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
80void		   acpi_print_verbose_real(struct acpi_softc *);
81void		   acpi_print_dev_real(const char *);
82static void	   acpi_print_madt(struct acpi_softc *);
83static ACPI_STATUS acpi_print_madt_callback(ACPI_SUBTABLE_HEADER *, void *);
84static void	   acpi_print_fadt(struct acpi_softc *);
85static void	   acpi_print_devnodes(struct acpi_softc *);
86static void	   acpi_print_tree(struct acpi_devnode *, uint32_t);
87
88extern ACPI_TABLE_HEADER *madt_header;
89
90MODULE(MODULE_CLASS_MISC, acpiverbose, NULL);
91
92static int
93acpiverbose_modcmd(modcmd_t cmd, void *arg)
94{
95	static void	(*saved_print_verbose)(struct acpi_softc *);
96	static void	(*saved_print_dev)(const char *);
97
98	switch (cmd) {
99
100	case MODULE_CMD_INIT:
101		saved_print_verbose = acpi_print_verbose;
102		saved_print_dev = acpi_print_dev;
103		acpi_print_verbose = acpi_print_verbose_real;
104		acpi_print_dev = acpi_print_dev_real;
105		acpi_verbose_loaded = 1;
106		return 0;
107
108	case MODULE_CMD_FINI:
109		acpi_print_verbose = saved_print_verbose;
110		acpi_print_dev = saved_print_dev;
111		acpi_verbose_loaded = 0;
112		return 0;
113
114	default:
115		return ENOTTY;
116	}
117}
118
119void
120acpi_print_verbose_real(struct acpi_softc *sc)
121{
122
123	acpi_print_madt(sc);
124	acpi_print_fadt(sc);
125	acpi_print_devnodes(sc);
126	acpi_print_tree(sc->sc_root, 0);
127}
128
129void
130acpi_print_dev_real(const char *pnpstr)
131{
132	int i;
133
134	for (i = 0; i < __arraycount(acpi_knowndevs); i++) {
135
136		if (strcmp(acpi_knowndevs[i].pnp, pnpstr) == 0)
137			aprint_normal("[%s] ", acpi_knowndevs[i].str);
138	}
139}
140
141static void
142acpi_print_madt(struct acpi_softc *sc)
143{
144	ACPI_TABLE_MADT *madt;
145	ACPI_STATUS rv;
146
147	rv = acpi_madt_map();
148
149	if (ACPI_FAILURE(rv) && rv != AE_ALREADY_EXISTS)
150		return;
151
152	if (madt_header == NULL)
153		return;
154
155	madt = (ACPI_TABLE_MADT *)madt_header;
156	acpi_madt_walk(acpi_print_madt_callback, sc);
157}
158
159static ACPI_STATUS
160acpi_print_madt_callback(ACPI_SUBTABLE_HEADER *hdr, void *aux)
161{
162	struct acpi_softc *sc = aux;
163	device_t self = sc->sc_dev;
164
165	/*
166	 * See ACPI 4.0, section 5.2.12.
167	 */
168	switch (hdr->Type) {
169
170	case ACPI_MADT_TYPE_LOCAL_APIC:
171
172		aprint_normal_dev(self, "[MADT] %-15s: "
173		    "CPU ID %u, LAPIC ID %u, FLAGS 0x%02X", "LAPIC",
174		    ((ACPI_MADT_LOCAL_APIC *)hdr)->ProcessorId,
175		    ((ACPI_MADT_LOCAL_APIC *)hdr)->Id,
176		    ((ACPI_MADT_LOCAL_APIC *)hdr)->LapicFlags);
177
178		break;
179
180	case ACPI_MADT_TYPE_IO_APIC:
181
182		aprint_normal_dev(self, "[MADT] %-15s: "
183		    "ID %u, GSI %u, ADDR 0x%04X", "I/O APIC",
184		    ((ACPI_MADT_IO_APIC *)hdr)->Id,
185		    ((ACPI_MADT_IO_APIC *)hdr)->GlobalIrqBase,
186		    ((ACPI_MADT_IO_APIC *)hdr)->Address);
187
188		break;
189
190	case ACPI_MADT_TYPE_INTERRUPT_OVERRIDE:
191
192		aprint_normal_dev(self, "[MADT] %-15s: "
193		    "BUS %u, IRQ %u, GSI %u, FLAGS 0x%02X", "INTR OVERRIDE",
194		    ((ACPI_MADT_INTERRUPT_OVERRIDE *)hdr)->Bus,
195		    ((ACPI_MADT_INTERRUPT_OVERRIDE *)hdr)->SourceIrq,
196		    ((ACPI_MADT_INTERRUPT_OVERRIDE *)hdr)->GlobalIrq,
197		    ((ACPI_MADT_INTERRUPT_OVERRIDE *)hdr)->IntiFlags);
198
199		break;
200
201	case ACPI_MADT_TYPE_NMI_SOURCE:
202
203		aprint_normal_dev(self, "[MADT] %-15s: "
204		    "GSI %u, FLAGS 0x%02X", "NMI SOURCE",
205		    ((ACPI_MADT_NMI_SOURCE *)hdr)->GlobalIrq,
206		    ((ACPI_MADT_NMI_SOURCE *)hdr)->IntiFlags);
207
208		break;
209
210	case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
211
212		aprint_normal_dev(self, "[MADT] %-15s: "
213		    "CPU ID %u, LINT %u, FLAGS 0x%02X", "LAPIC NMI",
214		    ((ACPI_MADT_LOCAL_APIC_NMI *)hdr)->ProcessorId,
215		    ((ACPI_MADT_LOCAL_APIC_NMI *)hdr)->Lint,
216		    ((ACPI_MADT_LOCAL_APIC_NMI *)hdr)->IntiFlags);
217
218		break;
219
220	case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
221
222		aprint_normal_dev(self, "[MADT] %-15s: "
223		    "ADDR 0x%016" PRIX64"", "APIC OVERRIDE",
224		    ((ACPI_MADT_LOCAL_APIC_OVERRIDE *)hdr)->Address);
225
226		break;
227
228	case ACPI_MADT_TYPE_IO_SAPIC:
229
230		aprint_normal_dev(self, "[MADT] %-15s: "
231		    "ID %u, GSI %u, ADDR 0x%016" PRIX64"", "I/O SAPIC",
232		    ((ACPI_MADT_IO_SAPIC *)hdr)->Id,
233		    ((ACPI_MADT_IO_SAPIC *)hdr)->GlobalIrqBase,
234		    ((ACPI_MADT_IO_SAPIC *)hdr)->Address);
235
236		break;
237
238	case ACPI_MADT_TYPE_LOCAL_SAPIC:
239
240		aprint_normal_dev(self, "[MADT] %-15s: "
241		    "CPU ID %u, ID %u, EID %u, UID %u, FLAGS 0x%02X", "LSAPIC",
242		    ((ACPI_MADT_LOCAL_SAPIC*)hdr)->ProcessorId,
243		    ((ACPI_MADT_LOCAL_SAPIC*)hdr)->Id,
244		    ((ACPI_MADT_LOCAL_SAPIC*)hdr)->Eid,
245		    ((ACPI_MADT_LOCAL_SAPIC*)hdr)->Uid,
246		    ((ACPI_MADT_LOCAL_SAPIC*)hdr)->LapicFlags);
247
248		break;
249
250	case ACPI_MADT_TYPE_INTERRUPT_SOURCE:
251
252		aprint_normal_dev(self, "[MADT] %-15s: ID %u, EID %u, "
253		    "TYPE %u, PMI %u, GSI %u, FLAGS 0x%02X", "INTR SOURCE",
254		    ((ACPI_MADT_INTERRUPT_SOURCE *)hdr)->Id,
255		    ((ACPI_MADT_INTERRUPT_SOURCE *)hdr)->Eid,
256		    ((ACPI_MADT_INTERRUPT_SOURCE *)hdr)->Type,
257		    ((ACPI_MADT_INTERRUPT_SOURCE *)hdr)->IoSapicVector,
258		    ((ACPI_MADT_INTERRUPT_SOURCE *)hdr)->GlobalIrq,
259		    ((ACPI_MADT_INTERRUPT_SOURCE *)hdr)->Flags);
260
261		break;
262
263	case ACPI_MADT_TYPE_LOCAL_X2APIC:
264
265		aprint_normal_dev(self, "[MADT] %-15s: "
266		    "ID %u, UID %u, FLAGS 0x%02X", "X2APIC",
267		    ((ACPI_MADT_LOCAL_X2APIC *)hdr)->LocalApicId,
268		    ((ACPI_MADT_LOCAL_X2APIC *)hdr)->Uid,
269		    ((ACPI_MADT_LOCAL_X2APIC *)hdr)->LapicFlags);
270
271		break;
272
273	case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
274
275		aprint_normal_dev(self, "[MADT] %-15s: "
276		    "UID %u, LINT %u, FLAGS 0x%02X", "X2APIC NMI",
277		    ((ACPI_MADT_LOCAL_X2APIC_NMI *)hdr)->Uid,
278		    ((ACPI_MADT_LOCAL_X2APIC_NMI *)hdr)->Lint,
279		    ((ACPI_MADT_LOCAL_X2APIC_NMI *)hdr)->IntiFlags);
280
281		break;
282
283	default:
284		aprint_normal_dev(self, "[MADT] %-15s", "UNKNOWN");
285		break;
286	}
287
288	aprint_normal("\n");
289
290	return AE_OK;
291}
292
293static void
294acpi_print_fadt(struct acpi_softc *sc)
295{
296	uint32_t i;
297
298	/*
299	 * See ACPI 4.0, section 5.2.9.
300	 */
301	struct acpi_fadt {
302		uint32_t	 fadt_offset;
303		const char	*fadt_name;
304		uint64_t	 fadt_value;
305	};
306
307	const struct acpi_fadt acpi_fadt_table[] = {
308
309		{ 36,	"FACS",		 AcpiGbl_FADT.Facs		},
310		{ 40,	"DSDT",		 AcpiGbl_FADT.Dsdt		},
311		{ 44,	"INT_MODEL",	 AcpiGbl_FADT.Model		},
312		{ 45,	"PM_PROFILE",	 AcpiGbl_FADT.PreferredProfile	},
313		{ 46,	"SCI_INT",	 AcpiGbl_FADT.SciInterrupt	},
314		{ 48,	"SMI_CMD",	 AcpiGbl_FADT.SmiCommand	},
315		{ 52,	"ACPI_ENABLE",	 AcpiGbl_FADT.AcpiEnable	},
316		{ 53,	"ACPI_DISABLE",	 AcpiGbl_FADT.AcpiDisable	},
317		{ 54,	"S4BIOS_REQ",	 AcpiGbl_FADT.S4BiosRequest	},
318		{ 55,	"PSTATE_CNT",	 AcpiGbl_FADT.PstateControl	},
319		{ 56,	"PM1a_EVT_BLK",	 AcpiGbl_FADT.Pm1aEventBlock	},
320		{ 60,	"PM1b_EVT_BLK",	 AcpiGbl_FADT.Pm1bEventBlock	},
321		{ 64,	"PM1a_CNT_BLK",	 AcpiGbl_FADT.Pm1aControlBlock	},
322		{ 68,	"PM1b_CNT_BLK",	 AcpiGbl_FADT.Pm1bControlBlock	},
323		{ 72,	"PM2_CNT_BLK",	 AcpiGbl_FADT.Pm2ControlBlock	},
324		{ 76,	"PM_TMR_BLK",	 AcpiGbl_FADT.PmTimerBlock	},
325		{ 80,	"GPE0_BLK",	 AcpiGbl_FADT.Gpe0Block		},
326		{ 84,	"GPE1_BLK",	 AcpiGbl_FADT.Gpe1Block		},
327		{ 88,	"PM1_EVT_LEN",	 AcpiGbl_FADT.Pm1EventLength	},
328		{ 89,	"PM1_CNT_LEN",	 AcpiGbl_FADT.Pm1ControlLength	},
329		{ 90,	"PM2_CNT_LEN",	 AcpiGbl_FADT.Pm2ControlLength	},
330		{ 91,	"PM_TMR_LEN",	 AcpiGbl_FADT.PmTimerLength	},
331		{ 92,	"GPE0_BLK_LEN",	 AcpiGbl_FADT.Gpe0BlockLength	},
332		{ 93,	"GPE1_BLK_LEN",	 AcpiGbl_FADT.Gpe1BlockLength	},
333		{ 94,	"GPE1_BASE",	 AcpiGbl_FADT.Gpe1Base		},
334		{ 95,	"CST_CNT",	 AcpiGbl_FADT.CstControl	},
335		{ 96,	"P_LVL2_LAT",	 AcpiGbl_FADT.C2Latency		},
336		{ 98,	"P_LVL3_LAT",	 AcpiGbl_FADT.C3Latency		},
337		{ 100,	"FLUSH_SIZE",	 AcpiGbl_FADT.FlushSize		},
338		{ 102,	"FLUSH_STRIDE",	 AcpiGbl_FADT.FlushStride	},
339		{ 104,	"DUTY_OFFSET",	 AcpiGbl_FADT.DutyOffset	},
340		{ 105,	"DUTY_WIDTH",	 AcpiGbl_FADT.DutyWidth		},
341		{ 106,	"DAY_ALRM",	 AcpiGbl_FADT.DayAlarm		},
342		{ 107,	"MON_ALRM",	 AcpiGbl_FADT.MonthAlarm	},
343		{ 108,	"CENTURY",	 AcpiGbl_FADT.Century		},
344		{ 109,	"IAPC_BOOT_ARCH",AcpiGbl_FADT.BootFlags		},
345		{ 128,	"RESET_VALUE",	 AcpiGbl_FADT.ResetValue	},
346	};
347
348	const struct acpi_fadt acpi_fadt_flags[] = {
349
350		{ 0,	"WBINVD",	ACPI_FADT_WBINVD		},
351		{ 1,	"WBINVD_FLUSH",	ACPI_FADT_WBINVD_FLUSH		},
352		{ 2,	"PROC_C1",	ACPI_FADT_C1_SUPPORTED		},
353		{ 3,	"P_LVL2_UP",	ACPI_FADT_C2_MP_SUPPORTED	},
354		{ 4,	"PWR_BUTTON",	ACPI_FADT_POWER_BUTTON		},
355		{ 5,	"SLP_BUTTON",	ACPI_FADT_SLEEP_BUTTON		},
356		{ 6,	"FIX_RTC",	ACPI_FADT_FIXED_RTC		},
357		{ 7,	"RTC_S4",	ACPI_FADT_S4_RTC_WAKE		},
358		{ 8,	"TMR_VAL_EXT",	ACPI_FADT_32BIT_TIMER		},
359		{ 9,	"DCK_CAP",	ACPI_FADT_DOCKING_SUPPORTED	},
360		{ 10,	"RESET_REG_SUP",ACPI_FADT_RESET_REGISTER	},
361		{ 11,	"SEALED_CASE",	ACPI_FADT_SEALED_CASE		},
362		{ 12,	"HEADLESS",	ACPI_FADT_HEADLESS		},
363		{ 13,	"CPU_SW_SLP",	ACPI_FADT_SLEEP_TYPE		},
364		{ 14,	"PCI_EXP_WAK",	ACPI_FADT_PCI_EXPRESS_WAKE	},
365		{ 15,	"PLATFORM_CLK", ACPI_FADT_PLATFORM_CLOCK	},
366		{ 16,	"S4_RTC_STS",	ACPI_FADT_S4_RTC_VALID		},
367		{ 17,	"REMOTE_POWER", ACPI_FADT_REMOTE_POWER_ON	},
368		{ 18,	"APIC_CLUSTER",	ACPI_FADT_APIC_CLUSTER		},
369		{ 19,	"APIC_PHYSICAL",ACPI_FADT_APIC_PHYSICAL		},
370	};
371
372	for (i = 0; i < __arraycount(acpi_fadt_table); i++) {
373
374		aprint_normal_dev(sc->sc_dev,
375		    "[FADT] %-15s: 0x%016" PRIX64"\n",
376		    acpi_fadt_table[i].fadt_name,
377		    acpi_fadt_table[i].fadt_value);
378	}
379
380	for (i = 0; i < __arraycount(acpi_fadt_flags); i++) {
381
382		aprint_normal_dev(sc->sc_dev,
383		    "[FADT] %-15s: 0x%016" PRIX64"\n",
384		    acpi_fadt_flags[i].fadt_name, AcpiGbl_FADT.Flags &
385		    acpi_fadt_flags[i].fadt_value);
386
387		KASSERT(i ==  acpi_fadt_flags[i].fadt_offset);
388		KASSERT(__BIT(acpi_fadt_flags[i].fadt_offset) ==
389		              acpi_fadt_flags[i].fadt_value);
390	}
391}
392
393static void
394acpi_print_devnodes(struct acpi_softc *sc)
395{
396	struct acpi_devnode *ad;
397	ACPI_DEVICE_INFO *di;
398
399	SIMPLEQ_FOREACH(ad, &sc->ad_head, ad_list) {
400
401		di = ad->ad_devinfo;
402		aprint_normal_dev(sc->sc_dev, "%-5s ", ad->ad_name);
403
404		aprint_normal("HID %-10s ",
405		    ((di->Valid & ACPI_VALID_HID) != 0) ?
406		    di->HardwareId.String: "-");
407
408		aprint_normal("UID %-4s ",
409		    ((di->Valid & ACPI_VALID_UID) != 0) ?
410		    di->UniqueId.String : "-");
411
412		if ((di->Valid & ACPI_VALID_STA) != 0)
413			aprint_normal("STA 0x%08X ", di->CurrentStatus);
414		else
415			aprint_normal("STA %10s ", "-");
416
417		if ((di->Valid & ACPI_VALID_ADR) != 0)
418			aprint_normal("ADR 0x%016" PRIX64"", di->Address);
419		else
420			aprint_normal("ADR -");
421
422		aprint_normal("\n");
423	}
424	aprint_normal("\n");
425}
426
427static void
428acpi_print_tree(struct acpi_devnode *ad, uint32_t level)
429{
430	struct acpi_devnode *child;
431	uint32_t i;
432
433	for (i = 0; i < level; i++)
434		aprint_normal("    ");
435
436	aprint_normal("%-5s [%02u] [%c%c] ", ad->ad_name, ad->ad_type,
437	    ((ad->ad_flags & ACPI_DEVICE_POWER)  != 0) ? 'P' : ' ',
438	    ((ad->ad_flags & ACPI_DEVICE_WAKEUP) != 0) ? 'W' : ' ');
439
440	if (ad->ad_pciinfo != NULL) {
441
442		aprint_normal("(PCI) @ 0x%02X:0x%02X:0x%02X:0x%02X ",
443		    ad->ad_pciinfo->ap_segment, ad->ad_pciinfo->ap_bus,
444		    ad->ad_pciinfo->ap_device, ad->ad_pciinfo->ap_function);
445
446		if ((ad->ad_devinfo->Flags & ACPI_PCI_ROOT_BRIDGE) != 0)
447			aprint_normal("[R] ");
448
449		if (ad->ad_pciinfo->ap_bridge != false)
450			aprint_normal("[B] -> 0x%02X",
451			    ad->ad_pciinfo->ap_downbus);
452	}
453
454	aprint_normal("\n");
455
456	SIMPLEQ_FOREACH(child, &ad->ad_child_head, ad_child_list)
457	    acpi_print_tree(child, level + 1);
458}
459