13446Smrj /******************************************************************************* 23446Smrj * 33446Smrj * Module Name: dmwalk - AML disassembly tree walk 4*7851SDana.Myers@Sun.COM * $Revision: 1.35 $ 53446Smrj * 63446Smrj ******************************************************************************/ 73446Smrj 83446Smrj /****************************************************************************** 93446Smrj * 103446Smrj * 1. Copyright Notice 113446Smrj * 12*7851SDana.Myers@Sun.COM * Some or all of this work - Copyright (c) 1999 - 2008, Intel Corp. 133446Smrj * All rights reserved. 143446Smrj * 153446Smrj * 2. License 163446Smrj * 173446Smrj * 2.1. This is your license from Intel Corp. under its intellectual property 183446Smrj * rights. You may have additional license terms from the party that provided 193446Smrj * you this software, covering your right to use that party's intellectual 203446Smrj * property rights. 213446Smrj * 223446Smrj * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 233446Smrj * copy of the source code appearing in this file ("Covered Code") an 243446Smrj * irrevocable, perpetual, worldwide license under Intel's copyrights in the 253446Smrj * base code distributed originally by Intel ("Original Intel Code") to copy, 263446Smrj * make derivatives, distribute, use and display any portion of the Covered 273446Smrj * Code in any form, with the right to sublicense such rights; and 283446Smrj * 293446Smrj * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 303446Smrj * license (with the right to sublicense), under only those claims of Intel 313446Smrj * patents that are infringed by the Original Intel Code, to make, use, sell, 323446Smrj * offer to sell, and import the Covered Code and derivative works thereof 333446Smrj * solely to the minimum extent necessary to exercise the above copyright 343446Smrj * license, and in no event shall the patent license extend to any additions 353446Smrj * to or modifications of the Original Intel Code. No other license or right 363446Smrj * is granted directly or by implication, estoppel or otherwise; 373446Smrj * 383446Smrj * The above copyright and patent license is granted only if the following 393446Smrj * conditions are met: 403446Smrj * 413446Smrj * 3. Conditions 423446Smrj * 433446Smrj * 3.1. Redistribution of Source with Rights to Further Distribute Source. 443446Smrj * Redistribution of source code of any substantial portion of the Covered 453446Smrj * Code or modification with rights to further distribute source must include 463446Smrj * the above Copyright Notice, the above License, this list of Conditions, 473446Smrj * and the following Disclaimer and Export Compliance provision. In addition, 483446Smrj * Licensee must cause all Covered Code to which Licensee contributes to 493446Smrj * contain a file documenting the changes Licensee made to create that Covered 503446Smrj * Code and the date of any change. Licensee must include in that file the 513446Smrj * documentation of any changes made by any predecessor Licensee. Licensee 523446Smrj * must include a prominent statement that the modification is derived, 533446Smrj * directly or indirectly, from Original Intel Code. 543446Smrj * 553446Smrj * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 563446Smrj * Redistribution of source code of any substantial portion of the Covered 573446Smrj * Code or modification without rights to further distribute source must 583446Smrj * include the following Disclaimer and Export Compliance provision in the 593446Smrj * documentation and/or other materials provided with distribution. In 603446Smrj * addition, Licensee may not authorize further sublicense of source of any 613446Smrj * portion of the Covered Code, and must include terms to the effect that the 623446Smrj * license from Licensee to its licensee is limited to the intellectual 633446Smrj * property embodied in the software Licensee provides to its licensee, and 643446Smrj * not to intellectual property embodied in modifications its licensee may 653446Smrj * make. 663446Smrj * 673446Smrj * 3.3. Redistribution of Executable. Redistribution in executable form of any 683446Smrj * substantial portion of the Covered Code or modification must reproduce the 693446Smrj * above Copyright Notice, and the following Disclaimer and Export Compliance 703446Smrj * provision in the documentation and/or other materials provided with the 713446Smrj * distribution. 723446Smrj * 733446Smrj * 3.4. Intel retains all right, title, and interest in and to the Original 743446Smrj * Intel Code. 753446Smrj * 763446Smrj * 3.5. Neither the name Intel nor any other trademark owned or controlled by 773446Smrj * Intel shall be used in advertising or otherwise to promote the sale, use or 783446Smrj * other dealings in products derived from or relating to the Covered Code 793446Smrj * without prior written authorization from Intel. 803446Smrj * 813446Smrj * 4. Disclaimer and Export Compliance 823446Smrj * 833446Smrj * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 843446Smrj * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 853446Smrj * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 863446Smrj * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 873446Smrj * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 883446Smrj * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 893446Smrj * PARTICULAR PURPOSE. 903446Smrj * 913446Smrj * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 923446Smrj * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 933446Smrj * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 943446Smrj * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 953446Smrj * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 963446Smrj * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 973446Smrj * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 983446Smrj * LIMITED REMEDY. 993446Smrj * 1003446Smrj * 4.3. Licensee shall not export, either directly or indirectly, any of this 1013446Smrj * software or system incorporating such software without first obtaining any 1023446Smrj * required license or other approval from the U. S. Department of Commerce or 1033446Smrj * any other agency or department of the United States Government. In the 1043446Smrj * event Licensee exports any such software from the United States or 1053446Smrj * re-exports any such software from a foreign destination, Licensee shall 1063446Smrj * ensure that the distribution and export/re-export of the software is in 1073446Smrj * compliance with all laws, regulations, orders, or other restrictions of the 1083446Smrj * U.S. Export Administration Regulations. Licensee agrees that neither it nor 1093446Smrj * any of its subsidiaries will export/re-export any technical data, process, 1103446Smrj * software, or service, directly or indirectly, to any country for which the 1113446Smrj * United States government or any agency thereof requires an export license, 1123446Smrj * other governmental approval, or letter of assurance, without first obtaining 1133446Smrj * such license, approval or letter. 1143446Smrj * 1153446Smrj *****************************************************************************/ 1163446Smrj 1173446Smrj 1183446Smrj #include "acpi.h" 1193446Smrj #include "acparser.h" 1203446Smrj #include "amlcode.h" 1213446Smrj #include "acdisasm.h" 1223446Smrj #include "acdebug.h" 1233446Smrj 1243446Smrj 1253446Smrj #ifdef ACPI_DISASSEMBLER 1263446Smrj 1273446Smrj #define _COMPONENT ACPI_CA_DEBUGGER 1283446Smrj ACPI_MODULE_NAME ("dmwalk") 1293446Smrj 1303446Smrj 1313446Smrj #define DB_FULL_OP_INFO "[%4.4s] @%5.5X #%4.4X: " 1323446Smrj 1333446Smrj /* Local prototypes */ 1343446Smrj 1353446Smrj static ACPI_STATUS 1363446Smrj AcpiDmDescendingOp ( 1373446Smrj ACPI_PARSE_OBJECT *Op, 1383446Smrj UINT32 Level, 1393446Smrj void *Context); 1403446Smrj 1413446Smrj static ACPI_STATUS 1423446Smrj AcpiDmAscendingOp ( 1433446Smrj ACPI_PARSE_OBJECT *Op, 1443446Smrj UINT32 Level, 1453446Smrj void *Context); 1463446Smrj 1473446Smrj static UINT32 1483446Smrj AcpiDmBlockType ( 1493446Smrj ACPI_PARSE_OBJECT *Op); 1503446Smrj 1513446Smrj 1523446Smrj /******************************************************************************* 1533446Smrj * 1543446Smrj * FUNCTION: AcpiDmDisassemble 1553446Smrj * 1563446Smrj * PARAMETERS: WalkState - Current state 1573446Smrj * Origin - Starting object 1583446Smrj * NumOpcodes - Max number of opcodes to be displayed 1593446Smrj * 1603446Smrj * RETURN: None 1613446Smrj * 1623446Smrj * DESCRIPTION: Disassemble parser object and its children. This is the 1633446Smrj * main entry point of the disassembler. 1643446Smrj * 1653446Smrj ******************************************************************************/ 1663446Smrj 1673446Smrj void 1683446Smrj AcpiDmDisassemble ( 1693446Smrj ACPI_WALK_STATE *WalkState, 1703446Smrj ACPI_PARSE_OBJECT *Origin, 1713446Smrj UINT32 NumOpcodes) 1723446Smrj { 1733446Smrj ACPI_PARSE_OBJECT *Op = Origin; 1743446Smrj ACPI_OP_WALK_INFO Info; 1753446Smrj 1763446Smrj 1773446Smrj if (!Op) 1783446Smrj { 1793446Smrj return; 1803446Smrj } 1813446Smrj 1823446Smrj Info.Flags = 0; 1833446Smrj Info.Level = 0; 1843446Smrj Info.Count = 0; 1853446Smrj Info.WalkState = WalkState; 1863446Smrj AcpiDmWalkParseTree (Op, AcpiDmDescendingOp, AcpiDmAscendingOp, &Info); 1873446Smrj return; 1883446Smrj } 1893446Smrj 1903446Smrj 1913446Smrj /******************************************************************************* 1923446Smrj * 1933446Smrj * FUNCTION: AcpiDmWalkParseTree 1943446Smrj * 1953446Smrj * PARAMETERS: Op - Root Op object 1963446Smrj * DescendingCallback - Called during tree descent 1973446Smrj * AscendingCallback - Called during tree ascent 1983446Smrj * Context - To be passed to the callbacks 1993446Smrj * 2003446Smrj * RETURN: Status from callback(s) 2013446Smrj * 2023446Smrj * DESCRIPTION: Walk the entire parse tree. 2033446Smrj * 2043446Smrj ******************************************************************************/ 2053446Smrj 2063446Smrj void 2073446Smrj AcpiDmWalkParseTree ( 2083446Smrj ACPI_PARSE_OBJECT *Op, 2093446Smrj ASL_WALK_CALLBACK DescendingCallback, 2103446Smrj ASL_WALK_CALLBACK AscendingCallback, 2113446Smrj void *Context) 2123446Smrj { 2133446Smrj BOOLEAN NodePreviouslyVisited; 2143446Smrj ACPI_PARSE_OBJECT *StartOp = Op; 2153446Smrj ACPI_STATUS Status; 2163446Smrj ACPI_PARSE_OBJECT *Next; 2173446Smrj ACPI_OP_WALK_INFO *Info = Context; 2183446Smrj 2193446Smrj 2203446Smrj Info->Level = 0; 2213446Smrj NodePreviouslyVisited = FALSE; 2223446Smrj 2233446Smrj while (Op) 2243446Smrj { 2253446Smrj if (NodePreviouslyVisited) 2263446Smrj { 2273446Smrj if (AscendingCallback) 2283446Smrj { 2293446Smrj Status = AscendingCallback (Op, Info->Level, Context); 2303446Smrj if (ACPI_FAILURE (Status)) 2313446Smrj { 2323446Smrj return; 2333446Smrj } 2343446Smrj } 2353446Smrj } 2363446Smrj else 2373446Smrj { 2383446Smrj /* Let the callback process the node */ 2393446Smrj 2403446Smrj Status = DescendingCallback (Op, Info->Level, Context); 2413446Smrj if (ACPI_SUCCESS (Status)) 2423446Smrj { 2433446Smrj /* Visit children first, once */ 2443446Smrj 2453446Smrj Next = AcpiPsGetArg (Op, 0); 2463446Smrj if (Next) 2473446Smrj { 2483446Smrj Info->Level++; 2493446Smrj Op = Next; 2503446Smrj continue; 2513446Smrj } 2523446Smrj } 2533446Smrj else if (Status != AE_CTRL_DEPTH) 2543446Smrj { 2553446Smrj /* Exit immediately on any error */ 2563446Smrj 2573446Smrj return; 2583446Smrj } 2593446Smrj } 2603446Smrj 2613446Smrj /* Terminate walk at start op */ 2623446Smrj 2633446Smrj if (Op == StartOp) 2643446Smrj { 2653446Smrj break; 2663446Smrj } 2673446Smrj 2683446Smrj /* No more children, re-visit this node */ 2693446Smrj 2703446Smrj if (!NodePreviouslyVisited) 2713446Smrj { 2723446Smrj NodePreviouslyVisited = TRUE; 2733446Smrj continue; 2743446Smrj } 2753446Smrj 2763446Smrj /* No more children, visit peers */ 2773446Smrj 2783446Smrj if (Op->Common.Next) 2793446Smrj { 2803446Smrj Op = Op->Common.Next; 2813446Smrj NodePreviouslyVisited = FALSE; 2823446Smrj } 2833446Smrj else 2843446Smrj { 2853446Smrj /* No peers, re-visit parent */ 2863446Smrj 2873446Smrj if (Info->Level != 0 ) 2883446Smrj { 2893446Smrj Info->Level--; 2903446Smrj } 2913446Smrj 2923446Smrj Op = Op->Common.Parent; 2933446Smrj NodePreviouslyVisited = TRUE; 2943446Smrj } 2953446Smrj } 2963446Smrj 2973446Smrj /* If we get here, the walk completed with no errors */ 2983446Smrj 2993446Smrj return; 3003446Smrj } 3013446Smrj 3023446Smrj 3033446Smrj /******************************************************************************* 3043446Smrj * 3053446Smrj * FUNCTION: AcpiDmBlockType 3063446Smrj * 3073446Smrj * PARAMETERS: Op - Object to be examined 3083446Smrj * 3093446Smrj * RETURN: BlockType - not a block, parens, braces, or even both. 3103446Smrj * 3113446Smrj * DESCRIPTION: Type of block for this op (parens or braces) 3123446Smrj * 3133446Smrj ******************************************************************************/ 3143446Smrj 3153446Smrj static UINT32 3163446Smrj AcpiDmBlockType ( 3173446Smrj ACPI_PARSE_OBJECT *Op) 3183446Smrj { 3193446Smrj const ACPI_OPCODE_INFO *OpInfo; 3203446Smrj 3213446Smrj 3223446Smrj if (!Op) 3233446Smrj { 3243446Smrj return (BLOCK_NONE); 3253446Smrj } 3263446Smrj 3273446Smrj switch (Op->Common.AmlOpcode) 3283446Smrj { 3293446Smrj case AML_ELSE_OP: 3303446Smrj 3313446Smrj return (BLOCK_BRACE); 3323446Smrj 3333446Smrj case AML_METHOD_OP: 3343446Smrj case AML_DEVICE_OP: 3353446Smrj case AML_SCOPE_OP: 3363446Smrj case AML_PROCESSOR_OP: 3373446Smrj case AML_POWER_RES_OP: 3383446Smrj case AML_THERMAL_ZONE_OP: 3393446Smrj case AML_IF_OP: 3403446Smrj case AML_WHILE_OP: 3413446Smrj case AML_FIELD_OP: 3423446Smrj case AML_INDEX_FIELD_OP: 3433446Smrj case AML_BANK_FIELD_OP: 3443446Smrj 3453446Smrj return (BLOCK_PAREN | BLOCK_BRACE); 3463446Smrj 3473446Smrj case AML_BUFFER_OP: 3483446Smrj 3493446Smrj if (Op->Common.DisasmOpcode == ACPI_DASM_UNICODE) 3503446Smrj { 3513446Smrj return (BLOCK_NONE); 3523446Smrj } 3533446Smrj 3543446Smrj /*lint -fallthrough */ 3553446Smrj 3563446Smrj case AML_PACKAGE_OP: 3573446Smrj case AML_VAR_PACKAGE_OP: 3583446Smrj 3593446Smrj return (BLOCK_PAREN | BLOCK_BRACE); 3603446Smrj 3613446Smrj case AML_EVENT_OP: 3623446Smrj 3633446Smrj return (BLOCK_PAREN); 3643446Smrj 3653446Smrj default: 3663446Smrj 3673446Smrj OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 3683446Smrj if (OpInfo->Flags & AML_HAS_ARGS) 3693446Smrj { 3703446Smrj return (BLOCK_PAREN); 3713446Smrj } 3723446Smrj 3733446Smrj return (BLOCK_NONE); 3743446Smrj } 3753446Smrj } 3763446Smrj 3773446Smrj 3783446Smrj /******************************************************************************* 3793446Smrj * 3803446Smrj * FUNCTION: AcpiDmListType 3813446Smrj * 3823446Smrj * PARAMETERS: Op - Object to be examined 3833446Smrj * 3843446Smrj * RETURN: ListType - has commas or not. 3853446Smrj * 3863446Smrj * DESCRIPTION: Type of block for this op (parens or braces) 3873446Smrj * 3883446Smrj ******************************************************************************/ 3893446Smrj 3903446Smrj UINT32 3913446Smrj AcpiDmListType ( 3923446Smrj ACPI_PARSE_OBJECT *Op) 3933446Smrj { 3943446Smrj const ACPI_OPCODE_INFO *OpInfo; 3953446Smrj 3963446Smrj 3973446Smrj if (!Op) 3983446Smrj { 3993446Smrj return (BLOCK_NONE); 4003446Smrj } 4013446Smrj 4023446Smrj switch (Op->Common.AmlOpcode) 4033446Smrj { 4043446Smrj 4053446Smrj case AML_ELSE_OP: 4063446Smrj case AML_METHOD_OP: 4073446Smrj case AML_DEVICE_OP: 4083446Smrj case AML_SCOPE_OP: 4093446Smrj case AML_POWER_RES_OP: 4103446Smrj case AML_PROCESSOR_OP: 4113446Smrj case AML_THERMAL_ZONE_OP: 4123446Smrj case AML_IF_OP: 4133446Smrj case AML_WHILE_OP: 4143446Smrj case AML_FIELD_OP: 4153446Smrj case AML_INDEX_FIELD_OP: 4163446Smrj case AML_BANK_FIELD_OP: 4173446Smrj 4183446Smrj return (BLOCK_NONE); 4193446Smrj 4203446Smrj case AML_BUFFER_OP: 4213446Smrj case AML_PACKAGE_OP: 4223446Smrj case AML_VAR_PACKAGE_OP: 4233446Smrj 4243446Smrj return (BLOCK_COMMA_LIST); 4253446Smrj 4263446Smrj default: 4273446Smrj 4283446Smrj OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 4293446Smrj if (OpInfo->Flags & AML_HAS_ARGS) 4303446Smrj { 4313446Smrj return (BLOCK_COMMA_LIST); 4323446Smrj } 4333446Smrj 4343446Smrj return (BLOCK_NONE); 4353446Smrj } 4363446Smrj } 4373446Smrj 4383446Smrj 4393446Smrj /******************************************************************************* 4403446Smrj * 4413446Smrj * FUNCTION: AcpiDmDescendingOp 4423446Smrj * 4433446Smrj * PARAMETERS: ASL_WALK_CALLBACK 4443446Smrj * 4453446Smrj * RETURN: Status 4463446Smrj * 4473446Smrj * DESCRIPTION: First visitation of a parse object during tree descent. 4483446Smrj * Decode opcode name and begin parameter list(s), if any. 4493446Smrj * 4503446Smrj ******************************************************************************/ 4513446Smrj 4523446Smrj static ACPI_STATUS 4533446Smrj AcpiDmDescendingOp ( 4543446Smrj ACPI_PARSE_OBJECT *Op, 4553446Smrj UINT32 Level, 4563446Smrj void *Context) 4573446Smrj { 4583446Smrj ACPI_OP_WALK_INFO *Info = Context; 4593446Smrj const ACPI_OPCODE_INFO *OpInfo; 4603446Smrj UINT32 Name; 4613446Smrj ACPI_PARSE_OBJECT *NextOp; 4623446Smrj ACPI_EXTERNAL_LIST *NextExternal; 4633446Smrj 4643446Smrj 4653446Smrj if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE) 4663446Smrj { 4673446Smrj /* Ignore this op -- it was handled elsewhere */ 4683446Smrj 4693446Smrj return (AE_CTRL_DEPTH); 4703446Smrj } 4713446Smrj 4723446Smrj /* Level 0 is at the Definition Block level */ 4733446Smrj 4743446Smrj if (Level == 0) 4753446Smrj { 4763446Smrj /* In verbose mode, print the AML offset, opcode and depth count */ 4773446Smrj 4783446Smrj if (Info->WalkState) 4793446Smrj { 4803446Smrj VERBOSE_PRINT ((DB_FULL_OP_INFO, 4813446Smrj (Info->WalkState->MethodNode ? 4823446Smrj Info->WalkState->MethodNode->Name.Ascii : " "), 4833446Smrj Op->Common.AmlOffset, (UINT32) Op->Common.AmlOpcode)); 4843446Smrj } 4853446Smrj 4863446Smrj if (Op->Common.AmlOpcode == AML_SCOPE_OP) 4873446Smrj { 4883446Smrj /* This is the beginning of the Definition Block */ 4893446Smrj 4903446Smrj AcpiOsPrintf ("{\n"); 4913446Smrj 4923446Smrj /* Emit all External() declarations here */ 4933446Smrj 4943446Smrj if (AcpiGbl_ExternalList) 4953446Smrj { 4963446Smrj /* 4973446Smrj * Walk the list of externals (unresolved references) 4983446Smrj * found during parsing 4993446Smrj */ 5003446Smrj while (AcpiGbl_ExternalList) 5013446Smrj { 5023446Smrj AcpiOsPrintf (" External (%s", 5033446Smrj AcpiGbl_ExternalList->Path); 5043446Smrj 5053446Smrj /* TBD: should be a lookup table */ 5063446Smrj 5073446Smrj switch (AcpiGbl_ExternalList->Type) 5083446Smrj { 5093446Smrj case ACPI_TYPE_DEVICE: 5103446Smrj AcpiOsPrintf (", DeviceObj"); 5113446Smrj break; 5123446Smrj 5133446Smrj case ACPI_TYPE_METHOD: 5143446Smrj AcpiOsPrintf (", MethodObj"); 5153446Smrj break; 5163446Smrj 5173446Smrj case ACPI_TYPE_INTEGER: 5183446Smrj AcpiOsPrintf (", IntObj"); 5193446Smrj break; 5203446Smrj 5213446Smrj default: 5223446Smrj break; 5233446Smrj } 5243446Smrj 5253446Smrj if (AcpiGbl_ExternalList->Type == ACPI_TYPE_METHOD) 5263446Smrj { 5273446Smrj AcpiOsPrintf (") // %d Arguments\n", AcpiGbl_ExternalList->Value); 5283446Smrj } 5293446Smrj else 5303446Smrj { 5313446Smrj AcpiOsPrintf (")\n"); 5323446Smrj } 5333446Smrj 5343446Smrj NextExternal = AcpiGbl_ExternalList->Next; 5353446Smrj ACPI_FREE (AcpiGbl_ExternalList->Path); 5363446Smrj ACPI_FREE (AcpiGbl_ExternalList); 5373446Smrj AcpiGbl_ExternalList = NextExternal; 5383446Smrj } 5393446Smrj AcpiOsPrintf ("\n"); 5403446Smrj } 5413446Smrj 5423446Smrj return (AE_OK); 5433446Smrj } 5443446Smrj } 5453446Smrj else if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) && 5463446Smrj (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) && 5473446Smrj (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP)) 5483446Smrj { 5493446Smrj /* 5503446Smrj * This is a first-level element of a term list, 5513446Smrj * indent a new line 5523446Smrj */ 5533446Smrj AcpiDmIndent (Level); 5543446Smrj Info->LastLevel = Level; 5553446Smrj Info->Count = 0; 5563446Smrj } 5573446Smrj 5583446Smrj /* 5593446Smrj * This is an inexpensive mechanism to try and keep lines from getting 5603446Smrj * too long. When the limit is hit, start a new line at the previous 5613446Smrj * indent plus one. A better but more expensive mechanism would be to 5623446Smrj * keep track of the current column. 5633446Smrj */ 5643446Smrj Info->Count++; 5653446Smrj if (Info->Count /*+Info->LastLevel*/ > 10) 5663446Smrj { 5673446Smrj Info->Count = 0; 5683446Smrj AcpiOsPrintf ("\n"); 5693446Smrj AcpiDmIndent (Info->LastLevel + 1); 5703446Smrj } 5713446Smrj 5723446Smrj /* Print the opcode name */ 5733446Smrj 5743446Smrj AcpiDmDisassembleOneOp (NULL, Info, Op); 5753446Smrj 5763446Smrj if (Op->Common.DisasmOpcode == ACPI_DASM_LNOT_PREFIX) 5773446Smrj { 5783446Smrj return (AE_OK); 5793446Smrj } 5803446Smrj 5813446Smrj if ((Op->Common.AmlOpcode == AML_NAME_OP) || 5823446Smrj (Op->Common.AmlOpcode == AML_RETURN_OP)) 5833446Smrj { 5843446Smrj Info->Level--; 5853446Smrj } 5863446Smrj 5873446Smrj /* Start the opcode argument list if necessary */ 5883446Smrj 5893446Smrj OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 5903446Smrj 5913446Smrj if ((OpInfo->Flags & AML_HAS_ARGS) || 5923446Smrj (Op->Common.AmlOpcode == AML_EVENT_OP)) 5933446Smrj { 5943446Smrj /* This opcode has an argument list */ 5953446Smrj 5963446Smrj if (AcpiDmBlockType (Op) & BLOCK_PAREN) 5973446Smrj { 5983446Smrj AcpiOsPrintf (" ("); 5993446Smrj } 6003446Smrj 6013446Smrj /* If this is a named opcode, print the associated name value */ 6023446Smrj 6033446Smrj if (OpInfo->Flags & AML_NAMED) 6043446Smrj { 6053446Smrj switch (Op->Common.AmlOpcode) 6063446Smrj { 6073446Smrj case AML_ALIAS_OP: 6083446Smrj 6093446Smrj NextOp = AcpiPsGetDepthNext (NULL, Op); 6103446Smrj NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 6113446Smrj AcpiDmNamestring (NextOp->Common.Value.Name); 6123446Smrj AcpiOsPrintf (", "); 6133446Smrj 6143446Smrj /*lint -fallthrough */ 6153446Smrj 6163446Smrj default: 6173446Smrj 6183446Smrj Name = AcpiPsGetName (Op); 6193446Smrj if (Op->Named.Path) 6203446Smrj { 6213446Smrj AcpiDmNamestring ((char *) Op->Named.Path); 6223446Smrj } 6233446Smrj else 6243446Smrj { 625*7851SDana.Myers@Sun.COM AcpiDmDumpName (Name); 6263446Smrj } 6273446Smrj 6283446Smrj if (Op->Common.AmlOpcode != AML_INT_NAMEDFIELD_OP) 6293446Smrj { 6303446Smrj if (AcpiGbl_DbOpt_verbose) 6313446Smrj { 6323446Smrj (void) AcpiPsDisplayObjectPathname (NULL, Op); 6333446Smrj } 6343446Smrj } 6353446Smrj break; 6363446Smrj } 6373446Smrj 6383446Smrj switch (Op->Common.AmlOpcode) 6393446Smrj { 6403446Smrj case AML_METHOD_OP: 6413446Smrj 6423446Smrj AcpiDmMethodFlags (Op); 6433446Smrj AcpiOsPrintf (")"); 6443446Smrj break; 6453446Smrj 6463446Smrj 6473446Smrj case AML_NAME_OP: 6483446Smrj 6493446Smrj /* Check for _HID and related EISAID() */ 6503446Smrj 6513446Smrj AcpiDmIsEisaId (Op); 6523446Smrj AcpiOsPrintf (", "); 6533446Smrj break; 6543446Smrj 6553446Smrj 6563446Smrj case AML_REGION_OP: 6573446Smrj 6583446Smrj AcpiDmRegionFlags (Op); 6593446Smrj break; 6603446Smrj 6613446Smrj 6623446Smrj case AML_POWER_RES_OP: 6633446Smrj 6643446Smrj /* Mark the next two Ops as part of the parameter list */ 6653446Smrj 6663446Smrj AcpiOsPrintf (", "); 6673446Smrj NextOp = AcpiPsGetDepthNext (NULL, Op); 6683446Smrj NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 6693446Smrj 6703446Smrj NextOp = NextOp->Common.Next; 6713446Smrj NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 6723446Smrj return (AE_OK); 6733446Smrj 6743446Smrj 6753446Smrj case AML_PROCESSOR_OP: 6763446Smrj 6773446Smrj /* Mark the next three Ops as part of the parameter list */ 6783446Smrj 6793446Smrj AcpiOsPrintf (", "); 6803446Smrj NextOp = AcpiPsGetDepthNext (NULL, Op); 6813446Smrj NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 6823446Smrj 6833446Smrj NextOp = NextOp->Common.Next; 6843446Smrj NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 6853446Smrj 6863446Smrj NextOp = NextOp->Common.Next; 6873446Smrj NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 6883446Smrj return (AE_OK); 6893446Smrj 6903446Smrj 6913446Smrj case AML_MUTEX_OP: 6923446Smrj case AML_DATA_REGION_OP: 6933446Smrj 6943446Smrj AcpiOsPrintf (", "); 6953446Smrj return (AE_OK); 6963446Smrj 6973446Smrj 6983446Smrj case AML_EVENT_OP: 6993446Smrj case AML_ALIAS_OP: 7003446Smrj 7013446Smrj return (AE_OK); 7023446Smrj 7033446Smrj 7043446Smrj case AML_SCOPE_OP: 7053446Smrj case AML_DEVICE_OP: 7063446Smrj case AML_THERMAL_ZONE_OP: 7073446Smrj 7083446Smrj AcpiOsPrintf (")"); 7093446Smrj break; 7103446Smrj 7113446Smrj 7123446Smrj default: 7133446Smrj 7143446Smrj AcpiOsPrintf ("*** Unhandled named opcode %X\n", Op->Common.AmlOpcode); 7153446Smrj break; 7163446Smrj } 7173446Smrj } 7183446Smrj 7193446Smrj else switch (Op->Common.AmlOpcode) 7203446Smrj { 7213446Smrj case AML_FIELD_OP: 7223446Smrj case AML_BANK_FIELD_OP: 7233446Smrj case AML_INDEX_FIELD_OP: 7243446Smrj 7253446Smrj Info->BitOffset = 0; 7263446Smrj 7273446Smrj /* Name of the parent OperationRegion */ 7283446Smrj 7293446Smrj NextOp = AcpiPsGetDepthNext (NULL, Op); 7303446Smrj AcpiDmNamestring (NextOp->Common.Value.Name); 7313446Smrj AcpiOsPrintf (", "); 7323446Smrj NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 7333446Smrj 7343446Smrj switch (Op->Common.AmlOpcode) 7353446Smrj { 7363446Smrj case AML_BANK_FIELD_OP: 7373446Smrj 7383446Smrj /* Namestring - Bank Name */ 7393446Smrj 7403446Smrj NextOp = AcpiPsGetDepthNext (NULL, NextOp); 7413446Smrj AcpiDmNamestring (NextOp->Common.Value.Name); 7423446Smrj NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 7433446Smrj AcpiOsPrintf (", "); 7443446Smrj 7453446Smrj /* 7463446Smrj * Bank Value. This is a TermArg in the middle of the parameter 7473446Smrj * list, must handle it here. 7483446Smrj * 7493446Smrj * Disassemble the TermArg parse tree. ACPI_PARSEOP_PARAMLIST 7503446Smrj * eliminates newline in the output. 7513446Smrj */ 7523446Smrj NextOp = NextOp->Common.Next; 7533446Smrj 7543446Smrj Info->Flags = ACPI_PARSEOP_PARAMLIST; 7553446Smrj AcpiDmWalkParseTree (NextOp, AcpiDmDescendingOp, AcpiDmAscendingOp, Info); 7563446Smrj Info->Flags = 0; 7573446Smrj Info->Level = Level; 7583446Smrj 7593446Smrj NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 7603446Smrj AcpiOsPrintf (", "); 7613446Smrj break; 7623446Smrj 7633446Smrj case AML_INDEX_FIELD_OP: 7643446Smrj 7653446Smrj /* Namestring - Data Name */ 7663446Smrj 7673446Smrj NextOp = AcpiPsGetDepthNext (NULL, NextOp); 7683446Smrj AcpiDmNamestring (NextOp->Common.Value.Name); 7693446Smrj AcpiOsPrintf (", "); 7703446Smrj NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 7713446Smrj break; 7723446Smrj 7733446Smrj default: 7743446Smrj 7753446Smrj break; 7763446Smrj } 7773446Smrj 7783446Smrj AcpiDmFieldFlags (NextOp); 7793446Smrj break; 7803446Smrj 7813446Smrj 7823446Smrj case AML_BUFFER_OP: 7833446Smrj 7843446Smrj /* The next op is the size parameter */ 7853446Smrj 7863446Smrj NextOp = AcpiPsGetDepthNext (NULL, Op); 7873446Smrj if (!NextOp) 7883446Smrj { 7893446Smrj /* Single-step support */ 7903446Smrj 7913446Smrj return (AE_OK); 7923446Smrj } 7933446Smrj 7943446Smrj if (Op->Common.DisasmOpcode == ACPI_DASM_RESOURCE) 7953446Smrj { 7963446Smrj /* 7973446Smrj * We have a resource list. Don't need to output 7983446Smrj * the buffer size Op. Open up a new block 7993446Smrj */ 8003446Smrj NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 8013446Smrj NextOp = NextOp->Common.Next; 8023446Smrj AcpiOsPrintf (")\n"); 8033446Smrj AcpiDmIndent (Info->Level); 8043446Smrj AcpiOsPrintf ("{\n"); 8053446Smrj return (AE_OK); 8063446Smrj } 8073446Smrj 8083446Smrj /* Normal Buffer, mark size as in the parameter list */ 8093446Smrj 8103446Smrj NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 8113446Smrj return (AE_OK); 8123446Smrj 8133446Smrj 8143446Smrj case AML_VAR_PACKAGE_OP: 8153446Smrj case AML_IF_OP: 8163446Smrj case AML_WHILE_OP: 8173446Smrj 8183446Smrj /* The next op is the size or predicate parameter */ 8193446Smrj 8203446Smrj NextOp = AcpiPsGetDepthNext (NULL, Op); 8213446Smrj if (NextOp) 8223446Smrj { 8233446Smrj NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 8243446Smrj } 8253446Smrj return (AE_OK); 8263446Smrj 8273446Smrj 8283446Smrj case AML_PACKAGE_OP: 8293446Smrj 8303446Smrj /* The next op is the size or predicate parameter */ 8313446Smrj 8323446Smrj NextOp = AcpiPsGetDepthNext (NULL, Op); 8333446Smrj if (NextOp) 8343446Smrj { 8353446Smrj NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 8363446Smrj } 8373446Smrj return (AE_OK); 8383446Smrj 8393446Smrj 8403446Smrj case AML_MATCH_OP: 8413446Smrj 8423446Smrj AcpiDmMatchOp (Op); 8433446Smrj break; 8443446Smrj 8453446Smrj 8463446Smrj default: 8473446Smrj 8483446Smrj break; 8493446Smrj } 8503446Smrj 8513446Smrj if (AcpiDmBlockType (Op) & BLOCK_BRACE) 8523446Smrj { 8533446Smrj AcpiOsPrintf ("\n"); 8543446Smrj AcpiDmIndent (Level); 8553446Smrj AcpiOsPrintf ("{\n"); 8563446Smrj } 8573446Smrj } 8583446Smrj 8593446Smrj return (AE_OK); 8603446Smrj } 8613446Smrj 8623446Smrj 8633446Smrj /******************************************************************************* 8643446Smrj * 8653446Smrj * FUNCTION: AcpiDmAscendingOp 8663446Smrj * 8673446Smrj * PARAMETERS: ASL_WALK_CALLBACK 8683446Smrj * 8693446Smrj * RETURN: Status 8703446Smrj * 8713446Smrj * DESCRIPTION: Second visitation of a parse object, during ascent of parse 8723446Smrj * tree. Close out any parameter lists and complete the opcode. 8733446Smrj * 8743446Smrj ******************************************************************************/ 8753446Smrj 8763446Smrj static ACPI_STATUS 8773446Smrj AcpiDmAscendingOp ( 8783446Smrj ACPI_PARSE_OBJECT *Op, 8793446Smrj UINT32 Level, 8803446Smrj void *Context) 8813446Smrj { 8823446Smrj ACPI_OP_WALK_INFO *Info = Context; 8833446Smrj 8843446Smrj 8853446Smrj if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE) 8863446Smrj { 8873446Smrj /* Ignore this op -- it was handled elsewhere */ 8883446Smrj 8893446Smrj return (AE_OK); 8903446Smrj } 8913446Smrj 8923446Smrj if ((Level == 0) && (Op->Common.AmlOpcode == AML_SCOPE_OP)) 8933446Smrj { 8943446Smrj /* Indicates the end of the current descriptor block (table) */ 8953446Smrj 8963446Smrj AcpiOsPrintf ("}\n\n"); 8973446Smrj return (AE_OK); 8983446Smrj } 8993446Smrj 9003446Smrj switch (AcpiDmBlockType (Op)) 9013446Smrj { 9023446Smrj case BLOCK_PAREN: 9033446Smrj 9043446Smrj /* Completed an op that has arguments, add closing paren */ 9053446Smrj 9063446Smrj AcpiOsPrintf (")"); 9073446Smrj 9083446Smrj /* Could be a nested operator, check if comma required */ 9093446Smrj 9103446Smrj if (!AcpiDmCommaIfListMember (Op)) 9113446Smrj { 9123446Smrj if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) && 9133446Smrj (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) && 9143446Smrj (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP)) 9153446Smrj { 9163446Smrj /* 9173446Smrj * This is a first-level element of a term list 9183446Smrj * start a new line 9193446Smrj */ 9203446Smrj if (!(Info->Flags & ACPI_PARSEOP_PARAMLIST)) 9213446Smrj { 9223446Smrj AcpiOsPrintf ("\n"); 9233446Smrj } 9243446Smrj } 9253446Smrj } 9263446Smrj break; 9273446Smrj 9283446Smrj 9293446Smrj case BLOCK_BRACE: 9303446Smrj case (BLOCK_BRACE | BLOCK_PAREN): 9313446Smrj 9323446Smrj /* Completed an op that has a term list, add closing brace */ 9333446Smrj 9343446Smrj if (Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST) 9353446Smrj { 9363446Smrj AcpiOsPrintf ("}"); 9373446Smrj } 9383446Smrj else 9393446Smrj { 9403446Smrj AcpiDmIndent (Level); 9413446Smrj AcpiOsPrintf ("}"); 9423446Smrj } 9433446Smrj 9443446Smrj AcpiDmCommaIfListMember (Op); 9453446Smrj 9463446Smrj if (AcpiDmBlockType (Op->Common.Parent) != BLOCK_PAREN) 9473446Smrj { 9483446Smrj AcpiOsPrintf ("\n"); 9493446Smrj if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST)) 9503446Smrj { 9513446Smrj if ((Op->Common.AmlOpcode == AML_IF_OP) && 9523446Smrj (Op->Common.Next) && 9533446Smrj (Op->Common.Next->Common.AmlOpcode == AML_ELSE_OP)) 9543446Smrj { 9553446Smrj break; 9563446Smrj } 9573446Smrj 9583446Smrj if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) && 9593446Smrj (!Op->Common.Next)) 9603446Smrj { 9613446Smrj break; 9623446Smrj } 9633446Smrj AcpiOsPrintf ("\n"); 9643446Smrj } 9653446Smrj } 9663446Smrj break; 9673446Smrj 9683446Smrj 9693446Smrj case BLOCK_NONE: 9703446Smrj default: 9713446Smrj 9723446Smrj /* Could be a nested operator, check if comma required */ 9733446Smrj 9743446Smrj if (!AcpiDmCommaIfListMember (Op)) 9753446Smrj { 9763446Smrj if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) && 9773446Smrj (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) && 9783446Smrj (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP)) 9793446Smrj { 9803446Smrj /* 9813446Smrj * This is a first-level element of a term list 9823446Smrj * start a new line 9833446Smrj */ 9843446Smrj AcpiOsPrintf ("\n"); 9853446Smrj } 9863446Smrj } 9873446Smrj else if (Op->Common.Parent) 9883446Smrj { 9893446Smrj switch (Op->Common.Parent->Common.AmlOpcode) 9903446Smrj { 9913446Smrj case AML_PACKAGE_OP: 9923446Smrj case AML_VAR_PACKAGE_OP: 9933446Smrj 9943446Smrj if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) 9953446Smrj { 9963446Smrj AcpiOsPrintf ("\n"); 9973446Smrj } 9983446Smrj break; 9993446Smrj 10003446Smrj default: 10013446Smrj 10023446Smrj break; 10033446Smrj } 10043446Smrj } 10053446Smrj break; 10063446Smrj } 10073446Smrj 10083446Smrj if (Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST) 10093446Smrj { 10103446Smrj if ((Op->Common.Next) && 10113446Smrj (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) 10123446Smrj { 10133446Smrj return (AE_OK); 10143446Smrj } 10153446Smrj 10163446Smrj /* 10173446Smrj * Just completed a parameter node for something like "Buffer (param)". 10183446Smrj * Close the paren and open up the term list block with a brace 10193446Smrj */ 10203446Smrj if (Op->Common.Next) 10213446Smrj { 10223446Smrj AcpiOsPrintf (")\n"); 10233446Smrj AcpiDmIndent (Level - 1); 10243446Smrj AcpiOsPrintf ("{\n"); 10253446Smrj } 10263446Smrj else 10273446Smrj { 10283446Smrj Op->Common.Parent->Common.DisasmFlags |= 10293446Smrj ACPI_PARSEOP_EMPTY_TERMLIST; 10303446Smrj AcpiOsPrintf (") {"); 10313446Smrj } 10323446Smrj } 10333446Smrj 10343446Smrj if ((Op->Common.AmlOpcode == AML_NAME_OP) || 10353446Smrj (Op->Common.AmlOpcode == AML_RETURN_OP)) 10363446Smrj { 10373446Smrj Info->Level++; 10383446Smrj } 10393446Smrj return (AE_OK); 10403446Smrj } 10413446Smrj 10423446Smrj 10433446Smrj #endif /* ACPI_DISASSEMBLER */ 1044