1 /******************************************************************************* 2 * 3 * Module Name: dbnames - Debugger commands for the acpi namespace 4 * 5 ******************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2021, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 ***************************************************************************** 115 * 116 * Alternatively, you may choose to be licensed under the terms of the 117 * following license: 118 * 119 * Redistribution and use in source and binary forms, with or without 120 * modification, are permitted provided that the following conditions 121 * are met: 122 * 1. Redistributions of source code must retain the above copyright 123 * notice, this list of conditions, and the following disclaimer, 124 * without modification. 125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126 * substantially similar to the "NO WARRANTY" disclaimer below 127 * ("Disclaimer") and any redistribution must be conditioned upon 128 * including a substantially similar Disclaimer requirement for further 129 * binary redistribution. 130 * 3. Neither the names of the above-listed copyright holders nor the names 131 * of any contributors may be used to endorse or promote products derived 132 * from this software without specific prior written permission. 133 * 134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145 * 146 * Alternatively, you may choose to be licensed under the terms of the 147 * GNU General Public License ("GPL") version 2 as published by the Free 148 * Software Foundation. 149 * 150 *****************************************************************************/ 151 152 #include "acpi.h" 153 #include "accommon.h" 154 #include "acnamesp.h" 155 #include "acdebug.h" 156 #include "acpredef.h" 157 #include "acinterp.h" 158 159 160 #ifdef ACPI_DEBUGGER 161 162 #define _COMPONENT ACPI_CA_DEBUGGER 163 ACPI_MODULE_NAME ("dbnames") 164 165 166 /* Local prototypes */ 167 168 static ACPI_STATUS 169 AcpiDbWalkAndMatchName ( 170 ACPI_HANDLE ObjHandle, 171 UINT32 NestingLevel, 172 void *Context, 173 void **ReturnValue); 174 175 static ACPI_STATUS 176 AcpiDbWalkForPredefinedNames ( 177 ACPI_HANDLE ObjHandle, 178 UINT32 NestingLevel, 179 void *Context, 180 void **ReturnValue); 181 182 static ACPI_STATUS 183 AcpiDbWalkForSpecificObjects ( 184 ACPI_HANDLE ObjHandle, 185 UINT32 NestingLevel, 186 void *Context, 187 void **ReturnValue); 188 189 static ACPI_STATUS 190 AcpiDbWalkForObjectCounts ( 191 ACPI_HANDLE ObjHandle, 192 UINT32 NestingLevel, 193 void *Context, 194 void **ReturnValue); 195 196 static ACPI_STATUS 197 AcpiDbIntegrityWalk ( 198 ACPI_HANDLE ObjHandle, 199 UINT32 NestingLevel, 200 void *Context, 201 void **ReturnValue); 202 203 static ACPI_STATUS 204 AcpiDbWalkForReferences ( 205 ACPI_HANDLE ObjHandle, 206 UINT32 NestingLevel, 207 void *Context, 208 void **ReturnValue); 209 210 static ACPI_STATUS 211 AcpiDbBusWalk ( 212 ACPI_HANDLE ObjHandle, 213 UINT32 NestingLevel, 214 void *Context, 215 void **ReturnValue); 216 217 /* 218 * Arguments for the Objects command 219 * These object types map directly to the ACPI_TYPES 220 */ 221 static ACPI_DB_ARGUMENT_INFO AcpiDbObjectTypes [] = 222 { 223 {"ANY"}, 224 {"INTEGERS"}, 225 {"STRINGS"}, 226 {"BUFFERS"}, 227 {"PACKAGES"}, 228 {"FIELDS"}, 229 {"DEVICES"}, 230 {"EVENTS"}, 231 {"METHODS"}, 232 {"MUTEXES"}, 233 {"REGIONS"}, 234 {"POWERRESOURCES"}, 235 {"PROCESSORS"}, 236 {"THERMALZONES"}, 237 {"BUFFERFIELDS"}, 238 {"DDBHANDLES"}, 239 {"DEBUG"}, 240 {"REGIONFIELDS"}, 241 {"BANKFIELDS"}, 242 {"INDEXFIELDS"}, 243 {"REFERENCES"}, 244 {"ALIASES"}, 245 {"METHODALIASES"}, 246 {"NOTIFY"}, 247 {"ADDRESSHANDLER"}, 248 {"RESOURCE"}, 249 {"RESOURCEFIELD"}, 250 {"SCOPES"}, 251 {NULL} /* Must be null terminated */ 252 }; 253 254 255 /******************************************************************************* 256 * 257 * FUNCTION: AcpiDbSetScope 258 * 259 * PARAMETERS: Name - New scope path 260 * 261 * RETURN: Status 262 * 263 * DESCRIPTION: Set the "current scope" as maintained by this utility. 264 * The scope is used as a prefix to ACPI paths. 265 * 266 ******************************************************************************/ 267 268 void 269 AcpiDbSetScope ( 270 char *Name) 271 { 272 ACPI_STATUS Status; 273 ACPI_NAMESPACE_NODE *Node; 274 275 276 if (!Name || Name[0] == 0) 277 { 278 AcpiOsPrintf ("Current scope: %s\n", AcpiGbl_DbScopeBuf); 279 return; 280 } 281 282 AcpiDbPrepNamestring (Name); 283 284 if (ACPI_IS_ROOT_PREFIX (Name[0])) 285 { 286 /* Validate new scope from the root */ 287 288 Status = AcpiNsGetNode (AcpiGbl_RootNode, Name, 289 ACPI_NS_NO_UPSEARCH, &Node); 290 if (ACPI_FAILURE (Status)) 291 { 292 goto ErrorExit; 293 } 294 295 AcpiGbl_DbScopeBuf[0] = 0; 296 } 297 else 298 { 299 /* Validate new scope relative to old scope */ 300 301 Status = AcpiNsGetNode (AcpiGbl_DbScopeNode, Name, 302 ACPI_NS_NO_UPSEARCH, &Node); 303 if (ACPI_FAILURE (Status)) 304 { 305 goto ErrorExit; 306 } 307 } 308 309 /* Build the final pathname */ 310 311 if (AcpiUtSafeStrcat (AcpiGbl_DbScopeBuf, sizeof (AcpiGbl_DbScopeBuf), 312 Name)) 313 { 314 Status = AE_BUFFER_OVERFLOW; 315 goto ErrorExit; 316 } 317 318 if (AcpiUtSafeStrcat (AcpiGbl_DbScopeBuf, sizeof (AcpiGbl_DbScopeBuf), 319 "\\")) 320 { 321 Status = AE_BUFFER_OVERFLOW; 322 goto ErrorExit; 323 } 324 325 AcpiGbl_DbScopeNode = Node; 326 AcpiOsPrintf ("New scope: %s\n", AcpiGbl_DbScopeBuf); 327 return; 328 329 ErrorExit: 330 331 AcpiOsPrintf ("Could not attach scope: %s, %s\n", 332 Name, AcpiFormatException (Status)); 333 } 334 335 336 /******************************************************************************* 337 * 338 * FUNCTION: AcpiDbDumpNamespace 339 * 340 * PARAMETERS: StartArg - Node to begin namespace dump 341 * DepthArg - Maximum tree depth to be dumped 342 * 343 * RETURN: None 344 * 345 * DESCRIPTION: Dump entire namespace or a subtree. Each node is displayed 346 * with type and other information. 347 * 348 ******************************************************************************/ 349 350 void 351 AcpiDbDumpNamespace ( 352 char *StartArg, 353 char *DepthArg) 354 { 355 ACPI_HANDLE SubtreeEntry = AcpiGbl_RootNode; 356 UINT32 MaxDepth = ACPI_UINT32_MAX; 357 358 359 /* No argument given, just start at the root and dump entire namespace */ 360 361 if (StartArg) 362 { 363 SubtreeEntry = AcpiDbConvertToNode (StartArg); 364 if (!SubtreeEntry) 365 { 366 return; 367 } 368 369 /* Now we can check for the depth argument */ 370 371 if (DepthArg) 372 { 373 MaxDepth = strtoul (DepthArg, NULL, 0); 374 } 375 } 376 377 AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 378 379 if (((ACPI_NAMESPACE_NODE *) SubtreeEntry)->Parent) 380 { 381 AcpiOsPrintf ("ACPI Namespace (from %4.4s (%p) subtree):\n", 382 ((ACPI_NAMESPACE_NODE *) SubtreeEntry)->Name.Ascii, SubtreeEntry); 383 } 384 else 385 { 386 AcpiOsPrintf ("ACPI Namespace (from %s):\n", 387 ACPI_NAMESPACE_ROOT); 388 } 389 390 /* Display the subtree */ 391 392 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 393 AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth, 394 ACPI_OWNER_ID_MAX, SubtreeEntry); 395 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 396 } 397 398 399 /******************************************************************************* 400 * 401 * FUNCTION: AcpiDbDumpNamespacePaths 402 * 403 * PARAMETERS: None 404 * 405 * RETURN: None 406 * 407 * DESCRIPTION: Dump entire namespace with full object pathnames and object 408 * type information. Alternative to "namespace" command. 409 * 410 ******************************************************************************/ 411 412 void 413 AcpiDbDumpNamespacePaths ( 414 void) 415 { 416 417 AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 418 AcpiOsPrintf ("ACPI Namespace (from root):\n"); 419 420 /* Display the entire namespace */ 421 422 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 423 AcpiNsDumpObjectPaths (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, 424 ACPI_UINT32_MAX, ACPI_OWNER_ID_MAX, AcpiGbl_RootNode); 425 426 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 427 } 428 429 430 /******************************************************************************* 431 * 432 * FUNCTION: AcpiDbDumpNamespaceByOwner 433 * 434 * PARAMETERS: OwnerArg - Owner ID whose nodes will be displayed 435 * DepthArg - Maximum tree depth to be dumped 436 * 437 * RETURN: None 438 * 439 * DESCRIPTION: Dump elements of the namespace that are owned by the OwnerId. 440 * 441 ******************************************************************************/ 442 443 void 444 AcpiDbDumpNamespaceByOwner ( 445 char *OwnerArg, 446 char *DepthArg) 447 { 448 ACPI_HANDLE SubtreeEntry = AcpiGbl_RootNode; 449 UINT32 MaxDepth = ACPI_UINT32_MAX; 450 ACPI_OWNER_ID OwnerId; 451 452 453 OwnerId = (ACPI_OWNER_ID) strtoul (OwnerArg, NULL, 0); 454 455 /* Now we can check for the depth argument */ 456 457 if (DepthArg) 458 { 459 MaxDepth = strtoul (DepthArg, NULL, 0); 460 } 461 462 AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 463 AcpiOsPrintf ("ACPI Namespace by owner %X:\n", OwnerId); 464 465 /* Display the subtree */ 466 467 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 468 AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth, 469 OwnerId, SubtreeEntry); 470 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 471 } 472 473 474 /******************************************************************************* 475 * 476 * FUNCTION: AcpiDbWalkAndMatchName 477 * 478 * PARAMETERS: Callback from WalkNamespace 479 * 480 * RETURN: Status 481 * 482 * DESCRIPTION: Find a particular name/names within the namespace. Wildcards 483 * are supported -- '?' matches any character. 484 * 485 ******************************************************************************/ 486 487 static ACPI_STATUS 488 AcpiDbWalkAndMatchName ( 489 ACPI_HANDLE ObjHandle, 490 UINT32 NestingLevel, 491 void *Context, 492 void **ReturnValue) 493 { 494 ACPI_STATUS Status; 495 char *RequestedName = (char *) Context; 496 UINT32 i; 497 ACPI_BUFFER Buffer; 498 ACPI_WALK_INFO Info; 499 500 501 /* Check for a name match */ 502 503 for (i = 0; i < 4; i++) 504 { 505 /* Wildcard support */ 506 507 if ((RequestedName[i] != '?') && 508 (RequestedName[i] != ((ACPI_NAMESPACE_NODE *) 509 ObjHandle)->Name.Ascii[i])) 510 { 511 /* No match, just exit */ 512 513 return (AE_OK); 514 } 515 } 516 517 /* Get the full pathname to this object */ 518 519 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 520 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer, TRUE); 521 if (ACPI_FAILURE (Status)) 522 { 523 AcpiOsPrintf ("Could Not get pathname for object %p\n", 524 ObjHandle); 525 } 526 else 527 { 528 Info.Count = 0; 529 Info.OwnerId = ACPI_OWNER_ID_MAX; 530 Info.DebugLevel = ACPI_UINT32_MAX; 531 Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT; 532 533 AcpiOsPrintf ("%32s", (char *) Buffer.Pointer); 534 (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, &Info, NULL); 535 ACPI_FREE (Buffer.Pointer); 536 } 537 538 return (AE_OK); 539 } 540 541 542 /******************************************************************************* 543 * 544 * FUNCTION: AcpiDbFindNameInNamespace 545 * 546 * PARAMETERS: NameArg - The 4-character ACPI name to find. 547 * wildcards are supported. 548 * 549 * RETURN: None 550 * 551 * DESCRIPTION: Search the namespace for a given name (with wildcards) 552 * 553 ******************************************************************************/ 554 555 ACPI_STATUS 556 AcpiDbFindNameInNamespace ( 557 char *NameArg) 558 { 559 char AcpiName[5] = "____"; 560 char *AcpiNamePtr = AcpiName; 561 562 563 if (strlen (NameArg) > ACPI_NAMESEG_SIZE) 564 { 565 AcpiOsPrintf ("Name must be no longer than 4 characters\n"); 566 return (AE_OK); 567 } 568 569 /* Pad out name with underscores as necessary to create a 4-char name */ 570 571 AcpiUtStrupr (NameArg); 572 while (*NameArg) 573 { 574 *AcpiNamePtr = *NameArg; 575 AcpiNamePtr++; 576 NameArg++; 577 } 578 579 /* Walk the namespace from the root */ 580 581 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 582 ACPI_UINT32_MAX, AcpiDbWalkAndMatchName, NULL, AcpiName, NULL); 583 584 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 585 return (AE_OK); 586 } 587 588 589 /******************************************************************************* 590 * 591 * FUNCTION: AcpiDbWalkForPredefinedNames 592 * 593 * PARAMETERS: Callback from WalkNamespace 594 * 595 * RETURN: Status 596 * 597 * DESCRIPTION: Detect and display predefined ACPI names (names that start with 598 * an underscore) 599 * 600 ******************************************************************************/ 601 602 static ACPI_STATUS 603 AcpiDbWalkForPredefinedNames ( 604 ACPI_HANDLE ObjHandle, 605 UINT32 NestingLevel, 606 void *Context, 607 void **ReturnValue) 608 { 609 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 610 UINT32 *Count = (UINT32 *) Context; 611 const ACPI_PREDEFINED_INFO *Predefined; 612 const ACPI_PREDEFINED_INFO *Package = NULL; 613 char *Pathname; 614 char StringBuffer[48]; 615 616 617 Predefined = AcpiUtMatchPredefinedMethod (Node->Name.Ascii); 618 if (!Predefined) 619 { 620 return (AE_OK); 621 } 622 623 Pathname = AcpiNsGetNormalizedPathname (Node, TRUE); 624 if (!Pathname) 625 { 626 return (AE_OK); 627 } 628 629 /* If method returns a package, the info is in the next table entry */ 630 631 if (Predefined->Info.ExpectedBtypes & ACPI_RTYPE_PACKAGE) 632 { 633 Package = Predefined + 1; 634 } 635 636 AcpiUtGetExpectedReturnTypes (StringBuffer, 637 Predefined->Info.ExpectedBtypes); 638 639 AcpiOsPrintf ("%-32s Arguments %X, Return Types: %s", Pathname, 640 METHOD_GET_ARG_COUNT (Predefined->Info.ArgumentList), 641 StringBuffer); 642 643 if (Package) 644 { 645 AcpiOsPrintf (" (PkgType %2.2X, ObjType %2.2X, Count %2.2X)", 646 Package->RetInfo.Type, Package->RetInfo.ObjectType1, 647 Package->RetInfo.Count1); 648 } 649 650 AcpiOsPrintf("\n"); 651 652 /* Check that the declared argument count matches the ACPI spec */ 653 654 AcpiNsCheckAcpiCompliance (Pathname, Node, Predefined); 655 656 ACPI_FREE (Pathname); 657 (*Count)++; 658 return (AE_OK); 659 } 660 661 662 /******************************************************************************* 663 * 664 * FUNCTION: AcpiDbCheckPredefinedNames 665 * 666 * PARAMETERS: None 667 * 668 * RETURN: None 669 * 670 * DESCRIPTION: Validate all predefined names in the namespace 671 * 672 ******************************************************************************/ 673 674 void 675 AcpiDbCheckPredefinedNames ( 676 void) 677 { 678 UINT32 Count = 0; 679 680 681 /* Search all nodes in namespace */ 682 683 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 684 ACPI_UINT32_MAX, AcpiDbWalkForPredefinedNames, 685 NULL, (void *) &Count, NULL); 686 687 AcpiOsPrintf ("Found %u predefined names in the namespace\n", Count); 688 } 689 690 691 /******************************************************************************* 692 * 693 * FUNCTION: AcpiDbWalkForObjectCounts 694 * 695 * PARAMETERS: Callback from WalkNamespace 696 * 697 * RETURN: Status 698 * 699 * DESCRIPTION: Display short info about objects in the namespace 700 * 701 ******************************************************************************/ 702 703 static ACPI_STATUS 704 AcpiDbWalkForObjectCounts ( 705 ACPI_HANDLE ObjHandle, 706 UINT32 NestingLevel, 707 void *Context, 708 void **ReturnValue) 709 { 710 ACPI_OBJECT_INFO *Info = (ACPI_OBJECT_INFO *) Context; 711 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 712 713 714 if (Node->Type > ACPI_TYPE_NS_NODE_MAX) 715 { 716 AcpiOsPrintf ("[%4.4s]: Unknown object type %X\n", 717 Node->Name.Ascii, Node->Type); 718 } 719 else 720 { 721 Info->Types[Node->Type]++; 722 } 723 724 return (AE_OK); 725 } 726 727 728 /******************************************************************************* 729 * 730 * FUNCTION: AcpiDbWalkForFields 731 * 732 * PARAMETERS: Callback from WalkNamespace 733 * 734 * RETURN: Status 735 * 736 * DESCRIPTION: Display short info about objects in the namespace 737 * 738 ******************************************************************************/ 739 740 static ACPI_STATUS 741 AcpiDbWalkForFields ( 742 ACPI_HANDLE ObjHandle, 743 UINT32 NestingLevel, 744 void *Context, 745 void **ReturnValue) 746 { 747 ACPI_OBJECT *RetValue; 748 ACPI_REGION_WALK_INFO *Info = (ACPI_REGION_WALK_INFO *) Context; 749 ACPI_BUFFER Buffer; 750 ACPI_STATUS Status; 751 ACPI_NAMESPACE_NODE *Node = AcpiNsValidateHandle (ObjHandle); 752 753 754 if (!Node) 755 { 756 return (AE_OK); 757 } 758 if (Node->Object->Field.RegionObj->Region.SpaceId != Info->AddressSpaceId) 759 { 760 return (AE_OK); 761 } 762 763 Info->Count++; 764 765 /* Get and display the full pathname to this object */ 766 767 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 768 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer, TRUE); 769 if (ACPI_FAILURE (Status)) 770 { 771 AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle); 772 return (AE_OK); 773 } 774 775 AcpiOsPrintf ("%s ", (char *) Buffer.Pointer); 776 ACPI_FREE (Buffer.Pointer); 777 778 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 779 AcpiEvaluateObject (ObjHandle, NULL, NULL, &Buffer); 780 781 /* 782 * Since this is a field unit, surround the output in braces 783 */ 784 AcpiOsPrintf ("{"); 785 786 RetValue = (ACPI_OBJECT *) Buffer.Pointer; 787 switch (RetValue->Type) 788 { 789 case ACPI_TYPE_INTEGER: 790 791 AcpiOsPrintf ("%8.8X%8.8X", ACPI_FORMAT_UINT64 (RetValue->Integer.Value)); 792 break; 793 794 case ACPI_TYPE_BUFFER: 795 796 AcpiUtDumpBuffer (RetValue->Buffer.Pointer, 797 RetValue->Buffer.Length, DB_DISPLAY_DATA_ONLY | DB_BYTE_DISPLAY, 0); 798 break; 799 800 default: 801 802 break; 803 } 804 805 AcpiOsPrintf ("}\n"); 806 807 ACPI_FREE (Buffer.Pointer); 808 return (AE_OK); 809 } 810 811 812 /******************************************************************************* 813 * 814 * FUNCTION: AcpiDbWalkForSpecificObjects 815 * 816 * PARAMETERS: Callback from WalkNamespace 817 * 818 * RETURN: Status 819 * 820 * DESCRIPTION: Display short info about objects in the namespace 821 * 822 ******************************************************************************/ 823 824 static ACPI_STATUS 825 AcpiDbWalkForSpecificObjects ( 826 ACPI_HANDLE ObjHandle, 827 UINT32 NestingLevel, 828 void *Context, 829 void **ReturnValue) 830 { 831 ACPI_WALK_INFO *Info = (ACPI_WALK_INFO *) Context; 832 ACPI_BUFFER Buffer; 833 ACPI_STATUS Status; 834 835 836 Info->Count++; 837 838 /* Get and display the full pathname to this object */ 839 840 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 841 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer, TRUE); 842 if (ACPI_FAILURE (Status)) 843 { 844 AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle); 845 return (AE_OK); 846 } 847 848 AcpiOsPrintf ("%32s", (char *) Buffer.Pointer); 849 ACPI_FREE (Buffer.Pointer); 850 851 /* Dump short info about the object */ 852 853 (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, Info, NULL); 854 return (AE_OK); 855 } 856 857 858 /******************************************************************************* 859 * 860 * FUNCTION: AcpiDbDisplayObjects 861 * 862 * PARAMETERS: ObjTypeArg - Type of object to display 863 * DisplayCountArg - Max depth to display 864 * 865 * RETURN: None 866 * 867 * DESCRIPTION: Display objects in the namespace of the requested type 868 * 869 ******************************************************************************/ 870 871 ACPI_STATUS 872 AcpiDbDisplayObjects ( 873 char *ObjTypeArg, 874 char *DisplayCountArg) 875 { 876 ACPI_WALK_INFO Info; 877 ACPI_OBJECT_TYPE Type; 878 ACPI_OBJECT_INFO *ObjectInfo; 879 UINT32 i; 880 UINT32 TotalObjects = 0; 881 882 883 /* No argument means display summary/count of all object types */ 884 885 if (!ObjTypeArg) 886 { 887 ObjectInfo = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_OBJECT_INFO)); 888 889 /* Walk the namespace from the root */ 890 891 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 892 ACPI_UINT32_MAX, AcpiDbWalkForObjectCounts, NULL, 893 (void *) ObjectInfo, NULL); 894 895 AcpiOsPrintf ("\nSummary of namespace objects:\n\n"); 896 897 for (i = 0; i < ACPI_TOTAL_TYPES; i++) 898 { 899 AcpiOsPrintf ("%8u %s\n", ObjectInfo->Types[i], 900 AcpiUtGetTypeName (i)); 901 902 TotalObjects += ObjectInfo->Types[i]; 903 } 904 905 AcpiOsPrintf ("\n%8u Total namespace objects\n\n", 906 TotalObjects); 907 908 ACPI_FREE (ObjectInfo); 909 return (AE_OK); 910 } 911 912 /* Get the object type */ 913 914 Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes); 915 if (Type == ACPI_TYPE_NOT_FOUND) 916 { 917 AcpiOsPrintf ("Invalid or unsupported argument\n"); 918 return (AE_OK); 919 } 920 921 AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 922 AcpiOsPrintf ( 923 "Objects of type [%s] defined in the current ACPI Namespace:\n", 924 AcpiUtGetTypeName (Type)); 925 926 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 927 928 Info.Count = 0; 929 Info.OwnerId = ACPI_OWNER_ID_MAX; 930 Info.DebugLevel = ACPI_UINT32_MAX; 931 Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT; 932 933 /* Walk the namespace from the root */ 934 935 (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, 936 AcpiDbWalkForSpecificObjects, NULL, (void *) &Info, NULL); 937 938 AcpiOsPrintf ( 939 "\nFound %u objects of type [%s] in the current ACPI Namespace\n", 940 Info.Count, AcpiUtGetTypeName (Type)); 941 942 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 943 return (AE_OK); 944 } 945 946 947 /******************************************************************************* 948 * 949 * FUNCTION: AcpiDbDisplayFields 950 * 951 * PARAMETERS: ObjTypeArg - Type of object to display 952 * DisplayCountArg - Max depth to display 953 * 954 * RETURN: None 955 * 956 * DESCRIPTION: Display objects in the namespace of the requested type 957 * 958 ******************************************************************************/ 959 960 ACPI_STATUS 961 AcpiDbDisplayFields ( 962 UINT32 AddressSpaceId) 963 { 964 ACPI_REGION_WALK_INFO Info; 965 966 967 Info.Count = 0; 968 Info.OwnerId = ACPI_OWNER_ID_MAX; 969 Info.DebugLevel = ACPI_UINT32_MAX; 970 Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT; 971 Info.AddressSpaceId = AddressSpaceId; 972 973 /* Walk the namespace from the root */ 974 975 (void) AcpiWalkNamespace (ACPI_TYPE_LOCAL_REGION_FIELD, ACPI_ROOT_OBJECT, 976 ACPI_UINT32_MAX, AcpiDbWalkForFields, NULL, 977 (void *) &Info, NULL); 978 979 return (AE_OK); 980 } 981 982 983 /******************************************************************************* 984 * 985 * FUNCTION: AcpiDbIntegrityWalk 986 * 987 * PARAMETERS: Callback from WalkNamespace 988 * 989 * RETURN: Status 990 * 991 * DESCRIPTION: Examine one NS node for valid values. 992 * 993 ******************************************************************************/ 994 995 static ACPI_STATUS 996 AcpiDbIntegrityWalk ( 997 ACPI_HANDLE ObjHandle, 998 UINT32 NestingLevel, 999 void *Context, 1000 void **ReturnValue) 1001 { 1002 ACPI_INTEGRITY_INFO *Info = (ACPI_INTEGRITY_INFO *) Context; 1003 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 1004 ACPI_OPERAND_OBJECT *Object; 1005 BOOLEAN Alias = TRUE; 1006 1007 1008 Info->Nodes++; 1009 1010 /* Verify the NS node, and dereference aliases */ 1011 1012 while (Alias) 1013 { 1014 if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED) 1015 { 1016 AcpiOsPrintf ( 1017 "Invalid Descriptor Type for Node %p [%s] - " 1018 "is %2.2X should be %2.2X\n", 1019 Node, AcpiUtGetDescriptorName (Node), 1020 ACPI_GET_DESCRIPTOR_TYPE (Node), ACPI_DESC_TYPE_NAMED); 1021 return (AE_OK); 1022 } 1023 1024 if ((Node->Type == ACPI_TYPE_LOCAL_ALIAS) || 1025 (Node->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) 1026 { 1027 Node = (ACPI_NAMESPACE_NODE *) Node->Object; 1028 } 1029 else 1030 { 1031 Alias = FALSE; 1032 } 1033 } 1034 1035 if (Node->Type > ACPI_TYPE_LOCAL_MAX) 1036 { 1037 AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n", 1038 Node, Node->Type); 1039 return (AE_OK); 1040 } 1041 1042 if (!AcpiUtValidNameseg (Node->Name.Ascii)) 1043 { 1044 AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node); 1045 return (AE_OK); 1046 } 1047 1048 Object = AcpiNsGetAttachedObject (Node); 1049 if (Object) 1050 { 1051 Info->Objects++; 1052 if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND) 1053 { 1054 AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n", 1055 Object, AcpiUtGetDescriptorName (Object)); 1056 } 1057 } 1058 1059 return (AE_OK); 1060 } 1061 1062 1063 /******************************************************************************* 1064 * 1065 * FUNCTION: AcpiDbCheckIntegrity 1066 * 1067 * PARAMETERS: None 1068 * 1069 * RETURN: None 1070 * 1071 * DESCRIPTION: Check entire namespace for data structure integrity 1072 * 1073 ******************************************************************************/ 1074 1075 void 1076 AcpiDbCheckIntegrity ( 1077 void) 1078 { 1079 ACPI_INTEGRITY_INFO Info = {0,0}; 1080 1081 /* Search all nodes in namespace */ 1082 1083 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 1084 ACPI_UINT32_MAX, AcpiDbIntegrityWalk, NULL, (void *) &Info, NULL); 1085 1086 AcpiOsPrintf ("Verified %u namespace nodes with %u Objects\n", 1087 Info.Nodes, Info.Objects); 1088 } 1089 1090 1091 /******************************************************************************* 1092 * 1093 * FUNCTION: AcpiDbWalkForReferences 1094 * 1095 * PARAMETERS: Callback from WalkNamespace 1096 * 1097 * RETURN: Status 1098 * 1099 * DESCRIPTION: Check if this namespace object refers to the target object 1100 * that is passed in as the context value. 1101 * 1102 * Note: Currently doesn't check subobjects within the Node's object 1103 * 1104 ******************************************************************************/ 1105 1106 static ACPI_STATUS 1107 AcpiDbWalkForReferences ( 1108 ACPI_HANDLE ObjHandle, 1109 UINT32 NestingLevel, 1110 void *Context, 1111 void **ReturnValue) 1112 { 1113 ACPI_OPERAND_OBJECT *ObjDesc = (ACPI_OPERAND_OBJECT *) Context; 1114 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 1115 1116 1117 /* Check for match against the namespace node itself */ 1118 1119 if (Node == (void *) ObjDesc) 1120 { 1121 AcpiOsPrintf ("Object is a Node [%4.4s]\n", 1122 AcpiUtGetNodeName (Node)); 1123 } 1124 1125 /* Check for match against the object attached to the node */ 1126 1127 if (AcpiNsGetAttachedObject (Node) == ObjDesc) 1128 { 1129 AcpiOsPrintf ("Reference at Node->Object %p [%4.4s]\n", 1130 Node, AcpiUtGetNodeName (Node)); 1131 } 1132 1133 return (AE_OK); 1134 } 1135 1136 1137 /******************************************************************************* 1138 * 1139 * FUNCTION: AcpiDbFindReferences 1140 * 1141 * PARAMETERS: ObjectArg - String with hex value of the object 1142 * 1143 * RETURN: None 1144 * 1145 * DESCRIPTION: Search namespace for all references to the input object 1146 * 1147 ******************************************************************************/ 1148 1149 void 1150 AcpiDbFindReferences ( 1151 char *ObjectArg) 1152 { 1153 ACPI_OPERAND_OBJECT *ObjDesc; 1154 ACPI_SIZE Address; 1155 1156 1157 /* Convert string to object pointer */ 1158 1159 Address = strtoul (ObjectArg, NULL, 16); 1160 ObjDesc = ACPI_TO_POINTER (Address); 1161 1162 /* Search all nodes in namespace */ 1163 1164 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 1165 ACPI_UINT32_MAX, AcpiDbWalkForReferences, NULL, 1166 (void *) ObjDesc, NULL); 1167 } 1168 1169 1170 /******************************************************************************* 1171 * 1172 * FUNCTION: AcpiDbBusWalk 1173 * 1174 * PARAMETERS: Callback from WalkNamespace 1175 * 1176 * RETURN: Status 1177 * 1178 * DESCRIPTION: Display info about device objects that have a corresponding 1179 * _PRT method. 1180 * 1181 ******************************************************************************/ 1182 1183 static ACPI_STATUS 1184 AcpiDbBusWalk ( 1185 ACPI_HANDLE ObjHandle, 1186 UINT32 NestingLevel, 1187 void *Context, 1188 void **ReturnValue) 1189 { 1190 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 1191 ACPI_STATUS Status; 1192 ACPI_BUFFER Buffer; 1193 ACPI_NAMESPACE_NODE *TempNode; 1194 ACPI_DEVICE_INFO *Info; 1195 UINT32 i; 1196 1197 1198 if ((Node->Type != ACPI_TYPE_DEVICE) && 1199 (Node->Type != ACPI_TYPE_PROCESSOR)) 1200 { 1201 return (AE_OK); 1202 } 1203 1204 /* Exit if there is no _PRT under this device */ 1205 1206 Status = AcpiGetHandle (Node, METHOD_NAME__PRT, 1207 ACPI_CAST_PTR (ACPI_HANDLE, &TempNode)); 1208 if (ACPI_FAILURE (Status)) 1209 { 1210 return (AE_OK); 1211 } 1212 1213 /* Get the full path to this device object */ 1214 1215 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 1216 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer, TRUE); 1217 if (ACPI_FAILURE (Status)) 1218 { 1219 AcpiOsPrintf ("Could Not get pathname for object %p\n", 1220 ObjHandle); 1221 return (AE_OK); 1222 } 1223 1224 Status = AcpiGetObjectInfo (ObjHandle, &Info); 1225 if (ACPI_FAILURE (Status)) 1226 { 1227 return (AE_OK); 1228 } 1229 1230 /* Display the full path */ 1231 1232 AcpiOsPrintf ("%-32s Type %X", (char *) Buffer.Pointer, Node->Type); 1233 ACPI_FREE (Buffer.Pointer); 1234 1235 if (Info->Flags & ACPI_PCI_ROOT_BRIDGE) 1236 { 1237 AcpiOsPrintf (" - Is PCI Root Bridge"); 1238 } 1239 AcpiOsPrintf ("\n"); 1240 1241 /* _PRT info */ 1242 1243 AcpiOsPrintf ("_PRT: %p\n", TempNode); 1244 1245 /* Dump _ADR, _HID, _UID, _CID */ 1246 1247 if (Info->Valid & ACPI_VALID_ADR) 1248 { 1249 AcpiOsPrintf ("_ADR: %8.8X%8.8X\n", 1250 ACPI_FORMAT_UINT64 (Info->Address)); 1251 } 1252 else 1253 { 1254 AcpiOsPrintf ("_ADR: <Not Present>\n"); 1255 } 1256 1257 if (Info->Valid & ACPI_VALID_HID) 1258 { 1259 AcpiOsPrintf ("_HID: %s\n", Info->HardwareId.String); 1260 } 1261 else 1262 { 1263 AcpiOsPrintf ("_HID: <Not Present>\n"); 1264 } 1265 1266 if (Info->Valid & ACPI_VALID_UID) 1267 { 1268 AcpiOsPrintf ("_UID: %s\n", Info->UniqueId.String); 1269 } 1270 else 1271 { 1272 AcpiOsPrintf ("_UID: <Not Present>\n"); 1273 } 1274 1275 if (Info->Valid & ACPI_VALID_CID) 1276 { 1277 for (i = 0; i < Info->CompatibleIdList.Count; i++) 1278 { 1279 AcpiOsPrintf ("_CID: %s\n", 1280 Info->CompatibleIdList.Ids[i].String); 1281 } 1282 } 1283 else 1284 { 1285 AcpiOsPrintf ("_CID: <Not Present>\n"); 1286 } 1287 1288 ACPI_FREE (Info); 1289 return (AE_OK); 1290 } 1291 1292 1293 /******************************************************************************* 1294 * 1295 * FUNCTION: AcpiDbGetBusInfo 1296 * 1297 * PARAMETERS: None 1298 * 1299 * RETURN: None 1300 * 1301 * DESCRIPTION: Display info about system buses. 1302 * 1303 ******************************************************************************/ 1304 1305 void 1306 AcpiDbGetBusInfo ( 1307 void) 1308 { 1309 /* Search all nodes in namespace */ 1310 1311 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 1312 ACPI_UINT32_MAX, AcpiDbBusWalk, NULL, NULL, NULL); 1313 } 1314 1315 #endif /* ACPI_DEBUGGER */ 1316