1 /******************************************************************************* 2 * 3 * Module Name: dbdisply - debug display commands 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2018, 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 "amlcode.h" 47 #include "acdispat.h" 48 #include "acnamesp.h" 49 #include "acparser.h" 50 #include "acinterp.h" 51 #include "acevents.h" 52 #include "acdebug.h" 53 54 #define _COMPONENT ACPI_CA_DEBUGGER 55 ACPI_MODULE_NAME("dbdisply") 56 57 /* Local prototypes */ 58 static void acpi_db_dump_parser_descriptor(union acpi_parse_object *op); 59 60 static void *acpi_db_get_pointer(void *target); 61 62 static acpi_status 63 acpi_db_display_non_root_handlers(acpi_handle obj_handle, 64 u32 nesting_level, 65 void *context, void **return_value); 66 67 /* 68 * System handler information. 69 * Used for Handlers command, in acpi_db_display_handlers. 70 */ 71 #define ACPI_PREDEFINED_PREFIX "%25s (%.2X) : " 72 #define ACPI_HANDLER_NAME_STRING "%30s : " 73 #define ACPI_HANDLER_PRESENT_STRING "%-9s (%p)\n" 74 #define ACPI_HANDLER_PRESENT_STRING2 "%-9s (%p)" 75 #define ACPI_HANDLER_NOT_PRESENT_STRING "%-9s\n" 76 77 /* All predefined Address Space IDs */ 78 79 static acpi_adr_space_type acpi_gbl_space_id_list[] = { 80 ACPI_ADR_SPACE_SYSTEM_MEMORY, 81 ACPI_ADR_SPACE_SYSTEM_IO, 82 ACPI_ADR_SPACE_PCI_CONFIG, 83 ACPI_ADR_SPACE_EC, 84 ACPI_ADR_SPACE_SMBUS, 85 ACPI_ADR_SPACE_CMOS, 86 ACPI_ADR_SPACE_PCI_BAR_TARGET, 87 ACPI_ADR_SPACE_IPMI, 88 ACPI_ADR_SPACE_GPIO, 89 ACPI_ADR_SPACE_GSBUS, 90 ACPI_ADR_SPACE_DATA_TABLE, 91 ACPI_ADR_SPACE_FIXED_HARDWARE 92 }; 93 94 /* Global handler information */ 95 96 typedef struct acpi_handler_info { 97 void *handler; 98 char *name; 99 100 } acpi_handler_info; 101 102 static struct acpi_handler_info acpi_gbl_handler_list[] = { 103 {&acpi_gbl_global_notify[0].handler, "System Notifications"}, 104 {&acpi_gbl_global_notify[1].handler, "Device Notifications"}, 105 {&acpi_gbl_table_handler, "ACPI Table Events"}, 106 {&acpi_gbl_exception_handler, "Control Method Exceptions"}, 107 {&acpi_gbl_interface_handler, "OSI Invocations"} 108 }; 109 110 /******************************************************************************* 111 * 112 * FUNCTION: acpi_db_get_pointer 113 * 114 * PARAMETERS: target - Pointer to string to be converted 115 * 116 * RETURN: Converted pointer 117 * 118 * DESCRIPTION: Convert an ascii pointer value to a real value 119 * 120 ******************************************************************************/ 121 122 static void *acpi_db_get_pointer(void *target) 123 { 124 void *obj_ptr; 125 acpi_size address; 126 127 address = strtoul(target, NULL, 16); 128 obj_ptr = ACPI_TO_POINTER(address); 129 return (obj_ptr); 130 } 131 132 /******************************************************************************* 133 * 134 * FUNCTION: acpi_db_dump_parser_descriptor 135 * 136 * PARAMETERS: op - A parser Op descriptor 137 * 138 * RETURN: None 139 * 140 * DESCRIPTION: Display a formatted parser object 141 * 142 ******************************************************************************/ 143 144 static void acpi_db_dump_parser_descriptor(union acpi_parse_object *op) 145 { 146 const struct acpi_opcode_info *info; 147 148 info = acpi_ps_get_opcode_info(op->common.aml_opcode); 149 150 acpi_os_printf("Parser Op Descriptor:\n"); 151 acpi_os_printf("%20.20s : %4.4X\n", "Opcode", op->common.aml_opcode); 152 153 ACPI_DEBUG_ONLY_MEMBERS(acpi_os_printf("%20.20s : %s\n", "Opcode Name", 154 info->name)); 155 156 acpi_os_printf("%20.20s : %p\n", "Value/ArgList", op->common.value.arg); 157 acpi_os_printf("%20.20s : %p\n", "Parent", op->common.parent); 158 acpi_os_printf("%20.20s : %p\n", "NextOp", op->common.next); 159 } 160 161 /******************************************************************************* 162 * 163 * FUNCTION: acpi_db_decode_and_display_object 164 * 165 * PARAMETERS: target - String with object to be displayed. Names 166 * and hex pointers are supported. 167 * output_type - Byte, Word, Dword, or Qword (B|W|D|Q) 168 * 169 * RETURN: None 170 * 171 * DESCRIPTION: Display a formatted ACPI object 172 * 173 ******************************************************************************/ 174 175 void acpi_db_decode_and_display_object(char *target, char *output_type) 176 { 177 void *obj_ptr; 178 struct acpi_namespace_node *node; 179 union acpi_operand_object *obj_desc; 180 u32 display = DB_BYTE_DISPLAY; 181 char buffer[80]; 182 struct acpi_buffer ret_buf; 183 acpi_status status; 184 u32 size; 185 186 if (!target) { 187 return; 188 } 189 190 /* Decode the output type */ 191 192 if (output_type) { 193 acpi_ut_strupr(output_type); 194 if (output_type[0] == 'W') { 195 display = DB_WORD_DISPLAY; 196 } else if (output_type[0] == 'D') { 197 display = DB_DWORD_DISPLAY; 198 } else if (output_type[0] == 'Q') { 199 display = DB_QWORD_DISPLAY; 200 } 201 } 202 203 ret_buf.length = sizeof(buffer); 204 ret_buf.pointer = buffer; 205 206 /* Differentiate between a number and a name */ 207 208 if ((target[0] >= 0x30) && (target[0] <= 0x39)) { 209 obj_ptr = acpi_db_get_pointer(target); 210 if (!acpi_os_readable(obj_ptr, 16)) { 211 acpi_os_printf 212 ("Address %p is invalid in this address space\n", 213 obj_ptr); 214 return; 215 } 216 217 /* Decode the object type */ 218 219 switch (ACPI_GET_DESCRIPTOR_TYPE(obj_ptr)) { 220 case ACPI_DESC_TYPE_NAMED: 221 222 /* This is a namespace Node */ 223 224 if (!acpi_os_readable 225 (obj_ptr, sizeof(struct acpi_namespace_node))) { 226 acpi_os_printf 227 ("Cannot read entire Named object at address %p\n", 228 obj_ptr); 229 return; 230 } 231 232 node = obj_ptr; 233 goto dump_node; 234 235 case ACPI_DESC_TYPE_OPERAND: 236 237 /* This is a ACPI OPERAND OBJECT */ 238 239 if (!acpi_os_readable 240 (obj_ptr, sizeof(union acpi_operand_object))) { 241 acpi_os_printf 242 ("Cannot read entire ACPI object at address %p\n", 243 obj_ptr); 244 return; 245 } 246 247 acpi_ut_debug_dump_buffer(obj_ptr, 248 sizeof(union 249 acpi_operand_object), 250 display, ACPI_UINT32_MAX); 251 acpi_ex_dump_object_descriptor(obj_ptr, 1); 252 break; 253 254 case ACPI_DESC_TYPE_PARSER: 255 256 /* This is a Parser Op object */ 257 258 if (!acpi_os_readable 259 (obj_ptr, sizeof(union acpi_parse_object))) { 260 acpi_os_printf 261 ("Cannot read entire Parser object at address %p\n", 262 obj_ptr); 263 return; 264 } 265 266 acpi_ut_debug_dump_buffer(obj_ptr, 267 sizeof(union 268 acpi_parse_object), 269 display, ACPI_UINT32_MAX); 270 acpi_db_dump_parser_descriptor((union acpi_parse_object 271 *)obj_ptr); 272 break; 273 274 default: 275 276 /* Is not a recognizeable object */ 277 278 acpi_os_printf 279 ("Not a known ACPI internal object, descriptor type %2.2X\n", 280 ACPI_GET_DESCRIPTOR_TYPE(obj_ptr)); 281 282 size = 16; 283 if (acpi_os_readable(obj_ptr, 64)) { 284 size = 64; 285 } 286 287 /* Just dump some memory */ 288 289 acpi_ut_debug_dump_buffer(obj_ptr, size, display, 290 ACPI_UINT32_MAX); 291 break; 292 } 293 294 return; 295 } 296 297 /* The parameter is a name string that must be resolved to a Named obj */ 298 299 node = acpi_db_local_ns_lookup(target); 300 if (!node) { 301 return; 302 } 303 304 dump_node: 305 /* Now dump the NS node */ 306 307 status = acpi_get_name(node, ACPI_FULL_PATHNAME_NO_TRAILING, &ret_buf); 308 if (ACPI_FAILURE(status)) { 309 acpi_os_printf("Could not convert name to pathname\n"); 310 } 311 312 else { 313 acpi_os_printf("Object %p: Namespace Node - Pathname: %s\n", 314 node, (char *)ret_buf.pointer); 315 } 316 317 if (!acpi_os_readable(node, sizeof(struct acpi_namespace_node))) { 318 acpi_os_printf("Invalid Named object at address %p\n", node); 319 return; 320 } 321 322 acpi_ut_debug_dump_buffer((void *)node, 323 sizeof(struct acpi_namespace_node), display, 324 ACPI_UINT32_MAX); 325 acpi_ex_dump_namespace_node(node, 1); 326 327 obj_desc = acpi_ns_get_attached_object(node); 328 if (obj_desc) { 329 acpi_os_printf("\nAttached Object %p:", obj_desc); 330 if (!acpi_os_readable 331 (obj_desc, sizeof(union acpi_operand_object))) { 332 acpi_os_printf 333 ("Invalid internal ACPI Object at address %p\n", 334 obj_desc); 335 return; 336 } 337 338 if (ACPI_GET_DESCRIPTOR_TYPE(((struct acpi_namespace_node *) 339 obj_desc)) == 340 ACPI_DESC_TYPE_NAMED) { 341 acpi_os_printf(" Namespace Node - "); 342 status = 343 acpi_get_name((struct acpi_namespace_node *) 344 obj_desc, 345 ACPI_FULL_PATHNAME_NO_TRAILING, 346 &ret_buf); 347 if (ACPI_FAILURE(status)) { 348 acpi_os_printf 349 ("Could not convert name to pathname\n"); 350 } else { 351 acpi_os_printf("Pathname: %s", 352 (char *)ret_buf.pointer); 353 } 354 355 acpi_os_printf("\n"); 356 acpi_ut_debug_dump_buffer((void *)obj_desc, 357 sizeof(struct 358 acpi_namespace_node), 359 display, ACPI_UINT32_MAX); 360 } else { 361 acpi_os_printf("\n"); 362 acpi_ut_debug_dump_buffer((void *)obj_desc, 363 sizeof(union 364 acpi_operand_object), 365 display, ACPI_UINT32_MAX); 366 } 367 368 acpi_ex_dump_object_descriptor(obj_desc, 1); 369 } 370 } 371 372 /******************************************************************************* 373 * 374 * FUNCTION: acpi_db_display_method_info 375 * 376 * PARAMETERS: start_op - Root of the control method parse tree 377 * 378 * RETURN: None 379 * 380 * DESCRIPTION: Display information about the current method 381 * 382 ******************************************************************************/ 383 384 void acpi_db_display_method_info(union acpi_parse_object *start_op) 385 { 386 struct acpi_walk_state *walk_state; 387 union acpi_operand_object *obj_desc; 388 struct acpi_namespace_node *node; 389 union acpi_parse_object *root_op; 390 union acpi_parse_object *op; 391 const struct acpi_opcode_info *op_info; 392 u32 num_ops = 0; 393 u32 num_operands = 0; 394 u32 num_operators = 0; 395 u32 num_remaining_ops = 0; 396 u32 num_remaining_operands = 0; 397 u32 num_remaining_operators = 0; 398 u8 count_remaining = FALSE; 399 400 walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list); 401 if (!walk_state) { 402 acpi_os_printf("There is no method currently executing\n"); 403 return; 404 } 405 406 obj_desc = walk_state->method_desc; 407 node = walk_state->method_node; 408 409 acpi_os_printf("Currently executing control method is [%4.4s]\n", 410 acpi_ut_get_node_name(node)); 411 acpi_os_printf("%X Arguments, SyncLevel = %X\n", 412 (u32)obj_desc->method.param_count, 413 (u32)obj_desc->method.sync_level); 414 415 root_op = start_op; 416 while (root_op->common.parent) { 417 root_op = root_op->common.parent; 418 } 419 420 op = root_op; 421 422 while (op) { 423 if (op == start_op) { 424 count_remaining = TRUE; 425 } 426 427 num_ops++; 428 if (count_remaining) { 429 num_remaining_ops++; 430 } 431 432 /* Decode the opcode */ 433 434 op_info = acpi_ps_get_opcode_info(op->common.aml_opcode); 435 switch (op_info->class) { 436 case AML_CLASS_ARGUMENT: 437 438 if (count_remaining) { 439 num_remaining_operands++; 440 } 441 442 num_operands++; 443 break; 444 445 case AML_CLASS_UNKNOWN: 446 447 /* Bad opcode or ASCII character */ 448 449 continue; 450 451 default: 452 453 if (count_remaining) { 454 num_remaining_operators++; 455 } 456 457 num_operators++; 458 break; 459 } 460 461 op = acpi_ps_get_depth_next(start_op, op); 462 } 463 464 acpi_os_printf 465 ("Method contains: %X AML Opcodes - %X Operators, %X Operands\n", 466 num_ops, num_operators, num_operands); 467 468 acpi_os_printf 469 ("Remaining to execute: %X AML Opcodes - %X Operators, %X Operands\n", 470 num_remaining_ops, num_remaining_operators, 471 num_remaining_operands); 472 } 473 474 /******************************************************************************* 475 * 476 * FUNCTION: acpi_db_display_locals 477 * 478 * PARAMETERS: None 479 * 480 * RETURN: None 481 * 482 * DESCRIPTION: Display all locals for the currently running control method 483 * 484 ******************************************************************************/ 485 486 void acpi_db_display_locals(void) 487 { 488 struct acpi_walk_state *walk_state; 489 490 walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list); 491 if (!walk_state) { 492 acpi_os_printf("There is no method currently executing\n"); 493 return; 494 } 495 496 acpi_db_decode_locals(walk_state); 497 } 498 499 /******************************************************************************* 500 * 501 * FUNCTION: acpi_db_display_arguments 502 * 503 * PARAMETERS: None 504 * 505 * RETURN: None 506 * 507 * DESCRIPTION: Display all arguments for the currently running control method 508 * 509 ******************************************************************************/ 510 511 void acpi_db_display_arguments(void) 512 { 513 struct acpi_walk_state *walk_state; 514 515 walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list); 516 if (!walk_state) { 517 acpi_os_printf("There is no method currently executing\n"); 518 return; 519 } 520 521 acpi_db_decode_arguments(walk_state); 522 } 523 524 /******************************************************************************* 525 * 526 * FUNCTION: acpi_db_display_results 527 * 528 * PARAMETERS: None 529 * 530 * RETURN: None 531 * 532 * DESCRIPTION: Display current contents of a method result stack 533 * 534 ******************************************************************************/ 535 536 void acpi_db_display_results(void) 537 { 538 u32 i; 539 struct acpi_walk_state *walk_state; 540 union acpi_operand_object *obj_desc; 541 u32 result_count = 0; 542 struct acpi_namespace_node *node; 543 union acpi_generic_state *frame; 544 u32 index; /* Index onto current frame */ 545 546 walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list); 547 if (!walk_state) { 548 acpi_os_printf("There is no method currently executing\n"); 549 return; 550 } 551 552 obj_desc = walk_state->method_desc; 553 node = walk_state->method_node; 554 555 if (walk_state->results) { 556 result_count = walk_state->result_count; 557 } 558 559 acpi_os_printf("Method [%4.4s] has %X stacked result objects\n", 560 acpi_ut_get_node_name(node), result_count); 561 562 /* From the top element of result stack */ 563 564 frame = walk_state->results; 565 index = (result_count - 1) % ACPI_RESULTS_FRAME_OBJ_NUM; 566 567 for (i = 0; i < result_count; i++) { 568 obj_desc = frame->results.obj_desc[index]; 569 acpi_os_printf("Result%u: ", i); 570 acpi_db_display_internal_object(obj_desc, walk_state); 571 572 if (index == 0) { 573 frame = frame->results.next; 574 index = ACPI_RESULTS_FRAME_OBJ_NUM; 575 } 576 577 index--; 578 } 579 } 580 581 /******************************************************************************* 582 * 583 * FUNCTION: acpi_db_display_calling_tree 584 * 585 * PARAMETERS: None 586 * 587 * RETURN: None 588 * 589 * DESCRIPTION: Display current calling tree of nested control methods 590 * 591 ******************************************************************************/ 592 593 void acpi_db_display_calling_tree(void) 594 { 595 struct acpi_walk_state *walk_state; 596 struct acpi_namespace_node *node; 597 598 walk_state = acpi_ds_get_current_walk_state(acpi_gbl_current_walk_list); 599 if (!walk_state) { 600 acpi_os_printf("There is no method currently executing\n"); 601 return; 602 } 603 604 node = walk_state->method_node; 605 acpi_os_printf("Current Control Method Call Tree\n"); 606 607 while (walk_state) { 608 node = walk_state->method_node; 609 acpi_os_printf(" [%4.4s]\n", acpi_ut_get_node_name(node)); 610 611 walk_state = walk_state->next; 612 } 613 } 614 615 /******************************************************************************* 616 * 617 * FUNCTION: acpi_db_display_object_type 618 * 619 * PARAMETERS: object_arg - User entered NS node handle 620 * 621 * RETURN: None 622 * 623 * DESCRIPTION: Display type of an arbitrary NS node 624 * 625 ******************************************************************************/ 626 627 void acpi_db_display_object_type(char *object_arg) 628 { 629 acpi_size arg; 630 acpi_handle handle; 631 struct acpi_device_info *info; 632 acpi_status status; 633 u32 i; 634 635 arg = strtoul(object_arg, NULL, 16); 636 handle = ACPI_TO_POINTER(arg); 637 638 status = acpi_get_object_info(handle, &info); 639 if (ACPI_FAILURE(status)) { 640 acpi_os_printf("Could not get object info, %s\n", 641 acpi_format_exception(status)); 642 return; 643 } 644 645 acpi_os_printf("ADR: %8.8X%8.8X, STA: %8.8X, Flags: %X\n", 646 ACPI_FORMAT_UINT64(info->address), 647 info->current_status, info->flags); 648 649 acpi_os_printf("S1D-%2.2X S2D-%2.2X S3D-%2.2X S4D-%2.2X\n", 650 info->highest_dstates[0], info->highest_dstates[1], 651 info->highest_dstates[2], info->highest_dstates[3]); 652 653 acpi_os_printf("S0W-%2.2X S1W-%2.2X S2W-%2.2X S3W-%2.2X S4W-%2.2X\n", 654 info->lowest_dstates[0], info->lowest_dstates[1], 655 info->lowest_dstates[2], info->lowest_dstates[3], 656 info->lowest_dstates[4]); 657 658 if (info->valid & ACPI_VALID_HID) { 659 acpi_os_printf("HID: %s\n", info->hardware_id.string); 660 } 661 662 if (info->valid & ACPI_VALID_UID) { 663 acpi_os_printf("UID: %s\n", info->unique_id.string); 664 } 665 666 if (info->valid & ACPI_VALID_CID) { 667 for (i = 0; i < info->compatible_id_list.count; i++) { 668 acpi_os_printf("CID %u: %s\n", i, 669 info->compatible_id_list.ids[i].string); 670 } 671 } 672 673 ACPI_FREE(info); 674 } 675 676 /******************************************************************************* 677 * 678 * FUNCTION: acpi_db_display_result_object 679 * 680 * PARAMETERS: obj_desc - Object to be displayed 681 * walk_state - Current walk state 682 * 683 * RETURN: None 684 * 685 * DESCRIPTION: Display the result of an AML opcode 686 * 687 * Note: Curently only displays the result object if we are single stepping. 688 * However, this output may be useful in other contexts and could be enabled 689 * to do so if needed. 690 * 691 ******************************************************************************/ 692 693 void 694 acpi_db_display_result_object(union acpi_operand_object *obj_desc, 695 struct acpi_walk_state *walk_state) 696 { 697 698 #ifndef ACPI_APPLICATION 699 if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) { 700 return; 701 } 702 #endif 703 704 /* Only display if single stepping */ 705 706 if (!acpi_gbl_cm_single_step) { 707 return; 708 } 709 710 acpi_os_printf("ResultObj: "); 711 acpi_db_display_internal_object(obj_desc, walk_state); 712 acpi_os_printf("\n"); 713 } 714 715 /******************************************************************************* 716 * 717 * FUNCTION: acpi_db_display_argument_object 718 * 719 * PARAMETERS: obj_desc - Object to be displayed 720 * walk_state - Current walk state 721 * 722 * RETURN: None 723 * 724 * DESCRIPTION: Display the result of an AML opcode 725 * 726 ******************************************************************************/ 727 728 void 729 acpi_db_display_argument_object(union acpi_operand_object *obj_desc, 730 struct acpi_walk_state *walk_state) 731 { 732 733 #ifndef ACPI_APPLICATION 734 if (acpi_gbl_db_thread_id != acpi_os_get_thread_id()) { 735 return; 736 } 737 #endif 738 739 if (!acpi_gbl_cm_single_step) { 740 return; 741 } 742 743 acpi_os_printf("ArgObj: "); 744 acpi_db_display_internal_object(obj_desc, walk_state); 745 } 746 747 #if (!ACPI_REDUCED_HARDWARE) 748 /******************************************************************************* 749 * 750 * FUNCTION: acpi_db_display_gpes 751 * 752 * PARAMETERS: None 753 * 754 * RETURN: None 755 * 756 * DESCRIPTION: Display the current GPE structures 757 * 758 ******************************************************************************/ 759 760 void acpi_db_display_gpes(void) 761 { 762 struct acpi_gpe_block_info *gpe_block; 763 struct acpi_gpe_xrupt_info *gpe_xrupt_info; 764 struct acpi_gpe_event_info *gpe_event_info; 765 struct acpi_gpe_register_info *gpe_register_info; 766 char *gpe_type; 767 struct acpi_gpe_notify_info *notify; 768 u32 gpe_index; 769 u32 block = 0; 770 u32 i; 771 u32 j; 772 u32 count; 773 char buffer[80]; 774 struct acpi_buffer ret_buf; 775 acpi_status status; 776 777 ret_buf.length = sizeof(buffer); 778 ret_buf.pointer = buffer; 779 780 block = 0; 781 782 /* Walk the GPE lists */ 783 784 gpe_xrupt_info = acpi_gbl_gpe_xrupt_list_head; 785 while (gpe_xrupt_info) { 786 gpe_block = gpe_xrupt_info->gpe_block_list_head; 787 while (gpe_block) { 788 status = acpi_get_name(gpe_block->node, 789 ACPI_FULL_PATHNAME_NO_TRAILING, 790 &ret_buf); 791 if (ACPI_FAILURE(status)) { 792 acpi_os_printf 793 ("Could not convert name to pathname\n"); 794 } 795 796 if (gpe_block->node == acpi_gbl_fadt_gpe_device) { 797 gpe_type = "FADT-defined GPE block"; 798 } else { 799 gpe_type = "GPE Block Device"; 800 } 801 802 acpi_os_printf 803 ("\nBlock %u - Info %p DeviceNode %p [%s] - %s\n", 804 block, gpe_block, gpe_block->node, buffer, 805 gpe_type); 806 807 acpi_os_printf(" Registers: %u (%u GPEs)\n", 808 gpe_block->register_count, 809 gpe_block->gpe_count); 810 811 acpi_os_printf 812 (" GPE range: 0x%X to 0x%X on interrupt %u\n", 813 gpe_block->block_base_number, 814 gpe_block->block_base_number + 815 (gpe_block->gpe_count - 1), 816 gpe_xrupt_info->interrupt_number); 817 818 acpi_os_printf 819 (" RegisterInfo: %p Status %8.8X%8.8X Enable %8.8X%8.8X\n", 820 gpe_block->register_info, 821 ACPI_FORMAT_UINT64(gpe_block->register_info-> 822 status_address.address), 823 ACPI_FORMAT_UINT64(gpe_block->register_info-> 824 enable_address.address)); 825 826 acpi_os_printf(" EventInfo: %p\n", 827 gpe_block->event_info); 828 829 /* Examine each GPE Register within the block */ 830 831 for (i = 0; i < gpe_block->register_count; i++) { 832 gpe_register_info = 833 &gpe_block->register_info[i]; 834 835 acpi_os_printf(" Reg %u: (GPE %.2X-%.2X) " 836 "RunEnable %2.2X WakeEnable %2.2X" 837 " Status %8.8X%8.8X Enable %8.8X%8.8X\n", 838 i, 839 gpe_register_info-> 840 base_gpe_number, 841 gpe_register_info-> 842 base_gpe_number + 843 (ACPI_GPE_REGISTER_WIDTH - 1), 844 gpe_register_info-> 845 enable_for_run, 846 gpe_register_info-> 847 enable_for_wake, 848 ACPI_FORMAT_UINT64 849 (gpe_register_info-> 850 status_address.address), 851 ACPI_FORMAT_UINT64 852 (gpe_register_info-> 853 enable_address.address)); 854 855 /* Now look at the individual GPEs in this byte register */ 856 857 for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) { 858 gpe_index = 859 (i * ACPI_GPE_REGISTER_WIDTH) + j; 860 gpe_event_info = 861 &gpe_block->event_info[gpe_index]; 862 863 if (ACPI_GPE_DISPATCH_TYPE 864 (gpe_event_info->flags) == 865 ACPI_GPE_DISPATCH_NONE) { 866 867 /* This GPE is not used (no method or handler), ignore it */ 868 869 continue; 870 } 871 872 acpi_os_printf 873 (" GPE %.2X: %p RunRefs %2.2X Flags %2.2X (", 874 gpe_block->block_base_number + 875 gpe_index, gpe_event_info, 876 gpe_event_info->runtime_count, 877 gpe_event_info->flags); 878 879 /* Decode the flags byte */ 880 881 if (gpe_event_info-> 882 flags & ACPI_GPE_LEVEL_TRIGGERED) { 883 acpi_os_printf("Level, "); 884 } else { 885 acpi_os_printf("Edge, "); 886 } 887 888 if (gpe_event_info-> 889 flags & ACPI_GPE_CAN_WAKE) { 890 acpi_os_printf("CanWake, "); 891 } else { 892 acpi_os_printf("RunOnly, "); 893 } 894 895 switch (ACPI_GPE_DISPATCH_TYPE 896 (gpe_event_info->flags)) { 897 case ACPI_GPE_DISPATCH_NONE: 898 899 acpi_os_printf("NotUsed"); 900 break; 901 902 case ACPI_GPE_DISPATCH_METHOD: 903 904 acpi_os_printf("Method"); 905 break; 906 907 case ACPI_GPE_DISPATCH_HANDLER: 908 909 acpi_os_printf("Handler"); 910 break; 911 912 case ACPI_GPE_DISPATCH_NOTIFY: 913 914 count = 0; 915 notify = 916 gpe_event_info->dispatch. 917 notify_list; 918 while (notify) { 919 count++; 920 notify = notify->next; 921 } 922 923 acpi_os_printf 924 ("Implicit Notify on %u devices", 925 count); 926 break; 927 928 case ACPI_GPE_DISPATCH_RAW_HANDLER: 929 930 acpi_os_printf("RawHandler"); 931 break; 932 933 default: 934 935 acpi_os_printf("UNKNOWN: %X", 936 ACPI_GPE_DISPATCH_TYPE 937 (gpe_event_info-> 938 flags)); 939 break; 940 } 941 942 acpi_os_printf(")\n"); 943 } 944 } 945 946 block++; 947 gpe_block = gpe_block->next; 948 } 949 950 gpe_xrupt_info = gpe_xrupt_info->next; 951 } 952 } 953 #endif /* !ACPI_REDUCED_HARDWARE */ 954 955 /******************************************************************************* 956 * 957 * FUNCTION: acpi_db_display_handlers 958 * 959 * PARAMETERS: None 960 * 961 * RETURN: None 962 * 963 * DESCRIPTION: Display the currently installed global handlers 964 * 965 ******************************************************************************/ 966 967 void acpi_db_display_handlers(void) 968 { 969 union acpi_operand_object *obj_desc; 970 union acpi_operand_object *handler_obj; 971 acpi_adr_space_type space_id; 972 u32 i; 973 974 /* Operation region handlers */ 975 976 acpi_os_printf("\nOperation Region Handlers at the namespace root:\n"); 977 978 obj_desc = acpi_ns_get_attached_object(acpi_gbl_root_node); 979 if (obj_desc) { 980 for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_gbl_space_id_list); i++) { 981 space_id = acpi_gbl_space_id_list[i]; 982 983 acpi_os_printf(ACPI_PREDEFINED_PREFIX, 984 acpi_ut_get_region_name((u8)space_id), 985 space_id); 986 987 handler_obj = 988 acpi_ev_find_region_handler(space_id, 989 obj_desc->common_notify. 990 handler); 991 if (handler_obj) { 992 acpi_os_printf(ACPI_HANDLER_PRESENT_STRING, 993 (handler_obj->address_space. 994 handler_flags & 995 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) 996 ? "Default" : "User", 997 handler_obj->address_space. 998 handler); 999 1000 goto found_handler; 1001 } 1002 1003 /* There is no handler for this space_id */ 1004 1005 acpi_os_printf("None\n"); 1006 1007 found_handler: ; 1008 } 1009 1010 /* Find all handlers for user-defined space_IDs */ 1011 1012 handler_obj = obj_desc->common_notify.handler; 1013 while (handler_obj) { 1014 if (handler_obj->address_space.space_id >= 1015 ACPI_USER_REGION_BEGIN) { 1016 acpi_os_printf(ACPI_PREDEFINED_PREFIX, 1017 "User-defined ID", 1018 handler_obj->address_space. 1019 space_id); 1020 acpi_os_printf(ACPI_HANDLER_PRESENT_STRING, 1021 (handler_obj->address_space. 1022 handler_flags & 1023 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) 1024 ? "Default" : "User", 1025 handler_obj->address_space. 1026 handler); 1027 } 1028 1029 handler_obj = handler_obj->address_space.next; 1030 } 1031 } 1032 #if (!ACPI_REDUCED_HARDWARE) 1033 1034 /* Fixed event handlers */ 1035 1036 acpi_os_printf("\nFixed Event Handlers:\n"); 1037 1038 for (i = 0; i < ACPI_NUM_FIXED_EVENTS; i++) { 1039 acpi_os_printf(ACPI_PREDEFINED_PREFIX, 1040 acpi_ut_get_event_name(i), i); 1041 if (acpi_gbl_fixed_event_handlers[i].handler) { 1042 acpi_os_printf(ACPI_HANDLER_PRESENT_STRING, "User", 1043 acpi_gbl_fixed_event_handlers[i]. 1044 handler); 1045 } else { 1046 acpi_os_printf(ACPI_HANDLER_NOT_PRESENT_STRING, "None"); 1047 } 1048 } 1049 1050 #endif /* !ACPI_REDUCED_HARDWARE */ 1051 1052 /* Miscellaneous global handlers */ 1053 1054 acpi_os_printf("\nMiscellaneous Global Handlers:\n"); 1055 1056 for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_gbl_handler_list); i++) { 1057 acpi_os_printf(ACPI_HANDLER_NAME_STRING, 1058 acpi_gbl_handler_list[i].name); 1059 1060 if (acpi_gbl_handler_list[i].handler) { 1061 acpi_os_printf(ACPI_HANDLER_PRESENT_STRING, "User", 1062 acpi_gbl_handler_list[i].handler); 1063 } else { 1064 acpi_os_printf(ACPI_HANDLER_NOT_PRESENT_STRING, "None"); 1065 } 1066 } 1067 1068 /* Other handlers that are installed throughout the namespace */ 1069 1070 acpi_os_printf("\nOperation Region Handlers for specific devices:\n"); 1071 1072 (void)acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 1073 ACPI_UINT32_MAX, 1074 acpi_db_display_non_root_handlers, NULL, NULL, 1075 NULL); 1076 } 1077 1078 /******************************************************************************* 1079 * 1080 * FUNCTION: acpi_db_display_non_root_handlers 1081 * 1082 * PARAMETERS: acpi_walk_callback 1083 * 1084 * RETURN: Status 1085 * 1086 * DESCRIPTION: Display information about all handlers installed for a 1087 * device object. 1088 * 1089 ******************************************************************************/ 1090 1091 static acpi_status 1092 acpi_db_display_non_root_handlers(acpi_handle obj_handle, 1093 u32 nesting_level, 1094 void *context, void **return_value) 1095 { 1096 struct acpi_namespace_node *node = 1097 ACPI_CAST_PTR(struct acpi_namespace_node, obj_handle); 1098 union acpi_operand_object *obj_desc; 1099 union acpi_operand_object *handler_obj; 1100 char *pathname; 1101 1102 obj_desc = acpi_ns_get_attached_object(node); 1103 if (!obj_desc) { 1104 return (AE_OK); 1105 } 1106 1107 pathname = acpi_ns_get_normalized_pathname(node, TRUE); 1108 if (!pathname) { 1109 return (AE_OK); 1110 } 1111 1112 /* Display all handlers associated with this device */ 1113 1114 handler_obj = obj_desc->common_notify.handler; 1115 while (handler_obj) { 1116 acpi_os_printf(ACPI_PREDEFINED_PREFIX, 1117 acpi_ut_get_region_name((u8)handler_obj-> 1118 address_space.space_id), 1119 handler_obj->address_space.space_id); 1120 1121 acpi_os_printf(ACPI_HANDLER_PRESENT_STRING2, 1122 (handler_obj->address_space.handler_flags & 1123 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) ? "Default" 1124 : "User", handler_obj->address_space.handler); 1125 1126 acpi_os_printf(" Device Name: %s (%p)\n", pathname, node); 1127 1128 handler_obj = handler_obj->address_space.next; 1129 } 1130 1131 ACPI_FREE(pathname); 1132 return (AE_OK); 1133 } 1134