1 /****************************************************************************** 2 * 3 * Module Name: exdebug - Support for stores to the AML Debug Object 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2015, Intel Corp. 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions, and the following disclaimer, 16 * without modification. 17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18 * substantially similar to the "NO WARRANTY" disclaimer below 19 * ("Disclaimer") and any redistribution must be conditioned upon 20 * including a substantially similar Disclaimer requirement for further 21 * binary redistribution. 22 * 3. Neither the names of the above-listed copyright holders nor the names 23 * of any contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * Alternatively, this software may be distributed under the terms of the 27 * GNU General Public License ("GPL") version 2 as published by the Free 28 * Software Foundation. 29 * 30 * NO WARRANTY 31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 * POSSIBILITY OF SUCH DAMAGES. 42 */ 43 44 #include <acpi/acpi.h> 45 #include "accommon.h" 46 #include "acnamesp.h" 47 #include "acinterp.h" 48 #include "acparser.h" 49 50 #define _COMPONENT ACPI_EXECUTER 51 ACPI_MODULE_NAME("exdebug") 52 53 static union acpi_operand_object *acpi_gbl_trace_method_object = NULL; 54 55 /* Local prototypes */ 56 57 #ifdef ACPI_DEBUG_OUTPUT 58 static const char *acpi_ex_get_trace_event_name(acpi_trace_event_type type); 59 #endif 60 61 #ifndef ACPI_NO_ERROR_MESSAGES 62 /******************************************************************************* 63 * 64 * FUNCTION: acpi_ex_do_debug_object 65 * 66 * PARAMETERS: source_desc - Object to be output to "Debug Object" 67 * level - Indentation level (used for packages) 68 * index - Current package element, zero if not pkg 69 * 70 * RETURN: None 71 * 72 * DESCRIPTION: Handles stores to the AML Debug Object. For example: 73 * Store(INT1, Debug) 74 * 75 * This function is not compiled if ACPI_NO_ERROR_MESSAGES is set. 76 * 77 * This function is only enabled if acpi_gbl_enable_aml_debug_object is set, or 78 * if ACPI_LV_DEBUG_OBJECT is set in the acpi_dbg_level. Thus, in the normal 79 * operational case, stores to the debug object are ignored but can be easily 80 * enabled if necessary. 81 * 82 ******************************************************************************/ 83 84 void 85 acpi_ex_do_debug_object(union acpi_operand_object *source_desc, 86 u32 level, u32 index) 87 { 88 u32 i; 89 u32 timer; 90 union acpi_operand_object *object_desc; 91 u32 value; 92 93 ACPI_FUNCTION_TRACE_PTR(ex_do_debug_object, source_desc); 94 95 /* Output must be enabled via the debug_object global or the dbg_level */ 96 97 if (!acpi_gbl_enable_aml_debug_object && 98 !(acpi_dbg_level & ACPI_LV_DEBUG_OBJECT)) { 99 return_VOID; 100 } 101 102 /* 103 * We will emit the current timer value (in microseconds) with each 104 * debug output. Only need the lower 26 bits. This allows for 67 105 * million microseconds or 67 seconds before rollover. 106 */ 107 timer = ((u32)acpi_os_get_timer() / 10); /* (100 nanoseconds to microseconds) */ 108 timer &= 0x03FFFFFF; 109 110 /* 111 * Print line header as long as we are not in the middle of an 112 * object display 113 */ 114 if (!((level > 0) && index == 0)) { 115 acpi_os_printf("[ACPI Debug %.8u] %*s", timer, level, " "); 116 } 117 118 /* Display the index for package output only */ 119 120 if (index > 0) { 121 acpi_os_printf("(%.2u) ", index - 1); 122 } 123 124 if (!source_desc) { 125 acpi_os_printf("[Null Object]\n"); 126 return_VOID; 127 } 128 129 if (ACPI_GET_DESCRIPTOR_TYPE(source_desc) == ACPI_DESC_TYPE_OPERAND) { 130 acpi_os_printf("%s ", 131 acpi_ut_get_object_type_name(source_desc)); 132 133 if (!acpi_ut_valid_internal_object(source_desc)) { 134 acpi_os_printf("%p, Invalid Internal Object!\n", 135 source_desc); 136 return_VOID; 137 } 138 } else if (ACPI_GET_DESCRIPTOR_TYPE(source_desc) == 139 ACPI_DESC_TYPE_NAMED) { 140 acpi_os_printf("%s: %p\n", 141 acpi_ut_get_type_name(((struct 142 acpi_namespace_node *) 143 source_desc)->type), 144 source_desc); 145 return_VOID; 146 } else { 147 return_VOID; 148 } 149 150 /* source_desc is of type ACPI_DESC_TYPE_OPERAND */ 151 152 switch (source_desc->common.type) { 153 case ACPI_TYPE_INTEGER: 154 155 /* Output correct integer width */ 156 157 if (acpi_gbl_integer_byte_width == 4) { 158 acpi_os_printf("0x%8.8X\n", 159 (u32)source_desc->integer.value); 160 } else { 161 acpi_os_printf("0x%8.8X%8.8X\n", 162 ACPI_FORMAT_UINT64(source_desc->integer. 163 value)); 164 } 165 break; 166 167 case ACPI_TYPE_BUFFER: 168 169 acpi_os_printf("[0x%.2X]\n", (u32)source_desc->buffer.length); 170 acpi_ut_dump_buffer(source_desc->buffer.pointer, 171 (source_desc->buffer.length < 256) ? 172 source_desc->buffer.length : 256, 173 DB_BYTE_DISPLAY, 0); 174 break; 175 176 case ACPI_TYPE_STRING: 177 178 acpi_os_printf("[0x%.2X] \"%s\"\n", 179 source_desc->string.length, 180 source_desc->string.pointer); 181 break; 182 183 case ACPI_TYPE_PACKAGE: 184 185 acpi_os_printf("[Contains 0x%.2X Elements]\n", 186 source_desc->package.count); 187 188 /* Output the entire contents of the package */ 189 190 for (i = 0; i < source_desc->package.count; i++) { 191 acpi_ex_do_debug_object(source_desc->package. 192 elements[i], level + 4, i + 1); 193 } 194 break; 195 196 case ACPI_TYPE_LOCAL_REFERENCE: 197 198 acpi_os_printf("[%s] ", 199 acpi_ut_get_reference_name(source_desc)); 200 201 /* Decode the reference */ 202 203 switch (source_desc->reference.class) { 204 case ACPI_REFCLASS_INDEX: 205 206 acpi_os_printf("0x%X\n", source_desc->reference.value); 207 break; 208 209 case ACPI_REFCLASS_TABLE: 210 211 /* Case for ddb_handle */ 212 213 acpi_os_printf("Table Index 0x%X\n", 214 source_desc->reference.value); 215 return_VOID; 216 217 default: 218 219 break; 220 } 221 222 acpi_os_printf(" "); 223 224 /* Check for valid node first, then valid object */ 225 226 if (source_desc->reference.node) { 227 if (ACPI_GET_DESCRIPTOR_TYPE 228 (source_desc->reference.node) != 229 ACPI_DESC_TYPE_NAMED) { 230 acpi_os_printf 231 (" %p - Not a valid namespace node\n", 232 source_desc->reference.node); 233 } else { 234 acpi_os_printf("Node %p [%4.4s] ", 235 source_desc->reference.node, 236 (source_desc->reference.node)-> 237 name.ascii); 238 239 switch ((source_desc->reference.node)->type) { 240 241 /* These types have no attached object */ 242 243 case ACPI_TYPE_DEVICE: 244 acpi_os_printf("Device\n"); 245 break; 246 247 case ACPI_TYPE_THERMAL: 248 acpi_os_printf("Thermal Zone\n"); 249 break; 250 251 default: 252 253 acpi_ex_do_debug_object((source_desc-> 254 reference. 255 node)->object, 256 level + 4, 0); 257 break; 258 } 259 } 260 } else if (source_desc->reference.object) { 261 if (ACPI_GET_DESCRIPTOR_TYPE 262 (source_desc->reference.object) == 263 ACPI_DESC_TYPE_NAMED) { 264 acpi_ex_do_debug_object(((struct 265 acpi_namespace_node *) 266 source_desc->reference. 267 object)->object, 268 level + 4, 0); 269 } else { 270 object_desc = source_desc->reference.object; 271 value = source_desc->reference.value; 272 273 switch (object_desc->common.type) { 274 case ACPI_TYPE_BUFFER: 275 276 acpi_os_printf("Buffer[%u] = 0x%2.2X\n", 277 value, 278 *source_desc->reference. 279 index_pointer); 280 break; 281 282 case ACPI_TYPE_STRING: 283 284 acpi_os_printf 285 ("String[%u] = \"%c\" (0x%2.2X)\n", 286 value, 287 *source_desc->reference. 288 index_pointer, 289 *source_desc->reference. 290 index_pointer); 291 break; 292 293 case ACPI_TYPE_PACKAGE: 294 295 acpi_os_printf("Package[%u] = ", value); 296 acpi_ex_do_debug_object(*source_desc-> 297 reference.where, 298 level + 4, 0); 299 break; 300 301 default: 302 303 acpi_os_printf 304 ("Unknown Reference object type %X\n", 305 object_desc->common.type); 306 break; 307 } 308 } 309 } 310 break; 311 312 default: 313 314 acpi_os_printf("%p\n", source_desc); 315 break; 316 } 317 318 ACPI_DEBUG_PRINT_RAW((ACPI_DB_EXEC, "\n")); 319 return_VOID; 320 } 321 #endif 322 323 /******************************************************************************* 324 * 325 * FUNCTION: acpi_ex_interpreter_trace_enabled 326 * 327 * PARAMETERS: name - Whether method name should be matched, 328 * this should be checked before starting 329 * the tracer 330 * 331 * RETURN: TRUE if interpreter trace is enabled. 332 * 333 * DESCRIPTION: Check whether interpreter trace is enabled 334 * 335 ******************************************************************************/ 336 337 static u8 acpi_ex_interpreter_trace_enabled(char *name) 338 { 339 340 /* Check if tracing is enabled */ 341 342 if (!(acpi_gbl_trace_flags & ACPI_TRACE_ENABLED)) { 343 return (FALSE); 344 } 345 346 /* 347 * Check if tracing is filtered: 348 * 349 * 1. If the tracer is started, acpi_gbl_trace_method_object should have 350 * been filled by the trace starter 351 * 2. If the tracer is not started, acpi_gbl_trace_method_name should be 352 * matched if it is specified 353 * 3. If the tracer is oneshot style, acpi_gbl_trace_method_name should 354 * not be cleared by the trace stopper during the first match 355 */ 356 if (acpi_gbl_trace_method_object) { 357 return (TRUE); 358 } 359 if (name && 360 (acpi_gbl_trace_method_name && 361 strcmp(acpi_gbl_trace_method_name, name))) { 362 return (FALSE); 363 } 364 if ((acpi_gbl_trace_flags & ACPI_TRACE_ONESHOT) && 365 !acpi_gbl_trace_method_name) { 366 return (FALSE); 367 } 368 369 return (TRUE); 370 } 371 372 /******************************************************************************* 373 * 374 * FUNCTION: acpi_ex_get_trace_event_name 375 * 376 * PARAMETERS: type - Trace event type 377 * 378 * RETURN: Trace event name. 379 * 380 * DESCRIPTION: Used to obtain the full trace event name. 381 * 382 ******************************************************************************/ 383 384 #ifdef ACPI_DEBUG_OUTPUT 385 386 static const char *acpi_ex_get_trace_event_name(acpi_trace_event_type type) 387 { 388 switch (type) { 389 case ACPI_TRACE_AML_METHOD: 390 391 return "Method"; 392 393 case ACPI_TRACE_AML_OPCODE: 394 395 return "Opcode"; 396 397 case ACPI_TRACE_AML_REGION: 398 399 return "Region"; 400 401 default: 402 403 return ""; 404 } 405 } 406 407 #endif 408 409 /******************************************************************************* 410 * 411 * FUNCTION: acpi_ex_trace_point 412 * 413 * PARAMETERS: type - Trace event type 414 * begin - TRUE if before execution 415 * aml - Executed AML address 416 * pathname - Object path 417 * 418 * RETURN: None 419 * 420 * DESCRIPTION: Internal interpreter execution trace. 421 * 422 ******************************************************************************/ 423 424 void 425 acpi_ex_trace_point(acpi_trace_event_type type, 426 u8 begin, u8 *aml, char *pathname) 427 { 428 429 ACPI_FUNCTION_NAME(ex_trace_point); 430 431 if (pathname) { 432 ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, 433 "%s %s [0x%p:%s] execution.\n", 434 acpi_ex_get_trace_event_name(type), 435 begin ? "Begin" : "End", aml, pathname)); 436 } else { 437 ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT, 438 "%s %s [0x%p] execution.\n", 439 acpi_ex_get_trace_event_name(type), 440 begin ? "Begin" : "End", aml)); 441 } 442 } 443 444 /******************************************************************************* 445 * 446 * FUNCTION: acpi_ex_start_trace_method 447 * 448 * PARAMETERS: method_node - Node of the method 449 * obj_desc - The method object 450 * walk_state - current state, NULL if not yet executing 451 * a method. 452 * 453 * RETURN: None 454 * 455 * DESCRIPTION: Start control method execution trace 456 * 457 ******************************************************************************/ 458 459 void 460 acpi_ex_start_trace_method(struct acpi_namespace_node *method_node, 461 union acpi_operand_object *obj_desc, 462 struct acpi_walk_state *walk_state) 463 { 464 acpi_status status; 465 char *pathname = NULL; 466 u8 enabled = FALSE; 467 468 ACPI_FUNCTION_NAME(ex_start_trace_method); 469 470 if (method_node) { 471 pathname = acpi_ns_get_normalized_pathname(method_node, TRUE); 472 } 473 474 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 475 if (ACPI_FAILURE(status)) { 476 goto exit; 477 } 478 479 enabled = acpi_ex_interpreter_trace_enabled(pathname); 480 if (enabled && !acpi_gbl_trace_method_object) { 481 acpi_gbl_trace_method_object = obj_desc; 482 acpi_gbl_original_dbg_level = acpi_dbg_level; 483 acpi_gbl_original_dbg_layer = acpi_dbg_layer; 484 acpi_dbg_level = ACPI_TRACE_LEVEL_ALL; 485 acpi_dbg_layer = ACPI_TRACE_LAYER_ALL; 486 487 if (acpi_gbl_trace_dbg_level) { 488 acpi_dbg_level = acpi_gbl_trace_dbg_level; 489 } 490 if (acpi_gbl_trace_dbg_layer) { 491 acpi_dbg_layer = acpi_gbl_trace_dbg_layer; 492 } 493 } 494 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 495 496 exit: 497 if (enabled) { 498 ACPI_TRACE_POINT(ACPI_TRACE_AML_METHOD, TRUE, 499 obj_desc ? obj_desc->method.aml_start : NULL, 500 pathname); 501 } 502 if (pathname) { 503 ACPI_FREE(pathname); 504 } 505 } 506 507 /******************************************************************************* 508 * 509 * FUNCTION: acpi_ex_stop_trace_method 510 * 511 * PARAMETERS: method_node - Node of the method 512 * obj_desc - The method object 513 * walk_state - current state, NULL if not yet executing 514 * a method. 515 * 516 * RETURN: None 517 * 518 * DESCRIPTION: Stop control method execution trace 519 * 520 ******************************************************************************/ 521 522 void 523 acpi_ex_stop_trace_method(struct acpi_namespace_node *method_node, 524 union acpi_operand_object *obj_desc, 525 struct acpi_walk_state *walk_state) 526 { 527 acpi_status status; 528 char *pathname = NULL; 529 u8 enabled; 530 531 ACPI_FUNCTION_NAME(ex_stop_trace_method); 532 533 if (method_node) { 534 pathname = acpi_ns_get_normalized_pathname(method_node, TRUE); 535 } 536 537 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 538 if (ACPI_FAILURE(status)) { 539 goto exit_path; 540 } 541 542 enabled = acpi_ex_interpreter_trace_enabled(NULL); 543 544 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 545 546 if (enabled) { 547 ACPI_TRACE_POINT(ACPI_TRACE_AML_METHOD, FALSE, 548 obj_desc ? obj_desc->method.aml_start : NULL, 549 pathname); 550 } 551 552 status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); 553 if (ACPI_FAILURE(status)) { 554 goto exit_path; 555 } 556 557 /* Check whether the tracer should be stopped */ 558 559 if (acpi_gbl_trace_method_object == obj_desc) { 560 561 /* Disable further tracing if type is one-shot */ 562 563 if (acpi_gbl_trace_flags & ACPI_TRACE_ONESHOT) { 564 acpi_gbl_trace_method_name = NULL; 565 } 566 567 acpi_dbg_level = acpi_gbl_original_dbg_level; 568 acpi_dbg_layer = acpi_gbl_original_dbg_layer; 569 acpi_gbl_trace_method_object = NULL; 570 } 571 572 (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); 573 574 exit_path: 575 if (pathname) { 576 ACPI_FREE(pathname); 577 } 578 } 579 580 /******************************************************************************* 581 * 582 * FUNCTION: acpi_ex_start_trace_opcode 583 * 584 * PARAMETERS: op - The parser opcode object 585 * walk_state - current state, NULL if not yet executing 586 * a method. 587 * 588 * RETURN: None 589 * 590 * DESCRIPTION: Start opcode execution trace 591 * 592 ******************************************************************************/ 593 594 void 595 acpi_ex_start_trace_opcode(union acpi_parse_object *op, 596 struct acpi_walk_state *walk_state) 597 { 598 599 ACPI_FUNCTION_NAME(ex_start_trace_opcode); 600 601 if (acpi_ex_interpreter_trace_enabled(NULL) && 602 (acpi_gbl_trace_flags & ACPI_TRACE_OPCODE)) { 603 ACPI_TRACE_POINT(ACPI_TRACE_AML_OPCODE, TRUE, 604 op->common.aml, op->common.aml_op_name); 605 } 606 } 607 608 /******************************************************************************* 609 * 610 * FUNCTION: acpi_ex_stop_trace_opcode 611 * 612 * PARAMETERS: op - The parser opcode object 613 * walk_state - current state, NULL if not yet executing 614 * a method. 615 * 616 * RETURN: None 617 * 618 * DESCRIPTION: Stop opcode execution trace 619 * 620 ******************************************************************************/ 621 622 void 623 acpi_ex_stop_trace_opcode(union acpi_parse_object *op, 624 struct acpi_walk_state *walk_state) 625 { 626 627 ACPI_FUNCTION_NAME(ex_stop_trace_opcode); 628 629 if (acpi_ex_interpreter_trace_enabled(NULL) && 630 (acpi_gbl_trace_flags & ACPI_TRACE_OPCODE)) { 631 ACPI_TRACE_POINT(ACPI_TRACE_AML_OPCODE, FALSE, 632 op->common.aml, op->common.aml_op_name); 633 } 634 } 635