1 /******************************************************************************* 2 * 3 * Module Name: dbnames - Debugger commands for the acpi namespace 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2017, 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 "acdebug.h" 48 #include "acpredef.h" 49 50 #define _COMPONENT ACPI_CA_DEBUGGER 51 ACPI_MODULE_NAME("dbnames") 52 53 /* Local prototypes */ 54 static acpi_status 55 acpi_db_walk_and_match_name(acpi_handle obj_handle, 56 u32 nesting_level, 57 void *context, void **return_value); 58 59 static acpi_status 60 acpi_db_walk_for_predefined_names(acpi_handle obj_handle, 61 u32 nesting_level, 62 void *context, void **return_value); 63 64 static acpi_status 65 acpi_db_walk_for_specific_objects(acpi_handle obj_handle, 66 u32 nesting_level, 67 void *context, void **return_value); 68 69 static acpi_status 70 acpi_db_walk_for_object_counts(acpi_handle obj_handle, 71 u32 nesting_level, 72 void *context, void **return_value); 73 74 static acpi_status 75 acpi_db_integrity_walk(acpi_handle obj_handle, 76 u32 nesting_level, void *context, void **return_value); 77 78 static acpi_status 79 acpi_db_walk_for_references(acpi_handle obj_handle, 80 u32 nesting_level, 81 void *context, void **return_value); 82 83 static acpi_status 84 acpi_db_bus_walk(acpi_handle obj_handle, 85 u32 nesting_level, void *context, void **return_value); 86 87 /* 88 * Arguments for the Objects command 89 * These object types map directly to the ACPI_TYPES 90 */ 91 static struct acpi_db_argument_info acpi_db_object_types[] = { 92 {"ANY"}, 93 {"INTEGERS"}, 94 {"STRINGS"}, 95 {"BUFFERS"}, 96 {"PACKAGES"}, 97 {"FIELDS"}, 98 {"DEVICES"}, 99 {"EVENTS"}, 100 {"METHODS"}, 101 {"MUTEXES"}, 102 {"REGIONS"}, 103 {"POWERRESOURCES"}, 104 {"PROCESSORS"}, 105 {"THERMALZONES"}, 106 {"BUFFERFIELDS"}, 107 {"DDBHANDLES"}, 108 {"DEBUG"}, 109 {"REGIONFIELDS"}, 110 {"BANKFIELDS"}, 111 {"INDEXFIELDS"}, 112 {"REFERENCES"}, 113 {"ALIASES"}, 114 {"METHODALIASES"}, 115 {"NOTIFY"}, 116 {"ADDRESSHANDLER"}, 117 {"RESOURCE"}, 118 {"RESOURCEFIELD"}, 119 {"SCOPES"}, 120 {NULL} /* Must be null terminated */ 121 }; 122 123 /******************************************************************************* 124 * 125 * FUNCTION: acpi_db_set_scope 126 * 127 * PARAMETERS: name - New scope path 128 * 129 * RETURN: Status 130 * 131 * DESCRIPTION: Set the "current scope" as maintained by this utility. 132 * The scope is used as a prefix to ACPI paths. 133 * 134 ******************************************************************************/ 135 136 void acpi_db_set_scope(char *name) 137 { 138 acpi_status status; 139 struct acpi_namespace_node *node; 140 141 if (!name || name[0] == 0) { 142 acpi_os_printf("Current scope: %s\n", acpi_gbl_db_scope_buf); 143 return; 144 } 145 146 acpi_db_prep_namestring(name); 147 148 if (ACPI_IS_ROOT_PREFIX(name[0])) { 149 150 /* Validate new scope from the root */ 151 152 status = acpi_ns_get_node(acpi_gbl_root_node, name, 153 ACPI_NS_NO_UPSEARCH, &node); 154 if (ACPI_FAILURE(status)) { 155 goto error_exit; 156 } 157 158 acpi_gbl_db_scope_buf[0] = 0; 159 } else { 160 /* Validate new scope relative to old scope */ 161 162 status = acpi_ns_get_node(acpi_gbl_db_scope_node, name, 163 ACPI_NS_NO_UPSEARCH, &node); 164 if (ACPI_FAILURE(status)) { 165 goto error_exit; 166 } 167 } 168 169 /* Build the final pathname */ 170 171 if (acpi_ut_safe_strcat 172 (acpi_gbl_db_scope_buf, sizeof(acpi_gbl_db_scope_buf), name)) { 173 status = AE_BUFFER_OVERFLOW; 174 goto error_exit; 175 } 176 177 if (acpi_ut_safe_strcat 178 (acpi_gbl_db_scope_buf, sizeof(acpi_gbl_db_scope_buf), "\\")) { 179 status = AE_BUFFER_OVERFLOW; 180 goto error_exit; 181 } 182 183 acpi_gbl_db_scope_node = node; 184 acpi_os_printf("New scope: %s\n", acpi_gbl_db_scope_buf); 185 return; 186 187 error_exit: 188 189 acpi_os_printf("Could not attach scope: %s, %s\n", 190 name, acpi_format_exception(status)); 191 } 192 193 /******************************************************************************* 194 * 195 * FUNCTION: acpi_db_dump_namespace 196 * 197 * PARAMETERS: start_arg - Node to begin namespace dump 198 * depth_arg - Maximum tree depth to be dumped 199 * 200 * RETURN: None 201 * 202 * DESCRIPTION: Dump entire namespace or a subtree. Each node is displayed 203 * with type and other information. 204 * 205 ******************************************************************************/ 206 207 void acpi_db_dump_namespace(char *start_arg, char *depth_arg) 208 { 209 acpi_handle subtree_entry = acpi_gbl_root_node; 210 u32 max_depth = ACPI_UINT32_MAX; 211 212 /* No argument given, just start at the root and dump entire namespace */ 213 214 if (start_arg) { 215 subtree_entry = acpi_db_convert_to_node(start_arg); 216 if (!subtree_entry) { 217 return; 218 } 219 220 /* Now we can check for the depth argument */ 221 222 if (depth_arg) { 223 max_depth = strtoul(depth_arg, NULL, 0); 224 } 225 } 226 227 acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT); 228 acpi_os_printf("ACPI Namespace (from %4.4s (%p) subtree):\n", 229 ((struct acpi_namespace_node *)subtree_entry)->name. 230 ascii, subtree_entry); 231 232 /* Display the subtree */ 233 234 acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT); 235 acpi_ns_dump_objects(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, max_depth, 236 ACPI_OWNER_ID_MAX, subtree_entry); 237 acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT); 238 } 239 240 /******************************************************************************* 241 * 242 * FUNCTION: acpi_db_dump_namespace_paths 243 * 244 * PARAMETERS: None 245 * 246 * RETURN: None 247 * 248 * DESCRIPTION: Dump entire namespace with full object pathnames and object 249 * type information. Alternative to "namespace" command. 250 * 251 ******************************************************************************/ 252 253 void acpi_db_dump_namespace_paths(void) 254 { 255 256 acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT); 257 acpi_os_printf("ACPI Namespace (from root):\n"); 258 259 /* Display the entire namespace */ 260 261 acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT); 262 acpi_ns_dump_object_paths(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, 263 ACPI_UINT32_MAX, ACPI_OWNER_ID_MAX, 264 acpi_gbl_root_node); 265 266 acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT); 267 } 268 269 /******************************************************************************* 270 * 271 * FUNCTION: acpi_db_dump_namespace_by_owner 272 * 273 * PARAMETERS: owner_arg - Owner ID whose nodes will be displayed 274 * depth_arg - Maximum tree depth to be dumped 275 * 276 * RETURN: None 277 * 278 * DESCRIPTION: Dump elements of the namespace that are owned by the owner_id. 279 * 280 ******************************************************************************/ 281 282 void acpi_db_dump_namespace_by_owner(char *owner_arg, char *depth_arg) 283 { 284 acpi_handle subtree_entry = acpi_gbl_root_node; 285 u32 max_depth = ACPI_UINT32_MAX; 286 acpi_owner_id owner_id; 287 288 owner_id = (acpi_owner_id)strtoul(owner_arg, NULL, 0); 289 290 /* Now we can check for the depth argument */ 291 292 if (depth_arg) { 293 max_depth = strtoul(depth_arg, NULL, 0); 294 } 295 296 acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT); 297 acpi_os_printf("ACPI Namespace by owner %X:\n", owner_id); 298 299 /* Display the subtree */ 300 301 acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT); 302 acpi_ns_dump_objects(ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, max_depth, 303 owner_id, subtree_entry); 304 acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT); 305 } 306 307 /******************************************************************************* 308 * 309 * FUNCTION: acpi_db_walk_and_match_name 310 * 311 * PARAMETERS: Callback from walk_namespace 312 * 313 * RETURN: Status 314 * 315 * DESCRIPTION: Find a particular name/names within the namespace. Wildcards 316 * are supported -- '?' matches any character. 317 * 318 ******************************************************************************/ 319 320 static acpi_status 321 acpi_db_walk_and_match_name(acpi_handle obj_handle, 322 u32 nesting_level, 323 void *context, void **return_value) 324 { 325 acpi_status status; 326 char *requested_name = (char *)context; 327 u32 i; 328 struct acpi_buffer buffer; 329 struct acpi_walk_info info; 330 331 /* Check for a name match */ 332 333 for (i = 0; i < 4; i++) { 334 335 /* Wildcard support */ 336 337 if ((requested_name[i] != '?') && 338 (requested_name[i] != ((struct acpi_namespace_node *) 339 obj_handle)->name.ascii[i])) { 340 341 /* No match, just exit */ 342 343 return (AE_OK); 344 } 345 } 346 347 /* Get the full pathname to this object */ 348 349 buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; 350 status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE); 351 if (ACPI_FAILURE(status)) { 352 acpi_os_printf("Could Not get pathname for object %p\n", 353 obj_handle); 354 } else { 355 info.owner_id = ACPI_OWNER_ID_MAX; 356 info.debug_level = ACPI_UINT32_MAX; 357 info.display_type = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT; 358 359 acpi_os_printf("%32s", (char *)buffer.pointer); 360 (void)acpi_ns_dump_one_object(obj_handle, nesting_level, &info, 361 NULL); 362 ACPI_FREE(buffer.pointer); 363 } 364 365 return (AE_OK); 366 } 367 368 /******************************************************************************* 369 * 370 * FUNCTION: acpi_db_find_name_in_namespace 371 * 372 * PARAMETERS: name_arg - The 4-character ACPI name to find. 373 * wildcards are supported. 374 * 375 * RETURN: None 376 * 377 * DESCRIPTION: Search the namespace for a given name (with wildcards) 378 * 379 ******************************************************************************/ 380 381 acpi_status acpi_db_find_name_in_namespace(char *name_arg) 382 { 383 char acpi_name[5] = "____"; 384 char *acpi_name_ptr = acpi_name; 385 386 if (strlen(name_arg) > ACPI_NAME_SIZE) { 387 acpi_os_printf("Name must be no longer than 4 characters\n"); 388 return (AE_OK); 389 } 390 391 /* Pad out name with underscores as necessary to create a 4-char name */ 392 393 acpi_ut_strupr(name_arg); 394 while (*name_arg) { 395 *acpi_name_ptr = *name_arg; 396 acpi_name_ptr++; 397 name_arg++; 398 } 399 400 /* Walk the namespace from the root */ 401 402 (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 403 ACPI_UINT32_MAX, acpi_db_walk_and_match_name, 404 NULL, acpi_name, NULL); 405 406 acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT); 407 return (AE_OK); 408 } 409 410 /******************************************************************************* 411 * 412 * FUNCTION: acpi_db_walk_for_predefined_names 413 * 414 * PARAMETERS: Callback from walk_namespace 415 * 416 * RETURN: Status 417 * 418 * DESCRIPTION: Detect and display predefined ACPI names (names that start with 419 * an underscore) 420 * 421 ******************************************************************************/ 422 423 static acpi_status 424 acpi_db_walk_for_predefined_names(acpi_handle obj_handle, 425 u32 nesting_level, 426 void *context, void **return_value) 427 { 428 struct acpi_namespace_node *node = 429 (struct acpi_namespace_node *)obj_handle; 430 u32 *count = (u32 *)context; 431 const union acpi_predefined_info *predefined; 432 const union acpi_predefined_info *package = NULL; 433 char *pathname; 434 char string_buffer[48]; 435 436 predefined = acpi_ut_match_predefined_method(node->name.ascii); 437 if (!predefined) { 438 return (AE_OK); 439 } 440 441 pathname = acpi_ns_get_normalized_pathname(node, TRUE); 442 if (!pathname) { 443 return (AE_OK); 444 } 445 446 /* If method returns a package, the info is in the next table entry */ 447 448 if (predefined->info.expected_btypes & ACPI_RTYPE_PACKAGE) { 449 package = predefined + 1; 450 } 451 452 acpi_ut_get_expected_return_types(string_buffer, 453 predefined->info.expected_btypes); 454 455 acpi_os_printf("%-32s Arguments %X, Return Types: %s", pathname, 456 METHOD_GET_ARG_COUNT(predefined->info.argument_list), 457 string_buffer); 458 459 if (package) { 460 acpi_os_printf(" (PkgType %2.2X, ObjType %2.2X, Count %2.2X)", 461 package->ret_info.type, 462 package->ret_info.object_type1, 463 package->ret_info.count1); 464 } 465 466 acpi_os_printf("\n"); 467 468 /* Check that the declared argument count matches the ACPI spec */ 469 470 acpi_ns_check_acpi_compliance(pathname, node, predefined); 471 472 ACPI_FREE(pathname); 473 (*count)++; 474 return (AE_OK); 475 } 476 477 /******************************************************************************* 478 * 479 * FUNCTION: acpi_db_check_predefined_names 480 * 481 * PARAMETERS: None 482 * 483 * RETURN: None 484 * 485 * DESCRIPTION: Validate all predefined names in the namespace 486 * 487 ******************************************************************************/ 488 489 void acpi_db_check_predefined_names(void) 490 { 491 u32 count = 0; 492 493 /* Search all nodes in namespace */ 494 495 (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 496 ACPI_UINT32_MAX, 497 acpi_db_walk_for_predefined_names, NULL, 498 (void *)&count, NULL); 499 500 acpi_os_printf("Found %u predefined names in the namespace\n", count); 501 } 502 503 /******************************************************************************* 504 * 505 * FUNCTION: acpi_db_walk_for_object_counts 506 * 507 * PARAMETERS: Callback from walk_namespace 508 * 509 * RETURN: Status 510 * 511 * DESCRIPTION: Display short info about objects in the namespace 512 * 513 ******************************************************************************/ 514 515 static acpi_status 516 acpi_db_walk_for_object_counts(acpi_handle obj_handle, 517 u32 nesting_level, 518 void *context, void **return_value) 519 { 520 struct acpi_object_info *info = (struct acpi_object_info *)context; 521 struct acpi_namespace_node *node = 522 (struct acpi_namespace_node *)obj_handle; 523 524 if (node->type > ACPI_TYPE_NS_NODE_MAX) { 525 acpi_os_printf("[%4.4s]: Unknown object type %X\n", 526 node->name.ascii, node->type); 527 } else { 528 info->types[node->type]++; 529 } 530 531 return (AE_OK); 532 } 533 534 /******************************************************************************* 535 * 536 * FUNCTION: acpi_db_walk_for_specific_objects 537 * 538 * PARAMETERS: Callback from walk_namespace 539 * 540 * RETURN: Status 541 * 542 * DESCRIPTION: Display short info about objects in the namespace 543 * 544 ******************************************************************************/ 545 546 static acpi_status 547 acpi_db_walk_for_specific_objects(acpi_handle obj_handle, 548 u32 nesting_level, 549 void *context, void **return_value) 550 { 551 struct acpi_walk_info *info = (struct acpi_walk_info *)context; 552 struct acpi_buffer buffer; 553 acpi_status status; 554 555 info->count++; 556 557 /* Get and display the full pathname to this object */ 558 559 buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; 560 status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE); 561 if (ACPI_FAILURE(status)) { 562 acpi_os_printf("Could Not get pathname for object %p\n", 563 obj_handle); 564 return (AE_OK); 565 } 566 567 acpi_os_printf("%32s", (char *)buffer.pointer); 568 ACPI_FREE(buffer.pointer); 569 570 /* Dump short info about the object */ 571 572 (void)acpi_ns_dump_one_object(obj_handle, nesting_level, info, NULL); 573 return (AE_OK); 574 } 575 576 /******************************************************************************* 577 * 578 * FUNCTION: acpi_db_display_objects 579 * 580 * PARAMETERS: obj_type_arg - Type of object to display 581 * display_count_arg - Max depth to display 582 * 583 * RETURN: None 584 * 585 * DESCRIPTION: Display objects in the namespace of the requested type 586 * 587 ******************************************************************************/ 588 589 acpi_status acpi_db_display_objects(char *obj_type_arg, char *display_count_arg) 590 { 591 struct acpi_walk_info info; 592 acpi_object_type type; 593 struct acpi_object_info *object_info; 594 u32 i; 595 u32 total_objects = 0; 596 597 /* No argument means display summary/count of all object types */ 598 599 if (!obj_type_arg) { 600 object_info = 601 ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_object_info)); 602 603 /* Walk the namespace from the root */ 604 605 (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 606 ACPI_UINT32_MAX, 607 acpi_db_walk_for_object_counts, NULL, 608 (void *)object_info, NULL); 609 610 acpi_os_printf("\nSummary of namespace objects:\n\n"); 611 612 for (i = 0; i < ACPI_TOTAL_TYPES; i++) { 613 acpi_os_printf("%8u %s\n", object_info->types[i], 614 acpi_ut_get_type_name(i)); 615 616 total_objects += object_info->types[i]; 617 } 618 619 acpi_os_printf("\n%8u Total namespace objects\n\n", 620 total_objects); 621 622 ACPI_FREE(object_info); 623 return (AE_OK); 624 } 625 626 /* Get the object type */ 627 628 type = acpi_db_match_argument(obj_type_arg, acpi_db_object_types); 629 if (type == ACPI_TYPE_NOT_FOUND) { 630 acpi_os_printf("Invalid or unsupported argument\n"); 631 return (AE_OK); 632 } 633 634 acpi_db_set_output_destination(ACPI_DB_DUPLICATE_OUTPUT); 635 acpi_os_printf 636 ("Objects of type [%s] defined in the current ACPI Namespace:\n", 637 acpi_ut_get_type_name(type)); 638 639 acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT); 640 641 info.count = 0; 642 info.owner_id = ACPI_OWNER_ID_MAX; 643 info.debug_level = ACPI_UINT32_MAX; 644 info.display_type = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT; 645 646 /* Walk the namespace from the root */ 647 648 (void)acpi_walk_namespace(type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, 649 acpi_db_walk_for_specific_objects, NULL, 650 (void *)&info, NULL); 651 652 acpi_os_printf 653 ("\nFound %u objects of type [%s] in the current ACPI Namespace\n", 654 info.count, acpi_ut_get_type_name(type)); 655 656 acpi_db_set_output_destination(ACPI_DB_CONSOLE_OUTPUT); 657 return (AE_OK); 658 } 659 660 /******************************************************************************* 661 * 662 * FUNCTION: acpi_db_integrity_walk 663 * 664 * PARAMETERS: Callback from walk_namespace 665 * 666 * RETURN: Status 667 * 668 * DESCRIPTION: Examine one NS node for valid values. 669 * 670 ******************************************************************************/ 671 672 static acpi_status 673 acpi_db_integrity_walk(acpi_handle obj_handle, 674 u32 nesting_level, void *context, void **return_value) 675 { 676 struct acpi_integrity_info *info = 677 (struct acpi_integrity_info *)context; 678 struct acpi_namespace_node *node = 679 (struct acpi_namespace_node *)obj_handle; 680 union acpi_operand_object *object; 681 u8 alias = TRUE; 682 683 info->nodes++; 684 685 /* Verify the NS node, and dereference aliases */ 686 687 while (alias) { 688 if (ACPI_GET_DESCRIPTOR_TYPE(node) != ACPI_DESC_TYPE_NAMED) { 689 acpi_os_printf 690 ("Invalid Descriptor Type for Node %p [%s] - " 691 "is %2.2X should be %2.2X\n", node, 692 acpi_ut_get_descriptor_name(node), 693 ACPI_GET_DESCRIPTOR_TYPE(node), 694 ACPI_DESC_TYPE_NAMED); 695 return (AE_OK); 696 } 697 698 if ((node->type == ACPI_TYPE_LOCAL_ALIAS) || 699 (node->type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) { 700 node = (struct acpi_namespace_node *)node->object; 701 } else { 702 alias = FALSE; 703 } 704 } 705 706 if (node->type > ACPI_TYPE_LOCAL_MAX) { 707 acpi_os_printf("Invalid Object Type for Node %p, Type = %X\n", 708 node, node->type); 709 return (AE_OK); 710 } 711 712 if (!acpi_ut_valid_nameseg(node->name.ascii)) { 713 acpi_os_printf("Invalid AcpiName for Node %p\n", node); 714 return (AE_OK); 715 } 716 717 object = acpi_ns_get_attached_object(node); 718 if (object) { 719 info->objects++; 720 if (ACPI_GET_DESCRIPTOR_TYPE(object) != ACPI_DESC_TYPE_OPERAND) { 721 acpi_os_printf 722 ("Invalid Descriptor Type for Object %p [%s]\n", 723 object, acpi_ut_get_descriptor_name(object)); 724 } 725 } 726 727 return (AE_OK); 728 } 729 730 /******************************************************************************* 731 * 732 * FUNCTION: acpi_db_check_integrity 733 * 734 * PARAMETERS: None 735 * 736 * RETURN: None 737 * 738 * DESCRIPTION: Check entire namespace for data structure integrity 739 * 740 ******************************************************************************/ 741 742 void acpi_db_check_integrity(void) 743 { 744 struct acpi_integrity_info info = { 0, 0 }; 745 746 /* Search all nodes in namespace */ 747 748 (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 749 ACPI_UINT32_MAX, acpi_db_integrity_walk, NULL, 750 (void *)&info, NULL); 751 752 acpi_os_printf("Verified %u namespace nodes with %u Objects\n", 753 info.nodes, info.objects); 754 } 755 756 /******************************************************************************* 757 * 758 * FUNCTION: acpi_db_walk_for_references 759 * 760 * PARAMETERS: Callback from walk_namespace 761 * 762 * RETURN: Status 763 * 764 * DESCRIPTION: Check if this namespace object refers to the target object 765 * that is passed in as the context value. 766 * 767 * Note: Currently doesn't check subobjects within the Node's object 768 * 769 ******************************************************************************/ 770 771 static acpi_status 772 acpi_db_walk_for_references(acpi_handle obj_handle, 773 u32 nesting_level, 774 void *context, void **return_value) 775 { 776 union acpi_operand_object *obj_desc = 777 (union acpi_operand_object *)context; 778 struct acpi_namespace_node *node = 779 (struct acpi_namespace_node *)obj_handle; 780 781 /* Check for match against the namespace node itself */ 782 783 if (node == (void *)obj_desc) { 784 acpi_os_printf("Object is a Node [%4.4s]\n", 785 acpi_ut_get_node_name(node)); 786 } 787 788 /* Check for match against the object attached to the node */ 789 790 if (acpi_ns_get_attached_object(node) == obj_desc) { 791 acpi_os_printf("Reference at Node->Object %p [%4.4s]\n", 792 node, acpi_ut_get_node_name(node)); 793 } 794 795 return (AE_OK); 796 } 797 798 /******************************************************************************* 799 * 800 * FUNCTION: acpi_db_find_references 801 * 802 * PARAMETERS: object_arg - String with hex value of the object 803 * 804 * RETURN: None 805 * 806 * DESCRIPTION: Search namespace for all references to the input object 807 * 808 ******************************************************************************/ 809 810 void acpi_db_find_references(char *object_arg) 811 { 812 union acpi_operand_object *obj_desc; 813 acpi_size address; 814 815 /* Convert string to object pointer */ 816 817 address = strtoul(object_arg, NULL, 16); 818 obj_desc = ACPI_TO_POINTER(address); 819 820 /* Search all nodes in namespace */ 821 822 (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 823 ACPI_UINT32_MAX, acpi_db_walk_for_references, 824 NULL, (void *)obj_desc, NULL); 825 } 826 827 /******************************************************************************* 828 * 829 * FUNCTION: acpi_db_bus_walk 830 * 831 * PARAMETERS: Callback from walk_namespace 832 * 833 * RETURN: Status 834 * 835 * DESCRIPTION: Display info about device objects that have a corresponding 836 * _PRT method. 837 * 838 ******************************************************************************/ 839 840 static acpi_status 841 acpi_db_bus_walk(acpi_handle obj_handle, 842 u32 nesting_level, void *context, void **return_value) 843 { 844 struct acpi_namespace_node *node = 845 (struct acpi_namespace_node *)obj_handle; 846 acpi_status status; 847 struct acpi_buffer buffer; 848 struct acpi_namespace_node *temp_node; 849 struct acpi_device_info *info; 850 u32 i; 851 852 if ((node->type != ACPI_TYPE_DEVICE) && 853 (node->type != ACPI_TYPE_PROCESSOR)) { 854 return (AE_OK); 855 } 856 857 /* Exit if there is no _PRT under this device */ 858 859 status = acpi_get_handle(node, METHOD_NAME__PRT, 860 ACPI_CAST_PTR(acpi_handle, &temp_node)); 861 if (ACPI_FAILURE(status)) { 862 return (AE_OK); 863 } 864 865 /* Get the full path to this device object */ 866 867 buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; 868 status = acpi_ns_handle_to_pathname(obj_handle, &buffer, TRUE); 869 if (ACPI_FAILURE(status)) { 870 acpi_os_printf("Could Not get pathname for object %p\n", 871 obj_handle); 872 return (AE_OK); 873 } 874 875 status = acpi_get_object_info(obj_handle, &info); 876 if (ACPI_FAILURE(status)) { 877 return (AE_OK); 878 } 879 880 /* Display the full path */ 881 882 acpi_os_printf("%-32s Type %X", (char *)buffer.pointer, node->type); 883 ACPI_FREE(buffer.pointer); 884 885 if (info->flags & ACPI_PCI_ROOT_BRIDGE) { 886 acpi_os_printf(" - Is PCI Root Bridge"); 887 } 888 acpi_os_printf("\n"); 889 890 /* _PRT info */ 891 892 acpi_os_printf("_PRT: %p\n", temp_node); 893 894 /* Dump _ADR, _HID, _UID, _CID */ 895 896 if (info->valid & ACPI_VALID_ADR) { 897 acpi_os_printf("_ADR: %8.8X%8.8X\n", 898 ACPI_FORMAT_UINT64(info->address)); 899 } else { 900 acpi_os_printf("_ADR: <Not Present>\n"); 901 } 902 903 if (info->valid & ACPI_VALID_HID) { 904 acpi_os_printf("_HID: %s\n", info->hardware_id.string); 905 } else { 906 acpi_os_printf("_HID: <Not Present>\n"); 907 } 908 909 if (info->valid & ACPI_VALID_UID) { 910 acpi_os_printf("_UID: %s\n", info->unique_id.string); 911 } else { 912 acpi_os_printf("_UID: <Not Present>\n"); 913 } 914 915 if (info->valid & ACPI_VALID_CID) { 916 for (i = 0; i < info->compatible_id_list.count; i++) { 917 acpi_os_printf("_CID: %s\n", 918 info->compatible_id_list.ids[i].string); 919 } 920 } else { 921 acpi_os_printf("_CID: <Not Present>\n"); 922 } 923 924 ACPI_FREE(info); 925 return (AE_OK); 926 } 927 928 /******************************************************************************* 929 * 930 * FUNCTION: acpi_db_get_bus_info 931 * 932 * PARAMETERS: None 933 * 934 * RETURN: None 935 * 936 * DESCRIPTION: Display info about system busses. 937 * 938 ******************************************************************************/ 939 940 void acpi_db_get_bus_info(void) 941 { 942 /* Search all nodes in namespace */ 943 944 (void)acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 945 ACPI_UINT32_MAX, acpi_db_bus_walk, NULL, NULL, 946 NULL); 947 } 948