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