1/****************************************************************************** 2 * 3 * Module Name: nsdump - table dumping routines for debug 4 * $Revision: 1.1.1.1 $ 5 * 6 *****************************************************************************/ 7 8/* 9 * Copyright (C) 2000, 2001 R. Byron Moore 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 */ 25 26 27#include "acpi.h" 28#include "acinterp.h" 29#include "acnamesp.h" 30#include "actables.h" 31#include "acparser.h" 32 33 34#define _COMPONENT ACPI_NAMESPACE 35 MODULE_NAME ("nsdump") 36 37 38#if defined(ACPI_DEBUG) || defined(ENABLE_DEBUGGER) 39 40/******************************************************************************* 41 * 42 * FUNCTION: Acpi_ns_dump_pathname 43 * 44 * PARAMETERS: Handle - Object 45 * Msg - Prefix message 46 * Level - Desired debug level 47 * Component - Caller's component ID 48 * 49 * DESCRIPTION: Print an object's full namespace pathname 50 * Manages allocation/freeing of a pathname buffer 51 * 52 ******************************************************************************/ 53 54acpi_status 55acpi_ns_dump_pathname ( 56 acpi_handle handle, 57 NATIVE_CHAR *msg, 58 u32 level, 59 u32 component) 60{ 61 NATIVE_CHAR *buffer; 62 u32 length; 63 64 65 FUNCTION_TRACE ("Ns_dump_pathname"); 66 67 68 /* Do this only if the requested debug level and component are enabled */ 69 70 if (!(acpi_dbg_level & level) || !(acpi_dbg_layer & component)) { 71 return_ACPI_STATUS (AE_OK); 72 } 73 74 buffer = ACPI_MEM_ALLOCATE (PATHNAME_MAX); 75 if (!buffer) { 76 return_ACPI_STATUS (AE_NO_MEMORY); 77 } 78 79 /* Convert handle to a full pathname and print it (with supplied message) */ 80 81 length = PATHNAME_MAX; 82 if (ACPI_SUCCESS (acpi_ns_handle_to_pathname (handle, &length, buffer))) { 83 acpi_os_printf ("%s %s (%p)\n", msg, buffer, handle); 84 } 85 86 ACPI_MEM_FREE (buffer); 87 88 return_ACPI_STATUS (AE_OK); 89} 90 91 92/******************************************************************************* 93 * 94 * FUNCTION: Acpi_ns_dump_one_object 95 * 96 * PARAMETERS: Handle - Node to be dumped 97 * Level - Nesting level of the handle 98 * Context - Passed into Walk_namespace 99 * 100 * DESCRIPTION: Dump a single Node 101 * This procedure is a User_function called by Acpi_ns_walk_namespace. 102 * 103 ******************************************************************************/ 104 105acpi_status 106acpi_ns_dump_one_object ( 107 acpi_handle obj_handle, 108 u32 level, 109 void *context, 110 void **return_value) 111{ 112 acpi_walk_info *info = (acpi_walk_info *) context; 113 acpi_namespace_node *this_node; 114 acpi_operand_object *obj_desc = NULL; 115 acpi_object_type8 obj_type; 116 acpi_object_type8 type; 117 u32 bytes_to_dump; 118 u32 downstream_sibling_mask = 0; 119 u32 level_tmp; 120 u32 which_bit; 121 u32 i; 122 123 124 PROC_NAME ("Ns_dump_one_object"); 125 126 127 this_node = acpi_ns_map_handle_to_node (obj_handle); 128 129 level_tmp = level; 130 type = this_node->type; 131 which_bit = 1; 132 133 134 if (!(acpi_dbg_level & info->debug_level)) { 135 return (AE_OK); 136 } 137 138 if (!obj_handle) { 139 ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Null object handle\n")); 140 return (AE_OK); 141 } 142 143 /* Check if the owner matches */ 144 145 if ((info->owner_id != ACPI_UINT32_MAX) && 146 (info->owner_id != this_node->owner_id)) { 147 return (AE_OK); 148 } 149 150 151 /* Indent the object according to the level */ 152 153 while (level_tmp--) { 154 155 /* Print appropriate characters to form tree structure */ 156 157 if (level_tmp) { 158 if (downstream_sibling_mask & which_bit) { 159 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "|")); 160 } 161 162 else { 163 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " ")); 164 } 165 166 which_bit <<= 1; 167 } 168 169 else { 170 if (acpi_ns_exist_downstream_sibling (this_node + 1)) { 171 downstream_sibling_mask |= (1 << (level - 1)); 172 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "+")); 173 } 174 175 else { 176 downstream_sibling_mask &= ACPI_UINT32_MAX ^ (1 << (level - 1)); 177 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "+")); 178 } 179 180 if (this_node->child == NULL) { 181 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "-")); 182 } 183 184 else if (acpi_ns_exist_downstream_sibling (this_node->child)) { 185 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "+")); 186 } 187 188 else { 189 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "-")); 190 } 191 } 192 } 193 194 195 /* Check the integrity of our data */ 196 197 if (type > INTERNAL_TYPE_MAX) { 198 type = INTERNAL_TYPE_DEF_ANY; /* prints as *ERROR* */ 199 } 200 201 if (!acpi_ut_valid_acpi_name (this_node->name)) { 202 REPORT_WARNING (("Invalid ACPI Name %08X\n", this_node->name)); 203 } 204 205 /* 206 * Now we can print out the pertinent information 207 */ 208 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " %4.4s %-12s %p", 209 (char*)&this_node->name, acpi_ut_get_type_name (type), this_node)); 210 211 obj_desc = this_node->object; 212 213 switch (info->display_type) { 214 case ACPI_DISPLAY_SUMMARY: 215 216 if (!obj_desc) { 217 /* No attached object, we are done */ 218 219 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n")); 220 return (AE_OK); 221 } 222 223 224 switch (type) { 225 case ACPI_TYPE_PROCESSOR: 226 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " ID %d Addr %.4X Len %.4X\n", 227 obj_desc->processor.proc_id, 228 obj_desc->processor.address, 229 (unsigned)obj_desc->processor.length)); 230 break; 231 232 case ACPI_TYPE_DEVICE: 233 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Notification object: %p", obj_desc)); 234 break; 235 236 case ACPI_TYPE_METHOD: 237 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Args %d Len %.4X Aml %p \n", 238 obj_desc->method.param_count, 239 obj_desc->method.aml_length, 240 obj_desc->method.aml_start)); 241 break; 242 243 case ACPI_TYPE_INTEGER: 244 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " = %8.8X%8.8X\n", 245 HIDWORD (obj_desc->integer.value), 246 LODWORD (obj_desc->integer.value))); 247 break; 248 249 case ACPI_TYPE_PACKAGE: 250 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Elements %.2X\n", 251 obj_desc->package.count)); 252 break; 253 254 case ACPI_TYPE_BUFFER: 255 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Len %.2X", 256 obj_desc->buffer.length)); 257 258 /* Dump some of the buffer */ 259 260 if (obj_desc->buffer.length > 0) { 261 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " =")); 262 for (i = 0; (i < obj_desc->buffer.length && i < 12); i++) { 263 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " %.2X", 264 obj_desc->buffer.pointer[i])); 265 } 266 } 267 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n")); 268 break; 269 270 case ACPI_TYPE_STRING: 271 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Len %.2X", 272 obj_desc->string.length)); 273 274 if (obj_desc->string.length > 0) { 275 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " = \"%.32s\"...", 276 obj_desc->string.pointer)); 277 } 278 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n")); 279 break; 280 281 case ACPI_TYPE_REGION: 282 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " [%s]", 283 acpi_ut_get_region_name (obj_desc->region.space_id))); 284 if (obj_desc->region.flags & AOPOBJ_DATA_VALID) { 285 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Addr %8.8X%8.8X Len %.4X\n", 286 HIDWORD(obj_desc->region.address), 287 LODWORD(obj_desc->region.address), 288 obj_desc->region.length)); 289 } 290 else { 291 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " [Address/Length not evaluated]\n")); 292 } 293 break; 294 295 case INTERNAL_TYPE_REFERENCE: 296 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " [%s]\n", 297 acpi_ps_get_opcode_name (obj_desc->reference.opcode))); 298 break; 299 300 case ACPI_TYPE_BUFFER_FIELD: 301 302 /* TBD: print Buffer name when we can easily get it */ 303 break; 304 305 case INTERNAL_TYPE_REGION_FIELD: 306 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Rgn [%4.4s]", 307 (char *) &obj_desc->common_field.region_obj->region.node->name)); 308 break; 309 310 case INTERNAL_TYPE_BANK_FIELD: 311 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Rgn [%4.4s]", 312 (char *) &obj_desc->common_field.region_obj->region.node->name)); 313 break; 314 315 case INTERNAL_TYPE_INDEX_FIELD: 316 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Rgn [%4.4s]", 317 (char *) &obj_desc->index_field.index_obj->common_field.region_obj->region.node->name)); 318 break; 319 320 default: 321 322 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Object %p\n", obj_desc)); 323 break; 324 } 325 326 /* Common field handling */ 327 328 switch (type) { 329 case ACPI_TYPE_BUFFER_FIELD: 330 case INTERNAL_TYPE_REGION_FIELD: 331 case INTERNAL_TYPE_BANK_FIELD: 332 case INTERNAL_TYPE_INDEX_FIELD: 333 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Off %.2X Len %.2X Acc %.2d\n", 334 (obj_desc->common_field.base_byte_offset * 8) + obj_desc->common_field.start_field_bit_offset, 335 obj_desc->common_field.bit_length, 336 obj_desc->common_field.access_bit_width)); 337 break; 338 } 339 340 break; 341 342 343 case ACPI_DISPLAY_OBJECTS: 344 345 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "%p O:%p", 346 this_node, obj_desc)); 347 348 if (!obj_desc) { 349 /* No attached object, we are done */ 350 351 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n")); 352 return (AE_OK); 353 } 354 355 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(R%d)", 356 obj_desc->common.reference_count)); 357 358 switch (type) { 359 360 case ACPI_TYPE_METHOD: 361 362 /* Name is a Method and its AML offset/length are set */ 363 364 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " M:%p-%X\n", 365 obj_desc->method.aml_start, 366 obj_desc->method.aml_length)); 367 368 break; 369 370 371 case ACPI_TYPE_INTEGER: 372 373 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " N:%X%X\n", 374 HIDWORD(obj_desc->integer.value), 375 LODWORD(obj_desc->integer.value))); 376 break; 377 378 379 case ACPI_TYPE_STRING: 380 381 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " S:%p-%X\n", 382 obj_desc->string.pointer, 383 obj_desc->string.length)); 384 break; 385 386 387 case ACPI_TYPE_BUFFER: 388 389 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " B:%p-%X\n", 390 obj_desc->buffer.pointer, 391 obj_desc->buffer.length)); 392 break; 393 394 395 default: 396 397 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n")); 398 break; 399 } 400 break; 401 } 402 403 /* If debug turned off, done */ 404 405 if (!(acpi_dbg_level & ACPI_LV_VALUES)) { 406 return (AE_OK); 407 } 408 409 410 /* If there is an attached object, display it */ 411 412 obj_desc = this_node->object; 413 414 /* Dump attached objects */ 415 416 while (obj_desc) { 417 obj_type = INTERNAL_TYPE_INVALID; 418 419 /* Decode the type of attached object and dump the contents */ 420 421 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Attached Object %p: ", obj_desc)); 422 423 if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) { 424 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to Node)\n")); 425 bytes_to_dump = sizeof (acpi_namespace_node); 426 } 427 428 429 else if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_INTERNAL)) { 430 obj_type = obj_desc->common.type; 431 432 if (obj_type > INTERNAL_TYPE_MAX) { 433 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to ACPI Object type %X [UNKNOWN])\n", obj_type)); 434 bytes_to_dump = 32; 435 } 436 437 else { 438 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to ACPI Object type %2.2X [%s])\n", 439 obj_type, acpi_ut_get_type_name (obj_type))); 440 bytes_to_dump = sizeof (acpi_operand_object); 441 } 442 } 443 444 else { 445 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(String or Buffer - not descriptor)\n")); 446 bytes_to_dump = 16; 447 } 448 449 DUMP_BUFFER (obj_desc, bytes_to_dump); 450 451 /* If value is NOT an internal object, we are done */ 452 453 if (VALID_DESCRIPTOR_TYPE (obj_desc, ACPI_DESC_TYPE_NAMED)) { 454 goto cleanup; 455 } 456 457 /* 458 * Valid object, get the pointer to next level, if any 459 */ 460 switch (obj_type) { 461 case ACPI_TYPE_STRING: 462 obj_desc = (acpi_operand_object *) obj_desc->string.pointer; 463 break; 464 465 case ACPI_TYPE_BUFFER: 466 obj_desc = (acpi_operand_object *) obj_desc->buffer.pointer; 467 break; 468 469 case ACPI_TYPE_BUFFER_FIELD: 470 obj_desc = (acpi_operand_object *) obj_desc->buffer_field.buffer_obj; 471 break; 472 473 case ACPI_TYPE_PACKAGE: 474 obj_desc = (acpi_operand_object *) obj_desc->package.elements; 475 break; 476 477 case ACPI_TYPE_METHOD: 478 obj_desc = (acpi_operand_object *) obj_desc->method.aml_start; 479 break; 480 481 case INTERNAL_TYPE_REGION_FIELD: 482 obj_desc = (acpi_operand_object *) obj_desc->field.region_obj; 483 break; 484 485 case INTERNAL_TYPE_BANK_FIELD: 486 obj_desc = (acpi_operand_object *) obj_desc->bank_field.region_obj; 487 break; 488 489 case INTERNAL_TYPE_INDEX_FIELD: 490 obj_desc = (acpi_operand_object *) obj_desc->index_field.index_obj; 491 break; 492 493 default: 494 goto cleanup; 495 } 496 497 obj_type = INTERNAL_TYPE_INVALID; /* Terminate loop after next pass */ 498 } 499 500cleanup: 501 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n")); 502 return (AE_OK); 503} 504 505 506/******************************************************************************* 507 * 508 * FUNCTION: Acpi_ns_dump_objects 509 * 510 * PARAMETERS: Type - Object type to be dumped 511 * Max_depth - Maximum depth of dump. Use ACPI_UINT32_MAX 512 * for an effectively unlimited depth. 513 * Owner_id - Dump only objects owned by this ID. Use 514 * ACPI_UINT32_MAX to match all owners. 515 * Start_handle - Where in namespace to start/end search 516 * 517 * DESCRIPTION: Dump typed objects within the loaded namespace. 518 * Uses Acpi_ns_walk_namespace in conjunction with Acpi_ns_dump_one_object. 519 * 520 ******************************************************************************/ 521 522void 523acpi_ns_dump_objects ( 524 acpi_object_type8 type, 525 u8 display_type, 526 u32 max_depth, 527 u32 owner_id, 528 acpi_handle start_handle) 529{ 530 acpi_walk_info info; 531 532 533 FUNCTION_ENTRY (); 534 535 536 info.debug_level = ACPI_LV_TABLES; 537 info.owner_id = owner_id; 538 info.display_type = display_type; 539 540 541 acpi_ns_walk_namespace (type, start_handle, max_depth, NS_WALK_NO_UNLOCK, acpi_ns_dump_one_object, 542 (void *) &info, NULL); 543} 544 545 546#ifndef _ACPI_ASL_COMPILER 547/******************************************************************************* 548 * 549 * FUNCTION: Acpi_ns_dump_one_device 550 * 551 * PARAMETERS: Handle - Node to be dumped 552 * Level - Nesting level of the handle 553 * Context - Passed into Walk_namespace 554 * 555 * DESCRIPTION: Dump a single Node that represents a device 556 * This procedure is a User_function called by Acpi_ns_walk_namespace. 557 * 558 ******************************************************************************/ 559 560acpi_status 561acpi_ns_dump_one_device ( 562 acpi_handle obj_handle, 563 u32 level, 564 void *context, 565 void **return_value) 566{ 567 acpi_device_info info; 568 acpi_status status; 569 u32 i; 570 571 572 PROC_NAME ("Ns_dump_one_device"); 573 574 575 status = acpi_ns_dump_one_object (obj_handle, level, context, return_value); 576 577 status = acpi_get_object_info (obj_handle, &info); 578 if (ACPI_SUCCESS (status)) { 579 for (i = 0; i < level; i++) { 580 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " ")); 581 } 582 583 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " HID: %s, ADR: %8.8X%8.8X, Status: %x\n", 584 info.hardware_id, HIDWORD(info.address), LODWORD(info.address), info.current_status)); 585 } 586 587 return (status); 588} 589 590 591/******************************************************************************* 592 * 593 * FUNCTION: Acpi_ns_dump_root_devices 594 * 595 * PARAMETERS: None 596 * 597 * DESCRIPTION: Dump all objects of type "device" 598 * 599 ******************************************************************************/ 600 601void 602acpi_ns_dump_root_devices (void) 603{ 604 acpi_handle sys_bus_handle; 605 606 607 PROC_NAME ("Ns_dump_root_devices"); 608 609 610 /* Only dump the table if tracing is enabled */ 611 612 if (!(ACPI_LV_TABLES & acpi_dbg_level)) { 613 return; 614 } 615 616 acpi_get_handle (0, NS_SYSTEM_BUS, &sys_bus_handle); 617 618 ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Display of all devices in the namespace:\n")); 619 acpi_ns_walk_namespace (ACPI_TYPE_DEVICE, sys_bus_handle, ACPI_UINT32_MAX, NS_WALK_NO_UNLOCK, 620 acpi_ns_dump_one_device, NULL, NULL); 621} 622 623#endif 624 625/******************************************************************************* 626 * 627 * FUNCTION: Acpi_ns_dump_tables 628 * 629 * PARAMETERS: Search_base - Root of subtree to be dumped, or 630 * NS_ALL to dump the entire namespace 631 * Max_depth - Maximum depth of dump. Use INT_MAX 632 * for an effectively unlimited depth. 633 * 634 * DESCRIPTION: Dump the name space, or a portion of it. 635 * 636 ******************************************************************************/ 637 638void 639acpi_ns_dump_tables ( 640 acpi_handle search_base, 641 u32 max_depth) 642{ 643 acpi_handle search_handle = search_base; 644 645 646 FUNCTION_TRACE ("Ns_dump_tables"); 647 648 649 if (!acpi_gbl_root_node) { 650 /* 651 * If the name space has not been initialized, 652 * there is nothing to dump. 653 */ 654 ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "name space not initialized!\n")); 655 return_VOID; 656 } 657 658 if (NS_ALL == search_base) { 659 /* entire namespace */ 660 661 search_handle = acpi_gbl_root_node; 662 ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "\\\n")); 663 } 664 665 666 acpi_ns_dump_objects (ACPI_TYPE_ANY, ACPI_DISPLAY_OBJECTS, max_depth, 667 ACPI_UINT32_MAX, search_handle); 668 return_VOID; 669} 670 671 672/******************************************************************************* 673 * 674 * FUNCTION: Acpi_ns_dump_entry 675 * 676 * PARAMETERS: Handle - Node to be dumped 677 * Debug_level - Output level 678 * 679 * DESCRIPTION: Dump a single Node 680 * 681 ******************************************************************************/ 682 683void 684acpi_ns_dump_entry ( 685 acpi_handle handle, 686 u32 debug_level) 687{ 688 acpi_walk_info info; 689 690 691 FUNCTION_ENTRY (); 692 693 694 info.debug_level = debug_level; 695 info.owner_id = ACPI_UINT32_MAX; 696 697 acpi_ns_dump_one_object (handle, 1, &info, NULL); 698} 699 700#endif 701 702