1 /******************************************************************************* 2 * 3 * Module Name: dbcmds - debug commands and output routines 4 * $Revision: 1.157 $ 5 * 6 ******************************************************************************/ 7 8 /****************************************************************************** 9 * 10 * 1. Copyright Notice 11 * 12 * Some or all of this work - Copyright (c) 1999 - 2008, Intel Corp. 13 * All rights reserved. 14 * 15 * 2. License 16 * 17 * 2.1. This is your license from Intel Corp. under its intellectual property 18 * rights. You may have additional license terms from the party that provided 19 * you this software, covering your right to use that party's intellectual 20 * property rights. 21 * 22 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 23 * copy of the source code appearing in this file ("Covered Code") an 24 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 25 * base code distributed originally by Intel ("Original Intel Code") to copy, 26 * make derivatives, distribute, use and display any portion of the Covered 27 * Code in any form, with the right to sublicense such rights; and 28 * 29 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 30 * license (with the right to sublicense), under only those claims of Intel 31 * patents that are infringed by the Original Intel Code, to make, use, sell, 32 * offer to sell, and import the Covered Code and derivative works thereof 33 * solely to the minimum extent necessary to exercise the above copyright 34 * license, and in no event shall the patent license extend to any additions 35 * to or modifications of the Original Intel Code. No other license or right 36 * is granted directly or by implication, estoppel or otherwise; 37 * 38 * The above copyright and patent license is granted only if the following 39 * conditions are met: 40 * 41 * 3. Conditions 42 * 43 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 44 * Redistribution of source code of any substantial portion of the Covered 45 * Code or modification with rights to further distribute source must include 46 * the above Copyright Notice, the above License, this list of Conditions, 47 * and the following Disclaimer and Export Compliance provision. In addition, 48 * Licensee must cause all Covered Code to which Licensee contributes to 49 * contain a file documenting the changes Licensee made to create that Covered 50 * Code and the date of any change. Licensee must include in that file the 51 * documentation of any changes made by any predecessor Licensee. Licensee 52 * must include a prominent statement that the modification is derived, 53 * directly or indirectly, from Original Intel Code. 54 * 55 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 56 * Redistribution of source code of any substantial portion of the Covered 57 * Code or modification without rights to further distribute source must 58 * include the following Disclaimer and Export Compliance provision in the 59 * documentation and/or other materials provided with distribution. In 60 * addition, Licensee may not authorize further sublicense of source of any 61 * portion of the Covered Code, and must include terms to the effect that the 62 * license from Licensee to its licensee is limited to the intellectual 63 * property embodied in the software Licensee provides to its licensee, and 64 * not to intellectual property embodied in modifications its licensee may 65 * make. 66 * 67 * 3.3. Redistribution of Executable. Redistribution in executable form of any 68 * substantial portion of the Covered Code or modification must reproduce the 69 * above Copyright Notice, and the following Disclaimer and Export Compliance 70 * provision in the documentation and/or other materials provided with the 71 * distribution. 72 * 73 * 3.4. Intel retains all right, title, and interest in and to the Original 74 * Intel Code. 75 * 76 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 77 * Intel shall be used in advertising or otherwise to promote the sale, use or 78 * other dealings in products derived from or relating to the Covered Code 79 * without prior written authorization from Intel. 80 * 81 * 4. Disclaimer and Export Compliance 82 * 83 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 84 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 85 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 86 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 87 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 88 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 89 * PARTICULAR PURPOSE. 90 * 91 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 92 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 93 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 94 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 95 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 96 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 97 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 98 * LIMITED REMEDY. 99 * 100 * 4.3. Licensee shall not export, either directly or indirectly, any of this 101 * software or system incorporating such software without first obtaining any 102 * required license or other approval from the U. S. Department of Commerce or 103 * any other agency or department of the United States Government. In the 104 * event Licensee exports any such software from the United States or 105 * re-exports any such software from a foreign destination, Licensee shall 106 * ensure that the distribution and export/re-export of the software is in 107 * compliance with all laws, regulations, orders, or other restrictions of the 108 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 109 * any of its subsidiaries will export/re-export any technical data, process, 110 * software, or service, directly or indirectly, to any country for which the 111 * United States government or any agency thereof requires an export license, 112 * other governmental approval, or letter of assurance, without first obtaining 113 * such license, approval or letter. 114 * 115 *****************************************************************************/ 116 117 118 #include "acpi.h" 119 #include "acdispat.h" 120 #include "acnamesp.h" 121 #include "acevents.h" 122 #include "acdebug.h" 123 #include "acresrc.h" 124 #include "acdisasm.h" 125 #include "actables.h" 126 #include "acparser.h" 127 128 #ifdef ACPI_DEBUGGER 129 130 #define _COMPONENT ACPI_CA_DEBUGGER 131 ACPI_MODULE_NAME ("dbcmds") 132 133 /* Local prototypes */ 134 135 static ACPI_STATUS 136 AcpiDbIntegrityWalk ( 137 ACPI_HANDLE ObjHandle, 138 UINT32 NestingLevel, 139 void *Context, 140 void **ReturnValue); 141 142 static ACPI_STATUS 143 AcpiDbWalkAndMatchName ( 144 ACPI_HANDLE ObjHandle, 145 UINT32 NestingLevel, 146 void *Context, 147 void **ReturnValue); 148 149 static ACPI_STATUS 150 AcpiDbWalkForReferences ( 151 ACPI_HANDLE ObjHandle, 152 UINT32 NestingLevel, 153 void *Context, 154 void **ReturnValue); 155 156 static ACPI_STATUS 157 AcpiDbWalkForSpecificObjects ( 158 ACPI_HANDLE ObjHandle, 159 UINT32 NestingLevel, 160 void *Context, 161 void **ReturnValue); 162 163 static ACPI_NAMESPACE_NODE * 164 AcpiDbConvertToNode ( 165 char *InString); 166 167 static void 168 AcpiDmCompareAmlResources ( 169 UINT8 *Aml1Buffer, 170 ACPI_RSDESC_SIZE Aml1BufferLength, 171 UINT8 *Aml2Buffer, 172 ACPI_RSDESC_SIZE Aml2BufferLength); 173 174 static ACPI_STATUS 175 AcpiDmTestResourceConversion ( 176 ACPI_NAMESPACE_NODE *Node, 177 char *Name); 178 179 180 /* 181 * Arguments for the Objects command 182 * These object types map directly to the ACPI_TYPES 183 */ 184 static ARGUMENT_INFO AcpiDbObjectTypes [] = 185 { 186 {"ANY"}, 187 {"INTEGERS"}, 188 {"STRINGS"}, 189 {"BUFFERS"}, 190 {"PACKAGES"}, 191 {"FIELDS"}, 192 {"DEVICES"}, 193 {"EVENTS"}, 194 {"METHODS"}, 195 {"MUTEXES"}, 196 {"REGIONS"}, 197 {"POWERRESOURCES"}, 198 {"PROCESSORS"}, 199 {"THERMALZONES"}, 200 {"BUFFERFIELDS"}, 201 {"DDBHANDLES"}, 202 {"DEBUG"}, 203 {"REGIONFIELDS"}, 204 {"BANKFIELDS"}, 205 {"INDEXFIELDS"}, 206 {"REFERENCES"}, 207 {"ALIAS"}, 208 {NULL} /* Must be null terminated */ 209 }; 210 211 212 /******************************************************************************* 213 * 214 * FUNCTION: AcpiDbConvertToNode 215 * 216 * PARAMETERS: InString - String to convert 217 * 218 * RETURN: Pointer to a NS node 219 * 220 * DESCRIPTION: Convert a string to a valid NS pointer. Handles numeric or 221 * alpha strings. 222 * 223 ******************************************************************************/ 224 225 static ACPI_NAMESPACE_NODE * 226 AcpiDbConvertToNode ( 227 char *InString) 228 { 229 ACPI_NAMESPACE_NODE *Node; 230 231 232 if ((*InString >= 0x30) && (*InString <= 0x39)) 233 { 234 /* Numeric argument, convert */ 235 236 Node = ACPI_TO_POINTER (ACPI_STRTOUL (InString, NULL, 16)); 237 if (!AcpiOsReadable (Node, sizeof (ACPI_NAMESPACE_NODE))) 238 { 239 AcpiOsPrintf ("Address %p is invalid in this address space\n", 240 Node); 241 return (NULL); 242 } 243 244 /* Make sure pointer is valid NS node */ 245 246 if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED) 247 { 248 AcpiOsPrintf ("Address %p is not a valid NS node [%s]\n", 249 Node, AcpiUtGetDescriptorName (Node)); 250 return (NULL); 251 } 252 } 253 else 254 { 255 /* Alpha argument */ 256 /* The parameter is a name string that must be resolved to a 257 * Named obj 258 */ 259 Node = AcpiDbLocalNsLookup (InString); 260 if (!Node) 261 { 262 Node = AcpiGbl_RootNode; 263 } 264 } 265 266 return (Node); 267 } 268 269 270 /******************************************************************************* 271 * 272 * FUNCTION: AcpiDbSleep 273 * 274 * PARAMETERS: ObjectArg - Desired sleep state (0-5) 275 * 276 * RETURN: Status 277 * 278 * DESCRIPTION: Simulate a sleep/wake sequence 279 * 280 ******************************************************************************/ 281 282 ACPI_STATUS 283 AcpiDbSleep ( 284 char *ObjectArg) 285 { 286 ACPI_STATUS Status; 287 UINT8 SleepState; 288 289 290 SleepState = (UINT8) ACPI_STRTOUL (ObjectArg, NULL, 0); 291 292 AcpiOsPrintf ("**** Prepare to sleep ****\n"); 293 Status = AcpiEnterSleepStatePrep (SleepState); 294 if (ACPI_FAILURE (Status)) 295 { 296 return (Status); 297 } 298 299 AcpiOsPrintf ("**** Going to sleep ****\n"); 300 Status = AcpiEnterSleepState (SleepState); 301 if (ACPI_FAILURE (Status)) 302 { 303 return (Status); 304 } 305 306 AcpiOsPrintf ("**** returning from sleep ****\n"); 307 Status = AcpiLeaveSleepState (SleepState); 308 309 return (Status); 310 } 311 312 313 /******************************************************************************* 314 * 315 * FUNCTION: AcpiDbWalkForReferences 316 * 317 * PARAMETERS: Callback from WalkNamespace 318 * 319 * RETURN: Status 320 * 321 * DESCRIPTION: Check if this namespace object refers to the target object 322 * that is passed in as the context value. 323 * 324 * Note: Currently doesn't check subobjects within the Node's object 325 * 326 ******************************************************************************/ 327 328 static ACPI_STATUS 329 AcpiDbWalkForReferences ( 330 ACPI_HANDLE ObjHandle, 331 UINT32 NestingLevel, 332 void *Context, 333 void **ReturnValue) 334 { 335 ACPI_OPERAND_OBJECT *ObjDesc = (ACPI_OPERAND_OBJECT *) Context; 336 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 337 338 339 /* Check for match against the namespace node itself */ 340 341 if (Node == (void *) ObjDesc) 342 { 343 AcpiOsPrintf ("Object is a Node [%4.4s]\n", 344 AcpiUtGetNodeName (Node)); 345 } 346 347 /* Check for match against the object attached to the node */ 348 349 if (AcpiNsGetAttachedObject (Node) == ObjDesc) 350 { 351 AcpiOsPrintf ("Reference at Node->Object %p [%4.4s]\n", 352 Node, AcpiUtGetNodeName (Node)); 353 } 354 355 return (AE_OK); 356 } 357 358 359 /******************************************************************************* 360 * 361 * FUNCTION: AcpiDbFindReferences 362 * 363 * PARAMETERS: ObjectArg - String with hex value of the object 364 * 365 * RETURN: None 366 * 367 * DESCRIPTION: Search namespace for all references to the input object 368 * 369 ******************************************************************************/ 370 371 void 372 AcpiDbFindReferences ( 373 char *ObjectArg) 374 { 375 ACPI_OPERAND_OBJECT *ObjDesc; 376 377 378 /* Convert string to object pointer */ 379 380 ObjDesc = ACPI_TO_POINTER (ACPI_STRTOUL (ObjectArg, NULL, 16)); 381 382 /* Search all nodes in namespace */ 383 384 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, 385 AcpiDbWalkForReferences, (void *) ObjDesc, NULL); 386 } 387 388 389 /******************************************************************************* 390 * 391 * FUNCTION: AcpiDbDisplayLocks 392 * 393 * PARAMETERS: None 394 * 395 * RETURN: None 396 * 397 * DESCRIPTION: Display information about internal mutexes. 398 * 399 ******************************************************************************/ 400 401 void 402 AcpiDbDisplayLocks ( 403 void) 404 { 405 UINT32 i; 406 407 408 for (i = 0; i < ACPI_MAX_MUTEX; i++) 409 { 410 AcpiOsPrintf ("%26s : %s\n", AcpiUtGetMutexName (i), 411 AcpiGbl_MutexInfo[i].ThreadId == ACPI_MUTEX_NOT_ACQUIRED 412 ? "Locked" : "Unlocked"); 413 } 414 } 415 416 417 /******************************************************************************* 418 * 419 * FUNCTION: AcpiDbDisplayTableInfo 420 * 421 * PARAMETERS: TableArg - String with name of table to be displayed 422 * 423 * RETURN: None 424 * 425 * DESCRIPTION: Display information about loaded tables. Current 426 * implementation displays all loaded tables. 427 * 428 ******************************************************************************/ 429 430 void 431 AcpiDbDisplayTableInfo ( 432 char *TableArg) 433 { 434 UINT32 i; 435 ACPI_TABLE_DESC *TableDesc; 436 437 438 /* Walk the entire root table list */ 439 440 for (i = 0; i < AcpiGbl_RootTableList.Count; i++) 441 { 442 TableDesc = &AcpiGbl_RootTableList.Tables[i]; 443 AcpiOsPrintf ("%d ", i); 444 445 /* Make sure that the table is mapped */ 446 447 AcpiTbVerifyTable (TableDesc); 448 449 /* Dump the table header */ 450 451 if (TableDesc->Pointer) 452 { 453 AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer); 454 } 455 else 456 { 457 /* If the pointer is null, the table has been unloaded */ 458 459 ACPI_INFO ((AE_INFO, "%4.4s - Table has been unloaded", 460 TableDesc->Signature.Ascii)); 461 } 462 } 463 } 464 465 466 /******************************************************************************* 467 * 468 * FUNCTION: AcpiDbUnloadAcpiTable 469 * 470 * PARAMETERS: TableArg - Name of the table to be unloaded 471 * InstanceArg - Which instance of the table to unload (if 472 * there are multiple tables of the same type) 473 * 474 * RETURN: Nonde 475 * 476 * DESCRIPTION: Unload an ACPI table. 477 * Instance is not implemented 478 * 479 ******************************************************************************/ 480 481 void 482 AcpiDbUnloadAcpiTable ( 483 char *TableArg, 484 char *InstanceArg) 485 { 486 /* TBD: Need to reimplement for new data structures */ 487 488 #if 0 489 UINT32 i; 490 ACPI_STATUS Status; 491 492 493 /* Search all tables for the target type */ 494 495 for (i = 0; i < (ACPI_TABLE_ID_MAX+1); i++) 496 { 497 if (!ACPI_STRNCMP (TableArg, AcpiGbl_TableData[i].Signature, 498 AcpiGbl_TableData[i].SigLength)) 499 { 500 /* Found the table, unload it */ 501 502 Status = AcpiUnloadTable (i); 503 if (ACPI_SUCCESS (Status)) 504 { 505 AcpiOsPrintf ("[%s] unloaded and uninstalled\n", TableArg); 506 } 507 else 508 { 509 AcpiOsPrintf ("%s, while unloading [%s]\n", 510 AcpiFormatException (Status), TableArg); 511 } 512 513 return; 514 } 515 } 516 517 AcpiOsPrintf ("Unknown table type [%s]\n", TableArg); 518 #endif 519 } 520 521 522 /******************************************************************************* 523 * 524 * FUNCTION: AcpiDbSetMethodBreakpoint 525 * 526 * PARAMETERS: Location - AML offset of breakpoint 527 * WalkState - Current walk info 528 * Op - Current Op (from parse walk) 529 * 530 * RETURN: None 531 * 532 * DESCRIPTION: Set a breakpoint in a control method at the specified 533 * AML offset 534 * 535 ******************************************************************************/ 536 537 void 538 AcpiDbSetMethodBreakpoint ( 539 char *Location, 540 ACPI_WALK_STATE *WalkState, 541 ACPI_PARSE_OBJECT *Op) 542 { 543 UINT32 Address; 544 545 546 if (!Op) 547 { 548 AcpiOsPrintf ("There is no method currently executing\n"); 549 return; 550 } 551 552 /* Get and verify the breakpoint address */ 553 554 Address = ACPI_STRTOUL (Location, NULL, 16); 555 if (Address <= Op->Common.AmlOffset) 556 { 557 AcpiOsPrintf ("Breakpoint %X is beyond current address %X\n", 558 Address, Op->Common.AmlOffset); 559 } 560 561 /* Save breakpoint in current walk */ 562 563 WalkState->UserBreakpoint = Address; 564 AcpiOsPrintf ("Breakpoint set at AML offset %X\n", Address); 565 } 566 567 568 /******************************************************************************* 569 * 570 * FUNCTION: AcpiDbSetMethodCallBreakpoint 571 * 572 * PARAMETERS: Op - Current Op (from parse walk) 573 * 574 * RETURN: None 575 * 576 * DESCRIPTION: Set a breakpoint in a control method at the specified 577 * AML offset 578 * 579 ******************************************************************************/ 580 581 void 582 AcpiDbSetMethodCallBreakpoint ( 583 ACPI_PARSE_OBJECT *Op) 584 { 585 586 587 if (!Op) 588 { 589 AcpiOsPrintf ("There is no method currently executing\n"); 590 return; 591 } 592 593 AcpiGbl_StepToNextCall = TRUE; 594 } 595 596 597 /******************************************************************************* 598 * 599 * FUNCTION: AcpiDbDisassembleAml 600 * 601 * PARAMETERS: Statements - Number of statements to disassemble 602 * Op - Current Op (from parse walk) 603 * 604 * RETURN: None 605 * 606 * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number 607 * of statements specified. 608 * 609 ******************************************************************************/ 610 611 void 612 AcpiDbDisassembleAml ( 613 char *Statements, 614 ACPI_PARSE_OBJECT *Op) 615 { 616 UINT32 NumStatements = 8; 617 618 619 if (!Op) 620 { 621 AcpiOsPrintf ("There is no method currently executing\n"); 622 return; 623 } 624 625 if (Statements) 626 { 627 NumStatements = ACPI_STRTOUL (Statements, NULL, 0); 628 } 629 630 AcpiDmDisassemble (NULL, Op, NumStatements); 631 } 632 633 634 /******************************************************************************* 635 * 636 * FUNCTION: AcpiDbDisassembleMethod 637 * 638 * PARAMETERS: Name - Name of control method 639 * 640 * RETURN: None 641 * 642 * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number 643 * of statements specified. 644 * 645 ******************************************************************************/ 646 647 ACPI_STATUS 648 AcpiDbDisassembleMethod ( 649 char *Name) 650 { 651 ACPI_STATUS Status; 652 ACPI_PARSE_OBJECT *Op; 653 ACPI_WALK_STATE *WalkState; 654 ACPI_OPERAND_OBJECT *ObjDesc; 655 ACPI_NAMESPACE_NODE *Method; 656 657 658 Method = AcpiDbConvertToNode (Name); 659 if (!Method) 660 { 661 return (AE_BAD_PARAMETER); 662 } 663 664 ObjDesc = Method->Object; 665 666 Op = AcpiPsCreateScopeOp (); 667 if (!Op) 668 { 669 return (AE_NO_MEMORY); 670 } 671 672 /* Create and initialize a new walk state */ 673 674 WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL); 675 if (!WalkState) 676 { 677 return (AE_NO_MEMORY); 678 } 679 680 Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, 681 ObjDesc->Method.AmlStart, 682 ObjDesc->Method.AmlLength, NULL, ACPI_IMODE_LOAD_PASS1); 683 if (ACPI_FAILURE (Status)) 684 { 685 return (Status); 686 } 687 688 /* Parse the AML */ 689 690 WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE; 691 WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE; 692 Status = AcpiPsParseAml (WalkState); 693 694 AcpiDmDisassemble (NULL, Op, 0); 695 AcpiPsDeleteParseTree (Op); 696 return (AE_OK); 697 } 698 699 700 /******************************************************************************* 701 * 702 * FUNCTION: AcpiDbDumpNamespace 703 * 704 * PARAMETERS: StartArg - Node to begin namespace dump 705 * DepthArg - Maximum tree depth to be dumped 706 * 707 * RETURN: None 708 * 709 * DESCRIPTION: Dump entire namespace or a subtree. Each node is displayed 710 * with type and other information. 711 * 712 ******************************************************************************/ 713 714 void 715 AcpiDbDumpNamespace ( 716 char *StartArg, 717 char *DepthArg) 718 { 719 ACPI_HANDLE SubtreeEntry = AcpiGbl_RootNode; 720 UINT32 MaxDepth = ACPI_UINT32_MAX; 721 722 723 /* No argument given, just start at the root and dump entire namespace */ 724 725 if (StartArg) 726 { 727 SubtreeEntry = AcpiDbConvertToNode (StartArg); 728 if (!SubtreeEntry) 729 { 730 return; 731 } 732 733 /* Now we can check for the depth argument */ 734 735 if (DepthArg) 736 { 737 MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0); 738 } 739 } 740 741 AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 742 AcpiOsPrintf ("ACPI Namespace (from %4.4s (%p) subtree):\n", 743 ((ACPI_NAMESPACE_NODE *) SubtreeEntry)->Name.Ascii, SubtreeEntry); 744 745 /* Display the subtree */ 746 747 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 748 AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth, 749 ACPI_OWNER_ID_MAX, SubtreeEntry); 750 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 751 } 752 753 754 /******************************************************************************* 755 * 756 * FUNCTION: AcpiDbDumpNamespaceByOwner 757 * 758 * PARAMETERS: OwnerArg - Owner ID whose nodes will be displayed 759 * DepthArg - Maximum tree depth to be dumped 760 * 761 * RETURN: None 762 * 763 * DESCRIPTION: Dump elements of the namespace that are owned by the OwnerId. 764 * 765 ******************************************************************************/ 766 767 void 768 AcpiDbDumpNamespaceByOwner ( 769 char *OwnerArg, 770 char *DepthArg) 771 { 772 ACPI_HANDLE SubtreeEntry = AcpiGbl_RootNode; 773 UINT32 MaxDepth = ACPI_UINT32_MAX; 774 ACPI_OWNER_ID OwnerId; 775 776 777 OwnerId = (ACPI_OWNER_ID) ACPI_STRTOUL (OwnerArg, NULL, 0); 778 779 /* Now we can check for the depth argument */ 780 781 if (DepthArg) 782 { 783 MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0); 784 } 785 786 AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 787 AcpiOsPrintf ("ACPI Namespace by owner %X:\n", OwnerId); 788 789 /* Display the subtree */ 790 791 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 792 AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth, OwnerId, 793 SubtreeEntry); 794 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 795 } 796 797 798 /******************************************************************************* 799 * 800 * FUNCTION: AcpiDbSendNotify 801 * 802 * PARAMETERS: Name - Name of ACPI object to send the notify to 803 * Value - Value of the notify to send. 804 * 805 * RETURN: None 806 * 807 * DESCRIPTION: Send an ACPI notification. The value specified is sent to the 808 * named object as an ACPI notify. 809 * 810 ******************************************************************************/ 811 812 void 813 AcpiDbSendNotify ( 814 char *Name, 815 UINT32 Value) 816 { 817 ACPI_NAMESPACE_NODE *Node; 818 ACPI_STATUS Status; 819 820 821 /* Translate name to an Named object */ 822 823 Node = AcpiDbConvertToNode (Name); 824 if (!Node) 825 { 826 return; 827 } 828 829 /* Decode Named object type */ 830 831 switch (Node->Type) 832 { 833 case ACPI_TYPE_DEVICE: 834 case ACPI_TYPE_THERMAL: 835 836 /* Send the notify */ 837 838 Status = AcpiEvQueueNotifyRequest (Node, Value); 839 if (ACPI_FAILURE (Status)) 840 { 841 AcpiOsPrintf ("Could not queue notify\n"); 842 } 843 break; 844 845 default: 846 AcpiOsPrintf ("Named object is not a device or a thermal object\n"); 847 break; 848 } 849 } 850 851 852 /******************************************************************************* 853 * 854 * FUNCTION: AcpiDbSetMethodData 855 * 856 * PARAMETERS: TypeArg - L for local, A for argument 857 * IndexArg - which one 858 * ValueArg - Value to set. 859 * 860 * RETURN: None 861 * 862 * DESCRIPTION: Set a local or argument for the running control method. 863 * NOTE: only object supported is Number. 864 * 865 ******************************************************************************/ 866 867 void 868 AcpiDbSetMethodData ( 869 char *TypeArg, 870 char *IndexArg, 871 char *ValueArg) 872 { 873 char Type; 874 UINT32 Index; 875 UINT32 Value; 876 ACPI_WALK_STATE *WalkState; 877 ACPI_OPERAND_OBJECT *ObjDesc; 878 ACPI_STATUS Status; 879 ACPI_NAMESPACE_NODE *Node; 880 881 882 /* Validate TypeArg */ 883 884 AcpiUtStrupr (TypeArg); 885 Type = TypeArg[0]; 886 if ((Type != 'L') && 887 (Type != 'A') && 888 (Type != 'N')) 889 { 890 AcpiOsPrintf ("Invalid SET operand: %s\n", TypeArg); 891 return; 892 } 893 894 Value = ACPI_STRTOUL (ValueArg, NULL, 16); 895 896 if (Type == 'N') 897 { 898 Node = AcpiDbConvertToNode (IndexArg); 899 if (Node->Type != ACPI_TYPE_INTEGER) 900 { 901 AcpiOsPrintf ("Can only set Integer nodes\n"); 902 return; 903 } 904 ObjDesc = Node->Object; 905 ObjDesc->Integer.Value = Value; 906 return; 907 } 908 909 /* Get the index and value */ 910 911 Index = ACPI_STRTOUL (IndexArg, NULL, 16); 912 913 WalkState = AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList); 914 if (!WalkState) 915 { 916 AcpiOsPrintf ("There is no method currently executing\n"); 917 return; 918 } 919 920 /* Create and initialize the new object */ 921 922 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); 923 if (!ObjDesc) 924 { 925 AcpiOsPrintf ("Could not create an internal object\n"); 926 return; 927 } 928 929 ObjDesc->Integer.Value = Value; 930 931 /* Store the new object into the target */ 932 933 switch (Type) 934 { 935 case 'A': 936 937 /* Set a method argument */ 938 939 if (Index > ACPI_METHOD_MAX_ARG) 940 { 941 AcpiOsPrintf ("Arg%d - Invalid argument name\n", Index); 942 goto Cleanup; 943 } 944 945 Status = AcpiDsStoreObjectToLocal (ACPI_REFCLASS_ARG, Index, ObjDesc, 946 WalkState); 947 if (ACPI_FAILURE (Status)) 948 { 949 goto Cleanup; 950 } 951 952 ObjDesc = WalkState->Arguments[Index].Object; 953 954 AcpiOsPrintf ("Arg%d: ", Index); 955 AcpiDmDisplayInternalObject (ObjDesc, WalkState); 956 break; 957 958 case 'L': 959 960 /* Set a method local */ 961 962 if (Index > ACPI_METHOD_MAX_LOCAL) 963 { 964 AcpiOsPrintf ("Local%d - Invalid local variable name\n", Index); 965 goto Cleanup; 966 } 967 968 Status = AcpiDsStoreObjectToLocal (ACPI_REFCLASS_LOCAL, Index, ObjDesc, 969 WalkState); 970 if (ACPI_FAILURE (Status)) 971 { 972 goto Cleanup; 973 } 974 975 ObjDesc = WalkState->LocalVariables[Index].Object; 976 977 AcpiOsPrintf ("Local%d: ", Index); 978 AcpiDmDisplayInternalObject (ObjDesc, WalkState); 979 break; 980 981 default: 982 break; 983 } 984 985 Cleanup: 986 AcpiUtRemoveReference (ObjDesc); 987 } 988 989 990 /******************************************************************************* 991 * 992 * FUNCTION: AcpiDbWalkForSpecificObjects 993 * 994 * PARAMETERS: Callback from WalkNamespace 995 * 996 * RETURN: Status 997 * 998 * DESCRIPTION: Display short info about objects in the namespace 999 * 1000 ******************************************************************************/ 1001 1002 static ACPI_STATUS 1003 AcpiDbWalkForSpecificObjects ( 1004 ACPI_HANDLE ObjHandle, 1005 UINT32 NestingLevel, 1006 void *Context, 1007 void **ReturnValue) 1008 { 1009 ACPI_WALK_INFO *Info = (ACPI_WALK_INFO *) Context; 1010 ACPI_BUFFER Buffer; 1011 ACPI_STATUS Status; 1012 1013 1014 Info->Count++; 1015 1016 /* Get and display the full pathname to this object */ 1017 1018 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 1019 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer); 1020 if (ACPI_FAILURE (Status)) 1021 { 1022 AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle); 1023 return (AE_OK); 1024 } 1025 1026 AcpiOsPrintf ("%32s", (char *) Buffer.Pointer); 1027 ACPI_FREE (Buffer.Pointer); 1028 1029 /* Dump short info about the object */ 1030 1031 (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, Info, NULL); 1032 return (AE_OK); 1033 } 1034 1035 1036 /******************************************************************************* 1037 * 1038 * FUNCTION: AcpiDbDisplayObjects 1039 * 1040 * PARAMETERS: ObjTypeArg - Type of object to display 1041 * DisplayCountArg - Max depth to display 1042 * 1043 * RETURN: None 1044 * 1045 * DESCRIPTION: Display objects in the namespace of the requested type 1046 * 1047 ******************************************************************************/ 1048 1049 ACPI_STATUS 1050 AcpiDbDisplayObjects ( 1051 char *ObjTypeArg, 1052 char *DisplayCountArg) 1053 { 1054 ACPI_WALK_INFO Info; 1055 ACPI_OBJECT_TYPE Type; 1056 1057 1058 /* Get the object type */ 1059 1060 Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes); 1061 if (Type == ACPI_TYPE_NOT_FOUND) 1062 { 1063 AcpiOsPrintf ("Invalid or unsupported argument\n"); 1064 return (AE_OK); 1065 } 1066 1067 AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 1068 AcpiOsPrintf ( 1069 "Objects of type [%s] defined in the current ACPI Namespace:\n", 1070 AcpiUtGetTypeName (Type)); 1071 1072 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 1073 1074 Info.Count = 0; 1075 Info.OwnerId = ACPI_OWNER_ID_MAX; 1076 Info.DebugLevel = ACPI_UINT32_MAX; 1077 Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT; 1078 1079 /* Walk the namespace from the root */ 1080 1081 (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, 1082 AcpiDbWalkForSpecificObjects, (void *) &Info, NULL); 1083 1084 AcpiOsPrintf ( 1085 "\nFound %u objects of type [%s] in the current ACPI Namespace\n", 1086 Info.Count, AcpiUtGetTypeName (Type)); 1087 1088 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 1089 return (AE_OK); 1090 } 1091 1092 1093 /******************************************************************************* 1094 * 1095 * FUNCTION: AcpiDbWalkAndMatchName 1096 * 1097 * PARAMETERS: Callback from WalkNamespace 1098 * 1099 * RETURN: Status 1100 * 1101 * DESCRIPTION: Find a particular name/names within the namespace. Wildcards 1102 * are supported -- '?' matches any character. 1103 * 1104 ******************************************************************************/ 1105 1106 static ACPI_STATUS 1107 AcpiDbWalkAndMatchName ( 1108 ACPI_HANDLE ObjHandle, 1109 UINT32 NestingLevel, 1110 void *Context, 1111 void **ReturnValue) 1112 { 1113 ACPI_STATUS Status; 1114 char *RequestedName = (char *) Context; 1115 UINT32 i; 1116 ACPI_BUFFER Buffer; 1117 ACPI_WALK_INFO Info; 1118 1119 1120 /* Check for a name match */ 1121 1122 for (i = 0; i < 4; i++) 1123 { 1124 /* Wildcard support */ 1125 1126 if ((RequestedName[i] != '?') && 1127 (RequestedName[i] != ((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Ascii[i])) 1128 { 1129 /* No match, just exit */ 1130 1131 return (AE_OK); 1132 } 1133 } 1134 1135 /* Get the full pathname to this object */ 1136 1137 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 1138 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer); 1139 if (ACPI_FAILURE (Status)) 1140 { 1141 AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle); 1142 } 1143 else 1144 { 1145 Info.OwnerId = ACPI_OWNER_ID_MAX; 1146 Info.DebugLevel = ACPI_UINT32_MAX; 1147 Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT; 1148 1149 AcpiOsPrintf ("%32s", (char *) Buffer.Pointer); 1150 (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, &Info, NULL); 1151 ACPI_FREE (Buffer.Pointer); 1152 } 1153 1154 return (AE_OK); 1155 } 1156 1157 1158 /******************************************************************************* 1159 * 1160 * FUNCTION: AcpiDbFindNameInNamespace 1161 * 1162 * PARAMETERS: NameArg - The 4-character ACPI name to find. 1163 * wildcards are supported. 1164 * 1165 * RETURN: None 1166 * 1167 * DESCRIPTION: Search the namespace for a given name (with wildcards) 1168 * 1169 ******************************************************************************/ 1170 1171 ACPI_STATUS 1172 AcpiDbFindNameInNamespace ( 1173 char *NameArg) 1174 { 1175 1176 if (ACPI_STRLEN (NameArg) > 4) 1177 { 1178 AcpiOsPrintf ("Name must be no longer than 4 characters\n"); 1179 return (AE_OK); 1180 } 1181 1182 /* Walk the namespace from the root */ 1183 1184 AcpiUtStrupr (NameArg); 1185 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, 1186 AcpiDbWalkAndMatchName, NameArg, NULL); 1187 1188 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 1189 return (AE_OK); 1190 } 1191 1192 1193 /******************************************************************************* 1194 * 1195 * FUNCTION: AcpiDbSetScope 1196 * 1197 * PARAMETERS: Name - New scope path 1198 * 1199 * RETURN: Status 1200 * 1201 * DESCRIPTION: Set the "current scope" as maintained by this utility. 1202 * The scope is used as a prefix to ACPI paths. 1203 * 1204 ******************************************************************************/ 1205 1206 void 1207 AcpiDbSetScope ( 1208 char *Name) 1209 { 1210 ACPI_STATUS Status; 1211 ACPI_NAMESPACE_NODE *Node; 1212 1213 1214 if (!Name || Name[0] == 0) 1215 { 1216 AcpiOsPrintf ("Current scope: %s\n", AcpiGbl_DbScopeBuf); 1217 return; 1218 } 1219 1220 AcpiDbPrepNamestring (Name); 1221 1222 if (Name[0] == '\\') 1223 { 1224 /* Validate new scope from the root */ 1225 1226 Status = AcpiNsGetNode (AcpiGbl_RootNode, Name, ACPI_NS_NO_UPSEARCH, 1227 &Node); 1228 if (ACPI_FAILURE (Status)) 1229 { 1230 goto ErrorExit; 1231 } 1232 1233 ACPI_STRCPY (AcpiGbl_DbScopeBuf, Name); 1234 ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\"); 1235 } 1236 else 1237 { 1238 /* Validate new scope relative to old scope */ 1239 1240 Status = AcpiNsGetNode (AcpiGbl_DbScopeNode, Name, ACPI_NS_NO_UPSEARCH, 1241 &Node); 1242 if (ACPI_FAILURE (Status)) 1243 { 1244 goto ErrorExit; 1245 } 1246 1247 ACPI_STRCAT (AcpiGbl_DbScopeBuf, Name); 1248 ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\"); 1249 } 1250 1251 AcpiGbl_DbScopeNode = Node; 1252 AcpiOsPrintf ("New scope: %s\n", AcpiGbl_DbScopeBuf); 1253 return; 1254 1255 ErrorExit: 1256 1257 AcpiOsPrintf ("Could not attach scope: %s, %s\n", 1258 Name, AcpiFormatException (Status)); 1259 } 1260 1261 1262 /******************************************************************************* 1263 * 1264 * FUNCTION: AcpiDmCompareAmlResources 1265 * 1266 * PARAMETERS: Aml1Buffer - Contains first resource list 1267 * Aml1BufferLength - Length of first resource list 1268 * Aml2Buffer - Contains second resource list 1269 * Aml2BufferLength - Length of second resource list 1270 * 1271 * RETURN: None 1272 * 1273 * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in 1274 * order to isolate a miscompare to an individual resource) 1275 * 1276 ******************************************************************************/ 1277 1278 static void 1279 AcpiDmCompareAmlResources ( 1280 UINT8 *Aml1Buffer, 1281 ACPI_RSDESC_SIZE Aml1BufferLength, 1282 UINT8 *Aml2Buffer, 1283 ACPI_RSDESC_SIZE Aml2BufferLength) 1284 { 1285 UINT8 *Aml1; 1286 UINT8 *Aml2; 1287 ACPI_RSDESC_SIZE Aml1Length; 1288 ACPI_RSDESC_SIZE Aml2Length; 1289 ACPI_RSDESC_SIZE Offset = 0; 1290 UINT8 ResourceType; 1291 UINT32 Count = 0; 1292 1293 1294 /* Compare overall buffer sizes (may be different due to size rounding) */ 1295 1296 if (Aml1BufferLength != Aml2BufferLength) 1297 { 1298 AcpiOsPrintf ( 1299 "**** Buffer length mismatch in converted AML: original %X new %X ****\n", 1300 Aml1BufferLength, Aml2BufferLength); 1301 } 1302 1303 Aml1 = Aml1Buffer; 1304 Aml2 = Aml2Buffer; 1305 1306 /* Walk the descriptor lists, comparing each descriptor */ 1307 1308 while (Aml1 < (Aml1Buffer + Aml1BufferLength)) 1309 { 1310 /* Get the lengths of each descriptor */ 1311 1312 Aml1Length = AcpiUtGetDescriptorLength (Aml1); 1313 Aml2Length = AcpiUtGetDescriptorLength (Aml2); 1314 ResourceType = AcpiUtGetResourceType (Aml1); 1315 1316 /* Check for descriptor length match */ 1317 1318 if (Aml1Length != Aml2Length) 1319 { 1320 AcpiOsPrintf ( 1321 "**** Length mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X L1 %X L2 %X ****\n", 1322 Count, ResourceType, Offset, Aml1Length, Aml2Length); 1323 } 1324 1325 /* Check for descriptor byte match */ 1326 1327 else if (ACPI_MEMCMP (Aml1, Aml2, Aml1Length)) 1328 { 1329 AcpiOsPrintf ( 1330 "**** Data mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X ****\n", 1331 Count, ResourceType, Offset); 1332 } 1333 1334 /* Exit on EndTag descriptor */ 1335 1336 if (ResourceType == ACPI_RESOURCE_NAME_END_TAG) 1337 { 1338 return; 1339 } 1340 1341 /* Point to next descriptor in each buffer */ 1342 1343 Count++; 1344 Offset += Aml1Length; 1345 Aml1 += Aml1Length; 1346 Aml2 += Aml2Length; 1347 } 1348 } 1349 1350 1351 /******************************************************************************* 1352 * 1353 * FUNCTION: AcpiDmTestResourceConversion 1354 * 1355 * PARAMETERS: Node - Parent device node 1356 * Name - resource method name (_CRS) 1357 * 1358 * RETURN: Status 1359 * 1360 * DESCRIPTION: Compare the original AML with a conversion of the AML to 1361 * internal resource list, then back to AML. 1362 * 1363 ******************************************************************************/ 1364 1365 static ACPI_STATUS 1366 AcpiDmTestResourceConversion ( 1367 ACPI_NAMESPACE_NODE *Node, 1368 char *Name) 1369 { 1370 ACPI_STATUS Status; 1371 ACPI_BUFFER ReturnObj; 1372 ACPI_BUFFER ResourceObj; 1373 ACPI_BUFFER NewAml; 1374 ACPI_OBJECT *OriginalAml; 1375 1376 1377 AcpiOsPrintf ("Resource Conversion Comparison:\n"); 1378 1379 NewAml.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 1380 ReturnObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 1381 ResourceObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 1382 1383 /* Get the original _CRS AML resource template */ 1384 1385 Status = AcpiEvaluateObject (Node, Name, NULL, &ReturnObj); 1386 if (ACPI_FAILURE (Status)) 1387 { 1388 AcpiOsPrintf ("Could not obtain %s: %s\n", 1389 Name, AcpiFormatException (Status)); 1390 return (Status); 1391 } 1392 1393 /* Get the AML resource template, converted to internal resource structs */ 1394 1395 Status = AcpiGetCurrentResources (Node, &ResourceObj); 1396 if (ACPI_FAILURE (Status)) 1397 { 1398 AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n", 1399 AcpiFormatException (Status)); 1400 goto Exit1; 1401 } 1402 1403 /* Convert internal resource list to external AML resource template */ 1404 1405 Status = AcpiRsCreateAmlResources (ResourceObj.Pointer, &NewAml); 1406 if (ACPI_FAILURE (Status)) 1407 { 1408 AcpiOsPrintf ("AcpiRsCreateAmlResources failed: %s\n", 1409 AcpiFormatException (Status)); 1410 goto Exit2; 1411 } 1412 1413 /* Compare original AML to the newly created AML resource list */ 1414 1415 OriginalAml = ReturnObj.Pointer; 1416 1417 AcpiDmCompareAmlResources ( 1418 OriginalAml->Buffer.Pointer, (ACPI_RSDESC_SIZE) OriginalAml->Buffer.Length, 1419 NewAml.Pointer, (ACPI_RSDESC_SIZE) NewAml.Length); 1420 1421 /* Cleanup and exit */ 1422 1423 ACPI_FREE (NewAml.Pointer); 1424 Exit2: 1425 ACPI_FREE (ResourceObj.Pointer); 1426 Exit1: 1427 ACPI_FREE (ReturnObj.Pointer); 1428 return (Status); 1429 } 1430 1431 1432 /******************************************************************************* 1433 * 1434 * FUNCTION: AcpiDbDisplayResources 1435 * 1436 * PARAMETERS: ObjectArg - String with hex value of the object 1437 * 1438 * RETURN: None 1439 * 1440 * DESCRIPTION: Display the resource objects associated with a device. 1441 * 1442 ******************************************************************************/ 1443 1444 void 1445 AcpiDbDisplayResources ( 1446 char *ObjectArg) 1447 { 1448 ACPI_NAMESPACE_NODE *Node; 1449 ACPI_STATUS Status; 1450 ACPI_BUFFER ReturnObj; 1451 1452 1453 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 1454 AcpiDbgLevel |= ACPI_LV_RESOURCES; 1455 1456 /* Convert string to object pointer */ 1457 1458 Node = AcpiDbConvertToNode (ObjectArg); 1459 if (!Node) 1460 { 1461 return; 1462 } 1463 1464 /* Prepare for a return object of arbitrary size */ 1465 1466 ReturnObj.Pointer = AcpiGbl_DbBuffer; 1467 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 1468 1469 /* _PRT */ 1470 1471 AcpiOsPrintf ("Evaluating _PRT\n"); 1472 1473 /* Check if _PRT exists */ 1474 1475 Status = AcpiEvaluateObject (Node, METHOD_NAME__PRT, NULL, &ReturnObj); 1476 if (ACPI_FAILURE (Status)) 1477 { 1478 AcpiOsPrintf ("Could not obtain _PRT: %s\n", 1479 AcpiFormatException (Status)); 1480 goto GetCrs; 1481 } 1482 1483 ReturnObj.Pointer = AcpiGbl_DbBuffer; 1484 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 1485 1486 Status = AcpiGetIrqRoutingTable (Node, &ReturnObj); 1487 if (ACPI_FAILURE (Status)) 1488 { 1489 AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n", 1490 AcpiFormatException (Status)); 1491 goto GetCrs; 1492 } 1493 1494 AcpiRsDumpIrqList (ACPI_CAST_PTR (UINT8, AcpiGbl_DbBuffer)); 1495 1496 1497 /* _CRS */ 1498 1499 GetCrs: 1500 AcpiOsPrintf ("Evaluating _CRS\n"); 1501 1502 ReturnObj.Pointer = AcpiGbl_DbBuffer; 1503 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 1504 1505 /* Check if _CRS exists */ 1506 1507 Status = AcpiEvaluateObject (Node, METHOD_NAME__CRS, NULL, &ReturnObj); 1508 if (ACPI_FAILURE (Status)) 1509 { 1510 AcpiOsPrintf ("Could not obtain _CRS: %s\n", 1511 AcpiFormatException (Status)); 1512 goto GetPrs; 1513 } 1514 1515 /* Get the _CRS resource list */ 1516 1517 ReturnObj.Pointer = AcpiGbl_DbBuffer; 1518 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 1519 1520 Status = AcpiGetCurrentResources (Node, &ReturnObj); 1521 if (ACPI_FAILURE (Status)) 1522 { 1523 AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n", 1524 AcpiFormatException (Status)); 1525 goto GetPrs; 1526 } 1527 1528 /* Dump the _CRS resource list */ 1529 1530 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, 1531 ReturnObj.Pointer)); 1532 1533 /* 1534 * Perform comparison of original AML to newly created AML. This tests both 1535 * the AML->Resource conversion and the Resource->Aml conversion. 1536 */ 1537 Status = AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS); 1538 1539 /* Execute _SRS with the resource list */ 1540 1541 Status = AcpiSetCurrentResources (Node, &ReturnObj); 1542 if (ACPI_FAILURE (Status)) 1543 { 1544 AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n", 1545 AcpiFormatException (Status)); 1546 goto GetPrs; 1547 } 1548 1549 1550 /* _PRS */ 1551 1552 GetPrs: 1553 AcpiOsPrintf ("Evaluating _PRS\n"); 1554 1555 ReturnObj.Pointer = AcpiGbl_DbBuffer; 1556 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 1557 1558 /* Check if _PRS exists */ 1559 1560 Status = AcpiEvaluateObject (Node, METHOD_NAME__PRS, NULL, &ReturnObj); 1561 if (ACPI_FAILURE (Status)) 1562 { 1563 AcpiOsPrintf ("Could not obtain _PRS: %s\n", 1564 AcpiFormatException (Status)); 1565 goto Cleanup; 1566 } 1567 1568 ReturnObj.Pointer = AcpiGbl_DbBuffer; 1569 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 1570 1571 Status = AcpiGetPossibleResources (Node, &ReturnObj); 1572 if (ACPI_FAILURE (Status)) 1573 { 1574 AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n", 1575 AcpiFormatException (Status)); 1576 goto Cleanup; 1577 } 1578 1579 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer)); 1580 1581 Cleanup: 1582 1583 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 1584 return; 1585 } 1586 1587 1588 /******************************************************************************* 1589 * 1590 * FUNCTION: AcpiDbIntegrityWalk 1591 * 1592 * PARAMETERS: Callback from WalkNamespace 1593 * 1594 * RETURN: Status 1595 * 1596 * DESCRIPTION: Examine one NS node for valid values. 1597 * 1598 ******************************************************************************/ 1599 1600 static ACPI_STATUS 1601 AcpiDbIntegrityWalk ( 1602 ACPI_HANDLE ObjHandle, 1603 UINT32 NestingLevel, 1604 void *Context, 1605 void **ReturnValue) 1606 { 1607 ACPI_INTEGRITY_INFO *Info = (ACPI_INTEGRITY_INFO *) Context; 1608 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 1609 ACPI_OPERAND_OBJECT *Object; 1610 BOOLEAN Alias = TRUE; 1611 1612 1613 Info->Nodes++; 1614 1615 /* Verify the NS node, and dereference aliases */ 1616 1617 while (Alias) 1618 { 1619 if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED) 1620 { 1621 AcpiOsPrintf ("Invalid Descriptor Type for Node %p [%s] - is %2.2X should be %2.2X\n", 1622 Node, AcpiUtGetDescriptorName (Node), ACPI_GET_DESCRIPTOR_TYPE (Node), 1623 ACPI_DESC_TYPE_NAMED); 1624 return (AE_OK); 1625 } 1626 1627 if ((Node->Type == ACPI_TYPE_LOCAL_ALIAS) || 1628 (Node->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) 1629 { 1630 Node = (ACPI_NAMESPACE_NODE *) Node->Object; 1631 } 1632 else 1633 { 1634 Alias = FALSE; 1635 } 1636 } 1637 1638 if (Node->Type > ACPI_TYPE_LOCAL_MAX) 1639 { 1640 AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n", 1641 Node, Node->Type); 1642 return (AE_OK); 1643 } 1644 1645 if (!AcpiUtValidAcpiName (Node->Name.Integer)) 1646 { 1647 AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node); 1648 return (AE_OK); 1649 } 1650 1651 Object = AcpiNsGetAttachedObject (Node); 1652 if (Object) 1653 { 1654 Info->Objects++; 1655 if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND) 1656 { 1657 AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n", 1658 Object, AcpiUtGetDescriptorName (Object)); 1659 } 1660 } 1661 1662 return (AE_OK); 1663 } 1664 1665 1666 /******************************************************************************* 1667 * 1668 * FUNCTION: AcpiDbCheckIntegrity 1669 * 1670 * PARAMETERS: None 1671 * 1672 * RETURN: None 1673 * 1674 * DESCRIPTION: Check entire namespace for data structure integrity 1675 * 1676 ******************************************************************************/ 1677 1678 void 1679 AcpiDbCheckIntegrity ( 1680 void) 1681 { 1682 ACPI_INTEGRITY_INFO Info = {0,0}; 1683 1684 /* Search all nodes in namespace */ 1685 1686 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, 1687 AcpiDbIntegrityWalk, (void *) &Info, NULL); 1688 1689 AcpiOsPrintf ("Verified %d namespace nodes with %d Objects\n", 1690 Info.Nodes, Info.Objects); 1691 } 1692 1693 1694 /******************************************************************************* 1695 * 1696 * FUNCTION: AcpiDbGenerateGpe 1697 * 1698 * PARAMETERS: GpeArg - Raw GPE number, ascii string 1699 * BlockArg - GPE block number, ascii string 1700 * 0 or 1 for FADT GPE blocks 1701 * 1702 * RETURN: None 1703 * 1704 * DESCRIPTION: Generate a GPE 1705 * 1706 ******************************************************************************/ 1707 1708 void 1709 AcpiDbGenerateGpe ( 1710 char *GpeArg, 1711 char *BlockArg) 1712 { 1713 UINT32 BlockNumber; 1714 UINT32 GpeNumber; 1715 ACPI_GPE_EVENT_INFO *GpeEventInfo; 1716 1717 1718 GpeNumber = ACPI_STRTOUL (GpeArg, NULL, 0); 1719 BlockNumber = ACPI_STRTOUL (BlockArg, NULL, 0); 1720 1721 1722 GpeEventInfo = AcpiEvGetGpeEventInfo (ACPI_TO_POINTER (BlockNumber), 1723 GpeNumber); 1724 if (!GpeEventInfo) 1725 { 1726 AcpiOsPrintf ("Invalid GPE\n"); 1727 return; 1728 } 1729 1730 (void) AcpiEvGpeDispatch (GpeEventInfo, GpeNumber); 1731 } 1732 1733 1734 /******************************************************************************* 1735 * 1736 * FUNCTION: AcpiDbBusWalk 1737 * 1738 * PARAMETERS: Callback from WalkNamespace 1739 * 1740 * RETURN: Status 1741 * 1742 * DESCRIPTION: Display info about device objects that have a corresponding 1743 * _PRT method. 1744 * 1745 ******************************************************************************/ 1746 1747 static ACPI_STATUS 1748 AcpiDbBusWalk ( 1749 ACPI_HANDLE ObjHandle, 1750 UINT32 NestingLevel, 1751 void *Context, 1752 void **ReturnValue) 1753 { 1754 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 1755 ACPI_STATUS Status; 1756 ACPI_BUFFER Buffer; 1757 ACPI_INTEGER ADR; 1758 ACPI_DEVICE_ID Id; 1759 ACPI_COMPATIBLE_ID_LIST *Cid; 1760 ACPI_NAMESPACE_NODE *TempNode; 1761 1762 1763 /* Exit if there is no _PRT under this device */ 1764 1765 Status = AcpiGetHandle (Node, METHOD_NAME__PRT, 1766 ACPI_CAST_PTR (ACPI_HANDLE, &TempNode)); 1767 if (ACPI_FAILURE (Status)) 1768 { 1769 return (AE_OK); 1770 } 1771 1772 /* Get the full path to this device object */ 1773 1774 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 1775 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer); 1776 if (ACPI_FAILURE (Status)) 1777 { 1778 AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle); 1779 return (AE_OK); 1780 } 1781 1782 /* Display the full path */ 1783 1784 AcpiOsPrintf ("%-32s", (char *) Buffer.Pointer); 1785 ACPI_FREE (Buffer.Pointer); 1786 1787 /* _PRT info */ 1788 1789 AcpiOsPrintf ("_PRT=%p", TempNode); 1790 1791 /* Get the _ADR value */ 1792 1793 Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node, &ADR); 1794 if (ACPI_FAILURE (Status)) 1795 { 1796 AcpiOsPrintf (" No _ADR "); 1797 } 1798 else 1799 { 1800 AcpiOsPrintf (" _ADR=%8.8X", (UINT32) ADR); 1801 } 1802 1803 /* Get the _HID if present */ 1804 1805 Status = AcpiUtExecute_HID (Node, &Id); 1806 if (ACPI_SUCCESS (Status)) 1807 { 1808 AcpiOsPrintf (" _HID=%s", Id.Value); 1809 } 1810 else 1811 { 1812 AcpiOsPrintf (" "); 1813 } 1814 1815 /* Get the _UID if present */ 1816 1817 Status = AcpiUtExecute_UID (Node, &Id); 1818 if (ACPI_SUCCESS (Status)) 1819 { 1820 AcpiOsPrintf (" _UID=%s", Id.Value); 1821 } 1822 1823 /* Get the _CID if present */ 1824 1825 Status = AcpiUtExecute_CID (Node, &Cid); 1826 if (ACPI_SUCCESS (Status)) 1827 { 1828 AcpiOsPrintf (" _CID=%s", Cid->Id[0].Value); 1829 ACPI_FREE (Cid); 1830 } 1831 1832 AcpiOsPrintf ("\n"); 1833 return (AE_OK); 1834 } 1835 1836 1837 /******************************************************************************* 1838 * 1839 * FUNCTION: AcpiDbGetBusInfo 1840 * 1841 * PARAMETERS: None 1842 * 1843 * RETURN: None 1844 * 1845 * DESCRIPTION: Display info about system busses. 1846 * 1847 ******************************************************************************/ 1848 1849 void 1850 AcpiDbGetBusInfo ( 1851 void) 1852 { 1853 /* Search all nodes in namespace */ 1854 1855 (void) AcpiWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, 1856 AcpiDbBusWalk, NULL, NULL); 1857 } 1858 1859 #endif /* ACPI_DEBUGGER */ 1860