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