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