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