From 4cd0ccf8abed3d995d4f3b3daa5e2c6ca270954b Mon Sep 17 00:00:00 2001 From: jruoho Date: Sun, 31 Jan 2010 11:26:20 +0000 Subject: Add dynamic debug options for ACPI_DEBUG kernels. ok jmcneill@, pooka@, pgoyette@ --- sys/dev/acpi/acpi.c | 8 +- sys/dev/acpi/acpi_debug.c | 310 ++++++++++++++++++++++++++++++++++++++++++++++ sys/dev/acpi/acpivar.h | 6 +- sys/dev/acpi/files.acpi | 3 +- 4 files changed, 323 insertions(+), 4 deletions(-) create mode 100644 sys/dev/acpi/acpi_debug.c (limited to 'sys/dev') diff --git a/sys/dev/acpi/acpi.c b/sys/dev/acpi/acpi.c index 38e94b55ebe..27b9c7e3538 100644 --- a/sys/dev/acpi/acpi.c +++ b/sys/dev/acpi/acpi.c @@ -1,4 +1,4 @@ -/* $NetBSD: acpi.c,v 1.147 2010/01/18 18:49:27 jruoho Exp $ */ +/* $NetBSD: acpi.c,v 1.148 2010/01/31 11:26:20 jruoho Exp $ */ /*- * Copyright (c) 2003, 2007 The NetBSD Foundation, Inc. @@ -70,7 +70,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.147 2010/01/18 18:49:27 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi.c,v 1.148 2010/01/31 11:26:20 jruoho Exp $"); #include "opt_acpi.h" #include "opt_pcifixup.h" @@ -546,6 +546,10 @@ acpi_attach(device_t parent, device_t self, void *aux) if (acpi_dbgr & ACPI_DBGR_RUNNING) acpi_osd_debugger(); #endif + +#ifdef ACPI_DEBUG + acpi_debug_init(); +#endif } static int diff --git a/sys/dev/acpi/acpi_debug.c b/sys/dev/acpi/acpi_debug.c new file mode 100644 index 00000000000..9b430f4e0bc --- /dev/null +++ b/sys/dev/acpi/acpi_debug.c @@ -0,0 +1,310 @@ +/* $NetBSD: acpi_debug.c,v 1.1 2010/01/31 11:26:20 jruoho Exp $ */ + +/*- + * Copyright (c) 2010 Jukka Ruohonen + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include +__KERNEL_RCSID(0, "$NetBSD: acpi_debug.c,v 1.1 2010/01/31 11:26:20 jruoho Exp $"); + +#include +#include + +#include +#include + +#include + +#ifdef ACPI_DEBUG + +#define _COMPONENT ACPI_UTILITIES +ACPI_MODULE_NAME ("acpi_debug") + +#define ACPI_DEBUG_MAX 64 +#define ACPI_DEBUG_NONE 0 + +#define ACPI_DEBUG_ADD(d, x) \ + do { \ + (void)prop_dictionary_set_uint32(d, #x, x); \ + \ + } while (/* CONSTCOND */ 0) + + +static prop_dictionary_t acpi_debug_layer_d; +static prop_dictionary_t acpi_debug_level_d; +static char acpi_debug_layer_s[ACPI_DEBUG_MAX]; +static char acpi_debug_level_s[ACPI_DEBUG_MAX]; + +static int acpi_debug_create(void); +static const char *acpi_debug_getkey(prop_dictionary_t, uint32_t); +static int acpi_debug_sysctl_layer(SYSCTLFN_PROTO); +static int acpi_debug_sysctl_level(SYSCTLFN_PROTO); + +void +acpi_debug_init(void) +{ + const struct sysctlnode *node; + const char *layer; + const char *level; + int rv; + + KASSERT(acpi_debug_layer_d == NULL); + KASSERT(acpi_debug_level_d == NULL); + + rv = acpi_debug_create(); + + if (rv != 0) + goto fail; + + rv = sysctl_createv(NULL, 0, NULL, NULL, + CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", + NULL, NULL, 0, NULL, 0, CTL_HW, CTL_EOL); + + if (rv != 0) + goto fail; + + rv = sysctl_createv(NULL, 0, NULL, &node, + CTLFLAG_PERMANENT, CTLTYPE_NODE, "acpi", + NULL, NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL); + + if (rv != 0) + goto fail; + + rv = sysctl_createv(NULL, 0, NULL, NULL, + CTLFLAG_READWRITE, CTLTYPE_STRING, "debug_layer", + SYSCTL_DESCR("ACPI debug layer"), + acpi_debug_sysctl_layer, 0, acpi_debug_layer_s, ACPI_DEBUG_MAX, + CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL); + + if (rv != 0) + goto fail; + + rv = sysctl_createv(NULL, 0, NULL, NULL, + CTLFLAG_READWRITE, CTLTYPE_STRING, "debug_level", + SYSCTL_DESCR("ACPI debug level"), + acpi_debug_sysctl_level, 0, acpi_debug_level_s, ACPI_DEBUG_MAX, + CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL); + + if (rv != 0) + goto fail; + + layer = acpi_debug_getkey(acpi_debug_layer_d, AcpiDbgLayer); + level = acpi_debug_getkey(acpi_debug_level_d, AcpiDbgLevel); + + (void)memcpy(acpi_debug_layer_s, layer, ACPI_DEBUG_MAX); + (void)memcpy(acpi_debug_level_s, level, ACPI_DEBUG_MAX); + + return; + +fail: + aprint_error("acpi0: failed to initialize ACPI debug\n"); +} + +static int +acpi_debug_create(void) +{ + + acpi_debug_layer_d = prop_dictionary_create(); + acpi_debug_level_d = prop_dictionary_create(); + + KASSERT(acpi_debug_layer_d != NULL); + KASSERT(acpi_debug_level_d != NULL); + + /* + * General components. + */ + ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_UTILITIES); + ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_HARDWARE); + ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_EVENTS); + ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_TABLES); + ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_NAMESPACE); + ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_PARSER); + ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_DISPATCHER); + ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_EXECUTER); + ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_RESOURCES); + ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_CA_DEBUGGER); + ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_OS_SERVICES); + ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_CA_DISASSEMBLER); + ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_COMPILER); + ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_TOOLS); + ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_EXAMPLE); + ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_DRIVER); + ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_ALL_COMPONENTS); + + /* + * NetBSD specific components. + */ + ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_BUS_COMPONENT); + ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_ACAD_COMPONENT); + ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_BAT_COMPONENT); + ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_BUTTON_COMPONENT); + ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_EC_COMPONENT); + ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_LID_COMPONENT); + ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_RESOURCE_COMPONENT); + ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_TZ_COMPONENT); + ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_ALL_DRIVERS); + + /* + * Debug levels. + */ + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_INIT); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_DEBUG_OBJECT); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_INFO); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_ALL_EXCEPTIONS); + + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_INIT_NAMES); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_PARSE); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_LOAD); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_DISPATCH); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_EXEC); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_NAMES); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_OPREGION); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_BFIELD); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_TABLES); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_VALUES); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_OBJECTS); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_RESOURCES); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_USER_REQUESTS); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_PACKAGE); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_VERBOSITY1); + + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_ALLOCATIONS); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_FUNCTIONS); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_OPTIMIZATIONS); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_VERBOSITY2); + + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_MUTEX); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_THREADS); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_IO); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_INTERRUPTS); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_VERBOSITY3); + + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_AML_DISASSEMBLE); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_VERBOSE_INFO); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_FULL_TABLES); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_EVENTS); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_VERBOSE); + + /* + * The default debug level. + */ + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_DEBUG_DEFAULT); + + /* + * A custom ACPI_DEBUG_NONE disables debugging. + */ + ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_DEBUG_NONE); + ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_DEBUG_NONE); + + prop_dictionary_make_immutable(acpi_debug_layer_d); + prop_dictionary_make_immutable(acpi_debug_level_d); + + return 0; +} + +static const char * +acpi_debug_getkey(prop_dictionary_t dict, uint32_t arg) +{ + prop_object_iterator_t i; + prop_object_t obj, val; + const char *key; + uint32_t num; + + i = prop_dictionary_iterator(dict); + + while ((obj = prop_object_iterator_next(i)) != NULL) { + + key = prop_dictionary_keysym_cstring_nocopy(obj); + val = prop_dictionary_get(dict, key); + num = prop_number_unsigned_integer_value(val); + + if (arg == num) + return key; + } + + return "UNKNOWN"; +} + +static int +acpi_debug_sysctl_layer(SYSCTLFN_ARGS) +{ + char buf[ACPI_DEBUG_MAX]; + struct sysctlnode node; + prop_object_t obj; + int error; + + node = *rnode; + node.sysctl_data = buf; + + (void)memcpy(node.sysctl_data, rnode->sysctl_data, ACPI_DEBUG_MAX); + + error = sysctl_lookup(SYSCTLFN_CALL(&node)); + + if (error || newp == NULL) + return error; + + obj = prop_dictionary_get(acpi_debug_layer_d, node.sysctl_data); + + if (obj == NULL) + return EINVAL; + + AcpiDbgLayer = prop_number_unsigned_integer_value(obj); + + (void)memcpy(rnode->sysctl_data, node.sysctl_data, ACPI_DEBUG_MAX); + + return 0; +} + +static int +acpi_debug_sysctl_level(SYSCTLFN_ARGS) +{ + char buf[ACPI_DEBUG_MAX]; + struct sysctlnode node; + prop_object_t obj; + int error; + + node = *rnode; + node.sysctl_data = buf; + + (void)memcpy(node.sysctl_data, rnode->sysctl_data, ACPI_DEBUG_MAX); + + error = sysctl_lookup(SYSCTLFN_CALL(&node)); + + if (error || newp == NULL) + return error; + + obj = prop_dictionary_get(acpi_debug_level_d, node.sysctl_data); + + if (obj == NULL) + return EINVAL; + + AcpiDbgLevel = prop_number_unsigned_integer_value(obj); + + (void)memcpy(rnode->sysctl_data, node.sysctl_data, ACPI_DEBUG_MAX); + + return 0; +} + +#endif /* ACPI_DEBUG */ diff --git a/sys/dev/acpi/acpivar.h b/sys/dev/acpi/acpivar.h index 4d124c32fe2..82c4fbe03f5 100644 --- a/sys/dev/acpi/acpivar.h +++ b/sys/dev/acpi/acpivar.h @@ -1,4 +1,4 @@ -/* $NetBSD: acpivar.h,v 1.39 2010/01/18 18:06:31 jruoho Exp $ */ +/* $NetBSD: acpivar.h,v 1.40 2010/01/31 11:26:20 jruoho Exp $ */ /* * Copyright 2001 Wasabi Systems, Inc. @@ -331,3 +331,7 @@ struct acpi_quirk { #define ACPI_QUIRK_IRQ0 0x00000008 /* bad 0->2 irq override */ int acpi_find_quirks(void); + +#ifdef ACPI_DEBUG +void acpi_debug_init(void); +#endif diff --git a/sys/dev/acpi/files.acpi b/sys/dev/acpi/files.acpi index 0550b314c34..a381b4fcb77 100644 --- a/sys/dev/acpi/files.acpi +++ b/sys/dev/acpi/files.acpi @@ -1,4 +1,4 @@ -# $NetBSD: files.acpi,v 1.64 2010/01/03 17:53:15 jruoho Exp $ +# $NetBSD: files.acpi,v 1.65 2010/01/31 11:26:20 jruoho Exp $ include "dev/acpi/acpica/files.acpica" @@ -14,6 +14,7 @@ define acpiwmibus { } device acpi: acpica, acpiapmbus, acpinodebus, acpiecdtbus, sysmon_power, sysmon_taskq attach acpi at acpibus file dev/acpi/acpi.c acpi +file dev/acpi/acpi_debug.c acpi file dev/acpi/acpi_resource.c acpi file dev/acpi/acpi_powerres.c acpi file dev/acpi/acpi_madt.c acpi -- cgit