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