1ae115bc7Smrj /******************************************************************************* 2ae115bc7Smrj * 3ae115bc7Smrj * Module Name: dmwalk - AML disassembly tree walk 4ae115bc7Smrj * 5ae115bc7Smrj ******************************************************************************/ 6ae115bc7Smrj 726f3cdf0SGordon Ross /* 8*385cc6b4SJerry Jelinek * Copyright (C) 2000 - 2016, Intel Corp. 9ae115bc7Smrj * All rights reserved. 10ae115bc7Smrj * 1126f3cdf0SGordon Ross * Redistribution and use in source and binary forms, with or without 1226f3cdf0SGordon Ross * modification, are permitted provided that the following conditions 1326f3cdf0SGordon Ross * are met: 1426f3cdf0SGordon Ross * 1. Redistributions of source code must retain the above copyright 1526f3cdf0SGordon Ross * notice, this list of conditions, and the following disclaimer, 1626f3cdf0SGordon Ross * without modification. 1726f3cdf0SGordon Ross * 2. Redistributions in binary form must reproduce at minimum a disclaimer 1826f3cdf0SGordon Ross * substantially similar to the "NO WARRANTY" disclaimer below 1926f3cdf0SGordon Ross * ("Disclaimer") and any redistribution must be conditioned upon 2026f3cdf0SGordon Ross * including a substantially similar Disclaimer requirement for further 2126f3cdf0SGordon Ross * binary redistribution. 2226f3cdf0SGordon Ross * 3. Neither the names of the above-listed copyright holders nor the names 2326f3cdf0SGordon Ross * of any contributors may be used to endorse or promote products derived 2426f3cdf0SGordon Ross * from this software without specific prior written permission. 25ae115bc7Smrj * 2626f3cdf0SGordon Ross * Alternatively, this software may be distributed under the terms of the 2726f3cdf0SGordon Ross * GNU General Public License ("GPL") version 2 as published by the Free 2826f3cdf0SGordon Ross * Software Foundation. 29ae115bc7Smrj * 3026f3cdf0SGordon Ross * NO WARRANTY 3126f3cdf0SGordon Ross * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3226f3cdf0SGordon Ross * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3326f3cdf0SGordon Ross * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 3426f3cdf0SGordon Ross * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3526f3cdf0SGordon Ross * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3626f3cdf0SGordon Ross * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3726f3cdf0SGordon Ross * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3826f3cdf0SGordon Ross * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 3926f3cdf0SGordon Ross * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 4026f3cdf0SGordon Ross * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 4126f3cdf0SGordon Ross * POSSIBILITY OF SUCH DAMAGES. 4226f3cdf0SGordon Ross */ 43ae115bc7Smrj 44ae115bc7Smrj #include "acpi.h" 45aa2aa9a6SDana Myers #include "accommon.h" 46ae115bc7Smrj #include "acparser.h" 47ae115bc7Smrj #include "amlcode.h" 48ae115bc7Smrj #include "acdebug.h" 49ae115bc7Smrj 50ae115bc7Smrj 51ae115bc7Smrj #define _COMPONENT ACPI_CA_DEBUGGER 52ae115bc7Smrj ACPI_MODULE_NAME ("dmwalk") 53ae115bc7Smrj 54ae115bc7Smrj 55ae115bc7Smrj #define DB_FULL_OP_INFO "[%4.4s] @%5.5X #%4.4X: " 56ae115bc7Smrj 5757190917SDana Myers /* Stub for non-compiler code */ 5857190917SDana Myers 5957190917SDana Myers #ifndef ACPI_ASL_COMPILER 6057190917SDana Myers void 6157190917SDana Myers AcpiDmEmitExternals ( 6257190917SDana Myers void) 6357190917SDana Myers { 6457190917SDana Myers return; 6557190917SDana Myers } 6657190917SDana Myers #endif 6757190917SDana Myers 68ae115bc7Smrj /* Local prototypes */ 69ae115bc7Smrj 70ae115bc7Smrj static ACPI_STATUS 71ae115bc7Smrj AcpiDmDescendingOp ( 72ae115bc7Smrj ACPI_PARSE_OBJECT *Op, 73ae115bc7Smrj UINT32 Level, 74ae115bc7Smrj void *Context); 75ae115bc7Smrj 76ae115bc7Smrj static ACPI_STATUS 77ae115bc7Smrj AcpiDmAscendingOp ( 78ae115bc7Smrj ACPI_PARSE_OBJECT *Op, 79ae115bc7Smrj UINT32 Level, 80ae115bc7Smrj void *Context); 81ae115bc7Smrj 82ae115bc7Smrj static UINT32 83ae115bc7Smrj AcpiDmBlockType ( 84ae115bc7Smrj ACPI_PARSE_OBJECT *Op); 85ae115bc7Smrj 86aa2aa9a6SDana Myers 87ae115bc7Smrj /******************************************************************************* 88ae115bc7Smrj * 89ae115bc7Smrj * FUNCTION: AcpiDmDisassemble 90ae115bc7Smrj * 91ae115bc7Smrj * PARAMETERS: WalkState - Current state 92ae115bc7Smrj * Origin - Starting object 93ae115bc7Smrj * NumOpcodes - Max number of opcodes to be displayed 94ae115bc7Smrj * 95ae115bc7Smrj * RETURN: None 96ae115bc7Smrj * 97ae115bc7Smrj * DESCRIPTION: Disassemble parser object and its children. This is the 98ae115bc7Smrj * main entry point of the disassembler. 99ae115bc7Smrj * 100ae115bc7Smrj ******************************************************************************/ 101ae115bc7Smrj 102ae115bc7Smrj void 103ae115bc7Smrj AcpiDmDisassemble ( 104ae115bc7Smrj ACPI_WALK_STATE *WalkState, 105ae115bc7Smrj ACPI_PARSE_OBJECT *Origin, 106ae115bc7Smrj UINT32 NumOpcodes) 107ae115bc7Smrj { 108ae115bc7Smrj ACPI_PARSE_OBJECT *Op = Origin; 109ae115bc7Smrj ACPI_OP_WALK_INFO Info; 110ae115bc7Smrj 111ae115bc7Smrj 112ae115bc7Smrj if (!Op) 113ae115bc7Smrj { 114ae115bc7Smrj return; 115ae115bc7Smrj } 116ae115bc7Smrj 117*385cc6b4SJerry Jelinek memset (&Info, 0, sizeof (ACPI_OP_WALK_INFO)); 118ae115bc7Smrj Info.WalkState = WalkState; 119*385cc6b4SJerry Jelinek Info.StartAml = Op->Common.Aml - sizeof (ACPI_TABLE_HEADER); 120*385cc6b4SJerry Jelinek Info.AmlOffset = Op->Common.Aml - Info.StartAml; 121*385cc6b4SJerry Jelinek 122ae115bc7Smrj AcpiDmWalkParseTree (Op, AcpiDmDescendingOp, AcpiDmAscendingOp, &Info); 123ae115bc7Smrj return; 124ae115bc7Smrj } 125ae115bc7Smrj 126ae115bc7Smrj 127ae115bc7Smrj /******************************************************************************* 128ae115bc7Smrj * 129ae115bc7Smrj * FUNCTION: AcpiDmWalkParseTree 130ae115bc7Smrj * 131ae115bc7Smrj * PARAMETERS: Op - Root Op object 132ae115bc7Smrj * DescendingCallback - Called during tree descent 133ae115bc7Smrj * AscendingCallback - Called during tree ascent 134ae115bc7Smrj * Context - To be passed to the callbacks 135ae115bc7Smrj * 136ae115bc7Smrj * RETURN: Status from callback(s) 137ae115bc7Smrj * 138ae115bc7Smrj * DESCRIPTION: Walk the entire parse tree. 139ae115bc7Smrj * 140ae115bc7Smrj ******************************************************************************/ 141ae115bc7Smrj 142ae115bc7Smrj void 143ae115bc7Smrj AcpiDmWalkParseTree ( 144ae115bc7Smrj ACPI_PARSE_OBJECT *Op, 145ae115bc7Smrj ASL_WALK_CALLBACK DescendingCallback, 146ae115bc7Smrj ASL_WALK_CALLBACK AscendingCallback, 147ae115bc7Smrj void *Context) 148ae115bc7Smrj { 149ae115bc7Smrj BOOLEAN NodePreviouslyVisited; 150ae115bc7Smrj ACPI_PARSE_OBJECT *StartOp = Op; 151ae115bc7Smrj ACPI_STATUS Status; 152ae115bc7Smrj ACPI_PARSE_OBJECT *Next; 153ae115bc7Smrj ACPI_OP_WALK_INFO *Info = Context; 154ae115bc7Smrj 155ae115bc7Smrj 156ae115bc7Smrj Info->Level = 0; 157ae115bc7Smrj NodePreviouslyVisited = FALSE; 158ae115bc7Smrj 159ae115bc7Smrj while (Op) 160ae115bc7Smrj { 161ae115bc7Smrj if (NodePreviouslyVisited) 162ae115bc7Smrj { 163ae115bc7Smrj if (AscendingCallback) 164ae115bc7Smrj { 165ae115bc7Smrj Status = AscendingCallback (Op, Info->Level, Context); 166ae115bc7Smrj if (ACPI_FAILURE (Status)) 167ae115bc7Smrj { 168ae115bc7Smrj return; 169ae115bc7Smrj } 170ae115bc7Smrj } 171ae115bc7Smrj } 172ae115bc7Smrj else 173ae115bc7Smrj { 174ae115bc7Smrj /* Let the callback process the node */ 175ae115bc7Smrj 176ae115bc7Smrj Status = DescendingCallback (Op, Info->Level, Context); 177ae115bc7Smrj if (ACPI_SUCCESS (Status)) 178ae115bc7Smrj { 179ae115bc7Smrj /* Visit children first, once */ 180ae115bc7Smrj 181ae115bc7Smrj Next = AcpiPsGetArg (Op, 0); 182ae115bc7Smrj if (Next) 183ae115bc7Smrj { 184ae115bc7Smrj Info->Level++; 185ae115bc7Smrj Op = Next; 186ae115bc7Smrj continue; 187ae115bc7Smrj } 188ae115bc7Smrj } 189ae115bc7Smrj else if (Status != AE_CTRL_DEPTH) 190ae115bc7Smrj { 191ae115bc7Smrj /* Exit immediately on any error */ 192ae115bc7Smrj 193ae115bc7Smrj return; 194ae115bc7Smrj } 195ae115bc7Smrj } 196ae115bc7Smrj 197ae115bc7Smrj /* Terminate walk at start op */ 198ae115bc7Smrj 199ae115bc7Smrj if (Op == StartOp) 200ae115bc7Smrj { 201ae115bc7Smrj break; 202ae115bc7Smrj } 203ae115bc7Smrj 204ae115bc7Smrj /* No more children, re-visit this node */ 205ae115bc7Smrj 206ae115bc7Smrj if (!NodePreviouslyVisited) 207ae115bc7Smrj { 208ae115bc7Smrj NodePreviouslyVisited = TRUE; 209ae115bc7Smrj continue; 210ae115bc7Smrj } 211ae115bc7Smrj 212ae115bc7Smrj /* No more children, visit peers */ 213ae115bc7Smrj 214ae115bc7Smrj if (Op->Common.Next) 215ae115bc7Smrj { 216ae115bc7Smrj Op = Op->Common.Next; 217ae115bc7Smrj NodePreviouslyVisited = FALSE; 218ae115bc7Smrj } 219ae115bc7Smrj else 220ae115bc7Smrj { 221ae115bc7Smrj /* No peers, re-visit parent */ 222ae115bc7Smrj 223ae115bc7Smrj if (Info->Level != 0 ) 224ae115bc7Smrj { 225ae115bc7Smrj Info->Level--; 226ae115bc7Smrj } 227ae115bc7Smrj 228ae115bc7Smrj Op = Op->Common.Parent; 229ae115bc7Smrj NodePreviouslyVisited = TRUE; 230ae115bc7Smrj } 231ae115bc7Smrj } 232ae115bc7Smrj 233ae115bc7Smrj /* If we get here, the walk completed with no errors */ 234ae115bc7Smrj 235ae115bc7Smrj return; 236ae115bc7Smrj } 237ae115bc7Smrj 238ae115bc7Smrj 239ae115bc7Smrj /******************************************************************************* 240ae115bc7Smrj * 241ae115bc7Smrj * FUNCTION: AcpiDmBlockType 242ae115bc7Smrj * 243ae115bc7Smrj * PARAMETERS: Op - Object to be examined 244ae115bc7Smrj * 245ae115bc7Smrj * RETURN: BlockType - not a block, parens, braces, or even both. 246ae115bc7Smrj * 247ae115bc7Smrj * DESCRIPTION: Type of block for this op (parens or braces) 248ae115bc7Smrj * 249ae115bc7Smrj ******************************************************************************/ 250ae115bc7Smrj 251ae115bc7Smrj static UINT32 252ae115bc7Smrj AcpiDmBlockType ( 253ae115bc7Smrj ACPI_PARSE_OBJECT *Op) 254ae115bc7Smrj { 255ae115bc7Smrj const ACPI_OPCODE_INFO *OpInfo; 256ae115bc7Smrj 257ae115bc7Smrj 258ae115bc7Smrj if (!Op) 259ae115bc7Smrj { 260ae115bc7Smrj return (BLOCK_NONE); 261ae115bc7Smrj } 262ae115bc7Smrj 263ae115bc7Smrj switch (Op->Common.AmlOpcode) 264ae115bc7Smrj { 265ae115bc7Smrj case AML_ELSE_OP: 266ae115bc7Smrj 267ae115bc7Smrj return (BLOCK_BRACE); 268ae115bc7Smrj 269ae115bc7Smrj case AML_METHOD_OP: 270ae115bc7Smrj case AML_DEVICE_OP: 271ae115bc7Smrj case AML_SCOPE_OP: 272ae115bc7Smrj case AML_PROCESSOR_OP: 273ae115bc7Smrj case AML_POWER_RES_OP: 274ae115bc7Smrj case AML_THERMAL_ZONE_OP: 275ae115bc7Smrj case AML_IF_OP: 276ae115bc7Smrj case AML_WHILE_OP: 277ae115bc7Smrj case AML_FIELD_OP: 278ae115bc7Smrj case AML_INDEX_FIELD_OP: 279ae115bc7Smrj case AML_BANK_FIELD_OP: 280ae115bc7Smrj 281ae115bc7Smrj return (BLOCK_PAREN | BLOCK_BRACE); 282ae115bc7Smrj 283ae115bc7Smrj case AML_BUFFER_OP: 284ae115bc7Smrj 285*385cc6b4SJerry Jelinek if ((Op->Common.DisasmOpcode == ACPI_DASM_UNICODE) || 286*385cc6b4SJerry Jelinek (Op->Common.DisasmOpcode == ACPI_DASM_UUID) || 287*385cc6b4SJerry Jelinek (Op->Common.DisasmOpcode == ACPI_DASM_PLD_METHOD)) 288ae115bc7Smrj { 289ae115bc7Smrj return (BLOCK_NONE); 290ae115bc7Smrj } 291ae115bc7Smrj 292ae115bc7Smrj /*lint -fallthrough */ 293ae115bc7Smrj 294ae115bc7Smrj case AML_PACKAGE_OP: 295ae115bc7Smrj case AML_VAR_PACKAGE_OP: 296ae115bc7Smrj 297ae115bc7Smrj return (BLOCK_PAREN | BLOCK_BRACE); 298ae115bc7Smrj 299ae115bc7Smrj case AML_EVENT_OP: 300ae115bc7Smrj 301ae115bc7Smrj return (BLOCK_PAREN); 302ae115bc7Smrj 303*385cc6b4SJerry Jelinek case AML_INT_METHODCALL_OP: 304*385cc6b4SJerry Jelinek 305*385cc6b4SJerry Jelinek if (Op->Common.Parent && 306*385cc6b4SJerry Jelinek ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || 307*385cc6b4SJerry Jelinek (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP))) 308*385cc6b4SJerry Jelinek { 309*385cc6b4SJerry Jelinek /* This is a reference to a method, not an invocation */ 310*385cc6b4SJerry Jelinek 311*385cc6b4SJerry Jelinek return (BLOCK_NONE); 312*385cc6b4SJerry Jelinek } 313*385cc6b4SJerry Jelinek 314*385cc6b4SJerry Jelinek /*lint -fallthrough */ 315*385cc6b4SJerry Jelinek 316ae115bc7Smrj default: 317ae115bc7Smrj 318ae115bc7Smrj OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 319ae115bc7Smrj if (OpInfo->Flags & AML_HAS_ARGS) 320ae115bc7Smrj { 321ae115bc7Smrj return (BLOCK_PAREN); 322ae115bc7Smrj } 323ae115bc7Smrj 324ae115bc7Smrj return (BLOCK_NONE); 325ae115bc7Smrj } 326ae115bc7Smrj } 327ae115bc7Smrj 328ae115bc7Smrj 329ae115bc7Smrj /******************************************************************************* 330ae115bc7Smrj * 331ae115bc7Smrj * FUNCTION: AcpiDmListType 332ae115bc7Smrj * 333ae115bc7Smrj * PARAMETERS: Op - Object to be examined 334ae115bc7Smrj * 335ae115bc7Smrj * RETURN: ListType - has commas or not. 336ae115bc7Smrj * 337ae115bc7Smrj * DESCRIPTION: Type of block for this op (parens or braces) 338ae115bc7Smrj * 339ae115bc7Smrj ******************************************************************************/ 340ae115bc7Smrj 341ae115bc7Smrj UINT32 342ae115bc7Smrj AcpiDmListType ( 343ae115bc7Smrj ACPI_PARSE_OBJECT *Op) 344ae115bc7Smrj { 345ae115bc7Smrj const ACPI_OPCODE_INFO *OpInfo; 346ae115bc7Smrj 347ae115bc7Smrj 348ae115bc7Smrj if (!Op) 349ae115bc7Smrj { 350ae115bc7Smrj return (BLOCK_NONE); 351ae115bc7Smrj } 352ae115bc7Smrj 353ae115bc7Smrj switch (Op->Common.AmlOpcode) 354ae115bc7Smrj { 355ae115bc7Smrj 356ae115bc7Smrj case AML_ELSE_OP: 357ae115bc7Smrj case AML_METHOD_OP: 358ae115bc7Smrj case AML_DEVICE_OP: 359ae115bc7Smrj case AML_SCOPE_OP: 360ae115bc7Smrj case AML_POWER_RES_OP: 361ae115bc7Smrj case AML_PROCESSOR_OP: 362ae115bc7Smrj case AML_THERMAL_ZONE_OP: 363ae115bc7Smrj case AML_IF_OP: 364ae115bc7Smrj case AML_WHILE_OP: 365ae115bc7Smrj case AML_FIELD_OP: 366ae115bc7Smrj case AML_INDEX_FIELD_OP: 367ae115bc7Smrj case AML_BANK_FIELD_OP: 368ae115bc7Smrj 369ae115bc7Smrj return (BLOCK_NONE); 370ae115bc7Smrj 371ae115bc7Smrj case AML_BUFFER_OP: 372ae115bc7Smrj case AML_PACKAGE_OP: 373ae115bc7Smrj case AML_VAR_PACKAGE_OP: 374ae115bc7Smrj 375ae115bc7Smrj return (BLOCK_COMMA_LIST); 376ae115bc7Smrj 377ae115bc7Smrj default: 378ae115bc7Smrj 379ae115bc7Smrj OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 380ae115bc7Smrj if (OpInfo->Flags & AML_HAS_ARGS) 381ae115bc7Smrj { 382ae115bc7Smrj return (BLOCK_COMMA_LIST); 383ae115bc7Smrj } 384ae115bc7Smrj 385ae115bc7Smrj return (BLOCK_NONE); 386ae115bc7Smrj } 387ae115bc7Smrj } 388ae115bc7Smrj 389ae115bc7Smrj 390ae115bc7Smrj /******************************************************************************* 391ae115bc7Smrj * 392ae115bc7Smrj * FUNCTION: AcpiDmDescendingOp 393ae115bc7Smrj * 394ae115bc7Smrj * PARAMETERS: ASL_WALK_CALLBACK 395ae115bc7Smrj * 396ae115bc7Smrj * RETURN: Status 397ae115bc7Smrj * 398ae115bc7Smrj * DESCRIPTION: First visitation of a parse object during tree descent. 399ae115bc7Smrj * Decode opcode name and begin parameter list(s), if any. 400ae115bc7Smrj * 401ae115bc7Smrj ******************************************************************************/ 402ae115bc7Smrj 403ae115bc7Smrj static ACPI_STATUS 404ae115bc7Smrj AcpiDmDescendingOp ( 405ae115bc7Smrj ACPI_PARSE_OBJECT *Op, 406ae115bc7Smrj UINT32 Level, 407ae115bc7Smrj void *Context) 408ae115bc7Smrj { 409ae115bc7Smrj ACPI_OP_WALK_INFO *Info = Context; 410ae115bc7Smrj const ACPI_OPCODE_INFO *OpInfo; 411ae115bc7Smrj UINT32 Name; 412ae115bc7Smrj ACPI_PARSE_OBJECT *NextOp; 413*385cc6b4SJerry Jelinek ACPI_PARSE_OBJECT *NextOp2; 414*385cc6b4SJerry Jelinek UINT32 AmlOffset; 415ae115bc7Smrj 416ae115bc7Smrj 417*385cc6b4SJerry Jelinek OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 418*385cc6b4SJerry Jelinek 419*385cc6b4SJerry Jelinek /* Listing support to dump the AML code after the ASL statement */ 420*385cc6b4SJerry Jelinek 421*385cc6b4SJerry Jelinek if (AcpiGbl_DmOpt_Listing) 422*385cc6b4SJerry Jelinek { 423*385cc6b4SJerry Jelinek /* We only care about these classes of objects */ 424*385cc6b4SJerry Jelinek 425*385cc6b4SJerry Jelinek if ((OpInfo->Class == AML_CLASS_NAMED_OBJECT) || 426*385cc6b4SJerry Jelinek (OpInfo->Class == AML_CLASS_CONTROL) || 427*385cc6b4SJerry Jelinek (OpInfo->Class == AML_CLASS_CREATE) || 428*385cc6b4SJerry Jelinek ((OpInfo->Class == AML_CLASS_EXECUTE) && (!Op->Common.Next))) 429*385cc6b4SJerry Jelinek { 430*385cc6b4SJerry Jelinek if (AcpiGbl_DmOpt_Listing && Info->PreviousAml) 431*385cc6b4SJerry Jelinek { 432*385cc6b4SJerry Jelinek /* Dump the AML byte code for the previous Op */ 433*385cc6b4SJerry Jelinek 434*385cc6b4SJerry Jelinek if (Op->Common.Aml > Info->PreviousAml) 435*385cc6b4SJerry Jelinek { 436*385cc6b4SJerry Jelinek AcpiOsPrintf ("\n"); 437*385cc6b4SJerry Jelinek AcpiUtDumpBuffer ( 438*385cc6b4SJerry Jelinek (Info->StartAml + Info->AmlOffset), 439*385cc6b4SJerry Jelinek (Op->Common.Aml - Info->PreviousAml), 440*385cc6b4SJerry Jelinek DB_BYTE_DISPLAY, Info->AmlOffset); 441*385cc6b4SJerry Jelinek AcpiOsPrintf ("\n"); 442*385cc6b4SJerry Jelinek } 443*385cc6b4SJerry Jelinek 444*385cc6b4SJerry Jelinek Info->AmlOffset = (Op->Common.Aml - Info->StartAml); 445*385cc6b4SJerry Jelinek } 446*385cc6b4SJerry Jelinek 447*385cc6b4SJerry Jelinek Info->PreviousAml = Op->Common.Aml; 448*385cc6b4SJerry Jelinek } 449*385cc6b4SJerry Jelinek } 450*385cc6b4SJerry Jelinek 451ae115bc7Smrj if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE) 452ae115bc7Smrj { 453ae115bc7Smrj /* Ignore this op -- it was handled elsewhere */ 454ae115bc7Smrj 455ae115bc7Smrj return (AE_CTRL_DEPTH); 456ae115bc7Smrj } 457ae115bc7Smrj 458*385cc6b4SJerry Jelinek if (Op->Common.AmlOpcode == AML_IF_OP) 459*385cc6b4SJerry Jelinek { 460*385cc6b4SJerry Jelinek NextOp = AcpiPsGetDepthNext (NULL, Op); 461*385cc6b4SJerry Jelinek if (NextOp) 462*385cc6b4SJerry Jelinek { 463*385cc6b4SJerry Jelinek NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST; 464*385cc6b4SJerry Jelinek 465*385cc6b4SJerry Jelinek /* Don't emit the actual embedded externals unless asked */ 466*385cc6b4SJerry Jelinek 467*385cc6b4SJerry Jelinek if (!AcpiGbl_DmEmitExternalOpcodes) 468*385cc6b4SJerry Jelinek { 469*385cc6b4SJerry Jelinek /* 470*385cc6b4SJerry Jelinek * A Zero predicate indicates the possibility of one or more 471*385cc6b4SJerry Jelinek * External() opcodes within the If() block. 472*385cc6b4SJerry Jelinek */ 473*385cc6b4SJerry Jelinek if (NextOp->Common.AmlOpcode == AML_ZERO_OP) 474*385cc6b4SJerry Jelinek { 475*385cc6b4SJerry Jelinek NextOp2 = NextOp->Common.Next; 476*385cc6b4SJerry Jelinek 477*385cc6b4SJerry Jelinek if (NextOp2 && 478*385cc6b4SJerry Jelinek (NextOp2->Common.AmlOpcode == AML_EXTERNAL_OP)) 479*385cc6b4SJerry Jelinek { 480*385cc6b4SJerry Jelinek /* Ignore the If 0 block and all children */ 481*385cc6b4SJerry Jelinek 482*385cc6b4SJerry Jelinek Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 483*385cc6b4SJerry Jelinek return (AE_CTRL_DEPTH); 484*385cc6b4SJerry Jelinek } 485*385cc6b4SJerry Jelinek } 486*385cc6b4SJerry Jelinek } 487*385cc6b4SJerry Jelinek } 488*385cc6b4SJerry Jelinek } 489*385cc6b4SJerry Jelinek 490ae115bc7Smrj /* Level 0 is at the Definition Block level */ 491ae115bc7Smrj 492ae115bc7Smrj if (Level == 0) 493ae115bc7Smrj { 494ae115bc7Smrj /* In verbose mode, print the AML offset, opcode and depth count */ 495ae115bc7Smrj 496ae115bc7Smrj if (Info->WalkState) 497ae115bc7Smrj { 498*385cc6b4SJerry Jelinek AmlOffset = (UINT32) ACPI_PTR_DIFF (Op->Common.Aml, 499*385cc6b4SJerry Jelinek Info->WalkState->ParserState.AmlStart); 500*385cc6b4SJerry Jelinek if (AcpiGbl_DmOpt_Verbose) 501*385cc6b4SJerry Jelinek { 502*385cc6b4SJerry Jelinek AcpiOsPrintf (DB_FULL_OP_INFO, 503ae115bc7Smrj (Info->WalkState->MethodNode ? 504ae115bc7Smrj Info->WalkState->MethodNode->Name.Ascii : " "), 505*385cc6b4SJerry Jelinek AmlOffset, (UINT32) Op->Common.AmlOpcode); 506*385cc6b4SJerry Jelinek } 507ae115bc7Smrj } 508ae115bc7Smrj 509ae115bc7Smrj if (Op->Common.AmlOpcode == AML_SCOPE_OP) 510ae115bc7Smrj { 511ae115bc7Smrj /* This is the beginning of the Definition Block */ 512ae115bc7Smrj 513ae115bc7Smrj AcpiOsPrintf ("{\n"); 514ae115bc7Smrj 515ae115bc7Smrj /* Emit all External() declarations here */ 516ae115bc7Smrj 51757190917SDana Myers AcpiDmEmitExternals (); 518ae115bc7Smrj return (AE_OK); 519ae115bc7Smrj } 520ae115bc7Smrj } 521ae115bc7Smrj else if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) && 522*385cc6b4SJerry Jelinek (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST)) && 523*385cc6b4SJerry Jelinek (!(Op->Common.DisasmFlags & ACPI_PARSEOP_ELSEIF)) && 524ae115bc7Smrj (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP)) 525ae115bc7Smrj { 526ae115bc7Smrj /* 527ae115bc7Smrj * This is a first-level element of a term list, 528ae115bc7Smrj * indent a new line 529ae115bc7Smrj */ 530*385cc6b4SJerry Jelinek switch (Op->Common.AmlOpcode) 531*385cc6b4SJerry Jelinek { 532*385cc6b4SJerry Jelinek case AML_NOOP_OP: 533*385cc6b4SJerry Jelinek /* 534*385cc6b4SJerry Jelinek * Optionally just ignore this opcode. Some tables use 535*385cc6b4SJerry Jelinek * NoOp opcodes for "padding" out packages that the BIOS 536*385cc6b4SJerry Jelinek * changes dynamically. This can leave hundreds or 537*385cc6b4SJerry Jelinek * thousands of NoOp opcodes that if disassembled, 538*385cc6b4SJerry Jelinek * cannot be compiled because they are syntactically 539*385cc6b4SJerry Jelinek * incorrect. 540*385cc6b4SJerry Jelinek */ 541*385cc6b4SJerry Jelinek if (AcpiGbl_IgnoreNoopOperator) 542*385cc6b4SJerry Jelinek { 543*385cc6b4SJerry Jelinek Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 544*385cc6b4SJerry Jelinek return (AE_OK); 545*385cc6b4SJerry Jelinek } 546*385cc6b4SJerry Jelinek 547*385cc6b4SJerry Jelinek /* Fallthrough */ 548*385cc6b4SJerry Jelinek 549*385cc6b4SJerry Jelinek default: 550*385cc6b4SJerry Jelinek 551ae115bc7Smrj AcpiDmIndent (Level); 552*385cc6b4SJerry Jelinek break; 553*385cc6b4SJerry Jelinek } 554*385cc6b4SJerry Jelinek 555ae115bc7Smrj Info->LastLevel = Level; 556ae115bc7Smrj Info->Count = 0; 557ae115bc7Smrj } 558ae115bc7Smrj 559ae115bc7Smrj /* 560ae115bc7Smrj * This is an inexpensive mechanism to try and keep lines from getting 561ae115bc7Smrj * too long. When the limit is hit, start a new line at the previous 562ae115bc7Smrj * indent plus one. A better but more expensive mechanism would be to 563ae115bc7Smrj * keep track of the current column. 564ae115bc7Smrj */ 565ae115bc7Smrj Info->Count++; 566*385cc6b4SJerry Jelinek if (Info->Count /* +Info->LastLevel */ > 12) 567ae115bc7Smrj { 568ae115bc7Smrj Info->Count = 0; 569ae115bc7Smrj AcpiOsPrintf ("\n"); 570ae115bc7Smrj AcpiDmIndent (Info->LastLevel + 1); 571ae115bc7Smrj } 572ae115bc7Smrj 573*385cc6b4SJerry Jelinek /* If ASL+ is enabled, check for a C-style operator */ 574*385cc6b4SJerry Jelinek 575*385cc6b4SJerry Jelinek if (AcpiDmCheckForSymbolicOpcode (Op, Info)) 576*385cc6b4SJerry Jelinek { 577*385cc6b4SJerry Jelinek return (AE_OK); 578*385cc6b4SJerry Jelinek } 579*385cc6b4SJerry Jelinek 580ae115bc7Smrj /* Print the opcode name */ 581ae115bc7Smrj 582ae115bc7Smrj AcpiDmDisassembleOneOp (NULL, Info, Op); 583ae115bc7Smrj 584*385cc6b4SJerry Jelinek if ((Op->Common.DisasmOpcode == ACPI_DASM_LNOT_PREFIX) || 585*385cc6b4SJerry Jelinek (Op->Common.AmlOpcode == AML_INT_CONNECTION_OP)) 586ae115bc7Smrj { 587ae115bc7Smrj return (AE_OK); 588ae115bc7Smrj } 589ae115bc7Smrj 590ae115bc7Smrj if ((Op->Common.AmlOpcode == AML_NAME_OP) || 591ae115bc7Smrj (Op->Common.AmlOpcode == AML_RETURN_OP)) 592ae115bc7Smrj { 593ae115bc7Smrj Info->Level--; 594ae115bc7Smrj } 595ae115bc7Smrj 596ae115bc7Smrj /* Start the opcode argument list if necessary */ 597ae115bc7Smrj 598ae115bc7Smrj if ((OpInfo->Flags & AML_HAS_ARGS) || 599ae115bc7Smrj (Op->Common.AmlOpcode == AML_EVENT_OP)) 600ae115bc7Smrj { 601ae115bc7Smrj /* This opcode has an argument list */ 602ae115bc7Smrj 603ae115bc7Smrj if (AcpiDmBlockType (Op) & BLOCK_PAREN) 604ae115bc7Smrj { 605ae115bc7Smrj AcpiOsPrintf (" ("); 606ae115bc7Smrj } 607ae115bc7Smrj 608ae115bc7Smrj /* If this is a named opcode, print the associated name value */ 609ae115bc7Smrj 610ae115bc7Smrj if (OpInfo->Flags & AML_NAMED) 611ae115bc7Smrj { 612ae115bc7Smrj switch (Op->Common.AmlOpcode) 613ae115bc7Smrj { 614ae115bc7Smrj case AML_ALIAS_OP: 615ae115bc7Smrj 616ae115bc7Smrj NextOp = AcpiPsGetDepthNext (NULL, Op); 617ae115bc7Smrj NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 618ae115bc7Smrj AcpiDmNamestring (NextOp->Common.Value.Name); 619ae115bc7Smrj AcpiOsPrintf (", "); 620ae115bc7Smrj 621ae115bc7Smrj /*lint -fallthrough */ 622ae115bc7Smrj 623ae115bc7Smrj default: 624ae115bc7Smrj 625ae115bc7Smrj Name = AcpiPsGetName (Op); 626ae115bc7Smrj if (Op->Named.Path) 627ae115bc7Smrj { 628ae115bc7Smrj AcpiDmNamestring ((char *) Op->Named.Path); 629ae115bc7Smrj } 630ae115bc7Smrj else 631ae115bc7Smrj { 632db2bae30SDana Myers AcpiDmDumpName (Name); 633ae115bc7Smrj } 634ae115bc7Smrj 635ae115bc7Smrj if (Op->Common.AmlOpcode != AML_INT_NAMEDFIELD_OP) 636ae115bc7Smrj { 637*385cc6b4SJerry Jelinek if (AcpiGbl_DmOpt_Verbose) 638ae115bc7Smrj { 639ae115bc7Smrj (void) AcpiPsDisplayObjectPathname (NULL, Op); 640ae115bc7Smrj } 641ae115bc7Smrj } 642ae115bc7Smrj break; 643ae115bc7Smrj } 644ae115bc7Smrj 645ae115bc7Smrj switch (Op->Common.AmlOpcode) 646ae115bc7Smrj { 647ae115bc7Smrj case AML_METHOD_OP: 648ae115bc7Smrj 649ae115bc7Smrj AcpiDmMethodFlags (Op); 650ae115bc7Smrj AcpiOsPrintf (")"); 651ae115bc7Smrj 652*385cc6b4SJerry Jelinek /* Emit description comment for Method() with a predefined ACPI name */ 653*385cc6b4SJerry Jelinek 654*385cc6b4SJerry Jelinek AcpiDmPredefinedDescription (Op); 655*385cc6b4SJerry Jelinek break; 656ae115bc7Smrj 657ae115bc7Smrj case AML_NAME_OP: 658ae115bc7Smrj 659ae115bc7Smrj /* Check for _HID and related EISAID() */ 660ae115bc7Smrj 661*385cc6b4SJerry Jelinek AcpiDmCheckForHardwareId (Op); 662ae115bc7Smrj AcpiOsPrintf (", "); 663ae115bc7Smrj break; 664ae115bc7Smrj 665ae115bc7Smrj case AML_REGION_OP: 666ae115bc7Smrj 667ae115bc7Smrj AcpiDmRegionFlags (Op); 668ae115bc7Smrj break; 669ae115bc7Smrj 670ae115bc7Smrj case AML_POWER_RES_OP: 671ae115bc7Smrj 672ae115bc7Smrj /* Mark the next two Ops as part of the parameter list */ 673ae115bc7Smrj 674ae115bc7Smrj AcpiOsPrintf (", "); 675ae115bc7Smrj NextOp = AcpiPsGetDepthNext (NULL, Op); 676*385cc6b4SJerry Jelinek NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST; 677ae115bc7Smrj 678ae115bc7Smrj NextOp = NextOp->Common.Next; 679*385cc6b4SJerry Jelinek NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST; 680ae115bc7Smrj return (AE_OK); 681ae115bc7Smrj 682ae115bc7Smrj case AML_PROCESSOR_OP: 683ae115bc7Smrj 684ae115bc7Smrj /* Mark the next three Ops as part of the parameter list */ 685ae115bc7Smrj 686ae115bc7Smrj AcpiOsPrintf (", "); 687ae115bc7Smrj NextOp = AcpiPsGetDepthNext (NULL, Op); 688*385cc6b4SJerry Jelinek NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST; 689ae115bc7Smrj 690ae115bc7Smrj NextOp = NextOp->Common.Next; 691*385cc6b4SJerry Jelinek NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST; 692ae115bc7Smrj 693ae115bc7Smrj NextOp = NextOp->Common.Next; 694*385cc6b4SJerry Jelinek NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST; 695ae115bc7Smrj return (AE_OK); 696ae115bc7Smrj 697ae115bc7Smrj case AML_MUTEX_OP: 698ae115bc7Smrj case AML_DATA_REGION_OP: 699ae115bc7Smrj 700ae115bc7Smrj AcpiOsPrintf (", "); 701ae115bc7Smrj return (AE_OK); 702ae115bc7Smrj 703ae115bc7Smrj case AML_EVENT_OP: 704ae115bc7Smrj case AML_ALIAS_OP: 705ae115bc7Smrj 706ae115bc7Smrj return (AE_OK); 707ae115bc7Smrj 708ae115bc7Smrj case AML_SCOPE_OP: 709ae115bc7Smrj case AML_DEVICE_OP: 710ae115bc7Smrj case AML_THERMAL_ZONE_OP: 711ae115bc7Smrj 712ae115bc7Smrj AcpiOsPrintf (")"); 713ae115bc7Smrj break; 714ae115bc7Smrj 715ae115bc7Smrj default: 716ae115bc7Smrj 717*385cc6b4SJerry Jelinek AcpiOsPrintf ("*** Unhandled named opcode %X\n", 718*385cc6b4SJerry Jelinek Op->Common.AmlOpcode); 719ae115bc7Smrj break; 720ae115bc7Smrj } 721ae115bc7Smrj } 722ae115bc7Smrj 723ae115bc7Smrj else switch (Op->Common.AmlOpcode) 724ae115bc7Smrj { 725ae115bc7Smrj case AML_FIELD_OP: 726ae115bc7Smrj case AML_BANK_FIELD_OP: 727ae115bc7Smrj case AML_INDEX_FIELD_OP: 728ae115bc7Smrj 729ae115bc7Smrj Info->BitOffset = 0; 730ae115bc7Smrj 731ae115bc7Smrj /* Name of the parent OperationRegion */ 732ae115bc7Smrj 733ae115bc7Smrj NextOp = AcpiPsGetDepthNext (NULL, Op); 734ae115bc7Smrj AcpiDmNamestring (NextOp->Common.Value.Name); 735ae115bc7Smrj AcpiOsPrintf (", "); 736ae115bc7Smrj NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 737ae115bc7Smrj 738ae115bc7Smrj switch (Op->Common.AmlOpcode) 739ae115bc7Smrj { 740ae115bc7Smrj case AML_BANK_FIELD_OP: 741ae115bc7Smrj 742ae115bc7Smrj /* Namestring - Bank Name */ 743ae115bc7Smrj 744ae115bc7Smrj NextOp = AcpiPsGetDepthNext (NULL, NextOp); 745ae115bc7Smrj AcpiDmNamestring (NextOp->Common.Value.Name); 746ae115bc7Smrj NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 747ae115bc7Smrj AcpiOsPrintf (", "); 748ae115bc7Smrj 749ae115bc7Smrj /* 750ae115bc7Smrj * Bank Value. This is a TermArg in the middle of the parameter 751ae115bc7Smrj * list, must handle it here. 752ae115bc7Smrj * 753*385cc6b4SJerry Jelinek * Disassemble the TermArg parse tree. ACPI_PARSEOP_PARAMETER_LIST 754ae115bc7Smrj * eliminates newline in the output. 755ae115bc7Smrj */ 756ae115bc7Smrj NextOp = NextOp->Common.Next; 757ae115bc7Smrj 758*385cc6b4SJerry Jelinek Info->Flags = ACPI_PARSEOP_PARAMETER_LIST; 759*385cc6b4SJerry Jelinek AcpiDmWalkParseTree (NextOp, AcpiDmDescendingOp, 760*385cc6b4SJerry Jelinek AcpiDmAscendingOp, Info); 761ae115bc7Smrj Info->Flags = 0; 762ae115bc7Smrj Info->Level = Level; 763ae115bc7Smrj 764ae115bc7Smrj NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 765ae115bc7Smrj AcpiOsPrintf (", "); 766ae115bc7Smrj break; 767ae115bc7Smrj 768ae115bc7Smrj case AML_INDEX_FIELD_OP: 769ae115bc7Smrj 770ae115bc7Smrj /* Namestring - Data Name */ 771ae115bc7Smrj 772ae115bc7Smrj NextOp = AcpiPsGetDepthNext (NULL, NextOp); 773ae115bc7Smrj AcpiDmNamestring (NextOp->Common.Value.Name); 774ae115bc7Smrj AcpiOsPrintf (", "); 775ae115bc7Smrj NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 776ae115bc7Smrj break; 777ae115bc7Smrj 778ae115bc7Smrj default: 779ae115bc7Smrj 780ae115bc7Smrj break; 781ae115bc7Smrj } 782ae115bc7Smrj 783ae115bc7Smrj AcpiDmFieldFlags (NextOp); 784ae115bc7Smrj break; 785ae115bc7Smrj 786ae115bc7Smrj case AML_BUFFER_OP: 787ae115bc7Smrj 788ae115bc7Smrj /* The next op is the size parameter */ 789ae115bc7Smrj 790ae115bc7Smrj NextOp = AcpiPsGetDepthNext (NULL, Op); 791ae115bc7Smrj if (!NextOp) 792ae115bc7Smrj { 793ae115bc7Smrj /* Single-step support */ 794ae115bc7Smrj 795ae115bc7Smrj return (AE_OK); 796ae115bc7Smrj } 797ae115bc7Smrj 798ae115bc7Smrj if (Op->Common.DisasmOpcode == ACPI_DASM_RESOURCE) 799ae115bc7Smrj { 800ae115bc7Smrj /* 801ae115bc7Smrj * We have a resource list. Don't need to output 802ae115bc7Smrj * the buffer size Op. Open up a new block 803ae115bc7Smrj */ 804ae115bc7Smrj NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 805ae115bc7Smrj NextOp = NextOp->Common.Next; 806*385cc6b4SJerry Jelinek AcpiOsPrintf (")"); 807*385cc6b4SJerry Jelinek 808*385cc6b4SJerry Jelinek /* Emit description comment for Name() with a predefined ACPI name */ 809*385cc6b4SJerry Jelinek 810*385cc6b4SJerry Jelinek AcpiDmPredefinedDescription (Op->Asl.Parent); 811*385cc6b4SJerry Jelinek 812*385cc6b4SJerry Jelinek AcpiOsPrintf ("\n"); 813ae115bc7Smrj AcpiDmIndent (Info->Level); 814ae115bc7Smrj AcpiOsPrintf ("{\n"); 815ae115bc7Smrj return (AE_OK); 816ae115bc7Smrj } 817ae115bc7Smrj 818ae115bc7Smrj /* Normal Buffer, mark size as in the parameter list */ 819ae115bc7Smrj 820*385cc6b4SJerry Jelinek NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST; 821ae115bc7Smrj return (AE_OK); 822ae115bc7Smrj 823ae115bc7Smrj case AML_IF_OP: 824*385cc6b4SJerry Jelinek case AML_VAR_PACKAGE_OP: 825ae115bc7Smrj case AML_WHILE_OP: 826ae115bc7Smrj 827ae115bc7Smrj /* The next op is the size or predicate parameter */ 828ae115bc7Smrj 829ae115bc7Smrj NextOp = AcpiPsGetDepthNext (NULL, Op); 830ae115bc7Smrj if (NextOp) 831ae115bc7Smrj { 832*385cc6b4SJerry Jelinek NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST; 833ae115bc7Smrj } 834ae115bc7Smrj return (AE_OK); 835ae115bc7Smrj 836ae115bc7Smrj case AML_PACKAGE_OP: 837ae115bc7Smrj 838*385cc6b4SJerry Jelinek /* The next op is the size parameter */ 839ae115bc7Smrj 840ae115bc7Smrj NextOp = AcpiPsGetDepthNext (NULL, Op); 841ae115bc7Smrj if (NextOp) 842ae115bc7Smrj { 843*385cc6b4SJerry Jelinek NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST; 844ae115bc7Smrj } 845ae115bc7Smrj return (AE_OK); 846ae115bc7Smrj 847ae115bc7Smrj case AML_MATCH_OP: 848ae115bc7Smrj 849ae115bc7Smrj AcpiDmMatchOp (Op); 850ae115bc7Smrj break; 851ae115bc7Smrj 852ae115bc7Smrj default: 853ae115bc7Smrj 854ae115bc7Smrj break; 855ae115bc7Smrj } 856ae115bc7Smrj 857ae115bc7Smrj if (AcpiDmBlockType (Op) & BLOCK_BRACE) 858ae115bc7Smrj { 859ae115bc7Smrj AcpiOsPrintf ("\n"); 860ae115bc7Smrj AcpiDmIndent (Level); 861ae115bc7Smrj AcpiOsPrintf ("{\n"); 862ae115bc7Smrj } 863ae115bc7Smrj } 864ae115bc7Smrj 865ae115bc7Smrj return (AE_OK); 866ae115bc7Smrj } 867ae115bc7Smrj 868ae115bc7Smrj 869ae115bc7Smrj /******************************************************************************* 870ae115bc7Smrj * 871ae115bc7Smrj * FUNCTION: AcpiDmAscendingOp 872ae115bc7Smrj * 873ae115bc7Smrj * PARAMETERS: ASL_WALK_CALLBACK 874ae115bc7Smrj * 875ae115bc7Smrj * RETURN: Status 876ae115bc7Smrj * 877ae115bc7Smrj * DESCRIPTION: Second visitation of a parse object, during ascent of parse 878ae115bc7Smrj * tree. Close out any parameter lists and complete the opcode. 879ae115bc7Smrj * 880ae115bc7Smrj ******************************************************************************/ 881ae115bc7Smrj 882ae115bc7Smrj static ACPI_STATUS 883ae115bc7Smrj AcpiDmAscendingOp ( 884ae115bc7Smrj ACPI_PARSE_OBJECT *Op, 885ae115bc7Smrj UINT32 Level, 886ae115bc7Smrj void *Context) 887ae115bc7Smrj { 888ae115bc7Smrj ACPI_OP_WALK_INFO *Info = Context; 889*385cc6b4SJerry Jelinek ACPI_PARSE_OBJECT *ParentOp; 890ae115bc7Smrj 891ae115bc7Smrj 892ae115bc7Smrj if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE) 893ae115bc7Smrj { 894ae115bc7Smrj /* Ignore this op -- it was handled elsewhere */ 895ae115bc7Smrj 896ae115bc7Smrj return (AE_OK); 897ae115bc7Smrj } 898ae115bc7Smrj 899ae115bc7Smrj if ((Level == 0) && (Op->Common.AmlOpcode == AML_SCOPE_OP)) 900ae115bc7Smrj { 901ae115bc7Smrj /* Indicates the end of the current descriptor block (table) */ 902ae115bc7Smrj 903ae115bc7Smrj AcpiOsPrintf ("}\n\n"); 904ae115bc7Smrj return (AE_OK); 905ae115bc7Smrj } 906ae115bc7Smrj 907ae115bc7Smrj switch (AcpiDmBlockType (Op)) 908ae115bc7Smrj { 909ae115bc7Smrj case BLOCK_PAREN: 910ae115bc7Smrj 911*385cc6b4SJerry Jelinek /* Completed an op that has arguments, add closing paren if needed */ 912ae115bc7Smrj 913*385cc6b4SJerry Jelinek AcpiDmCloseOperator (Op); 914*385cc6b4SJerry Jelinek 915*385cc6b4SJerry Jelinek if (Op->Common.AmlOpcode == AML_NAME_OP) 916*385cc6b4SJerry Jelinek { 917*385cc6b4SJerry Jelinek /* Emit description comment for Name() with a predefined ACPI name */ 918*385cc6b4SJerry Jelinek 919*385cc6b4SJerry Jelinek AcpiDmPredefinedDescription (Op); 920*385cc6b4SJerry Jelinek } 921*385cc6b4SJerry Jelinek else 922*385cc6b4SJerry Jelinek { 923*385cc6b4SJerry Jelinek /* For Create* operators, attempt to emit resource tag description */ 924*385cc6b4SJerry Jelinek 925*385cc6b4SJerry Jelinek AcpiDmFieldPredefinedDescription (Op); 926*385cc6b4SJerry Jelinek } 927*385cc6b4SJerry Jelinek 928*385cc6b4SJerry Jelinek /* Decode Notify() values */ 929*385cc6b4SJerry Jelinek 930*385cc6b4SJerry Jelinek if (Op->Common.AmlOpcode == AML_NOTIFY_OP) 931*385cc6b4SJerry Jelinek { 932*385cc6b4SJerry Jelinek AcpiDmNotifyDescription (Op); 933*385cc6b4SJerry Jelinek } 934*385cc6b4SJerry Jelinek 935*385cc6b4SJerry Jelinek AcpiDmDisplayTargetPathname (Op); 936ae115bc7Smrj 937ae115bc7Smrj /* Could be a nested operator, check if comma required */ 938ae115bc7Smrj 939ae115bc7Smrj if (!AcpiDmCommaIfListMember (Op)) 940ae115bc7Smrj { 941ae115bc7Smrj if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) && 942*385cc6b4SJerry Jelinek (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST)) && 943ae115bc7Smrj (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP)) 944ae115bc7Smrj { 945ae115bc7Smrj /* 946ae115bc7Smrj * This is a first-level element of a term list 947ae115bc7Smrj * start a new line 948ae115bc7Smrj */ 949*385cc6b4SJerry Jelinek if (!(Info->Flags & ACPI_PARSEOP_PARAMETER_LIST)) 950ae115bc7Smrj { 951ae115bc7Smrj AcpiOsPrintf ("\n"); 952ae115bc7Smrj } 953ae115bc7Smrj } 954ae115bc7Smrj } 955ae115bc7Smrj break; 956ae115bc7Smrj 957ae115bc7Smrj case BLOCK_BRACE: 958ae115bc7Smrj case (BLOCK_BRACE | BLOCK_PAREN): 959ae115bc7Smrj 960ae115bc7Smrj /* Completed an op that has a term list, add closing brace */ 961ae115bc7Smrj 962ae115bc7Smrj if (Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST) 963ae115bc7Smrj { 964ae115bc7Smrj AcpiOsPrintf ("}"); 965ae115bc7Smrj } 966ae115bc7Smrj else 967ae115bc7Smrj { 968ae115bc7Smrj AcpiDmIndent (Level); 969ae115bc7Smrj AcpiOsPrintf ("}"); 970ae115bc7Smrj } 971ae115bc7Smrj 972ae115bc7Smrj AcpiDmCommaIfListMember (Op); 973ae115bc7Smrj 974ae115bc7Smrj if (AcpiDmBlockType (Op->Common.Parent) != BLOCK_PAREN) 975ae115bc7Smrj { 976ae115bc7Smrj AcpiOsPrintf ("\n"); 977ae115bc7Smrj if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST)) 978ae115bc7Smrj { 979ae115bc7Smrj if ((Op->Common.AmlOpcode == AML_IF_OP) && 980ae115bc7Smrj (Op->Common.Next) && 981ae115bc7Smrj (Op->Common.Next->Common.AmlOpcode == AML_ELSE_OP)) 982ae115bc7Smrj { 983ae115bc7Smrj break; 984ae115bc7Smrj } 985ae115bc7Smrj 986ae115bc7Smrj if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) && 987ae115bc7Smrj (!Op->Common.Next)) 988ae115bc7Smrj { 989ae115bc7Smrj break; 990ae115bc7Smrj } 991ae115bc7Smrj AcpiOsPrintf ("\n"); 992ae115bc7Smrj } 993ae115bc7Smrj } 994ae115bc7Smrj break; 995ae115bc7Smrj 996ae115bc7Smrj case BLOCK_NONE: 997ae115bc7Smrj default: 998ae115bc7Smrj 999ae115bc7Smrj /* Could be a nested operator, check if comma required */ 1000ae115bc7Smrj 1001ae115bc7Smrj if (!AcpiDmCommaIfListMember (Op)) 1002ae115bc7Smrj { 1003ae115bc7Smrj if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) && 1004*385cc6b4SJerry Jelinek (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST)) && 1005ae115bc7Smrj (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP)) 1006ae115bc7Smrj { 1007ae115bc7Smrj /* 1008ae115bc7Smrj * This is a first-level element of a term list 1009ae115bc7Smrj * start a new line 1010ae115bc7Smrj */ 1011ae115bc7Smrj AcpiOsPrintf ("\n"); 1012ae115bc7Smrj } 1013ae115bc7Smrj } 1014ae115bc7Smrj else if (Op->Common.Parent) 1015ae115bc7Smrj { 1016ae115bc7Smrj switch (Op->Common.Parent->Common.AmlOpcode) 1017ae115bc7Smrj { 1018ae115bc7Smrj case AML_PACKAGE_OP: 1019ae115bc7Smrj case AML_VAR_PACKAGE_OP: 1020ae115bc7Smrj 1021*385cc6b4SJerry Jelinek if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST)) 1022ae115bc7Smrj { 1023ae115bc7Smrj AcpiOsPrintf ("\n"); 1024ae115bc7Smrj } 1025ae115bc7Smrj break; 1026ae115bc7Smrj 1027ae115bc7Smrj default: 1028ae115bc7Smrj 1029ae115bc7Smrj break; 1030ae115bc7Smrj } 1031ae115bc7Smrj } 1032ae115bc7Smrj break; 1033ae115bc7Smrj } 1034ae115bc7Smrj 1035*385cc6b4SJerry Jelinek if (Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST) 1036ae115bc7Smrj { 1037ae115bc7Smrj if ((Op->Common.Next) && 1038*385cc6b4SJerry Jelinek (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST)) 1039ae115bc7Smrj { 1040ae115bc7Smrj return (AE_OK); 1041ae115bc7Smrj } 1042ae115bc7Smrj 1043ae115bc7Smrj /* 1044*385cc6b4SJerry Jelinek * The parent Op is guaranteed to be valid because of the flag 1045*385cc6b4SJerry Jelinek * ACPI_PARSEOP_PARAMETER_LIST -- which means that this op is part of 1046*385cc6b4SJerry Jelinek * a parameter list and thus has a valid parent. 1047*385cc6b4SJerry Jelinek */ 1048*385cc6b4SJerry Jelinek ParentOp = Op->Common.Parent; 1049*385cc6b4SJerry Jelinek 1050*385cc6b4SJerry Jelinek /* 1051ae115bc7Smrj * Just completed a parameter node for something like "Buffer (param)". 1052ae115bc7Smrj * Close the paren and open up the term list block with a brace 1053ae115bc7Smrj */ 1054ae115bc7Smrj if (Op->Common.Next) 1055ae115bc7Smrj { 1056*385cc6b4SJerry Jelinek AcpiOsPrintf (")"); 1057*385cc6b4SJerry Jelinek 1058*385cc6b4SJerry Jelinek /* 1059*385cc6b4SJerry Jelinek * Emit a description comment for a Name() operator that is a 1060*385cc6b4SJerry Jelinek * predefined ACPI name. Must check the grandparent. 1061*385cc6b4SJerry Jelinek */ 1062*385cc6b4SJerry Jelinek ParentOp = ParentOp->Common.Parent; 1063*385cc6b4SJerry Jelinek if (ParentOp && 1064*385cc6b4SJerry Jelinek (ParentOp->Asl.AmlOpcode == AML_NAME_OP)) 1065*385cc6b4SJerry Jelinek { 1066*385cc6b4SJerry Jelinek AcpiDmPredefinedDescription (ParentOp); 1067*385cc6b4SJerry Jelinek } 1068*385cc6b4SJerry Jelinek 1069*385cc6b4SJerry Jelinek AcpiOsPrintf ("\n"); 1070ae115bc7Smrj AcpiDmIndent (Level - 1); 1071ae115bc7Smrj AcpiOsPrintf ("{\n"); 1072ae115bc7Smrj } 1073ae115bc7Smrj else 1074ae115bc7Smrj { 1075*385cc6b4SJerry Jelinek ParentOp->Common.DisasmFlags |= ACPI_PARSEOP_EMPTY_TERMLIST; 1076ae115bc7Smrj AcpiOsPrintf (") {"); 1077ae115bc7Smrj } 1078ae115bc7Smrj } 1079ae115bc7Smrj 1080ae115bc7Smrj if ((Op->Common.AmlOpcode == AML_NAME_OP) || 1081ae115bc7Smrj (Op->Common.AmlOpcode == AML_RETURN_OP)) 1082ae115bc7Smrj { 1083ae115bc7Smrj Info->Level++; 1084ae115bc7Smrj } 1085*385cc6b4SJerry Jelinek 1086*385cc6b4SJerry Jelinek /* 1087*385cc6b4SJerry Jelinek * For ASL+, check for and emit a C-style symbol. If valid, the 1088*385cc6b4SJerry Jelinek * symbol string has been deferred until after the first operand 1089*385cc6b4SJerry Jelinek */ 1090*385cc6b4SJerry Jelinek if (AcpiGbl_CstyleDisassembly) 1091*385cc6b4SJerry Jelinek { 1092*385cc6b4SJerry Jelinek if (Op->Asl.OperatorSymbol) 1093*385cc6b4SJerry Jelinek { 1094*385cc6b4SJerry Jelinek AcpiOsPrintf ("%s", Op->Asl.OperatorSymbol); 1095*385cc6b4SJerry Jelinek Op->Asl.OperatorSymbol = NULL; 1096*385cc6b4SJerry Jelinek } 1097ae115bc7Smrj } 1098ae115bc7Smrj 1099*385cc6b4SJerry Jelinek return (AE_OK); 1100*385cc6b4SJerry Jelinek } 1101