Home | History | Annotate | Line # | Download | only in acpi
acpi_debug.c revision 1.1.6.3
      1 /* $NetBSD: acpi_debug.c,v 1.1.6.3 2011/03/05 20:53:02 rmind Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 2010 Jukka Ruohonen <jruohonen (at) iki.fi>
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  *
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  *
     17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
     18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     27  * SUCH DAMAGE.
     28  */
     29 #include <sys/cdefs.h>
     30 __KERNEL_RCSID(0, "$NetBSD: acpi_debug.c,v 1.1.6.3 2011/03/05 20:53:02 rmind Exp $");
     31 
     32 #include <sys/param.h>
     33 #include <sys/sysctl.h>
     34 
     35 #include <dev/acpi/acpireg.h>
     36 #include <dev/acpi/acpivar.h>
     37 
     38 #include <prop/proplib.h>
     39 
     40 #ifdef ACPI_DEBUG
     41 
     42 #define _COMPONENT          ACPI_UTILITIES
     43 ACPI_MODULE_NAME            ("acpi_debug")
     44 
     45 #define ACPI_DEBUG_MAX  64
     46 #define ACPI_DEBUG_NONE  0
     47 
     48 #define ACPI_DEBUG_ADD(d, x)						      \
     49 	do {								      \
     50 		(void)prop_dictionary_set_uint32(d, #x, x);		      \
     51 									      \
     52 	} while (/* CONSTCOND */ 0)
     53 
     54 
     55 static prop_dictionary_t acpi_debug_layer_d;
     56 static prop_dictionary_t acpi_debug_level_d;
     57 static char              acpi_debug_layer_s[ACPI_DEBUG_MAX];
     58 static char              acpi_debug_level_s[ACPI_DEBUG_MAX];
     59 
     60 static int               acpi_debug_create(void);
     61 static const char       *acpi_debug_getkey(prop_dictionary_t, uint32_t);
     62 static int               acpi_debug_sysctl_layer(SYSCTLFN_PROTO);
     63 static int               acpi_debug_sysctl_level(SYSCTLFN_PROTO);
     64 
     65 void
     66 acpi_debug_init(void)
     67 {
     68 	const struct sysctlnode *rnode;
     69 	const char *layer, *level;
     70 	int rv;
     71 
     72 	KASSERT(acpi_debug_layer_d == NULL);
     73 	KASSERT(acpi_debug_level_d == NULL);
     74 
     75 	rv = acpi_debug_create();
     76 
     77 	if (rv != 0)
     78 		goto fail;
     79 
     80 	rv = sysctl_createv(NULL, 0, NULL, &rnode,
     81 	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw",
     82 	    NULL, NULL, 0, NULL, 0,
     83 	    CTL_HW, CTL_EOL);
     84 
     85 	if (rv != 0)
     86 		goto fail;
     87 
     88 	rv = sysctl_createv(NULL, 0, &rnode, &rnode,
     89 	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "acpi",
     90 	    NULL, NULL, 0, NULL, 0,
     91 	    CTL_CREATE, CTL_EOL);
     92 
     93 	if (rv != 0)
     94 		goto fail;
     95 
     96 	rv = sysctl_createv(NULL, 0, &rnode, &rnode,
     97 	    0, CTLTYPE_NODE, "debug",
     98 	    SYSCTL_DESCR("ACPI debug subtree"),
     99 	    NULL, 0, NULL, 0,
    100 	    CTL_CREATE, CTL_EOL);
    101 
    102 	if (rv != 0)
    103 		goto fail;
    104 
    105 	rv = sysctl_createv(NULL, 0, &rnode, NULL,
    106 	    CTLFLAG_READWRITE, CTLTYPE_STRING, "layer",
    107 	    SYSCTL_DESCR("ACPI debug layer"),
    108 	    acpi_debug_sysctl_layer, 0, acpi_debug_layer_s, ACPI_DEBUG_MAX,
    109 	    CTL_CREATE, CTL_EOL);
    110 
    111 	if (rv != 0)
    112 		goto fail;
    113 
    114 	rv = sysctl_createv(NULL, 0, &rnode, NULL,
    115 	    CTLFLAG_READWRITE, CTLTYPE_STRING, "level",
    116 	    SYSCTL_DESCR("ACPI debug level"),
    117 	    acpi_debug_sysctl_level, 0, acpi_debug_level_s, ACPI_DEBUG_MAX,
    118 	    CTL_CREATE, CTL_EOL);
    119 
    120 	if (rv != 0)
    121 		goto fail;
    122 
    123 	rv = sysctl_createv(NULL, 0, &rnode, NULL,
    124 	    CTLFLAG_READWRITE, CTLTYPE_BOOL, "object",
    125 	    SYSCTL_DESCR("ACPI debug object"),
    126 	    NULL, 0, &AcpiGbl_EnableAmlDebugObject, 0,
    127 	    CTL_CREATE, CTL_EOL);
    128 
    129 	if (rv != 0)
    130 		goto fail;
    131 
    132 	layer = acpi_debug_getkey(acpi_debug_layer_d, AcpiDbgLayer);
    133 	level = acpi_debug_getkey(acpi_debug_level_d, AcpiDbgLevel);
    134 
    135 	(void)memcpy(acpi_debug_layer_s, layer, ACPI_DEBUG_MAX);
    136 	(void)memcpy(acpi_debug_level_s, level, ACPI_DEBUG_MAX);
    137 
    138 	return;
    139 
    140 fail:
    141 	aprint_error("acpi0: failed to initialize ACPI debug\n");
    142 }
    143 
    144 static int
    145 acpi_debug_create(void)
    146 {
    147 
    148 	acpi_debug_layer_d = prop_dictionary_create();
    149 	acpi_debug_level_d = prop_dictionary_create();
    150 
    151 	KASSERT(acpi_debug_layer_d != NULL);
    152 	KASSERT(acpi_debug_level_d != NULL);
    153 
    154 	/*
    155 	 * General components.
    156 	 */
    157 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_UTILITIES);
    158 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_HARDWARE);
    159 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_EVENTS);
    160 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_TABLES);
    161 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_NAMESPACE);
    162 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_PARSER);
    163 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_DISPATCHER);
    164 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_EXECUTER);
    165 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_RESOURCES);
    166 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_CA_DEBUGGER);
    167 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_OS_SERVICES);
    168 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_CA_DISASSEMBLER);
    169 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_COMPILER);
    170 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_TOOLS);
    171 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_EXAMPLE);
    172 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_DRIVER);
    173 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_ALL_COMPONENTS);
    174 
    175 	/*
    176 	 * NetBSD specific components.
    177 	 */
    178 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_BUS_COMPONENT);
    179 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_ACAD_COMPONENT);
    180 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_BAT_COMPONENT);
    181 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_BUTTON_COMPONENT);
    182 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_EC_COMPONENT);
    183 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_LID_COMPONENT);
    184 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_RESOURCE_COMPONENT);
    185 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_TZ_COMPONENT);
    186 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_DISPLAY_COMPONENT);
    187 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_ALL_DRIVERS);
    188 
    189 	/*
    190 	 * Debug levels.
    191 	 */
    192 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_INIT);
    193 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_DEBUG_OBJECT);
    194 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_INFO);
    195 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_ALL_EXCEPTIONS);
    196 
    197 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_INIT_NAMES);
    198 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_PARSE);
    199 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_LOAD);
    200 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_DISPATCH);
    201 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_EXEC);
    202 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_NAMES);
    203 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_OPREGION);
    204 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_BFIELD);
    205 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_TABLES);
    206 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_VALUES);
    207 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_OBJECTS);
    208 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_RESOURCES);
    209 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_USER_REQUESTS);
    210 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_PACKAGE);
    211 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_VERBOSITY1);
    212 
    213 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_ALLOCATIONS);
    214 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_FUNCTIONS);
    215 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_OPTIMIZATIONS);
    216 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_VERBOSITY2);
    217 
    218 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_MUTEX);
    219 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_THREADS);
    220 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_IO);
    221 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_INTERRUPTS);
    222 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_VERBOSITY3);
    223 
    224 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_AML_DISASSEMBLE);
    225 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_VERBOSE_INFO);
    226 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_FULL_TABLES);
    227 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_EVENTS);
    228 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_LV_VERBOSE);
    229 
    230 	/*
    231 	 * The default debug level.
    232 	 */
    233 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_DEBUG_DEFAULT);
    234 
    235 	/*
    236 	 * A custom ACPI_DEBUG_NONE disables debugging.
    237 	 */
    238 	ACPI_DEBUG_ADD(acpi_debug_layer_d, ACPI_DEBUG_NONE);
    239 	ACPI_DEBUG_ADD(acpi_debug_level_d, ACPI_DEBUG_NONE);
    240 
    241 	prop_dictionary_make_immutable(acpi_debug_layer_d);
    242 	prop_dictionary_make_immutable(acpi_debug_level_d);
    243 
    244 	return 0;
    245 }
    246 
    247 static const char *
    248 acpi_debug_getkey(prop_dictionary_t dict, uint32_t arg)
    249 {
    250 	prop_object_iterator_t i;
    251 	prop_object_t obj, val;
    252 	const char *key;
    253 	uint32_t num;
    254 
    255 	i = prop_dictionary_iterator(dict);
    256 
    257 	while ((obj = prop_object_iterator_next(i)) != NULL) {
    258 
    259 		key = prop_dictionary_keysym_cstring_nocopy(obj);
    260 		val = prop_dictionary_get(dict, key);
    261 		num = prop_number_unsigned_integer_value(val);
    262 
    263 		if (arg == num)
    264 			return key;
    265 	}
    266 
    267 	return "UNKNOWN";
    268 }
    269 
    270 static int
    271 acpi_debug_sysctl_layer(SYSCTLFN_ARGS)
    272 {
    273 	char buf[ACPI_DEBUG_MAX];
    274 	struct sysctlnode node;
    275 	prop_object_t obj;
    276 	int error;
    277 
    278 	node = *rnode;
    279 	node.sysctl_data = buf;
    280 
    281 	(void)memcpy(node.sysctl_data, rnode->sysctl_data, ACPI_DEBUG_MAX);
    282 
    283 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    284 
    285 	if (error || newp == NULL)
    286 		return error;
    287 
    288 	obj = prop_dictionary_get(acpi_debug_layer_d, node.sysctl_data);
    289 
    290 	if (obj == NULL)
    291 		return EINVAL;
    292 
    293 	AcpiDbgLayer = prop_number_unsigned_integer_value(obj);
    294 
    295 	(void)memcpy(rnode->sysctl_data, node.sysctl_data, ACPI_DEBUG_MAX);
    296 
    297 	return 0;
    298 }
    299 
    300 static int
    301 acpi_debug_sysctl_level(SYSCTLFN_ARGS)
    302 {
    303 	char buf[ACPI_DEBUG_MAX];
    304 	struct sysctlnode node;
    305 	prop_object_t obj;
    306 	int error;
    307 
    308 	node = *rnode;
    309 	node.sysctl_data = buf;
    310 
    311 	(void)memcpy(node.sysctl_data, rnode->sysctl_data, ACPI_DEBUG_MAX);
    312 
    313 	error = sysctl_lookup(SYSCTLFN_CALL(&node));
    314 
    315 	if (error || newp == NULL)
    316 		return error;
    317 
    318 	obj = prop_dictionary_get(acpi_debug_level_d, node.sysctl_data);
    319 
    320 	if (obj == NULL)
    321 		return EINVAL;
    322 
    323 	AcpiDbgLevel = prop_number_unsigned_integer_value(obj);
    324 
    325 	(void)memcpy(rnode->sysctl_data, node.sysctl_data, ACPI_DEBUG_MAX);
    326 
    327 	return 0;
    328 }
    329 
    330 #endif	/* ACPI_DEBUG */
    331