1 /******************************************************************************* 2 * 3 * Module Name: dbcmds - debug commands and output routines 4 * 5 ******************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2009, 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 117 #include "acpi.h" 118 #include "accommon.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: AcpiDbWalkForPredefinedNames 392 * 393 * PARAMETERS: Callback from WalkNamespace 394 * 395 * RETURN: Status 396 * 397 * DESCRIPTION: Detect and display predefined ACPI names (names that start with 398 * an underscore) 399 * 400 ******************************************************************************/ 401 402 static ACPI_STATUS 403 AcpiDbWalkForPredefinedNames ( 404 ACPI_HANDLE ObjHandle, 405 UINT32 NestingLevel, 406 void *Context, 407 void **ReturnValue) 408 { 409 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 410 UINT32 *Count = (UINT32 *) Context; 411 const ACPI_PREDEFINED_INFO *Predefined; 412 const ACPI_PREDEFINED_INFO *Package = NULL; 413 char *Pathname; 414 415 416 Predefined = AcpiNsCheckForPredefinedName (Node); 417 if (!Predefined) 418 { 419 return (AE_OK); 420 } 421 422 Pathname = AcpiNsGetExternalPathname (Node); 423 if (!Pathname) 424 { 425 return (AE_OK); 426 } 427 428 /* If method returns a package, the info is in the next table entry */ 429 430 if (Predefined->Info.ExpectedBtypes & ACPI_BTYPE_PACKAGE) 431 { 432 Package = Predefined + 1; 433 } 434 435 AcpiOsPrintf ("%-32s arg %X ret %2.2X", Pathname, 436 Predefined->Info.ParamCount, Predefined->Info.ExpectedBtypes); 437 438 if (Package) 439 { 440 AcpiOsPrintf (" PkgType %2.2X ObjType %2.2X Count %2.2X", 441 Package->RetInfo.Type, Package->RetInfo.ObjectType1, 442 Package->RetInfo.Count1); 443 } 444 445 AcpiOsPrintf("\n"); 446 447 AcpiNsCheckParameterCount (Pathname, Node, ACPI_UINT32_MAX, Predefined); 448 ACPI_FREE (Pathname); 449 (*Count)++; 450 451 return (AE_OK); 452 } 453 454 455 /******************************************************************************* 456 * 457 * FUNCTION: AcpiDbCheckPredefinedNames 458 * 459 * PARAMETERS: None 460 * 461 * RETURN: None 462 * 463 * DESCRIPTION: Validate all predefined names in the namespace 464 * 465 ******************************************************************************/ 466 467 void 468 AcpiDbCheckPredefinedNames ( 469 void) 470 { 471 UINT32 Count = 0; 472 473 474 /* Search all nodes in namespace */ 475 476 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, 477 AcpiDbWalkForPredefinedNames, (void *) &Count, NULL); 478 479 AcpiOsPrintf ("Found %d predefined names in the namespace\n", Count); 480 } 481 482 483 /******************************************************************************* 484 * 485 * FUNCTION: AcpiDbWalkForExecute 486 * 487 * PARAMETERS: Callback from WalkNamespace 488 * 489 * RETURN: Status 490 * 491 * DESCRIPTION: Batch execution module. Currently only executes predefined 492 * ACPI names. 493 * 494 ******************************************************************************/ 495 496 static ACPI_STATUS 497 AcpiDbWalkForExecute ( 498 ACPI_HANDLE ObjHandle, 499 UINT32 NestingLevel, 500 void *Context, 501 void **ReturnValue) 502 { 503 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 504 UINT32 *Count = (UINT32 *) Context; 505 const ACPI_PREDEFINED_INFO *Predefined; 506 ACPI_BUFFER ReturnObj; 507 ACPI_STATUS Status; 508 char *Pathname; 509 ACPI_BUFFER Buffer; 510 UINT32 i; 511 ACPI_DEVICE_INFO *ObjInfo; 512 ACPI_OBJECT_LIST ParamObjects; 513 ACPI_OBJECT Params[ACPI_METHOD_NUM_ARGS]; 514 515 516 Predefined = AcpiNsCheckForPredefinedName (Node); 517 if (!Predefined) 518 { 519 return (AE_OK); 520 } 521 522 if (Node->Type == ACPI_TYPE_LOCAL_SCOPE) 523 { 524 return (AE_OK); 525 } 526 527 Pathname = AcpiNsGetExternalPathname (Node); 528 if (!Pathname) 529 { 530 return (AE_OK); 531 } 532 533 /* Get the object info for number of method parameters */ 534 535 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 536 Status = AcpiGetObjectInfo (ObjHandle, &Buffer); 537 if (ACPI_FAILURE (Status)) 538 { 539 return (Status); 540 } 541 542 ParamObjects.Pointer = NULL; 543 ParamObjects.Count = 0; 544 545 ObjInfo = Buffer.Pointer; 546 if (ObjInfo->Type == ACPI_TYPE_METHOD) 547 { 548 549 /* Setup default parameters */ 550 551 for (i = 0; i < ObjInfo->ParamCount; i++) 552 { 553 Params[i].Type = ACPI_TYPE_INTEGER; 554 Params[i].Integer.Value = 1; 555 } 556 557 ParamObjects.Pointer = Params; 558 ParamObjects.Count = ObjInfo->ParamCount; 559 } 560 561 ACPI_FREE (Buffer.Pointer); 562 563 ReturnObj.Pointer = NULL; 564 ReturnObj.Length = ACPI_ALLOCATE_BUFFER; 565 566 567 /* Do the actual method execution */ 568 569 AcpiGbl_MethodExecuting = TRUE; 570 571 Status = AcpiEvaluateObject (Node, NULL, &ParamObjects, &ReturnObj); 572 573 AcpiOsPrintf ("%-32s returned %s\n", Pathname, AcpiFormatException (Status)); 574 AcpiGbl_MethodExecuting = FALSE; 575 576 ACPI_FREE (Pathname); 577 (*Count)++; 578 579 return (AE_OK); 580 } 581 582 583 /******************************************************************************* 584 * 585 * FUNCTION: AcpiDbBatchExecute 586 * 587 * PARAMETERS: None 588 * 589 * RETURN: None 590 * 591 * DESCRIPTION: Namespace batch execution. 592 * 593 ******************************************************************************/ 594 595 void 596 AcpiDbBatchExecute ( 597 void) 598 { 599 UINT32 Count = 0; 600 601 602 /* Search all nodes in namespace */ 603 604 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, 605 AcpiDbWalkForExecute, (void *) &Count, NULL); 606 607 AcpiOsPrintf ("Executed %d predefined names in the namespace\n", Count); 608 } 609 610 611 /******************************************************************************* 612 * 613 * FUNCTION: AcpiDbDisplayLocks 614 * 615 * PARAMETERS: None 616 * 617 * RETURN: None 618 * 619 * DESCRIPTION: Display information about internal mutexes. 620 * 621 ******************************************************************************/ 622 623 void 624 AcpiDbDisplayLocks ( 625 void) 626 { 627 UINT32 i; 628 629 630 for (i = 0; i < ACPI_MAX_MUTEX; i++) 631 { 632 AcpiOsPrintf ("%26s : %s\n", AcpiUtGetMutexName (i), 633 AcpiGbl_MutexInfo[i].ThreadId == ACPI_MUTEX_NOT_ACQUIRED 634 ? "Locked" : "Unlocked"); 635 } 636 } 637 638 639 /******************************************************************************* 640 * 641 * FUNCTION: AcpiDbDisplayTableInfo 642 * 643 * PARAMETERS: TableArg - String with name of table to be displayed 644 * 645 * RETURN: None 646 * 647 * DESCRIPTION: Display information about loaded tables. Current 648 * implementation displays all loaded tables. 649 * 650 ******************************************************************************/ 651 652 void 653 AcpiDbDisplayTableInfo ( 654 char *TableArg) 655 { 656 UINT32 i; 657 ACPI_TABLE_DESC *TableDesc; 658 ACPI_STATUS Status; 659 660 661 /* Walk the entire root table list */ 662 663 for (i = 0; i < AcpiGbl_RootTableList.Count; i++) 664 { 665 TableDesc = &AcpiGbl_RootTableList.Tables[i]; 666 AcpiOsPrintf ("%d ", i); 667 668 /* Make sure that the table is mapped */ 669 670 Status = AcpiTbVerifyTable (TableDesc); 671 if (ACPI_FAILURE (Status)) 672 { 673 return; 674 } 675 676 /* Dump the table header */ 677 678 if (TableDesc->Pointer) 679 { 680 AcpiTbPrintTableHeader (TableDesc->Address, TableDesc->Pointer); 681 } 682 else 683 { 684 /* If the pointer is null, the table has been unloaded */ 685 686 ACPI_INFO ((AE_INFO, "%4.4s - Table has been unloaded", 687 TableDesc->Signature.Ascii)); 688 } 689 } 690 } 691 692 693 /******************************************************************************* 694 * 695 * FUNCTION: AcpiDbUnloadAcpiTable 696 * 697 * PARAMETERS: TableArg - Name of the table to be unloaded 698 * InstanceArg - Which instance of the table to unload (if 699 * there are multiple tables of the same type) 700 * 701 * RETURN: Nonde 702 * 703 * DESCRIPTION: Unload an ACPI table. 704 * Instance is not implemented 705 * 706 ******************************************************************************/ 707 708 void 709 AcpiDbUnloadAcpiTable ( 710 char *TableArg, 711 char *InstanceArg) 712 { 713 /* TBD: Need to reimplement for new data structures */ 714 715 #if 0 716 UINT32 i; 717 ACPI_STATUS Status; 718 719 720 /* Search all tables for the target type */ 721 722 for (i = 0; i < (ACPI_TABLE_ID_MAX+1); i++) 723 { 724 if (!ACPI_STRNCMP (TableArg, AcpiGbl_TableData[i].Signature, 725 AcpiGbl_TableData[i].SigLength)) 726 { 727 /* Found the table, unload it */ 728 729 Status = AcpiUnloadTable (i); 730 if (ACPI_SUCCESS (Status)) 731 { 732 AcpiOsPrintf ("[%s] unloaded and uninstalled\n", TableArg); 733 } 734 else 735 { 736 AcpiOsPrintf ("%s, while unloading [%s]\n", 737 AcpiFormatException (Status), TableArg); 738 } 739 740 return; 741 } 742 } 743 744 AcpiOsPrintf ("Unknown table type [%s]\n", TableArg); 745 #endif 746 } 747 748 749 /******************************************************************************* 750 * 751 * FUNCTION: AcpiDbSetMethodBreakpoint 752 * 753 * PARAMETERS: Location - AML offset of breakpoint 754 * WalkState - Current walk info 755 * Op - Current Op (from parse walk) 756 * 757 * RETURN: None 758 * 759 * DESCRIPTION: Set a breakpoint in a control method at the specified 760 * AML offset 761 * 762 ******************************************************************************/ 763 764 void 765 AcpiDbSetMethodBreakpoint ( 766 char *Location, 767 ACPI_WALK_STATE *WalkState, 768 ACPI_PARSE_OBJECT *Op) 769 { 770 UINT32 Address; 771 772 773 if (!Op) 774 { 775 AcpiOsPrintf ("There is no method currently executing\n"); 776 return; 777 } 778 779 /* Get and verify the breakpoint address */ 780 781 Address = ACPI_STRTOUL (Location, NULL, 16); 782 if (Address <= Op->Common.AmlOffset) 783 { 784 AcpiOsPrintf ("Breakpoint %X is beyond current address %X\n", 785 Address, Op->Common.AmlOffset); 786 } 787 788 /* Save breakpoint in current walk */ 789 790 WalkState->UserBreakpoint = Address; 791 AcpiOsPrintf ("Breakpoint set at AML offset %X\n", Address); 792 } 793 794 795 /******************************************************************************* 796 * 797 * FUNCTION: AcpiDbSetMethodCallBreakpoint 798 * 799 * PARAMETERS: Op - Current Op (from parse walk) 800 * 801 * RETURN: None 802 * 803 * DESCRIPTION: Set a breakpoint in a control method at the specified 804 * AML offset 805 * 806 ******************************************************************************/ 807 808 void 809 AcpiDbSetMethodCallBreakpoint ( 810 ACPI_PARSE_OBJECT *Op) 811 { 812 813 814 if (!Op) 815 { 816 AcpiOsPrintf ("There is no method currently executing\n"); 817 return; 818 } 819 820 AcpiGbl_StepToNextCall = TRUE; 821 } 822 823 824 /******************************************************************************* 825 * 826 * FUNCTION: AcpiDbDisassembleAml 827 * 828 * PARAMETERS: Statements - Number of statements to disassemble 829 * Op - Current Op (from parse walk) 830 * 831 * RETURN: None 832 * 833 * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number 834 * of statements specified. 835 * 836 ******************************************************************************/ 837 838 void 839 AcpiDbDisassembleAml ( 840 char *Statements, 841 ACPI_PARSE_OBJECT *Op) 842 { 843 UINT32 NumStatements = 8; 844 845 846 if (!Op) 847 { 848 AcpiOsPrintf ("There is no method currently executing\n"); 849 return; 850 } 851 852 if (Statements) 853 { 854 NumStatements = ACPI_STRTOUL (Statements, NULL, 0); 855 } 856 857 AcpiDmDisassemble (NULL, Op, NumStatements); 858 } 859 860 861 /******************************************************************************* 862 * 863 * FUNCTION: AcpiDbDisassembleMethod 864 * 865 * PARAMETERS: Name - Name of control method 866 * 867 * RETURN: None 868 * 869 * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number 870 * of statements specified. 871 * 872 ******************************************************************************/ 873 874 ACPI_STATUS 875 AcpiDbDisassembleMethod ( 876 char *Name) 877 { 878 ACPI_STATUS Status; 879 ACPI_PARSE_OBJECT *Op; 880 ACPI_WALK_STATE *WalkState; 881 ACPI_OPERAND_OBJECT *ObjDesc; 882 ACPI_NAMESPACE_NODE *Method; 883 884 885 Method = AcpiDbConvertToNode (Name); 886 if (!Method) 887 { 888 return (AE_BAD_PARAMETER); 889 } 890 891 ObjDesc = Method->Object; 892 893 Op = AcpiPsCreateScopeOp (); 894 if (!Op) 895 { 896 return (AE_NO_MEMORY); 897 } 898 899 /* Create and initialize a new walk state */ 900 901 WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL); 902 if (!WalkState) 903 { 904 return (AE_NO_MEMORY); 905 } 906 907 Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, 908 ObjDesc->Method.AmlStart, 909 ObjDesc->Method.AmlLength, NULL, ACPI_IMODE_LOAD_PASS1); 910 if (ACPI_FAILURE (Status)) 911 { 912 return (Status); 913 } 914 915 /* Parse the AML */ 916 917 WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE; 918 WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE; 919 Status = AcpiPsParseAml (WalkState); 920 921 AcpiDmDisassemble (NULL, Op, 0); 922 AcpiPsDeleteParseTree (Op); 923 return (AE_OK); 924 } 925 926 927 /******************************************************************************* 928 * 929 * FUNCTION: AcpiDbDumpNamespace 930 * 931 * PARAMETERS: StartArg - Node to begin namespace dump 932 * DepthArg - Maximum tree depth to be dumped 933 * 934 * RETURN: None 935 * 936 * DESCRIPTION: Dump entire namespace or a subtree. Each node is displayed 937 * with type and other information. 938 * 939 ******************************************************************************/ 940 941 void 942 AcpiDbDumpNamespace ( 943 char *StartArg, 944 char *DepthArg) 945 { 946 ACPI_HANDLE SubtreeEntry = AcpiGbl_RootNode; 947 UINT32 MaxDepth = ACPI_UINT32_MAX; 948 949 950 /* No argument given, just start at the root and dump entire namespace */ 951 952 if (StartArg) 953 { 954 SubtreeEntry = AcpiDbConvertToNode (StartArg); 955 if (!SubtreeEntry) 956 { 957 return; 958 } 959 960 /* Now we can check for the depth argument */ 961 962 if (DepthArg) 963 { 964 MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0); 965 } 966 } 967 968 AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 969 AcpiOsPrintf ("ACPI Namespace (from %4.4s (%p) subtree):\n", 970 ((ACPI_NAMESPACE_NODE *) SubtreeEntry)->Name.Ascii, SubtreeEntry); 971 972 /* Display the subtree */ 973 974 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 975 AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth, 976 ACPI_OWNER_ID_MAX, SubtreeEntry); 977 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 978 } 979 980 981 /******************************************************************************* 982 * 983 * FUNCTION: AcpiDbDumpNamespaceByOwner 984 * 985 * PARAMETERS: OwnerArg - Owner ID whose nodes will be displayed 986 * DepthArg - Maximum tree depth to be dumped 987 * 988 * RETURN: None 989 * 990 * DESCRIPTION: Dump elements of the namespace that are owned by the OwnerId. 991 * 992 ******************************************************************************/ 993 994 void 995 AcpiDbDumpNamespaceByOwner ( 996 char *OwnerArg, 997 char *DepthArg) 998 { 999 ACPI_HANDLE SubtreeEntry = AcpiGbl_RootNode; 1000 UINT32 MaxDepth = ACPI_UINT32_MAX; 1001 ACPI_OWNER_ID OwnerId; 1002 1003 1004 OwnerId = (ACPI_OWNER_ID) ACPI_STRTOUL (OwnerArg, NULL, 0); 1005 1006 /* Now we can check for the depth argument */ 1007 1008 if (DepthArg) 1009 { 1010 MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0); 1011 } 1012 1013 AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 1014 AcpiOsPrintf ("ACPI Namespace by owner %X:\n", OwnerId); 1015 1016 /* Display the subtree */ 1017 1018 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 1019 AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth, OwnerId, 1020 SubtreeEntry); 1021 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 1022 } 1023 1024 1025 /******************************************************************************* 1026 * 1027 * FUNCTION: AcpiDbSendNotify 1028 * 1029 * PARAMETERS: Name - Name of ACPI object to send the notify to 1030 * Value - Value of the notify to send. 1031 * 1032 * RETURN: None 1033 * 1034 * DESCRIPTION: Send an ACPI notification. The value specified is sent to the 1035 * named object as an ACPI notify. 1036 * 1037 ******************************************************************************/ 1038 1039 void 1040 AcpiDbSendNotify ( 1041 char *Name, 1042 UINT32 Value) 1043 { 1044 ACPI_NAMESPACE_NODE *Node; 1045 ACPI_STATUS Status; 1046 1047 1048 /* Translate name to an Named object */ 1049 1050 Node = AcpiDbConvertToNode (Name); 1051 if (!Node) 1052 { 1053 return; 1054 } 1055 1056 /* Decode Named object type */ 1057 1058 switch (Node->Type) 1059 { 1060 case ACPI_TYPE_DEVICE: 1061 case ACPI_TYPE_THERMAL: 1062 1063 /* Send the notify */ 1064 1065 Status = AcpiEvQueueNotifyRequest (Node, Value); 1066 if (ACPI_FAILURE (Status)) 1067 { 1068 AcpiOsPrintf ("Could not queue notify\n"); 1069 } 1070 break; 1071 1072 default: 1073 AcpiOsPrintf ("Named object is not a device or a thermal object\n"); 1074 break; 1075 } 1076 } 1077 1078 1079 /******************************************************************************* 1080 * 1081 * FUNCTION: AcpiDbSetMethodData 1082 * 1083 * PARAMETERS: TypeArg - L for local, A for argument 1084 * IndexArg - which one 1085 * ValueArg - Value to set. 1086 * 1087 * RETURN: None 1088 * 1089 * DESCRIPTION: Set a local or argument for the running control method. 1090 * NOTE: only object supported is Number. 1091 * 1092 ******************************************************************************/ 1093 1094 void 1095 AcpiDbSetMethodData ( 1096 char *TypeArg, 1097 char *IndexArg, 1098 char *ValueArg) 1099 { 1100 char Type; 1101 UINT32 Index; 1102 UINT32 Value; 1103 ACPI_WALK_STATE *WalkState; 1104 ACPI_OPERAND_OBJECT *ObjDesc; 1105 ACPI_STATUS Status; 1106 ACPI_NAMESPACE_NODE *Node; 1107 1108 1109 /* Validate TypeArg */ 1110 1111 AcpiUtStrupr (TypeArg); 1112 Type = TypeArg[0]; 1113 if ((Type != 'L') && 1114 (Type != 'A') && 1115 (Type != 'N')) 1116 { 1117 AcpiOsPrintf ("Invalid SET operand: %s\n", TypeArg); 1118 return; 1119 } 1120 1121 Value = ACPI_STRTOUL (ValueArg, NULL, 16); 1122 1123 if (Type == 'N') 1124 { 1125 Node = AcpiDbConvertToNode (IndexArg); 1126 if (Node->Type != ACPI_TYPE_INTEGER) 1127 { 1128 AcpiOsPrintf ("Can only set Integer nodes\n"); 1129 return; 1130 } 1131 ObjDesc = Node->Object; 1132 ObjDesc->Integer.Value = Value; 1133 return; 1134 } 1135 1136 /* Get the index and value */ 1137 1138 Index = ACPI_STRTOUL (IndexArg, NULL, 16); 1139 1140 WalkState = AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList); 1141 if (!WalkState) 1142 { 1143 AcpiOsPrintf ("There is no method currently executing\n"); 1144 return; 1145 } 1146 1147 /* Create and initialize the new object */ 1148 1149 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); 1150 if (!ObjDesc) 1151 { 1152 AcpiOsPrintf ("Could not create an internal object\n"); 1153 return; 1154 } 1155 1156 ObjDesc->Integer.Value = Value; 1157 1158 /* Store the new object into the target */ 1159 1160 switch (Type) 1161 { 1162 case 'A': 1163 1164 /* Set a method argument */ 1165 1166 if (Index > ACPI_METHOD_MAX_ARG) 1167 { 1168 AcpiOsPrintf ("Arg%d - Invalid argument name\n", Index); 1169 goto Cleanup; 1170 } 1171 1172 Status = AcpiDsStoreObjectToLocal (ACPI_REFCLASS_ARG, Index, ObjDesc, 1173 WalkState); 1174 if (ACPI_FAILURE (Status)) 1175 { 1176 goto Cleanup; 1177 } 1178 1179 ObjDesc = WalkState->Arguments[Index].Object; 1180 1181 AcpiOsPrintf ("Arg%d: ", Index); 1182 AcpiDmDisplayInternalObject (ObjDesc, WalkState); 1183 break; 1184 1185 case 'L': 1186 1187 /* Set a method local */ 1188 1189 if (Index > ACPI_METHOD_MAX_LOCAL) 1190 { 1191 AcpiOsPrintf ("Local%d - Invalid local variable name\n", Index); 1192 goto Cleanup; 1193 } 1194 1195 Status = AcpiDsStoreObjectToLocal (ACPI_REFCLASS_LOCAL, Index, ObjDesc, 1196 WalkState); 1197 if (ACPI_FAILURE (Status)) 1198 { 1199 goto Cleanup; 1200 } 1201 1202 ObjDesc = WalkState->LocalVariables[Index].Object; 1203 1204 AcpiOsPrintf ("Local%d: ", Index); 1205 AcpiDmDisplayInternalObject (ObjDesc, WalkState); 1206 break; 1207 1208 default: 1209 break; 1210 } 1211 1212 Cleanup: 1213 AcpiUtRemoveReference (ObjDesc); 1214 } 1215 1216 1217 /******************************************************************************* 1218 * 1219 * FUNCTION: AcpiDbWalkForSpecificObjects 1220 * 1221 * PARAMETERS: Callback from WalkNamespace 1222 * 1223 * RETURN: Status 1224 * 1225 * DESCRIPTION: Display short info about objects in the namespace 1226 * 1227 ******************************************************************************/ 1228 1229 static ACPI_STATUS 1230 AcpiDbWalkForSpecificObjects ( 1231 ACPI_HANDLE ObjHandle, 1232 UINT32 NestingLevel, 1233 void *Context, 1234 void **ReturnValue) 1235 { 1236 ACPI_WALK_INFO *Info = (ACPI_WALK_INFO *) Context; 1237 ACPI_BUFFER Buffer; 1238 ACPI_STATUS Status; 1239 1240 1241 Info->Count++; 1242 1243 /* Get and display the full pathname to this object */ 1244 1245 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 1246 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer); 1247 if (ACPI_FAILURE (Status)) 1248 { 1249 AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle); 1250 return (AE_OK); 1251 } 1252 1253 AcpiOsPrintf ("%32s", (char *) Buffer.Pointer); 1254 ACPI_FREE (Buffer.Pointer); 1255 1256 /* Dump short info about the object */ 1257 1258 (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, Info, NULL); 1259 return (AE_OK); 1260 } 1261 1262 1263 /******************************************************************************* 1264 * 1265 * FUNCTION: AcpiDbDisplayObjects 1266 * 1267 * PARAMETERS: ObjTypeArg - Type of object to display 1268 * DisplayCountArg - Max depth to display 1269 * 1270 * RETURN: None 1271 * 1272 * DESCRIPTION: Display objects in the namespace of the requested type 1273 * 1274 ******************************************************************************/ 1275 1276 ACPI_STATUS 1277 AcpiDbDisplayObjects ( 1278 char *ObjTypeArg, 1279 char *DisplayCountArg) 1280 { 1281 ACPI_WALK_INFO Info; 1282 ACPI_OBJECT_TYPE Type; 1283 1284 1285 /* Get the object type */ 1286 1287 Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes); 1288 if (Type == ACPI_TYPE_NOT_FOUND) 1289 { 1290 AcpiOsPrintf ("Invalid or unsupported argument\n"); 1291 return (AE_OK); 1292 } 1293 1294 AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 1295 AcpiOsPrintf ( 1296 "Objects of type [%s] defined in the current ACPI Namespace:\n", 1297 AcpiUtGetTypeName (Type)); 1298 1299 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 1300 1301 Info.Count = 0; 1302 Info.OwnerId = ACPI_OWNER_ID_MAX; 1303 Info.DebugLevel = ACPI_UINT32_MAX; 1304 Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT; 1305 1306 /* Walk the namespace from the root */ 1307 1308 (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, 1309 AcpiDbWalkForSpecificObjects, (void *) &Info, NULL); 1310 1311 AcpiOsPrintf ( 1312 "\nFound %u objects of type [%s] in the current ACPI Namespace\n", 1313 Info.Count, AcpiUtGetTypeName (Type)); 1314 1315 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 1316 return (AE_OK); 1317 } 1318 1319 1320 /******************************************************************************* 1321 * 1322 * FUNCTION: AcpiDbWalkAndMatchName 1323 * 1324 * PARAMETERS: Callback from WalkNamespace 1325 * 1326 * RETURN: Status 1327 * 1328 * DESCRIPTION: Find a particular name/names within the namespace. Wildcards 1329 * are supported -- '?' matches any character. 1330 * 1331 ******************************************************************************/ 1332 1333 static ACPI_STATUS 1334 AcpiDbWalkAndMatchName ( 1335 ACPI_HANDLE ObjHandle, 1336 UINT32 NestingLevel, 1337 void *Context, 1338 void **ReturnValue) 1339 { 1340 ACPI_STATUS Status; 1341 char *RequestedName = (char *) Context; 1342 UINT32 i; 1343 ACPI_BUFFER Buffer; 1344 ACPI_WALK_INFO Info; 1345 1346 1347 /* Check for a name match */ 1348 1349 for (i = 0; i < 4; i++) 1350 { 1351 /* Wildcard support */ 1352 1353 if ((RequestedName[i] != '?') && 1354 (RequestedName[i] != ((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Ascii[i])) 1355 { 1356 /* No match, just exit */ 1357 1358 return (AE_OK); 1359 } 1360 } 1361 1362 /* Get the full pathname to this object */ 1363 1364 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 1365 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer); 1366 if (ACPI_FAILURE (Status)) 1367 { 1368 AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle); 1369 } 1370 else 1371 { 1372 Info.OwnerId = ACPI_OWNER_ID_MAX; 1373 Info.DebugLevel = ACPI_UINT32_MAX; 1374 Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT; 1375 1376 AcpiOsPrintf ("%32s", (char *) Buffer.Pointer); 1377 (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, &Info, NULL); 1378 ACPI_FREE (Buffer.Pointer); 1379 } 1380 1381 return (AE_OK); 1382 } 1383 1384 1385 /******************************************************************************* 1386 * 1387 * FUNCTION: AcpiDbFindNameInNamespace 1388 * 1389 * PARAMETERS: NameArg - The 4-character ACPI name to find. 1390 * wildcards are supported. 1391 * 1392 * RETURN: None 1393 * 1394 * DESCRIPTION: Search the namespace for a given name (with wildcards) 1395 * 1396 ******************************************************************************/ 1397 1398 ACPI_STATUS 1399 AcpiDbFindNameInNamespace ( 1400 char *NameArg) 1401 { 1402 char AcpiName[5] = "____"; 1403 char *AcpiNamePtr = AcpiName; 1404 1405 1406 if (ACPI_STRLEN (NameArg) > 4) 1407 { 1408 AcpiOsPrintf ("Name must be no longer than 4 characters\n"); 1409 return (AE_OK); 1410 } 1411 1412 /* Pad out name with underscores as necessary to create a 4-char name */ 1413 1414 AcpiUtStrupr (NameArg); 1415 while (*NameArg) 1416 { 1417 *AcpiNamePtr = *NameArg; 1418 AcpiNamePtr++; 1419 NameArg++; 1420 } 1421 1422 /* Walk the namespace from the root */ 1423 1424 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, 1425 AcpiDbWalkAndMatchName, AcpiName, NULL); 1426 1427 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 1428 return (AE_OK); 1429 } 1430 1431 1432 /******************************************************************************* 1433 * 1434 * FUNCTION: AcpiDbSetScope 1435 * 1436 * PARAMETERS: Name - New scope path 1437 * 1438 * RETURN: Status 1439 * 1440 * DESCRIPTION: Set the "current scope" as maintained by this utility. 1441 * The scope is used as a prefix to ACPI paths. 1442 * 1443 ******************************************************************************/ 1444 1445 void 1446 AcpiDbSetScope ( 1447 char *Name) 1448 { 1449 ACPI_STATUS Status; 1450 ACPI_NAMESPACE_NODE *Node; 1451 1452 1453 if (!Name || Name[0] == 0) 1454 { 1455 AcpiOsPrintf ("Current scope: %s\n", AcpiGbl_DbScopeBuf); 1456 return; 1457 } 1458 1459 AcpiDbPrepNamestring (Name); 1460 1461 if (Name[0] == '\\') 1462 { 1463 /* Validate new scope from the root */ 1464 1465 Status = AcpiNsGetNode (AcpiGbl_RootNode, Name, ACPI_NS_NO_UPSEARCH, 1466 &Node); 1467 if (ACPI_FAILURE (Status)) 1468 { 1469 goto ErrorExit; 1470 } 1471 1472 ACPI_STRCPY (AcpiGbl_DbScopeBuf, Name); 1473 ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\"); 1474 } 1475 else 1476 { 1477 /* Validate new scope relative to old scope */ 1478 1479 Status = AcpiNsGetNode (AcpiGbl_DbScopeNode, Name, ACPI_NS_NO_UPSEARCH, 1480 &Node); 1481 if (ACPI_FAILURE (Status)) 1482 { 1483 goto ErrorExit; 1484 } 1485 1486 ACPI_STRCAT (AcpiGbl_DbScopeBuf, Name); 1487 ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\"); 1488 } 1489 1490 AcpiGbl_DbScopeNode = Node; 1491 AcpiOsPrintf ("New scope: %s\n", AcpiGbl_DbScopeBuf); 1492 return; 1493 1494 ErrorExit: 1495 1496 AcpiOsPrintf ("Could not attach scope: %s, %s\n", 1497 Name, AcpiFormatException (Status)); 1498 } 1499 1500 1501 /******************************************************************************* 1502 * 1503 * FUNCTION: AcpiDmCompareAmlResources 1504 * 1505 * PARAMETERS: Aml1Buffer - Contains first resource list 1506 * Aml1BufferLength - Length of first resource list 1507 * Aml2Buffer - Contains second resource list 1508 * Aml2BufferLength - Length of second resource list 1509 * 1510 * RETURN: None 1511 * 1512 * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in 1513 * order to isolate a miscompare to an individual resource) 1514 * 1515 ******************************************************************************/ 1516 1517 static void 1518 AcpiDmCompareAmlResources ( 1519 UINT8 *Aml1Buffer, 1520 ACPI_RSDESC_SIZE Aml1BufferLength, 1521 UINT8 *Aml2Buffer, 1522 ACPI_RSDESC_SIZE Aml2BufferLength) 1523 { 1524 UINT8 *Aml1; 1525 UINT8 *Aml2; 1526 ACPI_RSDESC_SIZE Aml1Length; 1527 ACPI_RSDESC_SIZE Aml2Length; 1528 ACPI_RSDESC_SIZE Offset = 0; 1529 UINT8 ResourceType; 1530 UINT32 Count = 0; 1531 1532 1533 /* Compare overall buffer sizes (may be different due to size rounding) */ 1534 1535 if (Aml1BufferLength != Aml2BufferLength) 1536 { 1537 AcpiOsPrintf ( 1538 "**** Buffer length mismatch in converted AML: original %X new %X ****\n", 1539 Aml1BufferLength, Aml2BufferLength); 1540 } 1541 1542 Aml1 = Aml1Buffer; 1543 Aml2 = Aml2Buffer; 1544 1545 /* Walk the descriptor lists, comparing each descriptor */ 1546 1547 while (Aml1 < (Aml1Buffer + Aml1BufferLength)) 1548 { 1549 /* Get the lengths of each descriptor */ 1550 1551 Aml1Length = AcpiUtGetDescriptorLength (Aml1); 1552 Aml2Length = AcpiUtGetDescriptorLength (Aml2); 1553 ResourceType = AcpiUtGetResourceType (Aml1); 1554 1555 /* Check for descriptor length match */ 1556 1557 if (Aml1Length != Aml2Length) 1558 { 1559 AcpiOsPrintf ( 1560 "**** Length mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X L1 %X L2 %X ****\n", 1561 Count, ResourceType, Offset, Aml1Length, Aml2Length); 1562 } 1563 1564 /* Check for descriptor byte match */ 1565 1566 else if (ACPI_MEMCMP (Aml1, Aml2, Aml1Length)) 1567 { 1568 AcpiOsPrintf ( 1569 "**** Data mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X ****\n", 1570 Count, ResourceType, Offset); 1571 } 1572 1573 /* Exit on EndTag descriptor */ 1574 1575 if (ResourceType == ACPI_RESOURCE_NAME_END_TAG) 1576 { 1577 return; 1578 } 1579 1580 /* Point to next descriptor in each buffer */ 1581 1582 Count++; 1583 Offset += Aml1Length; 1584 Aml1 += Aml1Length; 1585 Aml2 += Aml2Length; 1586 } 1587 } 1588 1589 1590 /******************************************************************************* 1591 * 1592 * FUNCTION: AcpiDmTestResourceConversion 1593 * 1594 * PARAMETERS: Node - Parent device node 1595 * Name - resource method name (_CRS) 1596 * 1597 * RETURN: Status 1598 * 1599 * DESCRIPTION: Compare the original AML with a conversion of the AML to 1600 * internal resource list, then back to AML. 1601 * 1602 ******************************************************************************/ 1603 1604 static ACPI_STATUS 1605 AcpiDmTestResourceConversion ( 1606 ACPI_NAMESPACE_NODE *Node, 1607 char *Name) 1608 { 1609 ACPI_STATUS Status; 1610 ACPI_BUFFER ReturnObj; 1611 ACPI_BUFFER ResourceObj; 1612 ACPI_BUFFER NewAml; 1613 ACPI_OBJECT *OriginalAml; 1614 1615 1616 AcpiOsPrintf ("Resource Conversion Comparison:\n"); 1617 1618 NewAml.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 1619 ReturnObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 1620 ResourceObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 1621 1622 /* Get the original _CRS AML resource template */ 1623 1624 Status = AcpiEvaluateObject (Node, Name, NULL, &ReturnObj); 1625 if (ACPI_FAILURE (Status)) 1626 { 1627 AcpiOsPrintf ("Could not obtain %s: %s\n", 1628 Name, AcpiFormatException (Status)); 1629 return (Status); 1630 } 1631 1632 /* Get the AML resource template, converted to internal resource structs */ 1633 1634 Status = AcpiGetCurrentResources (Node, &ResourceObj); 1635 if (ACPI_FAILURE (Status)) 1636 { 1637 AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n", 1638 AcpiFormatException (Status)); 1639 goto Exit1; 1640 } 1641 1642 /* Convert internal resource list to external AML resource template */ 1643 1644 Status = AcpiRsCreateAmlResources (ResourceObj.Pointer, &NewAml); 1645 if (ACPI_FAILURE (Status)) 1646 { 1647 AcpiOsPrintf ("AcpiRsCreateAmlResources failed: %s\n", 1648 AcpiFormatException (Status)); 1649 goto Exit2; 1650 } 1651 1652 /* Compare original AML to the newly created AML resource list */ 1653 1654 OriginalAml = ReturnObj.Pointer; 1655 1656 AcpiDmCompareAmlResources ( 1657 OriginalAml->Buffer.Pointer, (ACPI_RSDESC_SIZE) OriginalAml->Buffer.Length, 1658 NewAml.Pointer, (ACPI_RSDESC_SIZE) NewAml.Length); 1659 1660 /* Cleanup and exit */ 1661 1662 ACPI_FREE (NewAml.Pointer); 1663 Exit2: 1664 ACPI_FREE (ResourceObj.Pointer); 1665 Exit1: 1666 ACPI_FREE (ReturnObj.Pointer); 1667 return (Status); 1668 } 1669 1670 1671 /******************************************************************************* 1672 * 1673 * FUNCTION: AcpiDbDisplayResources 1674 * 1675 * PARAMETERS: ObjectArg - String with hex value of the object 1676 * 1677 * RETURN: None 1678 * 1679 * DESCRIPTION: Display the resource objects associated with a device. 1680 * 1681 ******************************************************************************/ 1682 1683 void 1684 AcpiDbDisplayResources ( 1685 char *ObjectArg) 1686 { 1687 ACPI_NAMESPACE_NODE *Node; 1688 ACPI_STATUS Status; 1689 ACPI_BUFFER ReturnObj; 1690 1691 1692 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 1693 AcpiDbgLevel |= ACPI_LV_RESOURCES; 1694 1695 /* Convert string to object pointer */ 1696 1697 Node = AcpiDbConvertToNode (ObjectArg); 1698 if (!Node) 1699 { 1700 return; 1701 } 1702 1703 /* Prepare for a return object of arbitrary size */ 1704 1705 ReturnObj.Pointer = AcpiGbl_DbBuffer; 1706 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 1707 1708 /* _PRT */ 1709 1710 AcpiOsPrintf ("Evaluating _PRT\n"); 1711 1712 /* Check if _PRT exists */ 1713 1714 Status = AcpiEvaluateObject (Node, METHOD_NAME__PRT, NULL, &ReturnObj); 1715 if (ACPI_FAILURE (Status)) 1716 { 1717 AcpiOsPrintf ("Could not obtain _PRT: %s\n", 1718 AcpiFormatException (Status)); 1719 goto GetCrs; 1720 } 1721 1722 ReturnObj.Pointer = AcpiGbl_DbBuffer; 1723 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 1724 1725 Status = AcpiGetIrqRoutingTable (Node, &ReturnObj); 1726 if (ACPI_FAILURE (Status)) 1727 { 1728 AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n", 1729 AcpiFormatException (Status)); 1730 goto GetCrs; 1731 } 1732 1733 AcpiRsDumpIrqList (ACPI_CAST_PTR (UINT8, AcpiGbl_DbBuffer)); 1734 1735 1736 /* _CRS */ 1737 1738 GetCrs: 1739 AcpiOsPrintf ("Evaluating _CRS\n"); 1740 1741 ReturnObj.Pointer = AcpiGbl_DbBuffer; 1742 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 1743 1744 /* Check if _CRS exists */ 1745 1746 Status = AcpiEvaluateObject (Node, METHOD_NAME__CRS, NULL, &ReturnObj); 1747 if (ACPI_FAILURE (Status)) 1748 { 1749 AcpiOsPrintf ("Could not obtain _CRS: %s\n", 1750 AcpiFormatException (Status)); 1751 goto GetPrs; 1752 } 1753 1754 /* Get the _CRS resource list */ 1755 1756 ReturnObj.Pointer = AcpiGbl_DbBuffer; 1757 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 1758 1759 Status = AcpiGetCurrentResources (Node, &ReturnObj); 1760 if (ACPI_FAILURE (Status)) 1761 { 1762 AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n", 1763 AcpiFormatException (Status)); 1764 goto GetPrs; 1765 } 1766 1767 /* Dump the _CRS resource list */ 1768 1769 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, 1770 ReturnObj.Pointer)); 1771 1772 /* 1773 * Perform comparison of original AML to newly created AML. This tests both 1774 * the AML->Resource conversion and the Resource->Aml conversion. 1775 */ 1776 Status = AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS); 1777 1778 /* Execute _SRS with the resource list */ 1779 1780 Status = AcpiSetCurrentResources (Node, &ReturnObj); 1781 if (ACPI_FAILURE (Status)) 1782 { 1783 AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n", 1784 AcpiFormatException (Status)); 1785 goto GetPrs; 1786 } 1787 1788 1789 /* _PRS */ 1790 1791 GetPrs: 1792 AcpiOsPrintf ("Evaluating _PRS\n"); 1793 1794 ReturnObj.Pointer = AcpiGbl_DbBuffer; 1795 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 1796 1797 /* Check if _PRS exists */ 1798 1799 Status = AcpiEvaluateObject (Node, METHOD_NAME__PRS, NULL, &ReturnObj); 1800 if (ACPI_FAILURE (Status)) 1801 { 1802 AcpiOsPrintf ("Could not obtain _PRS: %s\n", 1803 AcpiFormatException (Status)); 1804 goto Cleanup; 1805 } 1806 1807 ReturnObj.Pointer = AcpiGbl_DbBuffer; 1808 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 1809 1810 Status = AcpiGetPossibleResources (Node, &ReturnObj); 1811 if (ACPI_FAILURE (Status)) 1812 { 1813 AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n", 1814 AcpiFormatException (Status)); 1815 goto Cleanup; 1816 } 1817 1818 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer)); 1819 1820 Cleanup: 1821 1822 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 1823 return; 1824 } 1825 1826 1827 /******************************************************************************* 1828 * 1829 * FUNCTION: AcpiDbIntegrityWalk 1830 * 1831 * PARAMETERS: Callback from WalkNamespace 1832 * 1833 * RETURN: Status 1834 * 1835 * DESCRIPTION: Examine one NS node for valid values. 1836 * 1837 ******************************************************************************/ 1838 1839 static ACPI_STATUS 1840 AcpiDbIntegrityWalk ( 1841 ACPI_HANDLE ObjHandle, 1842 UINT32 NestingLevel, 1843 void *Context, 1844 void **ReturnValue) 1845 { 1846 ACPI_INTEGRITY_INFO *Info = (ACPI_INTEGRITY_INFO *) Context; 1847 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 1848 ACPI_OPERAND_OBJECT *Object; 1849 BOOLEAN Alias = TRUE; 1850 1851 1852 Info->Nodes++; 1853 1854 /* Verify the NS node, and dereference aliases */ 1855 1856 while (Alias) 1857 { 1858 if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED) 1859 { 1860 AcpiOsPrintf ("Invalid Descriptor Type for Node %p [%s] - is %2.2X should be %2.2X\n", 1861 Node, AcpiUtGetDescriptorName (Node), ACPI_GET_DESCRIPTOR_TYPE (Node), 1862 ACPI_DESC_TYPE_NAMED); 1863 return (AE_OK); 1864 } 1865 1866 if ((Node->Type == ACPI_TYPE_LOCAL_ALIAS) || 1867 (Node->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) 1868 { 1869 Node = (ACPI_NAMESPACE_NODE *) Node->Object; 1870 } 1871 else 1872 { 1873 Alias = FALSE; 1874 } 1875 } 1876 1877 if (Node->Type > ACPI_TYPE_LOCAL_MAX) 1878 { 1879 AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n", 1880 Node, Node->Type); 1881 return (AE_OK); 1882 } 1883 1884 if (!AcpiUtValidAcpiName (Node->Name.Integer)) 1885 { 1886 AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node); 1887 return (AE_OK); 1888 } 1889 1890 Object = AcpiNsGetAttachedObject (Node); 1891 if (Object) 1892 { 1893 Info->Objects++; 1894 if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND) 1895 { 1896 AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n", 1897 Object, AcpiUtGetDescriptorName (Object)); 1898 } 1899 } 1900 1901 return (AE_OK); 1902 } 1903 1904 1905 /******************************************************************************* 1906 * 1907 * FUNCTION: AcpiDbCheckIntegrity 1908 * 1909 * PARAMETERS: None 1910 * 1911 * RETURN: None 1912 * 1913 * DESCRIPTION: Check entire namespace for data structure integrity 1914 * 1915 ******************************************************************************/ 1916 1917 void 1918 AcpiDbCheckIntegrity ( 1919 void) 1920 { 1921 ACPI_INTEGRITY_INFO Info = {0,0}; 1922 1923 /* Search all nodes in namespace */ 1924 1925 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, 1926 AcpiDbIntegrityWalk, (void *) &Info, NULL); 1927 1928 AcpiOsPrintf ("Verified %d namespace nodes with %d Objects\n", 1929 Info.Nodes, Info.Objects); 1930 } 1931 1932 1933 /******************************************************************************* 1934 * 1935 * FUNCTION: AcpiDbGenerateGpe 1936 * 1937 * PARAMETERS: GpeArg - Raw GPE number, ascii string 1938 * BlockArg - GPE block number, ascii string 1939 * 0 or 1 for FADT GPE blocks 1940 * 1941 * RETURN: None 1942 * 1943 * DESCRIPTION: Generate a GPE 1944 * 1945 ******************************************************************************/ 1946 1947 void 1948 AcpiDbGenerateGpe ( 1949 char *GpeArg, 1950 char *BlockArg) 1951 { 1952 UINT32 BlockNumber; 1953 UINT32 GpeNumber; 1954 ACPI_GPE_EVENT_INFO *GpeEventInfo; 1955 1956 1957 GpeNumber = ACPI_STRTOUL (GpeArg, NULL, 0); 1958 BlockNumber = ACPI_STRTOUL (BlockArg, NULL, 0); 1959 1960 1961 GpeEventInfo = AcpiEvGetGpeEventInfo (ACPI_TO_POINTER (BlockNumber), 1962 GpeNumber); 1963 if (!GpeEventInfo) 1964 { 1965 AcpiOsPrintf ("Invalid GPE\n"); 1966 return; 1967 } 1968 1969 (void) AcpiEvGpeDispatch (GpeEventInfo, GpeNumber); 1970 } 1971 1972 1973 /******************************************************************************* 1974 * 1975 * FUNCTION: AcpiDbBusWalk 1976 * 1977 * PARAMETERS: Callback from WalkNamespace 1978 * 1979 * RETURN: Status 1980 * 1981 * DESCRIPTION: Display info about device objects that have a corresponding 1982 * _PRT method. 1983 * 1984 ******************************************************************************/ 1985 1986 static ACPI_STATUS 1987 AcpiDbBusWalk ( 1988 ACPI_HANDLE ObjHandle, 1989 UINT32 NestingLevel, 1990 void *Context, 1991 void **ReturnValue) 1992 { 1993 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 1994 ACPI_STATUS Status; 1995 ACPI_BUFFER Buffer; 1996 ACPI_INTEGER ADR; 1997 ACPI_DEVICE_ID Id; 1998 ACPI_COMPATIBLE_ID_LIST *Cid; 1999 ACPI_NAMESPACE_NODE *TempNode; 2000 2001 2002 /* Exit if there is no _PRT under this device */ 2003 2004 Status = AcpiGetHandle (Node, METHOD_NAME__PRT, 2005 ACPI_CAST_PTR (ACPI_HANDLE, &TempNode)); 2006 if (ACPI_FAILURE (Status)) 2007 { 2008 return (AE_OK); 2009 } 2010 2011 /* Get the full path to this device object */ 2012 2013 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 2014 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer); 2015 if (ACPI_FAILURE (Status)) 2016 { 2017 AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle); 2018 return (AE_OK); 2019 } 2020 2021 /* Display the full path */ 2022 2023 AcpiOsPrintf ("%-32s", (char *) Buffer.Pointer); 2024 ACPI_FREE (Buffer.Pointer); 2025 2026 /* _PRT info */ 2027 2028 AcpiOsPrintf ("_PRT=%p", TempNode); 2029 2030 /* Get the _ADR value */ 2031 2032 Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node, &ADR); 2033 if (ACPI_FAILURE (Status)) 2034 { 2035 AcpiOsPrintf (" No _ADR "); 2036 } 2037 else 2038 { 2039 AcpiOsPrintf (" _ADR=%8.8X", (UINT32) ADR); 2040 } 2041 2042 /* Get the _HID if present */ 2043 2044 Status = AcpiUtExecute_HID (Node, &Id); 2045 if (ACPI_SUCCESS (Status)) 2046 { 2047 AcpiOsPrintf (" _HID=%s", Id.Value); 2048 } 2049 else 2050 { 2051 AcpiOsPrintf (" "); 2052 } 2053 2054 /* Get the _UID if present */ 2055 2056 Status = AcpiUtExecute_UID (Node, &Id); 2057 if (ACPI_SUCCESS (Status)) 2058 { 2059 AcpiOsPrintf (" _UID=%s", Id.Value); 2060 } 2061 2062 /* Get the _CID if present */ 2063 2064 Status = AcpiUtExecute_CID (Node, &Cid); 2065 if (ACPI_SUCCESS (Status)) 2066 { 2067 AcpiOsPrintf (" _CID=%s", Cid->Id[0].Value); 2068 ACPI_FREE (Cid); 2069 } 2070 2071 AcpiOsPrintf ("\n"); 2072 return (AE_OK); 2073 } 2074 2075 2076 /******************************************************************************* 2077 * 2078 * FUNCTION: AcpiDbGetBusInfo 2079 * 2080 * PARAMETERS: None 2081 * 2082 * RETURN: None 2083 * 2084 * DESCRIPTION: Display info about system busses. 2085 * 2086 ******************************************************************************/ 2087 2088 void 2089 AcpiDbGetBusInfo ( 2090 void) 2091 { 2092 /* Search all nodes in namespace */ 2093 2094 (void) AcpiWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, 2095 AcpiDbBusWalk, NULL, NULL); 2096 } 2097 2098 #endif /* ACPI_DEBUGGER */ 2099