dmwalk.c revision 237412
1100966Siwasaki/******************************************************************************* 2100966Siwasaki * 3100966Siwasaki * Module Name: dmwalk - AML disassembly tree walk 4100966Siwasaki * 5100966Siwasaki ******************************************************************************/ 6100966Siwasaki 7217365Sjkim/* 8229989Sjkim * Copyright (C) 2000 - 2012, Intel Corp. 9100966Siwasaki * All rights reserved. 10100966Siwasaki * 11217365Sjkim * Redistribution and use in source and binary forms, with or without 12217365Sjkim * modification, are permitted provided that the following conditions 13217365Sjkim * are met: 14217365Sjkim * 1. Redistributions of source code must retain the above copyright 15217365Sjkim * notice, this list of conditions, and the following disclaimer, 16217365Sjkim * without modification. 17217365Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18217365Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19217365Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20217365Sjkim * including a substantially similar Disclaimer requirement for further 21217365Sjkim * binary redistribution. 22217365Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23217365Sjkim * of any contributors may be used to endorse or promote products derived 24217365Sjkim * from this software without specific prior written permission. 25100966Siwasaki * 26217365Sjkim * Alternatively, this software may be distributed under the terms of the 27217365Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28217365Sjkim * Software Foundation. 29100966Siwasaki * 30217365Sjkim * NO WARRANTY 31217365Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32217365Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33217365Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34217365Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35217365Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36217365Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37217365Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38217365Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39217365Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40217365Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41217365Sjkim * POSSIBILITY OF SUCH DAMAGES. 42217365Sjkim */ 43100966Siwasaki 44100966Siwasaki 45193341Sjkim#include <contrib/dev/acpica/include/acpi.h> 46193341Sjkim#include <contrib/dev/acpica/include/accommon.h> 47193341Sjkim#include <contrib/dev/acpica/include/acparser.h> 48193341Sjkim#include <contrib/dev/acpica/include/amlcode.h> 49193341Sjkim#include <contrib/dev/acpica/include/acdisasm.h> 50193341Sjkim#include <contrib/dev/acpica/include/acdebug.h> 51100966Siwasaki 52100966Siwasaki 53100966Siwasaki#ifdef ACPI_DISASSEMBLER 54100966Siwasaki 55102550Siwasaki#define _COMPONENT ACPI_CA_DEBUGGER 56100966Siwasaki ACPI_MODULE_NAME ("dmwalk") 57100966Siwasaki 58100966Siwasaki 59151937Sjkim#define DB_FULL_OP_INFO "[%4.4s] @%5.5X #%4.4X: " 60100966Siwasaki 61198237Sjkim/* Stub for non-compiler code */ 62198237Sjkim 63198237Sjkim#ifndef ACPI_ASL_COMPILER 64198237Sjkimvoid 65198237SjkimAcpiDmEmitExternals ( 66198237Sjkim void) 67198237Sjkim{ 68198237Sjkim return; 69198237Sjkim} 70198237Sjkim#endif 71198237Sjkim 72151937Sjkim/* Local prototypes */ 73100966Siwasaki 74151937Sjkimstatic ACPI_STATUS 75151937SjkimAcpiDmDescendingOp ( 76151937Sjkim ACPI_PARSE_OBJECT *Op, 77151937Sjkim UINT32 Level, 78151937Sjkim void *Context); 79151937Sjkim 80151937Sjkimstatic ACPI_STATUS 81151937SjkimAcpiDmAscendingOp ( 82151937Sjkim ACPI_PARSE_OBJECT *Op, 83151937Sjkim UINT32 Level, 84151937Sjkim void *Context); 85151937Sjkim 86151937Sjkimstatic UINT32 87151937SjkimAcpiDmBlockType ( 88151937Sjkim ACPI_PARSE_OBJECT *Op); 89151937Sjkim 90151937Sjkim 91100966Siwasaki/******************************************************************************* 92100966Siwasaki * 93100966Siwasaki * FUNCTION: AcpiDmDisassemble 94100966Siwasaki * 95151937Sjkim * PARAMETERS: WalkState - Current state 96151937Sjkim * Origin - Starting object 97100966Siwasaki * NumOpcodes - Max number of opcodes to be displayed 98100966Siwasaki * 99100966Siwasaki * RETURN: None 100100966Siwasaki * 101100966Siwasaki * DESCRIPTION: Disassemble parser object and its children. This is the 102100966Siwasaki * main entry point of the disassembler. 103100966Siwasaki * 104100966Siwasaki ******************************************************************************/ 105100966Siwasaki 106100966Siwasakivoid 107100966SiwasakiAcpiDmDisassemble ( 108100966Siwasaki ACPI_WALK_STATE *WalkState, 109100966Siwasaki ACPI_PARSE_OBJECT *Origin, 110100966Siwasaki UINT32 NumOpcodes) 111100966Siwasaki{ 112100966Siwasaki ACPI_PARSE_OBJECT *Op = Origin; 113100966Siwasaki ACPI_OP_WALK_INFO Info; 114100966Siwasaki 115100966Siwasaki 116100966Siwasaki if (!Op) 117100966Siwasaki { 118100966Siwasaki return; 119100966Siwasaki } 120100966Siwasaki 121167802Sjkim Info.Flags = 0; 122100966Siwasaki Info.Level = 0; 123167802Sjkim Info.Count = 0; 124151937Sjkim Info.WalkState = WalkState; 125100966Siwasaki AcpiDmWalkParseTree (Op, AcpiDmDescendingOp, AcpiDmAscendingOp, &Info); 126100966Siwasaki return; 127100966Siwasaki} 128100966Siwasaki 129100966Siwasaki 130100966Siwasaki/******************************************************************************* 131100966Siwasaki * 132100966Siwasaki * FUNCTION: AcpiDmWalkParseTree 133100966Siwasaki * 134151937Sjkim * PARAMETERS: Op - Root Op object 135151937Sjkim * DescendingCallback - Called during tree descent 136100966Siwasaki * AscendingCallback - Called during tree ascent 137100966Siwasaki * Context - To be passed to the callbacks 138100966Siwasaki * 139100966Siwasaki * RETURN: Status from callback(s) 140100966Siwasaki * 141100966Siwasaki * DESCRIPTION: Walk the entire parse tree. 142100966Siwasaki * 143100966Siwasaki ******************************************************************************/ 144100966Siwasaki 145167802Sjkimvoid 146100966SiwasakiAcpiDmWalkParseTree ( 147100966Siwasaki ACPI_PARSE_OBJECT *Op, 148100966Siwasaki ASL_WALK_CALLBACK DescendingCallback, 149100966Siwasaki ASL_WALK_CALLBACK AscendingCallback, 150100966Siwasaki void *Context) 151100966Siwasaki{ 152100966Siwasaki BOOLEAN NodePreviouslyVisited; 153100966Siwasaki ACPI_PARSE_OBJECT *StartOp = Op; 154100966Siwasaki ACPI_STATUS Status; 155100966Siwasaki ACPI_PARSE_OBJECT *Next; 156100966Siwasaki ACPI_OP_WALK_INFO *Info = Context; 157100966Siwasaki 158100966Siwasaki 159100966Siwasaki Info->Level = 0; 160100966Siwasaki NodePreviouslyVisited = FALSE; 161100966Siwasaki 162100966Siwasaki while (Op) 163100966Siwasaki { 164100966Siwasaki if (NodePreviouslyVisited) 165100966Siwasaki { 166167802Sjkim if (AscendingCallback) 167100966Siwasaki { 168167802Sjkim Status = AscendingCallback (Op, Info->Level, Context); 169167802Sjkim if (ACPI_FAILURE (Status)) 170167802Sjkim { 171167802Sjkim return; 172167802Sjkim } 173100966Siwasaki } 174100966Siwasaki } 175100966Siwasaki else 176100966Siwasaki { 177117521Snjl /* Let the callback process the node */ 178117521Snjl 179100966Siwasaki Status = DescendingCallback (Op, Info->Level, Context); 180100966Siwasaki if (ACPI_SUCCESS (Status)) 181100966Siwasaki { 182100966Siwasaki /* Visit children first, once */ 183100966Siwasaki 184100966Siwasaki Next = AcpiPsGetArg (Op, 0); 185100966Siwasaki if (Next) 186100966Siwasaki { 187100966Siwasaki Info->Level++; 188100966Siwasaki Op = Next; 189100966Siwasaki continue; 190100966Siwasaki } 191100966Siwasaki } 192100966Siwasaki else if (Status != AE_CTRL_DEPTH) 193100966Siwasaki { 194100966Siwasaki /* Exit immediately on any error */ 195100966Siwasaki 196100966Siwasaki return; 197100966Siwasaki } 198100966Siwasaki } 199100966Siwasaki 200100966Siwasaki /* Terminate walk at start op */ 201100966Siwasaki 202100966Siwasaki if (Op == StartOp) 203100966Siwasaki { 204100966Siwasaki break; 205100966Siwasaki } 206100966Siwasaki 207100966Siwasaki /* No more children, re-visit this node */ 208100966Siwasaki 209100966Siwasaki if (!NodePreviouslyVisited) 210100966Siwasaki { 211100966Siwasaki NodePreviouslyVisited = TRUE; 212100966Siwasaki continue; 213100966Siwasaki } 214100966Siwasaki 215100966Siwasaki /* No more children, visit peers */ 216100966Siwasaki 217100966Siwasaki if (Op->Common.Next) 218100966Siwasaki { 219100966Siwasaki Op = Op->Common.Next; 220100966Siwasaki NodePreviouslyVisited = FALSE; 221100966Siwasaki } 222100966Siwasaki else 223100966Siwasaki { 224100966Siwasaki /* No peers, re-visit parent */ 225100966Siwasaki 226100966Siwasaki if (Info->Level != 0 ) 227100966Siwasaki { 228100966Siwasaki Info->Level--; 229100966Siwasaki } 230100966Siwasaki 231100966Siwasaki Op = Op->Common.Parent; 232100966Siwasaki NodePreviouslyVisited = TRUE; 233100966Siwasaki } 234100966Siwasaki } 235100966Siwasaki 236100966Siwasaki /* If we get here, the walk completed with no errors */ 237100966Siwasaki 238100966Siwasaki return; 239100966Siwasaki} 240100966Siwasaki 241100966Siwasaki 242100966Siwasaki/******************************************************************************* 243100966Siwasaki * 244100966Siwasaki * FUNCTION: AcpiDmBlockType 245100966Siwasaki * 246100966Siwasaki * PARAMETERS: Op - Object to be examined 247100966Siwasaki * 248151937Sjkim * RETURN: BlockType - not a block, parens, braces, or even both. 249100966Siwasaki * 250100966Siwasaki * DESCRIPTION: Type of block for this op (parens or braces) 251100966Siwasaki * 252100966Siwasaki ******************************************************************************/ 253100966Siwasaki 254151937Sjkimstatic UINT32 255100966SiwasakiAcpiDmBlockType ( 256100966Siwasaki ACPI_PARSE_OBJECT *Op) 257100966Siwasaki{ 258100966Siwasaki const ACPI_OPCODE_INFO *OpInfo; 259100966Siwasaki 260100966Siwasaki 261100966Siwasaki if (!Op) 262100966Siwasaki { 263100966Siwasaki return (BLOCK_NONE); 264100966Siwasaki } 265100966Siwasaki 266100966Siwasaki switch (Op->Common.AmlOpcode) 267100966Siwasaki { 268100966Siwasaki case AML_ELSE_OP: 269100966Siwasaki 270100966Siwasaki return (BLOCK_BRACE); 271100966Siwasaki 272100966Siwasaki case AML_METHOD_OP: 273100966Siwasaki case AML_DEVICE_OP: 274100966Siwasaki case AML_SCOPE_OP: 275100966Siwasaki case AML_PROCESSOR_OP: 276100966Siwasaki case AML_POWER_RES_OP: 277100966Siwasaki case AML_THERMAL_ZONE_OP: 278100966Siwasaki case AML_IF_OP: 279100966Siwasaki case AML_WHILE_OP: 280100966Siwasaki case AML_FIELD_OP: 281100966Siwasaki case AML_INDEX_FIELD_OP: 282100966Siwasaki case AML_BANK_FIELD_OP: 283100966Siwasaki 284100966Siwasaki return (BLOCK_PAREN | BLOCK_BRACE); 285100966Siwasaki 286100966Siwasaki case AML_BUFFER_OP: 287100966Siwasaki 288100966Siwasaki if (Op->Common.DisasmOpcode == ACPI_DASM_UNICODE) 289100966Siwasaki { 290100966Siwasaki return (BLOCK_NONE); 291100966Siwasaki } 292100966Siwasaki 293100966Siwasaki /*lint -fallthrough */ 294100966Siwasaki 295100966Siwasaki case AML_PACKAGE_OP: 296100966Siwasaki case AML_VAR_PACKAGE_OP: 297100966Siwasaki 298100966Siwasaki return (BLOCK_PAREN | BLOCK_BRACE); 299100966Siwasaki 300100966Siwasaki case AML_EVENT_OP: 301100966Siwasaki 302100966Siwasaki return (BLOCK_PAREN); 303100966Siwasaki 304100966Siwasaki default: 305100966Siwasaki 306100966Siwasaki OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 307100966Siwasaki if (OpInfo->Flags & AML_HAS_ARGS) 308100966Siwasaki { 309100966Siwasaki return (BLOCK_PAREN); 310100966Siwasaki } 311100966Siwasaki 312100966Siwasaki return (BLOCK_NONE); 313100966Siwasaki } 314100966Siwasaki} 315100966Siwasaki 316100966Siwasaki 317100966Siwasaki/******************************************************************************* 318100966Siwasaki * 319100966Siwasaki * FUNCTION: AcpiDmListType 320100966Siwasaki * 321100966Siwasaki * PARAMETERS: Op - Object to be examined 322100966Siwasaki * 323151937Sjkim * RETURN: ListType - has commas or not. 324100966Siwasaki * 325100966Siwasaki * DESCRIPTION: Type of block for this op (parens or braces) 326100966Siwasaki * 327100966Siwasaki ******************************************************************************/ 328100966Siwasaki 329100966SiwasakiUINT32 330100966SiwasakiAcpiDmListType ( 331100966Siwasaki ACPI_PARSE_OBJECT *Op) 332100966Siwasaki{ 333100966Siwasaki const ACPI_OPCODE_INFO *OpInfo; 334100966Siwasaki 335100966Siwasaki 336100966Siwasaki if (!Op) 337100966Siwasaki { 338100966Siwasaki return (BLOCK_NONE); 339100966Siwasaki } 340100966Siwasaki 341100966Siwasaki switch (Op->Common.AmlOpcode) 342100966Siwasaki { 343100966Siwasaki 344100966Siwasaki case AML_ELSE_OP: 345100966Siwasaki case AML_METHOD_OP: 346100966Siwasaki case AML_DEVICE_OP: 347100966Siwasaki case AML_SCOPE_OP: 348100966Siwasaki case AML_POWER_RES_OP: 349100966Siwasaki case AML_PROCESSOR_OP: 350100966Siwasaki case AML_THERMAL_ZONE_OP: 351100966Siwasaki case AML_IF_OP: 352100966Siwasaki case AML_WHILE_OP: 353100966Siwasaki case AML_FIELD_OP: 354100966Siwasaki case AML_INDEX_FIELD_OP: 355100966Siwasaki case AML_BANK_FIELD_OP: 356100966Siwasaki 357151937Sjkim return (BLOCK_NONE); 358100966Siwasaki 359100966Siwasaki case AML_BUFFER_OP: 360100966Siwasaki case AML_PACKAGE_OP: 361100966Siwasaki case AML_VAR_PACKAGE_OP: 362100966Siwasaki 363100966Siwasaki return (BLOCK_COMMA_LIST); 364100966Siwasaki 365100966Siwasaki default: 366100966Siwasaki 367100966Siwasaki OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 368100966Siwasaki if (OpInfo->Flags & AML_HAS_ARGS) 369100966Siwasaki { 370100966Siwasaki return (BLOCK_COMMA_LIST); 371100966Siwasaki } 372100966Siwasaki 373100966Siwasaki return (BLOCK_NONE); 374100966Siwasaki } 375100966Siwasaki} 376100966Siwasaki 377100966Siwasaki 378100966Siwasaki/******************************************************************************* 379100966Siwasaki * 380100966Siwasaki * FUNCTION: AcpiDmDescendingOp 381100966Siwasaki * 382100966Siwasaki * PARAMETERS: ASL_WALK_CALLBACK 383100966Siwasaki * 384100966Siwasaki * RETURN: Status 385100966Siwasaki * 386102550Siwasaki * DESCRIPTION: First visitation of a parse object during tree descent. 387100966Siwasaki * Decode opcode name and begin parameter list(s), if any. 388100966Siwasaki * 389100966Siwasaki ******************************************************************************/ 390100966Siwasaki 391151937Sjkimstatic ACPI_STATUS 392100966SiwasakiAcpiDmDescendingOp ( 393100966Siwasaki ACPI_PARSE_OBJECT *Op, 394100966Siwasaki UINT32 Level, 395100966Siwasaki void *Context) 396100966Siwasaki{ 397100966Siwasaki ACPI_OP_WALK_INFO *Info = Context; 398100966Siwasaki const ACPI_OPCODE_INFO *OpInfo; 399100966Siwasaki UINT32 Name; 400100966Siwasaki ACPI_PARSE_OBJECT *NextOp; 401100966Siwasaki 402100966Siwasaki 403100966Siwasaki if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE) 404100966Siwasaki { 405100966Siwasaki /* Ignore this op -- it was handled elsewhere */ 406100966Siwasaki 407100966Siwasaki return (AE_CTRL_DEPTH); 408100966Siwasaki } 409100966Siwasaki 410128212Snjl /* Level 0 is at the Definition Block level */ 411100966Siwasaki 412100966Siwasaki if (Level == 0) 413100966Siwasaki { 414100966Siwasaki /* In verbose mode, print the AML offset, opcode and depth count */ 415100966Siwasaki 416151937Sjkim if (Info->WalkState) 417151937Sjkim { 418151937Sjkim VERBOSE_PRINT ((DB_FULL_OP_INFO, 419151937Sjkim (Info->WalkState->MethodNode ? 420151937Sjkim Info->WalkState->MethodNode->Name.Ascii : " "), 421151937Sjkim Op->Common.AmlOffset, (UINT32) Op->Common.AmlOpcode)); 422151937Sjkim } 423100966Siwasaki 424100966Siwasaki if (Op->Common.AmlOpcode == AML_SCOPE_OP) 425100966Siwasaki { 426128212Snjl /* This is the beginning of the Definition Block */ 427128212Snjl 428100966Siwasaki AcpiOsPrintf ("{\n"); 429128212Snjl 430128212Snjl /* Emit all External() declarations here */ 431128212Snjl 432198237Sjkim AcpiDmEmitExternals (); 433100966Siwasaki return (AE_OK); 434100966Siwasaki } 435100966Siwasaki } 436100966Siwasaki else if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) && 437100966Siwasaki (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) && 438100966Siwasaki (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP)) 439100966Siwasaki { 440151937Sjkim /* 441151937Sjkim * This is a first-level element of a term list, 442151937Sjkim * indent a new line 443151937Sjkim */ 444100966Siwasaki AcpiDmIndent (Level); 445167802Sjkim Info->LastLevel = Level; 446167802Sjkim Info->Count = 0; 447100966Siwasaki } 448100966Siwasaki 449167802Sjkim /* 450167802Sjkim * This is an inexpensive mechanism to try and keep lines from getting 451167802Sjkim * too long. When the limit is hit, start a new line at the previous 452167802Sjkim * indent plus one. A better but more expensive mechanism would be to 453167802Sjkim * keep track of the current column. 454167802Sjkim */ 455167802Sjkim Info->Count++; 456237412Sjkim if (Info->Count /* +Info->LastLevel */ > 10) 457167802Sjkim { 458167802Sjkim Info->Count = 0; 459167802Sjkim AcpiOsPrintf ("\n"); 460167802Sjkim AcpiDmIndent (Info->LastLevel + 1); 461167802Sjkim } 462167802Sjkim 463100966Siwasaki /* Print the opcode name */ 464100966Siwasaki 465100966Siwasaki AcpiDmDisassembleOneOp (NULL, Info, Op); 466100966Siwasaki 467228110Sjkim if ((Op->Common.DisasmOpcode == ACPI_DASM_LNOT_PREFIX) || 468228110Sjkim (Op->Common.AmlOpcode == AML_INT_CONNECTION_OP)) 469167802Sjkim { 470167802Sjkim return (AE_OK); 471167802Sjkim } 472167802Sjkim 473100966Siwasaki if ((Op->Common.AmlOpcode == AML_NAME_OP) || 474100966Siwasaki (Op->Common.AmlOpcode == AML_RETURN_OP)) 475100966Siwasaki { 476100966Siwasaki Info->Level--; 477100966Siwasaki } 478100966Siwasaki 479117521Snjl /* Start the opcode argument list if necessary */ 480117521Snjl 481100966Siwasaki OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 482100966Siwasaki 483102550Siwasaki if ((OpInfo->Flags & AML_HAS_ARGS) || 484100966Siwasaki (Op->Common.AmlOpcode == AML_EVENT_OP)) 485100966Siwasaki { 486100966Siwasaki /* This opcode has an argument list */ 487100966Siwasaki 488100966Siwasaki if (AcpiDmBlockType (Op) & BLOCK_PAREN) 489100966Siwasaki { 490100966Siwasaki AcpiOsPrintf (" ("); 491100966Siwasaki } 492100966Siwasaki 493117521Snjl /* If this is a named opcode, print the associated name value */ 494117521Snjl 495100966Siwasaki if (OpInfo->Flags & AML_NAMED) 496100966Siwasaki { 497100966Siwasaki switch (Op->Common.AmlOpcode) 498100966Siwasaki { 499100966Siwasaki case AML_ALIAS_OP: 500100966Siwasaki 501100966Siwasaki NextOp = AcpiPsGetDepthNext (NULL, Op); 502100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 503100966Siwasaki AcpiDmNamestring (NextOp->Common.Value.Name); 504100966Siwasaki AcpiOsPrintf (", "); 505100966Siwasaki 506100966Siwasaki /*lint -fallthrough */ 507100966Siwasaki 508100966Siwasaki default: 509100966Siwasaki 510100966Siwasaki Name = AcpiPsGetName (Op); 511100966Siwasaki if (Op->Named.Path) 512100966Siwasaki { 513100966Siwasaki AcpiDmNamestring ((char *) Op->Named.Path); 514100966Siwasaki } 515100966Siwasaki else 516100966Siwasaki { 517193267Sjkim AcpiDmDumpName (Name); 518100966Siwasaki } 519100966Siwasaki 520100966Siwasaki if (Op->Common.AmlOpcode != AML_INT_NAMEDFIELD_OP) 521100966Siwasaki { 522100966Siwasaki if (AcpiGbl_DbOpt_verbose) 523100966Siwasaki { 524100966Siwasaki (void) AcpiPsDisplayObjectPathname (NULL, Op); 525100966Siwasaki } 526100966Siwasaki } 527100966Siwasaki break; 528100966Siwasaki } 529100966Siwasaki 530100966Siwasaki switch (Op->Common.AmlOpcode) 531100966Siwasaki { 532100966Siwasaki case AML_METHOD_OP: 533100966Siwasaki 534100966Siwasaki AcpiDmMethodFlags (Op); 535100966Siwasaki AcpiOsPrintf (")"); 536237412Sjkim 537237412Sjkim /* Emit description comment for Method() with a predefined ACPI name */ 538237412Sjkim 539237412Sjkim AcpiDmPredefinedDescription (Op); 540100966Siwasaki break; 541100966Siwasaki 542100966Siwasaki 543100966Siwasaki case AML_NAME_OP: 544100966Siwasaki 545100966Siwasaki /* Check for _HID and related EISAID() */ 546100966Siwasaki 547151937Sjkim AcpiDmIsEisaId (Op); 548100966Siwasaki AcpiOsPrintf (", "); 549100966Siwasaki break; 550100966Siwasaki 551100966Siwasaki 552100966Siwasaki case AML_REGION_OP: 553100966Siwasaki 554100966Siwasaki AcpiDmRegionFlags (Op); 555100966Siwasaki break; 556100966Siwasaki 557100966Siwasaki 558100966Siwasaki case AML_POWER_RES_OP: 559100966Siwasaki 560100966Siwasaki /* Mark the next two Ops as part of the parameter list */ 561100966Siwasaki 562100966Siwasaki AcpiOsPrintf (", "); 563100966Siwasaki NextOp = AcpiPsGetDepthNext (NULL, Op); 564100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 565100966Siwasaki 566100966Siwasaki NextOp = NextOp->Common.Next; 567100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 568100966Siwasaki return (AE_OK); 569100966Siwasaki 570100966Siwasaki 571100966Siwasaki case AML_PROCESSOR_OP: 572100966Siwasaki 573100966Siwasaki /* Mark the next three Ops as part of the parameter list */ 574100966Siwasaki 575100966Siwasaki AcpiOsPrintf (", "); 576100966Siwasaki NextOp = AcpiPsGetDepthNext (NULL, Op); 577100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 578100966Siwasaki 579100966Siwasaki NextOp = NextOp->Common.Next; 580100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 581100966Siwasaki 582100966Siwasaki NextOp = NextOp->Common.Next; 583100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 584100966Siwasaki return (AE_OK); 585100966Siwasaki 586100966Siwasaki 587100966Siwasaki case AML_MUTEX_OP: 588167802Sjkim case AML_DATA_REGION_OP: 589100966Siwasaki 590100966Siwasaki AcpiOsPrintf (", "); 591100966Siwasaki return (AE_OK); 592100966Siwasaki 593100966Siwasaki 594100966Siwasaki case AML_EVENT_OP: 595100966Siwasaki case AML_ALIAS_OP: 596100966Siwasaki 597100966Siwasaki return (AE_OK); 598100966Siwasaki 599100966Siwasaki 600100966Siwasaki case AML_SCOPE_OP: 601100966Siwasaki case AML_DEVICE_OP: 602100966Siwasaki case AML_THERMAL_ZONE_OP: 603100966Siwasaki 604100966Siwasaki AcpiOsPrintf (")"); 605100966Siwasaki break; 606100966Siwasaki 607100966Siwasaki 608100966Siwasaki default: 609100966Siwasaki 610237412Sjkim AcpiOsPrintf ("*** Unhandled named opcode %X\n", 611237412Sjkim Op->Common.AmlOpcode); 612100966Siwasaki break; 613100966Siwasaki } 614100966Siwasaki } 615100966Siwasaki 616100966Siwasaki else switch (Op->Common.AmlOpcode) 617100966Siwasaki { 618100966Siwasaki case AML_FIELD_OP: 619100966Siwasaki case AML_BANK_FIELD_OP: 620100966Siwasaki case AML_INDEX_FIELD_OP: 621100966Siwasaki 622100966Siwasaki Info->BitOffset = 0; 623100966Siwasaki 624100966Siwasaki /* Name of the parent OperationRegion */ 625100966Siwasaki 626100966Siwasaki NextOp = AcpiPsGetDepthNext (NULL, Op); 627100966Siwasaki AcpiDmNamestring (NextOp->Common.Value.Name); 628100966Siwasaki AcpiOsPrintf (", "); 629100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 630100966Siwasaki 631100966Siwasaki switch (Op->Common.AmlOpcode) 632100966Siwasaki { 633100966Siwasaki case AML_BANK_FIELD_OP: 634100966Siwasaki 635167802Sjkim /* Namestring - Bank Name */ 636100966Siwasaki 637100966Siwasaki NextOp = AcpiPsGetDepthNext (NULL, NextOp); 638100966Siwasaki AcpiDmNamestring (NextOp->Common.Value.Name); 639100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 640100966Siwasaki AcpiOsPrintf (", "); 641100966Siwasaki 642167802Sjkim /* 643167802Sjkim * Bank Value. This is a TermArg in the middle of the parameter 644167802Sjkim * list, must handle it here. 645167802Sjkim * 646167802Sjkim * Disassemble the TermArg parse tree. ACPI_PARSEOP_PARAMLIST 647167802Sjkim * eliminates newline in the output. 648167802Sjkim */ 649167802Sjkim NextOp = NextOp->Common.Next; 650100966Siwasaki 651167802Sjkim Info->Flags = ACPI_PARSEOP_PARAMLIST; 652237412Sjkim AcpiDmWalkParseTree (NextOp, AcpiDmDescendingOp, 653237412Sjkim AcpiDmAscendingOp, Info); 654167802Sjkim Info->Flags = 0; 655167802Sjkim Info->Level = Level; 656167802Sjkim 657100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 658100966Siwasaki AcpiOsPrintf (", "); 659100966Siwasaki break; 660100966Siwasaki 661100966Siwasaki case AML_INDEX_FIELD_OP: 662100966Siwasaki 663167802Sjkim /* Namestring - Data Name */ 664100966Siwasaki 665100966Siwasaki NextOp = AcpiPsGetDepthNext (NULL, NextOp); 666100966Siwasaki AcpiDmNamestring (NextOp->Common.Value.Name); 667100966Siwasaki AcpiOsPrintf (", "); 668100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 669100966Siwasaki break; 670100966Siwasaki 671100966Siwasaki default: 672100966Siwasaki 673100966Siwasaki break; 674100966Siwasaki } 675100966Siwasaki 676100966Siwasaki AcpiDmFieldFlags (NextOp); 677100966Siwasaki break; 678100966Siwasaki 679100966Siwasaki 680100966Siwasaki case AML_BUFFER_OP: 681100966Siwasaki 682100966Siwasaki /* The next op is the size parameter */ 683100966Siwasaki 684100966Siwasaki NextOp = AcpiPsGetDepthNext (NULL, Op); 685100966Siwasaki if (!NextOp) 686100966Siwasaki { 687100966Siwasaki /* Single-step support */ 688100966Siwasaki 689100966Siwasaki return (AE_OK); 690100966Siwasaki } 691100966Siwasaki 692100966Siwasaki if (Op->Common.DisasmOpcode == ACPI_DASM_RESOURCE) 693100966Siwasaki { 694100966Siwasaki /* 695237412Sjkim * We have a resource list. Don't need to output 696237412Sjkim * the buffer size Op. Open up a new block 697100966Siwasaki */ 698100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 699100966Siwasaki NextOp = NextOp->Common.Next; 700237412Sjkim AcpiOsPrintf (")"); 701237412Sjkim 702237412Sjkim /* Emit description comment for Name() with a predefined ACPI name */ 703237412Sjkim 704237412Sjkim AcpiDmPredefinedDescription (Op->Asl.Parent); 705237412Sjkim 706237412Sjkim AcpiOsPrintf ("\n"); 707100966Siwasaki AcpiDmIndent (Info->Level); 708100966Siwasaki AcpiOsPrintf ("{\n"); 709100966Siwasaki return (AE_OK); 710100966Siwasaki } 711100966Siwasaki 712100966Siwasaki /* Normal Buffer, mark size as in the parameter list */ 713100966Siwasaki 714100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 715100966Siwasaki return (AE_OK); 716100966Siwasaki 717100966Siwasaki 718100966Siwasaki case AML_VAR_PACKAGE_OP: 719100966Siwasaki case AML_IF_OP: 720100966Siwasaki case AML_WHILE_OP: 721100966Siwasaki 722100966Siwasaki /* The next op is the size or predicate parameter */ 723100966Siwasaki 724100966Siwasaki NextOp = AcpiPsGetDepthNext (NULL, Op); 725100966Siwasaki if (NextOp) 726100966Siwasaki { 727100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 728100966Siwasaki } 729100966Siwasaki return (AE_OK); 730100966Siwasaki 731100966Siwasaki 732100966Siwasaki case AML_PACKAGE_OP: 733100966Siwasaki 734237412Sjkim /* The next op is the size parameter */ 735100966Siwasaki 736100966Siwasaki NextOp = AcpiPsGetDepthNext (NULL, Op); 737100966Siwasaki if (NextOp) 738100966Siwasaki { 739100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 740100966Siwasaki } 741100966Siwasaki return (AE_OK); 742100966Siwasaki 743100966Siwasaki 744100966Siwasaki case AML_MATCH_OP: 745100966Siwasaki 746100966Siwasaki AcpiDmMatchOp (Op); 747100966Siwasaki break; 748100966Siwasaki 749100966Siwasaki 750100966Siwasaki default: 751100966Siwasaki 752100966Siwasaki break; 753100966Siwasaki } 754100966Siwasaki 755100966Siwasaki if (AcpiDmBlockType (Op) & BLOCK_BRACE) 756100966Siwasaki { 757100966Siwasaki AcpiOsPrintf ("\n"); 758100966Siwasaki AcpiDmIndent (Level); 759100966Siwasaki AcpiOsPrintf ("{\n"); 760100966Siwasaki } 761100966Siwasaki } 762100966Siwasaki 763100966Siwasaki return (AE_OK); 764100966Siwasaki} 765100966Siwasaki 766100966Siwasaki 767100966Siwasaki/******************************************************************************* 768100966Siwasaki * 769100966Siwasaki * FUNCTION: AcpiDmAscendingOp 770100966Siwasaki * 771100966Siwasaki * PARAMETERS: ASL_WALK_CALLBACK 772100966Siwasaki * 773100966Siwasaki * RETURN: Status 774100966Siwasaki * 775100966Siwasaki * DESCRIPTION: Second visitation of a parse object, during ascent of parse 776100966Siwasaki * tree. Close out any parameter lists and complete the opcode. 777100966Siwasaki * 778100966Siwasaki ******************************************************************************/ 779100966Siwasaki 780151937Sjkimstatic ACPI_STATUS 781100966SiwasakiAcpiDmAscendingOp ( 782100966Siwasaki ACPI_PARSE_OBJECT *Op, 783100966Siwasaki UINT32 Level, 784100966Siwasaki void *Context) 785100966Siwasaki{ 786100966Siwasaki ACPI_OP_WALK_INFO *Info = Context; 787237412Sjkim ACPI_PARSE_OBJECT *ParentOp; 788100966Siwasaki 789100966Siwasaki 790100966Siwasaki if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE) 791100966Siwasaki { 792100966Siwasaki /* Ignore this op -- it was handled elsewhere */ 793100966Siwasaki 794100966Siwasaki return (AE_OK); 795100966Siwasaki } 796100966Siwasaki 797100966Siwasaki if ((Level == 0) && (Op->Common.AmlOpcode == AML_SCOPE_OP)) 798100966Siwasaki { 799100966Siwasaki /* Indicates the end of the current descriptor block (table) */ 800100966Siwasaki 801100966Siwasaki AcpiOsPrintf ("}\n\n"); 802100966Siwasaki return (AE_OK); 803100966Siwasaki } 804100966Siwasaki 805100966Siwasaki switch (AcpiDmBlockType (Op)) 806100966Siwasaki { 807100966Siwasaki case BLOCK_PAREN: 808100966Siwasaki 809100966Siwasaki /* Completed an op that has arguments, add closing paren */ 810100966Siwasaki 811100966Siwasaki AcpiOsPrintf (")"); 812100966Siwasaki 813237412Sjkim if (Op->Common.AmlOpcode == AML_NAME_OP) 814237412Sjkim { 815237412Sjkim /* Emit description comment for Name() with a predefined ACPI name */ 816237412Sjkim 817237412Sjkim AcpiDmPredefinedDescription (Op); 818237412Sjkim } 819237412Sjkim else 820237412Sjkim { 821237412Sjkim /* For Create* operators, attempt to emit resource tag description */ 822237412Sjkim 823237412Sjkim AcpiDmFieldPredefinedDescription (Op); 824237412Sjkim } 825237412Sjkim 826100966Siwasaki /* Could be a nested operator, check if comma required */ 827100966Siwasaki 828100966Siwasaki if (!AcpiDmCommaIfListMember (Op)) 829100966Siwasaki { 830100966Siwasaki if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) && 831100966Siwasaki (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) && 832100966Siwasaki (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP)) 833100966Siwasaki { 834151937Sjkim /* 835151937Sjkim * This is a first-level element of a term list 836151937Sjkim * start a new line 837151937Sjkim */ 838167802Sjkim if (!(Info->Flags & ACPI_PARSEOP_PARAMLIST)) 839167802Sjkim { 840167802Sjkim AcpiOsPrintf ("\n"); 841167802Sjkim } 842100966Siwasaki } 843100966Siwasaki } 844100966Siwasaki break; 845100966Siwasaki 846100966Siwasaki 847100966Siwasaki case BLOCK_BRACE: 848100966Siwasaki case (BLOCK_BRACE | BLOCK_PAREN): 849100966Siwasaki 850100966Siwasaki /* Completed an op that has a term list, add closing brace */ 851100966Siwasaki 852100966Siwasaki if (Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST) 853100966Siwasaki { 854100966Siwasaki AcpiOsPrintf ("}"); 855100966Siwasaki } 856100966Siwasaki else 857100966Siwasaki { 858100966Siwasaki AcpiDmIndent (Level); 859100966Siwasaki AcpiOsPrintf ("}"); 860100966Siwasaki } 861100966Siwasaki 862100966Siwasaki AcpiDmCommaIfListMember (Op); 863100966Siwasaki 864100966Siwasaki if (AcpiDmBlockType (Op->Common.Parent) != BLOCK_PAREN) 865100966Siwasaki { 866100966Siwasaki AcpiOsPrintf ("\n"); 867100966Siwasaki if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST)) 868100966Siwasaki { 869100966Siwasaki if ((Op->Common.AmlOpcode == AML_IF_OP) && 870100966Siwasaki (Op->Common.Next) && 871100966Siwasaki (Op->Common.Next->Common.AmlOpcode == AML_ELSE_OP)) 872100966Siwasaki { 873100966Siwasaki break; 874100966Siwasaki } 875100966Siwasaki 876100966Siwasaki if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) && 877100966Siwasaki (!Op->Common.Next)) 878100966Siwasaki { 879100966Siwasaki break; 880100966Siwasaki } 881100966Siwasaki AcpiOsPrintf ("\n"); 882100966Siwasaki } 883100966Siwasaki } 884100966Siwasaki break; 885100966Siwasaki 886100966Siwasaki 887100966Siwasaki case BLOCK_NONE: 888100966Siwasaki default: 889100966Siwasaki 890100966Siwasaki /* Could be a nested operator, check if comma required */ 891100966Siwasaki 892100966Siwasaki if (!AcpiDmCommaIfListMember (Op)) 893100966Siwasaki { 894100966Siwasaki if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) && 895100966Siwasaki (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) && 896100966Siwasaki (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP)) 897100966Siwasaki { 898151937Sjkim /* 899151937Sjkim * This is a first-level element of a term list 900151937Sjkim * start a new line 901151937Sjkim */ 902100966Siwasaki AcpiOsPrintf ("\n"); 903100966Siwasaki } 904100966Siwasaki } 905100966Siwasaki else if (Op->Common.Parent) 906100966Siwasaki { 907100966Siwasaki switch (Op->Common.Parent->Common.AmlOpcode) 908100966Siwasaki { 909100966Siwasaki case AML_PACKAGE_OP: 910100966Siwasaki case AML_VAR_PACKAGE_OP: 911100966Siwasaki 912100966Siwasaki if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) 913100966Siwasaki { 914100966Siwasaki AcpiOsPrintf ("\n"); 915100966Siwasaki } 916100966Siwasaki break; 917100966Siwasaki 918100966Siwasaki default: 919100966Siwasaki 920100966Siwasaki break; 921100966Siwasaki } 922100966Siwasaki } 923100966Siwasaki break; 924100966Siwasaki } 925100966Siwasaki 926100966Siwasaki if (Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST) 927100966Siwasaki { 928100966Siwasaki if ((Op->Common.Next) && 929100966Siwasaki (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) 930100966Siwasaki { 931100966Siwasaki return (AE_OK); 932100966Siwasaki } 933100966Siwasaki 934100966Siwasaki /* 935100966Siwasaki * Just completed a parameter node for something like "Buffer (param)". 936100966Siwasaki * Close the paren and open up the term list block with a brace 937100966Siwasaki */ 938100966Siwasaki if (Op->Common.Next) 939100966Siwasaki { 940237412Sjkim AcpiOsPrintf (")"); 941237412Sjkim 942237412Sjkim /* Emit description comment for Name() with a predefined ACPI name */ 943237412Sjkim 944237412Sjkim ParentOp = Op->Common.Parent; 945237412Sjkim if (ParentOp) 946237412Sjkim { 947237412Sjkim ParentOp = ParentOp->Common.Parent; 948237412Sjkim if (ParentOp && ParentOp->Asl.AmlOpcode == AML_NAME_OP) 949237412Sjkim { 950237412Sjkim AcpiDmPredefinedDescription (ParentOp); 951237412Sjkim } 952237412Sjkim } 953237412Sjkim AcpiOsPrintf ("\n"); 954100966Siwasaki AcpiDmIndent (Level - 1); 955100966Siwasaki AcpiOsPrintf ("{\n"); 956100966Siwasaki } 957100966Siwasaki else 958100966Siwasaki { 959151937Sjkim Op->Common.Parent->Common.DisasmFlags |= 960151937Sjkim ACPI_PARSEOP_EMPTY_TERMLIST; 961100966Siwasaki AcpiOsPrintf (") {"); 962100966Siwasaki } 963100966Siwasaki } 964100966Siwasaki 965100966Siwasaki if ((Op->Common.AmlOpcode == AML_NAME_OP) || 966100966Siwasaki (Op->Common.AmlOpcode == AML_RETURN_OP)) 967100966Siwasaki { 968100966Siwasaki Info->Level++; 969100966Siwasaki } 970100966Siwasaki return (AE_OK); 971100966Siwasaki} 972100966Siwasaki 973100966Siwasaki 974100966Siwasaki#endif /* ACPI_DISASSEMBLER */ 975