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