dbcmds.c revision 193341
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 <contrib/dev/acpica/include/acpi.h> 118#include <contrib/dev/acpica/include/accommon.h> 119#include <contrib/dev/acpica/include/acdispat.h> 120#include <contrib/dev/acpica/include/acnamesp.h> 121#include <contrib/dev/acpica/include/acevents.h> 122#include <contrib/dev/acpica/include/acdebug.h> 123#include <contrib/dev/acpica/include/acresrc.h> 124#include <contrib/dev/acpica/include/acdisasm.h> 125#include <contrib/dev/acpica/include/actables.h> 126#include <contrib/dev/acpica/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 135static ACPI_STATUS 136AcpiDbIntegrityWalk ( 137 ACPI_HANDLE ObjHandle, 138 UINT32 NestingLevel, 139 void *Context, 140 void **ReturnValue); 141 142static ACPI_STATUS 143AcpiDbWalkAndMatchName ( 144 ACPI_HANDLE ObjHandle, 145 UINT32 NestingLevel, 146 void *Context, 147 void **ReturnValue); 148 149static ACPI_STATUS 150AcpiDbWalkForReferences ( 151 ACPI_HANDLE ObjHandle, 152 UINT32 NestingLevel, 153 void *Context, 154 void **ReturnValue); 155 156static ACPI_STATUS 157AcpiDbWalkForSpecificObjects ( 158 ACPI_HANDLE ObjHandle, 159 UINT32 NestingLevel, 160 void *Context, 161 void **ReturnValue); 162 163static ACPI_NAMESPACE_NODE * 164AcpiDbConvertToNode ( 165 char *InString); 166 167static void 168AcpiDmCompareAmlResources ( 169 UINT8 *Aml1Buffer, 170 ACPI_RSDESC_SIZE Aml1BufferLength, 171 UINT8 *Aml2Buffer, 172 ACPI_RSDESC_SIZE Aml2BufferLength); 173 174static ACPI_STATUS 175AcpiDmTestResourceConversion ( 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 */ 184static 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 225static ACPI_NAMESPACE_NODE * 226AcpiDbConvertToNode ( 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 282ACPI_STATUS 283AcpiDbSleep ( 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 328static ACPI_STATUS 329AcpiDbWalkForReferences ( 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 371void 372AcpiDbFindReferences ( 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 402static ACPI_STATUS 403AcpiDbWalkForPredefinedNames ( 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 467void 468AcpiDbCheckPredefinedNames ( 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 496static ACPI_STATUS 497AcpiDbWalkForExecute ( 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 595void 596AcpiDbBatchExecute ( 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 623void 624AcpiDbDisplayLocks ( 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 652void 653AcpiDbDisplayTableInfo ( 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 708void 709AcpiDbUnloadAcpiTable ( 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 764void 765AcpiDbSetMethodBreakpoint ( 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 808void 809AcpiDbSetMethodCallBreakpoint ( 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 838void 839AcpiDbDisassembleAml ( 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#ifdef ACPI_DISASSEMBLER 858 AcpiDmDisassemble (NULL, Op, NumStatements); 859#endif 860} 861 862 863/******************************************************************************* 864 * 865 * FUNCTION: AcpiDbDisassembleMethod 866 * 867 * PARAMETERS: Name - Name of control method 868 * 869 * RETURN: None 870 * 871 * DESCRIPTION: Display disassembled AML (ASL) starting from Op for the number 872 * of statements specified. 873 * 874 ******************************************************************************/ 875 876ACPI_STATUS 877AcpiDbDisassembleMethod ( 878 char *Name) 879{ 880 ACPI_STATUS Status; 881 ACPI_PARSE_OBJECT *Op; 882 ACPI_WALK_STATE *WalkState; 883 ACPI_OPERAND_OBJECT *ObjDesc; 884 ACPI_NAMESPACE_NODE *Method; 885 886 887 Method = AcpiDbConvertToNode (Name); 888 if (!Method) 889 { 890 return (AE_BAD_PARAMETER); 891 } 892 893 ObjDesc = Method->Object; 894 895 Op = AcpiPsCreateScopeOp (); 896 if (!Op) 897 { 898 return (AE_NO_MEMORY); 899 } 900 901 /* Create and initialize a new walk state */ 902 903 WalkState = AcpiDsCreateWalkState (0, Op, NULL, NULL); 904 if (!WalkState) 905 { 906 return (AE_NO_MEMORY); 907 } 908 909 Status = AcpiDsInitAmlWalk (WalkState, Op, NULL, 910 ObjDesc->Method.AmlStart, 911 ObjDesc->Method.AmlLength, NULL, ACPI_IMODE_LOAD_PASS1); 912 if (ACPI_FAILURE (Status)) 913 { 914 return (Status); 915 } 916 917 /* Parse the AML */ 918 919 WalkState->ParseFlags &= ~ACPI_PARSE_DELETE_TREE; 920 WalkState->ParseFlags |= ACPI_PARSE_DISASSEMBLE; 921 Status = AcpiPsParseAml (WalkState); 922 923#ifdef ACPI_DISASSEMBLER 924 AcpiDmDisassemble (NULL, Op, 0); 925#endif 926 AcpiPsDeleteParseTree (Op); 927 return (AE_OK); 928} 929 930 931/******************************************************************************* 932 * 933 * FUNCTION: AcpiDbDumpNamespace 934 * 935 * PARAMETERS: StartArg - Node to begin namespace dump 936 * DepthArg - Maximum tree depth to be dumped 937 * 938 * RETURN: None 939 * 940 * DESCRIPTION: Dump entire namespace or a subtree. Each node is displayed 941 * with type and other information. 942 * 943 ******************************************************************************/ 944 945void 946AcpiDbDumpNamespace ( 947 char *StartArg, 948 char *DepthArg) 949{ 950 ACPI_HANDLE SubtreeEntry = AcpiGbl_RootNode; 951 UINT32 MaxDepth = ACPI_UINT32_MAX; 952 953 954 /* No argument given, just start at the root and dump entire namespace */ 955 956 if (StartArg) 957 { 958 SubtreeEntry = AcpiDbConvertToNode (StartArg); 959 if (!SubtreeEntry) 960 { 961 return; 962 } 963 964 /* Now we can check for the depth argument */ 965 966 if (DepthArg) 967 { 968 MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0); 969 } 970 } 971 972 AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 973 AcpiOsPrintf ("ACPI Namespace (from %4.4s (%p) subtree):\n", 974 ((ACPI_NAMESPACE_NODE *) SubtreeEntry)->Name.Ascii, SubtreeEntry); 975 976 /* Display the subtree */ 977 978 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 979 AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth, 980 ACPI_OWNER_ID_MAX, SubtreeEntry); 981 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 982} 983 984 985/******************************************************************************* 986 * 987 * FUNCTION: AcpiDbDumpNamespaceByOwner 988 * 989 * PARAMETERS: OwnerArg - Owner ID whose nodes will be displayed 990 * DepthArg - Maximum tree depth to be dumped 991 * 992 * RETURN: None 993 * 994 * DESCRIPTION: Dump elements of the namespace that are owned by the OwnerId. 995 * 996 ******************************************************************************/ 997 998void 999AcpiDbDumpNamespaceByOwner ( 1000 char *OwnerArg, 1001 char *DepthArg) 1002{ 1003 ACPI_HANDLE SubtreeEntry = AcpiGbl_RootNode; 1004 UINT32 MaxDepth = ACPI_UINT32_MAX; 1005 ACPI_OWNER_ID OwnerId; 1006 1007 1008 OwnerId = (ACPI_OWNER_ID) ACPI_STRTOUL (OwnerArg, NULL, 0); 1009 1010 /* Now we can check for the depth argument */ 1011 1012 if (DepthArg) 1013 { 1014 MaxDepth = ACPI_STRTOUL (DepthArg, NULL, 0); 1015 } 1016 1017 AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 1018 AcpiOsPrintf ("ACPI Namespace by owner %X:\n", OwnerId); 1019 1020 /* Display the subtree */ 1021 1022 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 1023 AcpiNsDumpObjects (ACPI_TYPE_ANY, ACPI_DISPLAY_SUMMARY, MaxDepth, OwnerId, 1024 SubtreeEntry); 1025 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 1026} 1027 1028 1029/******************************************************************************* 1030 * 1031 * FUNCTION: AcpiDbSendNotify 1032 * 1033 * PARAMETERS: Name - Name of ACPI object to send the notify to 1034 * Value - Value of the notify to send. 1035 * 1036 * RETURN: None 1037 * 1038 * DESCRIPTION: Send an ACPI notification. The value specified is sent to the 1039 * named object as an ACPI notify. 1040 * 1041 ******************************************************************************/ 1042 1043void 1044AcpiDbSendNotify ( 1045 char *Name, 1046 UINT32 Value) 1047{ 1048 ACPI_NAMESPACE_NODE *Node; 1049 ACPI_STATUS Status; 1050 1051 1052 /* Translate name to an Named object */ 1053 1054 Node = AcpiDbConvertToNode (Name); 1055 if (!Node) 1056 { 1057 return; 1058 } 1059 1060 /* Decode Named object type */ 1061 1062 switch (Node->Type) 1063 { 1064 case ACPI_TYPE_DEVICE: 1065 case ACPI_TYPE_THERMAL: 1066 1067 /* Send the notify */ 1068 1069 Status = AcpiEvQueueNotifyRequest (Node, Value); 1070 if (ACPI_FAILURE (Status)) 1071 { 1072 AcpiOsPrintf ("Could not queue notify\n"); 1073 } 1074 break; 1075 1076 default: 1077 AcpiOsPrintf ("Named object is not a device or a thermal object\n"); 1078 break; 1079 } 1080} 1081 1082 1083/******************************************************************************* 1084 * 1085 * FUNCTION: AcpiDbSetMethodData 1086 * 1087 * PARAMETERS: TypeArg - L for local, A for argument 1088 * IndexArg - which one 1089 * ValueArg - Value to set. 1090 * 1091 * RETURN: None 1092 * 1093 * DESCRIPTION: Set a local or argument for the running control method. 1094 * NOTE: only object supported is Number. 1095 * 1096 ******************************************************************************/ 1097 1098void 1099AcpiDbSetMethodData ( 1100 char *TypeArg, 1101 char *IndexArg, 1102 char *ValueArg) 1103{ 1104 char Type; 1105 UINT32 Index; 1106 UINT32 Value; 1107 ACPI_WALK_STATE *WalkState; 1108 ACPI_OPERAND_OBJECT *ObjDesc; 1109 ACPI_STATUS Status; 1110 ACPI_NAMESPACE_NODE *Node; 1111 1112 1113 /* Validate TypeArg */ 1114 1115 AcpiUtStrupr (TypeArg); 1116 Type = TypeArg[0]; 1117 if ((Type != 'L') && 1118 (Type != 'A') && 1119 (Type != 'N')) 1120 { 1121 AcpiOsPrintf ("Invalid SET operand: %s\n", TypeArg); 1122 return; 1123 } 1124 1125 Value = ACPI_STRTOUL (ValueArg, NULL, 16); 1126 1127 if (Type == 'N') 1128 { 1129 Node = AcpiDbConvertToNode (IndexArg); 1130 if (Node->Type != ACPI_TYPE_INTEGER) 1131 { 1132 AcpiOsPrintf ("Can only set Integer nodes\n"); 1133 return; 1134 } 1135 ObjDesc = Node->Object; 1136 ObjDesc->Integer.Value = Value; 1137 return; 1138 } 1139 1140 /* Get the index and value */ 1141 1142 Index = ACPI_STRTOUL (IndexArg, NULL, 16); 1143 1144 WalkState = AcpiDsGetCurrentWalkState (AcpiGbl_CurrentWalkList); 1145 if (!WalkState) 1146 { 1147 AcpiOsPrintf ("There is no method currently executing\n"); 1148 return; 1149 } 1150 1151 /* Create and initialize the new object */ 1152 1153 ObjDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); 1154 if (!ObjDesc) 1155 { 1156 AcpiOsPrintf ("Could not create an internal object\n"); 1157 return; 1158 } 1159 1160 ObjDesc->Integer.Value = Value; 1161 1162 /* Store the new object into the target */ 1163 1164 switch (Type) 1165 { 1166 case 'A': 1167 1168 /* Set a method argument */ 1169 1170 if (Index > ACPI_METHOD_MAX_ARG) 1171 { 1172 AcpiOsPrintf ("Arg%d - Invalid argument name\n", Index); 1173 goto Cleanup; 1174 } 1175 1176 Status = AcpiDsStoreObjectToLocal (ACPI_REFCLASS_ARG, Index, ObjDesc, 1177 WalkState); 1178 if (ACPI_FAILURE (Status)) 1179 { 1180 goto Cleanup; 1181 } 1182 1183 ObjDesc = WalkState->Arguments[Index].Object; 1184 1185 AcpiOsPrintf ("Arg%d: ", Index); 1186 AcpiDmDisplayInternalObject (ObjDesc, WalkState); 1187 break; 1188 1189 case 'L': 1190 1191 /* Set a method local */ 1192 1193 if (Index > ACPI_METHOD_MAX_LOCAL) 1194 { 1195 AcpiOsPrintf ("Local%d - Invalid local variable name\n", Index); 1196 goto Cleanup; 1197 } 1198 1199 Status = AcpiDsStoreObjectToLocal (ACPI_REFCLASS_LOCAL, Index, ObjDesc, 1200 WalkState); 1201 if (ACPI_FAILURE (Status)) 1202 { 1203 goto Cleanup; 1204 } 1205 1206 ObjDesc = WalkState->LocalVariables[Index].Object; 1207 1208 AcpiOsPrintf ("Local%d: ", Index); 1209 AcpiDmDisplayInternalObject (ObjDesc, WalkState); 1210 break; 1211 1212 default: 1213 break; 1214 } 1215 1216Cleanup: 1217 AcpiUtRemoveReference (ObjDesc); 1218} 1219 1220 1221/******************************************************************************* 1222 * 1223 * FUNCTION: AcpiDbWalkForSpecificObjects 1224 * 1225 * PARAMETERS: Callback from WalkNamespace 1226 * 1227 * RETURN: Status 1228 * 1229 * DESCRIPTION: Display short info about objects in the namespace 1230 * 1231 ******************************************************************************/ 1232 1233static ACPI_STATUS 1234AcpiDbWalkForSpecificObjects ( 1235 ACPI_HANDLE ObjHandle, 1236 UINT32 NestingLevel, 1237 void *Context, 1238 void **ReturnValue) 1239{ 1240 ACPI_WALK_INFO *Info = (ACPI_WALK_INFO *) Context; 1241 ACPI_BUFFER Buffer; 1242 ACPI_STATUS Status; 1243 1244 1245 Info->Count++; 1246 1247 /* Get and display the full pathname to this object */ 1248 1249 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 1250 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer); 1251 if (ACPI_FAILURE (Status)) 1252 { 1253 AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle); 1254 return (AE_OK); 1255 } 1256 1257 AcpiOsPrintf ("%32s", (char *) Buffer.Pointer); 1258 ACPI_FREE (Buffer.Pointer); 1259 1260 /* Dump short info about the object */ 1261 1262 (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, Info, NULL); 1263 return (AE_OK); 1264} 1265 1266 1267/******************************************************************************* 1268 * 1269 * FUNCTION: AcpiDbDisplayObjects 1270 * 1271 * PARAMETERS: ObjTypeArg - Type of object to display 1272 * DisplayCountArg - Max depth to display 1273 * 1274 * RETURN: None 1275 * 1276 * DESCRIPTION: Display objects in the namespace of the requested type 1277 * 1278 ******************************************************************************/ 1279 1280ACPI_STATUS 1281AcpiDbDisplayObjects ( 1282 char *ObjTypeArg, 1283 char *DisplayCountArg) 1284{ 1285 ACPI_WALK_INFO Info; 1286 ACPI_OBJECT_TYPE Type; 1287 1288 1289 /* Get the object type */ 1290 1291 Type = AcpiDbMatchArgument (ObjTypeArg, AcpiDbObjectTypes); 1292 if (Type == ACPI_TYPE_NOT_FOUND) 1293 { 1294 AcpiOsPrintf ("Invalid or unsupported argument\n"); 1295 return (AE_OK); 1296 } 1297 1298 AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); 1299 AcpiOsPrintf ( 1300 "Objects of type [%s] defined in the current ACPI Namespace:\n", 1301 AcpiUtGetTypeName (Type)); 1302 1303 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 1304 1305 Info.Count = 0; 1306 Info.OwnerId = ACPI_OWNER_ID_MAX; 1307 Info.DebugLevel = ACPI_UINT32_MAX; 1308 Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT; 1309 1310 /* Walk the namespace from the root */ 1311 1312 (void) AcpiWalkNamespace (Type, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, 1313 AcpiDbWalkForSpecificObjects, (void *) &Info, NULL); 1314 1315 AcpiOsPrintf ( 1316 "\nFound %u objects of type [%s] in the current ACPI Namespace\n", 1317 Info.Count, AcpiUtGetTypeName (Type)); 1318 1319 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 1320 return (AE_OK); 1321} 1322 1323 1324/******************************************************************************* 1325 * 1326 * FUNCTION: AcpiDbWalkAndMatchName 1327 * 1328 * PARAMETERS: Callback from WalkNamespace 1329 * 1330 * RETURN: Status 1331 * 1332 * DESCRIPTION: Find a particular name/names within the namespace. Wildcards 1333 * are supported -- '?' matches any character. 1334 * 1335 ******************************************************************************/ 1336 1337static ACPI_STATUS 1338AcpiDbWalkAndMatchName ( 1339 ACPI_HANDLE ObjHandle, 1340 UINT32 NestingLevel, 1341 void *Context, 1342 void **ReturnValue) 1343{ 1344 ACPI_STATUS Status; 1345 char *RequestedName = (char *) Context; 1346 UINT32 i; 1347 ACPI_BUFFER Buffer; 1348 ACPI_WALK_INFO Info; 1349 1350 1351 /* Check for a name match */ 1352 1353 for (i = 0; i < 4; i++) 1354 { 1355 /* Wildcard support */ 1356 1357 if ((RequestedName[i] != '?') && 1358 (RequestedName[i] != ((ACPI_NAMESPACE_NODE *) ObjHandle)->Name.Ascii[i])) 1359 { 1360 /* No match, just exit */ 1361 1362 return (AE_OK); 1363 } 1364 } 1365 1366 /* Get the full pathname to this object */ 1367 1368 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 1369 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer); 1370 if (ACPI_FAILURE (Status)) 1371 { 1372 AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle); 1373 } 1374 else 1375 { 1376 Info.OwnerId = ACPI_OWNER_ID_MAX; 1377 Info.DebugLevel = ACPI_UINT32_MAX; 1378 Info.DisplayType = ACPI_DISPLAY_SUMMARY | ACPI_DISPLAY_SHORT; 1379 1380 AcpiOsPrintf ("%32s", (char *) Buffer.Pointer); 1381 (void) AcpiNsDumpOneObject (ObjHandle, NestingLevel, &Info, NULL); 1382 ACPI_FREE (Buffer.Pointer); 1383 } 1384 1385 return (AE_OK); 1386} 1387 1388 1389/******************************************************************************* 1390 * 1391 * FUNCTION: AcpiDbFindNameInNamespace 1392 * 1393 * PARAMETERS: NameArg - The 4-character ACPI name to find. 1394 * wildcards are supported. 1395 * 1396 * RETURN: None 1397 * 1398 * DESCRIPTION: Search the namespace for a given name (with wildcards) 1399 * 1400 ******************************************************************************/ 1401 1402ACPI_STATUS 1403AcpiDbFindNameInNamespace ( 1404 char *NameArg) 1405{ 1406 char AcpiName[5] = "____"; 1407 char *AcpiNamePtr = AcpiName; 1408 1409 1410 if (ACPI_STRLEN (NameArg) > 4) 1411 { 1412 AcpiOsPrintf ("Name must be no longer than 4 characters\n"); 1413 return (AE_OK); 1414 } 1415 1416 /* Pad out name with underscores as necessary to create a 4-char name */ 1417 1418 AcpiUtStrupr (NameArg); 1419 while (*NameArg) 1420 { 1421 *AcpiNamePtr = *NameArg; 1422 AcpiNamePtr++; 1423 NameArg++; 1424 } 1425 1426 /* Walk the namespace from the root */ 1427 1428 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, 1429 AcpiDbWalkAndMatchName, AcpiName, NULL); 1430 1431 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 1432 return (AE_OK); 1433} 1434 1435 1436/******************************************************************************* 1437 * 1438 * FUNCTION: AcpiDbSetScope 1439 * 1440 * PARAMETERS: Name - New scope path 1441 * 1442 * RETURN: Status 1443 * 1444 * DESCRIPTION: Set the "current scope" as maintained by this utility. 1445 * The scope is used as a prefix to ACPI paths. 1446 * 1447 ******************************************************************************/ 1448 1449void 1450AcpiDbSetScope ( 1451 char *Name) 1452{ 1453 ACPI_STATUS Status; 1454 ACPI_NAMESPACE_NODE *Node; 1455 1456 1457 if (!Name || Name[0] == 0) 1458 { 1459 AcpiOsPrintf ("Current scope: %s\n", AcpiGbl_DbScopeBuf); 1460 return; 1461 } 1462 1463 AcpiDbPrepNamestring (Name); 1464 1465 if (Name[0] == '\\') 1466 { 1467 /* Validate new scope from the root */ 1468 1469 Status = AcpiNsGetNode (AcpiGbl_RootNode, Name, ACPI_NS_NO_UPSEARCH, 1470 &Node); 1471 if (ACPI_FAILURE (Status)) 1472 { 1473 goto ErrorExit; 1474 } 1475 1476 ACPI_STRCPY (AcpiGbl_DbScopeBuf, Name); 1477 ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\"); 1478 } 1479 else 1480 { 1481 /* Validate new scope relative to old scope */ 1482 1483 Status = AcpiNsGetNode (AcpiGbl_DbScopeNode, Name, ACPI_NS_NO_UPSEARCH, 1484 &Node); 1485 if (ACPI_FAILURE (Status)) 1486 { 1487 goto ErrorExit; 1488 } 1489 1490 ACPI_STRCAT (AcpiGbl_DbScopeBuf, Name); 1491 ACPI_STRCAT (AcpiGbl_DbScopeBuf, "\\"); 1492 } 1493 1494 AcpiGbl_DbScopeNode = Node; 1495 AcpiOsPrintf ("New scope: %s\n", AcpiGbl_DbScopeBuf); 1496 return; 1497 1498ErrorExit: 1499 1500 AcpiOsPrintf ("Could not attach scope: %s, %s\n", 1501 Name, AcpiFormatException (Status)); 1502} 1503 1504 1505/******************************************************************************* 1506 * 1507 * FUNCTION: AcpiDmCompareAmlResources 1508 * 1509 * PARAMETERS: Aml1Buffer - Contains first resource list 1510 * Aml1BufferLength - Length of first resource list 1511 * Aml2Buffer - Contains second resource list 1512 * Aml2BufferLength - Length of second resource list 1513 * 1514 * RETURN: None 1515 * 1516 * DESCRIPTION: Compare two AML resource lists, descriptor by descriptor (in 1517 * order to isolate a miscompare to an individual resource) 1518 * 1519 ******************************************************************************/ 1520 1521static void 1522AcpiDmCompareAmlResources ( 1523 UINT8 *Aml1Buffer, 1524 ACPI_RSDESC_SIZE Aml1BufferLength, 1525 UINT8 *Aml2Buffer, 1526 ACPI_RSDESC_SIZE Aml2BufferLength) 1527{ 1528 UINT8 *Aml1; 1529 UINT8 *Aml2; 1530 ACPI_RSDESC_SIZE Aml1Length; 1531 ACPI_RSDESC_SIZE Aml2Length; 1532 ACPI_RSDESC_SIZE Offset = 0; 1533 UINT8 ResourceType; 1534 UINT32 Count = 0; 1535 1536 1537 /* Compare overall buffer sizes (may be different due to size rounding) */ 1538 1539 if (Aml1BufferLength != Aml2BufferLength) 1540 { 1541 AcpiOsPrintf ( 1542 "**** Buffer length mismatch in converted AML: original %X new %X ****\n", 1543 Aml1BufferLength, Aml2BufferLength); 1544 } 1545 1546 Aml1 = Aml1Buffer; 1547 Aml2 = Aml2Buffer; 1548 1549 /* Walk the descriptor lists, comparing each descriptor */ 1550 1551 while (Aml1 < (Aml1Buffer + Aml1BufferLength)) 1552 { 1553 /* Get the lengths of each descriptor */ 1554 1555 Aml1Length = AcpiUtGetDescriptorLength (Aml1); 1556 Aml2Length = AcpiUtGetDescriptorLength (Aml2); 1557 ResourceType = AcpiUtGetResourceType (Aml1); 1558 1559 /* Check for descriptor length match */ 1560 1561 if (Aml1Length != Aml2Length) 1562 { 1563 AcpiOsPrintf ( 1564 "**** Length mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X L1 %X L2 %X ****\n", 1565 Count, ResourceType, Offset, Aml1Length, Aml2Length); 1566 } 1567 1568 /* Check for descriptor byte match */ 1569 1570 else if (ACPI_MEMCMP (Aml1, Aml2, Aml1Length)) 1571 { 1572 AcpiOsPrintf ( 1573 "**** Data mismatch in descriptor [%.2X] type %2.2X, Offset %8.8X ****\n", 1574 Count, ResourceType, Offset); 1575 } 1576 1577 /* Exit on EndTag descriptor */ 1578 1579 if (ResourceType == ACPI_RESOURCE_NAME_END_TAG) 1580 { 1581 return; 1582 } 1583 1584 /* Point to next descriptor in each buffer */ 1585 1586 Count++; 1587 Offset += Aml1Length; 1588 Aml1 += Aml1Length; 1589 Aml2 += Aml2Length; 1590 } 1591} 1592 1593 1594/******************************************************************************* 1595 * 1596 * FUNCTION: AcpiDmTestResourceConversion 1597 * 1598 * PARAMETERS: Node - Parent device node 1599 * Name - resource method name (_CRS) 1600 * 1601 * RETURN: Status 1602 * 1603 * DESCRIPTION: Compare the original AML with a conversion of the AML to 1604 * internal resource list, then back to AML. 1605 * 1606 ******************************************************************************/ 1607 1608static ACPI_STATUS 1609AcpiDmTestResourceConversion ( 1610 ACPI_NAMESPACE_NODE *Node, 1611 char *Name) 1612{ 1613 ACPI_STATUS Status; 1614 ACPI_BUFFER ReturnObj; 1615 ACPI_BUFFER ResourceObj; 1616 ACPI_BUFFER NewAml; 1617 ACPI_OBJECT *OriginalAml; 1618 1619 1620 AcpiOsPrintf ("Resource Conversion Comparison:\n"); 1621 1622 NewAml.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 1623 ReturnObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 1624 ResourceObj.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 1625 1626 /* Get the original _CRS AML resource template */ 1627 1628 Status = AcpiEvaluateObject (Node, Name, NULL, &ReturnObj); 1629 if (ACPI_FAILURE (Status)) 1630 { 1631 AcpiOsPrintf ("Could not obtain %s: %s\n", 1632 Name, AcpiFormatException (Status)); 1633 return (Status); 1634 } 1635 1636 /* Get the AML resource template, converted to internal resource structs */ 1637 1638 Status = AcpiGetCurrentResources (Node, &ResourceObj); 1639 if (ACPI_FAILURE (Status)) 1640 { 1641 AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n", 1642 AcpiFormatException (Status)); 1643 goto Exit1; 1644 } 1645 1646 /* Convert internal resource list to external AML resource template */ 1647 1648 Status = AcpiRsCreateAmlResources (ResourceObj.Pointer, &NewAml); 1649 if (ACPI_FAILURE (Status)) 1650 { 1651 AcpiOsPrintf ("AcpiRsCreateAmlResources failed: %s\n", 1652 AcpiFormatException (Status)); 1653 goto Exit2; 1654 } 1655 1656 /* Compare original AML to the newly created AML resource list */ 1657 1658 OriginalAml = ReturnObj.Pointer; 1659 1660 AcpiDmCompareAmlResources ( 1661 OriginalAml->Buffer.Pointer, (ACPI_RSDESC_SIZE) OriginalAml->Buffer.Length, 1662 NewAml.Pointer, (ACPI_RSDESC_SIZE) NewAml.Length); 1663 1664 /* Cleanup and exit */ 1665 1666 ACPI_FREE (NewAml.Pointer); 1667Exit2: 1668 ACPI_FREE (ResourceObj.Pointer); 1669Exit1: 1670 ACPI_FREE (ReturnObj.Pointer); 1671 return (Status); 1672} 1673 1674 1675/******************************************************************************* 1676 * 1677 * FUNCTION: AcpiDbDisplayResources 1678 * 1679 * PARAMETERS: ObjectArg - String with hex value of the object 1680 * 1681 * RETURN: None 1682 * 1683 * DESCRIPTION: Display the resource objects associated with a device. 1684 * 1685 ******************************************************************************/ 1686 1687void 1688AcpiDbDisplayResources ( 1689 char *ObjectArg) 1690{ 1691 ACPI_NAMESPACE_NODE *Node; 1692 ACPI_STATUS Status; 1693 ACPI_BUFFER ReturnObj; 1694 1695 1696 AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); 1697 AcpiDbgLevel |= ACPI_LV_RESOURCES; 1698 1699 /* Convert string to object pointer */ 1700 1701 Node = AcpiDbConvertToNode (ObjectArg); 1702 if (!Node) 1703 { 1704 return; 1705 } 1706 1707 /* Prepare for a return object of arbitrary size */ 1708 1709 ReturnObj.Pointer = AcpiGbl_DbBuffer; 1710 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 1711 1712 /* _PRT */ 1713 1714 AcpiOsPrintf ("Evaluating _PRT\n"); 1715 1716 /* Check if _PRT exists */ 1717 1718 Status = AcpiEvaluateObject (Node, METHOD_NAME__PRT, NULL, &ReturnObj); 1719 if (ACPI_FAILURE (Status)) 1720 { 1721 AcpiOsPrintf ("Could not obtain _PRT: %s\n", 1722 AcpiFormatException (Status)); 1723 goto GetCrs; 1724 } 1725 1726 ReturnObj.Pointer = AcpiGbl_DbBuffer; 1727 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 1728 1729 Status = AcpiGetIrqRoutingTable (Node, &ReturnObj); 1730 if (ACPI_FAILURE (Status)) 1731 { 1732 AcpiOsPrintf ("GetIrqRoutingTable failed: %s\n", 1733 AcpiFormatException (Status)); 1734 goto GetCrs; 1735 } 1736 1737 AcpiRsDumpIrqList (ACPI_CAST_PTR (UINT8, AcpiGbl_DbBuffer)); 1738 1739 1740 /* _CRS */ 1741 1742GetCrs: 1743 AcpiOsPrintf ("Evaluating _CRS\n"); 1744 1745 ReturnObj.Pointer = AcpiGbl_DbBuffer; 1746 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 1747 1748 /* Check if _CRS exists */ 1749 1750 Status = AcpiEvaluateObject (Node, METHOD_NAME__CRS, NULL, &ReturnObj); 1751 if (ACPI_FAILURE (Status)) 1752 { 1753 AcpiOsPrintf ("Could not obtain _CRS: %s\n", 1754 AcpiFormatException (Status)); 1755 goto GetPrs; 1756 } 1757 1758 /* Get the _CRS resource list */ 1759 1760 ReturnObj.Pointer = AcpiGbl_DbBuffer; 1761 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 1762 1763 Status = AcpiGetCurrentResources (Node, &ReturnObj); 1764 if (ACPI_FAILURE (Status)) 1765 { 1766 AcpiOsPrintf ("AcpiGetCurrentResources failed: %s\n", 1767 AcpiFormatException (Status)); 1768 goto GetPrs; 1769 } 1770 1771 /* Dump the _CRS resource list */ 1772 1773 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, 1774 ReturnObj.Pointer)); 1775 1776 /* 1777 * Perform comparison of original AML to newly created AML. This tests both 1778 * the AML->Resource conversion and the Resource->Aml conversion. 1779 */ 1780 Status = AcpiDmTestResourceConversion (Node, METHOD_NAME__CRS); 1781 1782 /* Execute _SRS with the resource list */ 1783 1784 Status = AcpiSetCurrentResources (Node, &ReturnObj); 1785 if (ACPI_FAILURE (Status)) 1786 { 1787 AcpiOsPrintf ("AcpiSetCurrentResources failed: %s\n", 1788 AcpiFormatException (Status)); 1789 goto GetPrs; 1790 } 1791 1792 1793 /* _PRS */ 1794 1795GetPrs: 1796 AcpiOsPrintf ("Evaluating _PRS\n"); 1797 1798 ReturnObj.Pointer = AcpiGbl_DbBuffer; 1799 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 1800 1801 /* Check if _PRS exists */ 1802 1803 Status = AcpiEvaluateObject (Node, METHOD_NAME__PRS, NULL, &ReturnObj); 1804 if (ACPI_FAILURE (Status)) 1805 { 1806 AcpiOsPrintf ("Could not obtain _PRS: %s\n", 1807 AcpiFormatException (Status)); 1808 goto Cleanup; 1809 } 1810 1811 ReturnObj.Pointer = AcpiGbl_DbBuffer; 1812 ReturnObj.Length = ACPI_DEBUG_BUFFER_SIZE; 1813 1814 Status = AcpiGetPossibleResources (Node, &ReturnObj); 1815 if (ACPI_FAILURE (Status)) 1816 { 1817 AcpiOsPrintf ("AcpiGetPossibleResources failed: %s\n", 1818 AcpiFormatException (Status)); 1819 goto Cleanup; 1820 } 1821 1822 AcpiRsDumpResourceList (ACPI_CAST_PTR (ACPI_RESOURCE, AcpiGbl_DbBuffer)); 1823 1824Cleanup: 1825 1826 AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); 1827 return; 1828} 1829 1830 1831/******************************************************************************* 1832 * 1833 * FUNCTION: AcpiDbIntegrityWalk 1834 * 1835 * PARAMETERS: Callback from WalkNamespace 1836 * 1837 * RETURN: Status 1838 * 1839 * DESCRIPTION: Examine one NS node for valid values. 1840 * 1841 ******************************************************************************/ 1842 1843static ACPI_STATUS 1844AcpiDbIntegrityWalk ( 1845 ACPI_HANDLE ObjHandle, 1846 UINT32 NestingLevel, 1847 void *Context, 1848 void **ReturnValue) 1849{ 1850 ACPI_INTEGRITY_INFO *Info = (ACPI_INTEGRITY_INFO *) Context; 1851 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 1852 ACPI_OPERAND_OBJECT *Object; 1853 BOOLEAN Alias = TRUE; 1854 1855 1856 Info->Nodes++; 1857 1858 /* Verify the NS node, and dereference aliases */ 1859 1860 while (Alias) 1861 { 1862 if (ACPI_GET_DESCRIPTOR_TYPE (Node) != ACPI_DESC_TYPE_NAMED) 1863 { 1864 AcpiOsPrintf ("Invalid Descriptor Type for Node %p [%s] - is %2.2X should be %2.2X\n", 1865 Node, AcpiUtGetDescriptorName (Node), ACPI_GET_DESCRIPTOR_TYPE (Node), 1866 ACPI_DESC_TYPE_NAMED); 1867 return (AE_OK); 1868 } 1869 1870 if ((Node->Type == ACPI_TYPE_LOCAL_ALIAS) || 1871 (Node->Type == ACPI_TYPE_LOCAL_METHOD_ALIAS)) 1872 { 1873 Node = (ACPI_NAMESPACE_NODE *) Node->Object; 1874 } 1875 else 1876 { 1877 Alias = FALSE; 1878 } 1879 } 1880 1881 if (Node->Type > ACPI_TYPE_LOCAL_MAX) 1882 { 1883 AcpiOsPrintf ("Invalid Object Type for Node %p, Type = %X\n", 1884 Node, Node->Type); 1885 return (AE_OK); 1886 } 1887 1888 if (!AcpiUtValidAcpiName (Node->Name.Integer)) 1889 { 1890 AcpiOsPrintf ("Invalid AcpiName for Node %p\n", Node); 1891 return (AE_OK); 1892 } 1893 1894 Object = AcpiNsGetAttachedObject (Node); 1895 if (Object) 1896 { 1897 Info->Objects++; 1898 if (ACPI_GET_DESCRIPTOR_TYPE (Object) != ACPI_DESC_TYPE_OPERAND) 1899 { 1900 AcpiOsPrintf ("Invalid Descriptor Type for Object %p [%s]\n", 1901 Object, AcpiUtGetDescriptorName (Object)); 1902 } 1903 } 1904 1905 return (AE_OK); 1906} 1907 1908 1909/******************************************************************************* 1910 * 1911 * FUNCTION: AcpiDbCheckIntegrity 1912 * 1913 * PARAMETERS: None 1914 * 1915 * RETURN: None 1916 * 1917 * DESCRIPTION: Check entire namespace for data structure integrity 1918 * 1919 ******************************************************************************/ 1920 1921void 1922AcpiDbCheckIntegrity ( 1923 void) 1924{ 1925 ACPI_INTEGRITY_INFO Info = {0,0}; 1926 1927 /* Search all nodes in namespace */ 1928 1929 (void) AcpiWalkNamespace (ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, 1930 AcpiDbIntegrityWalk, (void *) &Info, NULL); 1931 1932 AcpiOsPrintf ("Verified %d namespace nodes with %d Objects\n", 1933 Info.Nodes, Info.Objects); 1934} 1935 1936 1937/******************************************************************************* 1938 * 1939 * FUNCTION: AcpiDbGenerateGpe 1940 * 1941 * PARAMETERS: GpeArg - Raw GPE number, ascii string 1942 * BlockArg - GPE block number, ascii string 1943 * 0 or 1 for FADT GPE blocks 1944 * 1945 * RETURN: None 1946 * 1947 * DESCRIPTION: Generate a GPE 1948 * 1949 ******************************************************************************/ 1950 1951void 1952AcpiDbGenerateGpe ( 1953 char *GpeArg, 1954 char *BlockArg) 1955{ 1956 UINT32 BlockNumber; 1957 UINT32 GpeNumber; 1958 ACPI_GPE_EVENT_INFO *GpeEventInfo; 1959 1960 1961 GpeNumber = ACPI_STRTOUL (GpeArg, NULL, 0); 1962 BlockNumber = ACPI_STRTOUL (BlockArg, NULL, 0); 1963 1964 1965 GpeEventInfo = AcpiEvGetGpeEventInfo (ACPI_TO_POINTER (BlockNumber), 1966 GpeNumber); 1967 if (!GpeEventInfo) 1968 { 1969 AcpiOsPrintf ("Invalid GPE\n"); 1970 return; 1971 } 1972 1973 (void) AcpiEvGpeDispatch (GpeEventInfo, GpeNumber); 1974} 1975 1976 1977/******************************************************************************* 1978 * 1979 * FUNCTION: AcpiDbBusWalk 1980 * 1981 * PARAMETERS: Callback from WalkNamespace 1982 * 1983 * RETURN: Status 1984 * 1985 * DESCRIPTION: Display info about device objects that have a corresponding 1986 * _PRT method. 1987 * 1988 ******************************************************************************/ 1989 1990static ACPI_STATUS 1991AcpiDbBusWalk ( 1992 ACPI_HANDLE ObjHandle, 1993 UINT32 NestingLevel, 1994 void *Context, 1995 void **ReturnValue) 1996{ 1997 ACPI_NAMESPACE_NODE *Node = (ACPI_NAMESPACE_NODE *) ObjHandle; 1998 ACPI_STATUS Status; 1999 ACPI_BUFFER Buffer; 2000 ACPI_INTEGER ADR; 2001 ACPI_DEVICE_ID Id; 2002 ACPI_COMPATIBLE_ID_LIST *Cid; 2003 ACPI_NAMESPACE_NODE *TempNode; 2004 2005 2006 /* Exit if there is no _PRT under this device */ 2007 2008 Status = AcpiGetHandle (Node, METHOD_NAME__PRT, 2009 ACPI_CAST_PTR (ACPI_HANDLE, &TempNode)); 2010 if (ACPI_FAILURE (Status)) 2011 { 2012 return (AE_OK); 2013 } 2014 2015 /* Get the full path to this device object */ 2016 2017 Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER; 2018 Status = AcpiNsHandleToPathname (ObjHandle, &Buffer); 2019 if (ACPI_FAILURE (Status)) 2020 { 2021 AcpiOsPrintf ("Could Not get pathname for object %p\n", ObjHandle); 2022 return (AE_OK); 2023 } 2024 2025 /* Display the full path */ 2026 2027 AcpiOsPrintf ("%-32s", (char *) Buffer.Pointer); 2028 ACPI_FREE (Buffer.Pointer); 2029 2030 /* _PRT info */ 2031 2032 AcpiOsPrintf ("_PRT=%p", TempNode); 2033 2034 /* Get the _ADR value */ 2035 2036 Status = AcpiUtEvaluateNumericObject (METHOD_NAME__ADR, Node, &ADR); 2037 if (ACPI_FAILURE (Status)) 2038 { 2039 AcpiOsPrintf (" No _ADR "); 2040 } 2041 else 2042 { 2043 AcpiOsPrintf (" _ADR=%8.8X", (UINT32) ADR); 2044 } 2045 2046 /* Get the _HID if present */ 2047 2048 Status = AcpiUtExecute_HID (Node, &Id); 2049 if (ACPI_SUCCESS (Status)) 2050 { 2051 AcpiOsPrintf (" _HID=%s", Id.Value); 2052 } 2053 else 2054 { 2055 AcpiOsPrintf (" "); 2056 } 2057 2058 /* Get the _UID if present */ 2059 2060 Status = AcpiUtExecute_UID (Node, &Id); 2061 if (ACPI_SUCCESS (Status)) 2062 { 2063 AcpiOsPrintf (" _UID=%s", Id.Value); 2064 } 2065 2066 /* Get the _CID if present */ 2067 2068 Status = AcpiUtExecute_CID (Node, &Cid); 2069 if (ACPI_SUCCESS (Status)) 2070 { 2071 AcpiOsPrintf (" _CID=%s", Cid->Id[0].Value); 2072 ACPI_FREE (Cid); 2073 } 2074 2075 AcpiOsPrintf ("\n"); 2076 return (AE_OK); 2077} 2078 2079 2080/******************************************************************************* 2081 * 2082 * FUNCTION: AcpiDbGetBusInfo 2083 * 2084 * PARAMETERS: None 2085 * 2086 * RETURN: None 2087 * 2088 * DESCRIPTION: Display info about system busses. 2089 * 2090 ******************************************************************************/ 2091 2092void 2093AcpiDbGetBusInfo ( 2094 void) 2095{ 2096 /* Search all nodes in namespace */ 2097 2098 (void) AcpiWalkNamespace (ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, 2099 AcpiDbBusWalk, NULL, NULL); 2100} 2101 2102#endif /* ACPI_DEBUGGER */ 2103