1 /******************************************************************************* 2 * 3 * Module Name: dbnames - Debugger commands for the acpi namespace 4 * 5 ******************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2016, 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 = AcpiNsGetNormalizedPathname (Node, TRUE); 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, 566 NULL, (void *) &Count, NULL); 567 568 AcpiOsPrintf ("Found %u predefined names in the namespace\n", Count); 569 } 570 571 572 /******************************************************************************* 573 * 574 * FUNCTION: AcpiDbWalkForObjectCounts 575 * 576 * PARAMETERS: Callback from WalkNamespace 577 * 578 * RETURN: Status 579 * 580 * DESCRIPTION: Display short info about objects in the namespace 581 * 582 ******************************************************************************/ 583 584 static ACPI_STATUS 585 AcpiDbWalkForObjectCounts ( 586 ACPI_HANDLE ObjHandle, 587 UINT32 NestingLevel, 588 void *Context, 589 void **ReturnValue) 590 { 591 ACPI_OBJECT_INFO *Info = (ACPI_OBJECT_INFO *) Context; 592 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 593 594 595 if (Node->Type > ACPI_TYPE_NS_NODE_MAX) 596 { 597 AcpiOsPrintf ("[%4.4s]: Unknown object type %X\n", 598 Node->Name.Ascii, Node->Type); 599 } 600 else 601 { 602 Info->Types[Node->Type]++; 603 } 604 605 return (AE_OK); 606 } 607 608 609 /******************************************************************************* 610 * 611 * FUNCTION: AcpiDbWalkForSpecificObjects 612 * 613 * PARAMETERS: Callback from WalkNamespace 614 * 615 * RETURN: Status 616 * 617 * DESCRIPTION: Display short info about objects in the namespace 618 * 619 ******************************************************************************/ 620 621 static ACPI_STATUS 622 AcpiDbWalkForSpecificObjects ( 623 ACPI_HANDLE ObjHandle, 624 UINT32 NestingLevel, 625 void *Context, 626 void **ReturnValue) 627 { 628 ACPI_WALK_INFO *Info = (ACPI_WALK_INFO *) Context; 629 ACPI_BUFFER Buffer; 630 ACPI_STATUS Status; 631 632 633 Info->Count++; 634 635 /* Get and display the full pathname to this object */ 636 637 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 638 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer, TRUE); 639 if (ACPI_FAILURE (Status)) 640 { 641 AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle); 642 return (AE_OK); 643 } 644 645 AcpiOsPrintf ("%32s", (char *) Buffer.Pointer); 646 ACPI_FREE (Buffer.Pointer); 647 648 /* Dump short info about the object */ 649 650 (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, Info, NULL); 651 return (AE_OK); 652 } 653 654 655 /******************************************************************************* 656 * 657 * FUNCTION: AcpiDbDisplayObjects 658 * 659 * PARAMETERS: ObjTypeArg - Type of object to display 660 * DisplayCountArg - Max depth to display 661 * 662 * RETURN: None 663 * 664 * DESCRIPTION: Display objects in the namespace of the requested type 665 * 666 ******************************************************************************/ 667 668 ACPI_STATUS 669 AcpiDbDisplayObjects ( 670 char *ObjTypeArg, 671 char *DisplayCountArg) 672 { 673 ACPI_WALK_INFO Info; 674 ACPI_OBJECT_TYPE Type; 675 ACPI_OBJECT_INFO *ObjectInfo; 676 UINT32 i; 677 UINT32 TotalObjects = 0; 678 679 680 /* No argument means display summary/count of all object types */ 681 682 if (!ObjTypeArg) 683 { 684 ObjectInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_OBJECT_INFO)); 685 686 /* Walk the namespace from the root */ 687 688 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 689 ACPI_UINT32_MAX, AcpiDbWalkForObjectCounts, NULL, 690 (void *) ObjectInfo, NULL); 691 692 AcpiOsPrintf ("\nSummary of namespace objects:\n\n"); 693 694 for (i = 0; i < ACPI_TOTAL_TYPES; i++) 695 { 696 AcpiOsPrintf ("%8u %s\n", ObjectInfo->Types[i], 697 AcpiUtGetTypeName (i)); 698 699 TotalObjects += ObjectInfo->Types[i]; 700 } 701 702 AcpiOsPrintf ("\n%8u Total namespace objects\n\n", 703 TotalObjects); 704 705 ACPI_FREE (ObjectInfo); 706 return (AE_OK); 707 } 708 709 /* Get the object type */ 710 711 Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes); 712 if (Type == ACPI_TYPE_NOT_FOUND) 713 { 714 AcpiOsPrintf ("Invalid or unsupported argument\n"); 715 return (AE_OK); 716 } 717 718 AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 719 AcpiOsPrintf ( 720 "Objects of type [%s] defined in the current ACPI Namespace:\n", 721 AcpiUtGetTypeName (Type)); 722 723 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 724 725 Info.Count = 0; 726 Info.OwnerId = ACPI_OWNER_ID_MAX; 727 Info.DebugLevel = ACPI_UINT32_MAX; 728 Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT; 729 730 /* Walk the namespace from the root */ 731 732 (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, 733 AcpiDbWalkForSpecificObjects, NULL, (void *) &Info, NULL); 734 735 AcpiOsPrintf ( 736 "\nFound %u objects of type [%s] in the current ACPI Namespace\n", 737 Info.Count, AcpiUtGetTypeName (Type)); 738 739 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 740 return (AE_OK); 741 } 742 743 744 /******************************************************************************* 745 * 746 * FUNCTION: AcpiDbIntegrityWalk 747 * 748 * PARAMETERS: Callback from WalkNamespace 749 * 750 * RETURN: Status 751 * 752 * DESCRIPTION: Examine one NS node for valid values. 753 * 754 ******************************************************************************/ 755 756 static ACPI_STATUS 757 AcpiDbIntegrityWalk ( 758 ACPI_HANDLE ObjHandle, 759 UINT32 NestingLevel, 760 void *Context, 761 void **ReturnValue) 762 { 763 ACPI_INTEGRITY_INFO *Info = (ACPI_INTEGRITY_INFO *) Context; 764 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 765 ACPI_OPERAND_OBJECT *Object; 766 BOOLEAN Alias = TRUE; 767 768 769 Info->Nodes++; 770 771 /* Verify the NS node, and dereference aliases */ 772 773 while (Alias) 774 { 775 if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED) 776 { 777 AcpiOsPrintf ( 778 "Invalid Descriptor Type for Node %p [%s] - " 779 "is %2.2X should be %2.2X\n", 780 Node, AcpiUtGetDescriptorName (Node), 781 ACPI_GET_DESCRIPTOR_TYPE (Node), ACPI_DESC_TYPE_NAMED); 782 return (AE_OK); 783 } 784 785 if ((Node->Type == ACPI_TYPE_LOCAL_ALIAS) || 786 (Node->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) 787 { 788 Node = (ACPI_NAMESPACE_NODE *) Node->Object; 789 } 790 else 791 { 792 Alias = FALSE; 793 } 794 } 795 796 if (Node->Type > ACPI_TYPE_LOCAL_MAX) 797 { 798 AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n", 799 Node, Node->Type); 800 return (AE_OK); 801 } 802 803 if (!AcpiUtValidNameseg (Node->Name.Ascii)) 804 { 805 AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node); 806 return (AE_OK); 807 } 808 809 Object = AcpiNsGetAttachedObject (Node); 810 if (Object) 811 { 812 Info->Objects++; 813 if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND) 814 { 815 AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n", 816 Object, AcpiUtGetDescriptorName (Object)); 817 } 818 } 819 820 return (AE_OK); 821 } 822 823 824 /******************************************************************************* 825 * 826 * FUNCTION: AcpiDbCheckIntegrity 827 * 828 * PARAMETERS: None 829 * 830 * RETURN: None 831 * 832 * DESCRIPTION: Check entire namespace for data structure integrity 833 * 834 ******************************************************************************/ 835 836 void 837 AcpiDbCheckIntegrity ( 838 void) 839 { 840 ACPI_INTEGRITY_INFO Info = {0,0}; 841 842 /* Search all nodes in namespace */ 843 844 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 845 ACPI_UINT32_MAX, AcpiDbIntegrityWalk, NULL, (void *) &Info, NULL); 846 847 AcpiOsPrintf ("Verified %u namespace nodes with %u Objects\n", 848 Info.Nodes, Info.Objects); 849 } 850 851 852 /******************************************************************************* 853 * 854 * FUNCTION: AcpiDbWalkForReferences 855 * 856 * PARAMETERS: Callback from WalkNamespace 857 * 858 * RETURN: Status 859 * 860 * DESCRIPTION: Check if this namespace object refers to the target object 861 * that is passed in as the context value. 862 * 863 * Note: Currently doesn't check subobjects within the Node's object 864 * 865 ******************************************************************************/ 866 867 static ACPI_STATUS 868 AcpiDbWalkForReferences ( 869 ACPI_HANDLE ObjHandle, 870 UINT32 NestingLevel, 871 void *Context, 872 void **ReturnValue) 873 { 874 ACPI_OPERAND_OBJECT *ObjDesc = (ACPI_OPERAND_OBJECT *) Context; 875 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 876 877 878 /* Check for match against the namespace node itself */ 879 880 if (Node == (void *) ObjDesc) 881 { 882 AcpiOsPrintf ("Object is a Node [%4.4s]\n", 883 AcpiUtGetNodeName (Node)); 884 } 885 886 /* Check for match against the object attached to the node */ 887 888 if (AcpiNsGetAttachedObject (Node) == ObjDesc) 889 { 890 AcpiOsPrintf ("Reference at Node->Object %p [%4.4s]\n", 891 Node, AcpiUtGetNodeName (Node)); 892 } 893 894 return (AE_OK); 895 } 896 897 898 /******************************************************************************* 899 * 900 * FUNCTION: AcpiDbFindReferences 901 * 902 * PARAMETERS: ObjectArg - String with hex value of the object 903 * 904 * RETURN: None 905 * 906 * DESCRIPTION: Search namespace for all references to the input object 907 * 908 ******************************************************************************/ 909 910 void 911 AcpiDbFindReferences ( 912 char *ObjectArg) 913 { 914 ACPI_OPERAND_OBJECT *ObjDesc; 915 ACPI_SIZE Address; 916 917 918 /* Convert string to object pointer */ 919 920 Address = strtoul (ObjectArg, NULL, 16); 921 ObjDesc = ACPI_TO_POINTER (Address); 922 923 /* Search all nodes in namespace */ 924 925 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 926 ACPI_UINT32_MAX, AcpiDbWalkForReferences, NULL, 927 (void *) ObjDesc, NULL); 928 } 929 930 931 /******************************************************************************* 932 * 933 * FUNCTION: AcpiDbBusWalk 934 * 935 * PARAMETERS: Callback from WalkNamespace 936 * 937 * RETURN: Status 938 * 939 * DESCRIPTION: Display info about device objects that have a corresponding 940 * _PRT method. 941 * 942 ******************************************************************************/ 943 944 static ACPI_STATUS 945 AcpiDbBusWalk ( 946 ACPI_HANDLE ObjHandle, 947 UINT32 NestingLevel, 948 void *Context, 949 void **ReturnValue) 950 { 951 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 952 ACPI_STATUS Status; 953 ACPI_BUFFER Buffer; 954 ACPI_NAMESPACE_NODE *TempNode; 955 ACPI_DEVICE_INFO *Info; 956 UINT32 i; 957 958 959 if ((Node->Type != ACPI_TYPE_DEVICE) && 960 (Node->Type != ACPI_TYPE_PROCESSOR)) 961 { 962 return (AE_OK); 963 } 964 965 /* Exit if there is no _PRT under this device */ 966 967 Status = AcpiGetHandle (Node, METHOD_NAME__PRT, 968 ACPI_CAST_PTR (ACPI_HANDLE, &TempNode)); 969 if (ACPI_FAILURE (Status)) 970 { 971 return (AE_OK); 972 } 973 974 /* Get the full path to this device object */ 975 976 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 977 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer, TRUE); 978 if (ACPI_FAILURE (Status)) 979 { 980 AcpiOsPrintf ("Could Not get pathname for object %p\n", 981 ObjHandle); 982 return (AE_OK); 983 } 984 985 Status = AcpiGetObjectInfo (ObjHandle, &Info); 986 if (ACPI_FAILURE (Status)) 987 { 988 return (AE_OK); 989 } 990 991 /* Display the full path */ 992 993 AcpiOsPrintf ("%-32s Type %X", (char *) Buffer.Pointer, Node->Type); 994 ACPI_FREE (Buffer.Pointer); 995 996 if (Info->Flags & ACPI_PCI_ROOT_BRIDGE) 997 { 998 AcpiOsPrintf (" - Is PCI Root Bridge"); 999 } 1000 AcpiOsPrintf ("\n"); 1001 1002 /* _PRT info */ 1003 1004 AcpiOsPrintf ("_PRT: %p\n", TempNode); 1005 1006 /* Dump _ADR, _HID, _UID, _CID */ 1007 1008 if (Info->Valid & ACPI_VALID_ADR) 1009 { 1010 AcpiOsPrintf ("_ADR: %8.8X%8.8X\n", 1011 ACPI_FORMAT_UINT64 (Info->Address)); 1012 } 1013 else 1014 { 1015 AcpiOsPrintf ("_ADR: <Not Present>\n"); 1016 } 1017 1018 if (Info->Valid & ACPI_VALID_HID) 1019 { 1020 AcpiOsPrintf ("_HID: %s\n", Info->HardwareId.String); 1021 } 1022 else 1023 { 1024 AcpiOsPrintf ("_HID: <Not Present>\n"); 1025 } 1026 1027 if (Info->Valid & ACPI_VALID_UID) 1028 { 1029 AcpiOsPrintf ("_UID: %s\n", Info->UniqueId.String); 1030 } 1031 else 1032 { 1033 AcpiOsPrintf ("_UID: <Not Present>\n"); 1034 } 1035 1036 if (Info->Valid & ACPI_VALID_CID) 1037 { 1038 for (i = 0; i < Info->CompatibleIdList.Count; i++) 1039 { 1040 AcpiOsPrintf ("_CID: %s\n", 1041 Info->CompatibleIdList.Ids[i].String); 1042 } 1043 } 1044 else 1045 { 1046 AcpiOsPrintf ("_CID: <Not Present>\n"); 1047 } 1048 1049 ACPI_FREE (Info); 1050 return (AE_OK); 1051 } 1052 1053 1054 /******************************************************************************* 1055 * 1056 * FUNCTION: AcpiDbGetBusInfo 1057 * 1058 * PARAMETERS: None 1059 * 1060 * RETURN: None 1061 * 1062 * DESCRIPTION: Display info about system busses. 1063 * 1064 ******************************************************************************/ 1065 1066 void 1067 AcpiDbGetBusInfo ( 1068 void) 1069 { 1070 /* Search all nodes in namespace */ 1071 1072 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 1073 ACPI_UINT32_MAX, AcpiDbBusWalk, NULL, NULL, NULL); 1074 } 1075 1076 #endif /* ACPI_DEBUGGER */ 1077