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