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