1100966Siwasaki/******************************************************************************* 2100966Siwasaki * 3100966Siwasaki * Module Name: dmwalk - AML disassembly tree walk 4100966Siwasaki * 5100966Siwasaki ******************************************************************************/ 6100966Siwasaki 7217365Sjkim/* 8217365Sjkim * Copyright (C) 2000 - 2011, 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++; 456167802Sjkim 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 467167802Sjkim if (Op->Common.DisasmOpcode == ACPI_DASM_LNOT_PREFIX) 468167802Sjkim { 469167802Sjkim return (AE_OK); 470167802Sjkim } 471167802Sjkim 472100966Siwasaki if ((Op->Common.AmlOpcode == AML_NAME_OP) || 473100966Siwasaki (Op->Common.AmlOpcode == AML_RETURN_OP)) 474100966Siwasaki { 475100966Siwasaki Info->Level--; 476100966Siwasaki } 477100966Siwasaki 478117521Snjl /* Start the opcode argument list if necessary */ 479117521Snjl 480100966Siwasaki OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); 481100966Siwasaki 482102550Siwasaki if ((OpInfo->Flags & AML_HAS_ARGS) || 483100966Siwasaki (Op->Common.AmlOpcode == AML_EVENT_OP)) 484100966Siwasaki { 485100966Siwasaki /* This opcode has an argument list */ 486100966Siwasaki 487100966Siwasaki if (AcpiDmBlockType (Op) & BLOCK_PAREN) 488100966Siwasaki { 489100966Siwasaki AcpiOsPrintf (" ("); 490100966Siwasaki } 491100966Siwasaki 492117521Snjl /* If this is a named opcode, print the associated name value */ 493117521Snjl 494100966Siwasaki if (OpInfo->Flags & AML_NAMED) 495100966Siwasaki { 496100966Siwasaki switch (Op->Common.AmlOpcode) 497100966Siwasaki { 498100966Siwasaki case AML_ALIAS_OP: 499100966Siwasaki 500100966Siwasaki NextOp = AcpiPsGetDepthNext (NULL, Op); 501100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 502100966Siwasaki AcpiDmNamestring (NextOp->Common.Value.Name); 503100966Siwasaki AcpiOsPrintf (", "); 504100966Siwasaki 505100966Siwasaki /*lint -fallthrough */ 506100966Siwasaki 507100966Siwasaki default: 508100966Siwasaki 509100966Siwasaki Name = AcpiPsGetName (Op); 510100966Siwasaki if (Op->Named.Path) 511100966Siwasaki { 512100966Siwasaki AcpiDmNamestring ((char *) Op->Named.Path); 513100966Siwasaki } 514100966Siwasaki else 515100966Siwasaki { 516193267Sjkim AcpiDmDumpName (Name); 517100966Siwasaki } 518100966Siwasaki 519100966Siwasaki if (Op->Common.AmlOpcode != AML_INT_NAMEDFIELD_OP) 520100966Siwasaki { 521100966Siwasaki if (AcpiGbl_DbOpt_verbose) 522100966Siwasaki { 523100966Siwasaki (void) AcpiPsDisplayObjectPathname (NULL, Op); 524100966Siwasaki } 525100966Siwasaki } 526100966Siwasaki break; 527100966Siwasaki } 528100966Siwasaki 529100966Siwasaki switch (Op->Common.AmlOpcode) 530100966Siwasaki { 531100966Siwasaki case AML_METHOD_OP: 532100966Siwasaki 533100966Siwasaki AcpiDmMethodFlags (Op); 534100966Siwasaki AcpiOsPrintf (")"); 535100966Siwasaki break; 536100966Siwasaki 537100966Siwasaki 538100966Siwasaki case AML_NAME_OP: 539100966Siwasaki 540100966Siwasaki /* Check for _HID and related EISAID() */ 541100966Siwasaki 542151937Sjkim AcpiDmIsEisaId (Op); 543100966Siwasaki AcpiOsPrintf (", "); 544100966Siwasaki break; 545100966Siwasaki 546100966Siwasaki 547100966Siwasaki case AML_REGION_OP: 548100966Siwasaki 549100966Siwasaki AcpiDmRegionFlags (Op); 550100966Siwasaki break; 551100966Siwasaki 552100966Siwasaki 553100966Siwasaki case AML_POWER_RES_OP: 554100966Siwasaki 555100966Siwasaki /* Mark the next two Ops as part of the parameter list */ 556100966Siwasaki 557100966Siwasaki AcpiOsPrintf (", "); 558100966Siwasaki NextOp = AcpiPsGetDepthNext (NULL, Op); 559100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 560100966Siwasaki 561100966Siwasaki NextOp = NextOp->Common.Next; 562100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 563100966Siwasaki return (AE_OK); 564100966Siwasaki 565100966Siwasaki 566100966Siwasaki case AML_PROCESSOR_OP: 567100966Siwasaki 568100966Siwasaki /* Mark the next three Ops as part of the parameter list */ 569100966Siwasaki 570100966Siwasaki AcpiOsPrintf (", "); 571100966Siwasaki NextOp = AcpiPsGetDepthNext (NULL, Op); 572100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 573100966Siwasaki 574100966Siwasaki NextOp = NextOp->Common.Next; 575100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 576100966Siwasaki 577100966Siwasaki NextOp = NextOp->Common.Next; 578100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 579100966Siwasaki return (AE_OK); 580100966Siwasaki 581100966Siwasaki 582100966Siwasaki case AML_MUTEX_OP: 583167802Sjkim case AML_DATA_REGION_OP: 584100966Siwasaki 585100966Siwasaki AcpiOsPrintf (", "); 586100966Siwasaki return (AE_OK); 587100966Siwasaki 588100966Siwasaki 589100966Siwasaki case AML_EVENT_OP: 590100966Siwasaki case AML_ALIAS_OP: 591100966Siwasaki 592100966Siwasaki return (AE_OK); 593100966Siwasaki 594100966Siwasaki 595100966Siwasaki case AML_SCOPE_OP: 596100966Siwasaki case AML_DEVICE_OP: 597100966Siwasaki case AML_THERMAL_ZONE_OP: 598100966Siwasaki 599100966Siwasaki AcpiOsPrintf (")"); 600100966Siwasaki break; 601100966Siwasaki 602100966Siwasaki 603100966Siwasaki default: 604100966Siwasaki 605167802Sjkim AcpiOsPrintf ("*** Unhandled named opcode %X\n", Op->Common.AmlOpcode); 606100966Siwasaki break; 607100966Siwasaki } 608100966Siwasaki } 609100966Siwasaki 610100966Siwasaki else switch (Op->Common.AmlOpcode) 611100966Siwasaki { 612100966Siwasaki case AML_FIELD_OP: 613100966Siwasaki case AML_BANK_FIELD_OP: 614100966Siwasaki case AML_INDEX_FIELD_OP: 615100966Siwasaki 616100966Siwasaki Info->BitOffset = 0; 617100966Siwasaki 618100966Siwasaki /* Name of the parent OperationRegion */ 619100966Siwasaki 620100966Siwasaki NextOp = AcpiPsGetDepthNext (NULL, Op); 621100966Siwasaki AcpiDmNamestring (NextOp->Common.Value.Name); 622100966Siwasaki AcpiOsPrintf (", "); 623100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 624100966Siwasaki 625100966Siwasaki switch (Op->Common.AmlOpcode) 626100966Siwasaki { 627100966Siwasaki case AML_BANK_FIELD_OP: 628100966Siwasaki 629167802Sjkim /* Namestring - Bank Name */ 630100966Siwasaki 631100966Siwasaki NextOp = AcpiPsGetDepthNext (NULL, NextOp); 632100966Siwasaki AcpiDmNamestring (NextOp->Common.Value.Name); 633100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 634100966Siwasaki AcpiOsPrintf (", "); 635100966Siwasaki 636167802Sjkim /* 637167802Sjkim * Bank Value. This is a TermArg in the middle of the parameter 638167802Sjkim * list, must handle it here. 639167802Sjkim * 640167802Sjkim * Disassemble the TermArg parse tree. ACPI_PARSEOP_PARAMLIST 641167802Sjkim * eliminates newline in the output. 642167802Sjkim */ 643167802Sjkim NextOp = NextOp->Common.Next; 644100966Siwasaki 645167802Sjkim Info->Flags = ACPI_PARSEOP_PARAMLIST; 646167802Sjkim AcpiDmWalkParseTree (NextOp, AcpiDmDescendingOp, AcpiDmAscendingOp, Info); 647167802Sjkim Info->Flags = 0; 648167802Sjkim Info->Level = Level; 649167802Sjkim 650100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 651100966Siwasaki AcpiOsPrintf (", "); 652100966Siwasaki break; 653100966Siwasaki 654100966Siwasaki case AML_INDEX_FIELD_OP: 655100966Siwasaki 656167802Sjkim /* Namestring - Data Name */ 657100966Siwasaki 658100966Siwasaki NextOp = AcpiPsGetDepthNext (NULL, NextOp); 659100966Siwasaki AcpiDmNamestring (NextOp->Common.Value.Name); 660100966Siwasaki AcpiOsPrintf (", "); 661100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 662100966Siwasaki break; 663100966Siwasaki 664100966Siwasaki default: 665100966Siwasaki 666100966Siwasaki break; 667100966Siwasaki } 668100966Siwasaki 669100966Siwasaki AcpiDmFieldFlags (NextOp); 670100966Siwasaki break; 671100966Siwasaki 672100966Siwasaki 673100966Siwasaki case AML_BUFFER_OP: 674100966Siwasaki 675100966Siwasaki /* The next op is the size parameter */ 676100966Siwasaki 677100966Siwasaki NextOp = AcpiPsGetDepthNext (NULL, Op); 678100966Siwasaki if (!NextOp) 679100966Siwasaki { 680100966Siwasaki /* Single-step support */ 681100966Siwasaki 682100966Siwasaki return (AE_OK); 683100966Siwasaki } 684100966Siwasaki 685100966Siwasaki if (Op->Common.DisasmOpcode == ACPI_DASM_RESOURCE) 686100966Siwasaki { 687100966Siwasaki /* 688102550Siwasaki * We have a resource list. Don't need to output 689100966Siwasaki * the buffer size Op. Open up a new block 690100966Siwasaki */ 691100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; 692100966Siwasaki NextOp = NextOp->Common.Next; 693100966Siwasaki AcpiOsPrintf (")\n"); 694100966Siwasaki AcpiDmIndent (Info->Level); 695100966Siwasaki AcpiOsPrintf ("{\n"); 696100966Siwasaki return (AE_OK); 697100966Siwasaki } 698100966Siwasaki 699100966Siwasaki /* Normal Buffer, mark size as in the parameter list */ 700100966Siwasaki 701100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 702100966Siwasaki return (AE_OK); 703100966Siwasaki 704100966Siwasaki 705100966Siwasaki case AML_VAR_PACKAGE_OP: 706100966Siwasaki case AML_IF_OP: 707100966Siwasaki case AML_WHILE_OP: 708100966Siwasaki 709100966Siwasaki /* The next op is the size or predicate parameter */ 710100966Siwasaki 711100966Siwasaki NextOp = AcpiPsGetDepthNext (NULL, Op); 712100966Siwasaki if (NextOp) 713100966Siwasaki { 714100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 715100966Siwasaki } 716100966Siwasaki return (AE_OK); 717100966Siwasaki 718100966Siwasaki 719100966Siwasaki case AML_PACKAGE_OP: 720100966Siwasaki 721100966Siwasaki /* The next op is the size or predicate parameter */ 722100966Siwasaki 723100966Siwasaki NextOp = AcpiPsGetDepthNext (NULL, Op); 724100966Siwasaki if (NextOp) 725100966Siwasaki { 726100966Siwasaki NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMLIST; 727100966Siwasaki } 728100966Siwasaki return (AE_OK); 729100966Siwasaki 730100966Siwasaki 731100966Siwasaki case AML_MATCH_OP: 732100966Siwasaki 733100966Siwasaki AcpiDmMatchOp (Op); 734100966Siwasaki break; 735100966Siwasaki 736100966Siwasaki 737100966Siwasaki default: 738100966Siwasaki 739100966Siwasaki break; 740100966Siwasaki } 741100966Siwasaki 742100966Siwasaki if (AcpiDmBlockType (Op) & BLOCK_BRACE) 743100966Siwasaki { 744100966Siwasaki AcpiOsPrintf ("\n"); 745100966Siwasaki AcpiDmIndent (Level); 746100966Siwasaki AcpiOsPrintf ("{\n"); 747100966Siwasaki } 748100966Siwasaki } 749100966Siwasaki 750100966Siwasaki return (AE_OK); 751100966Siwasaki} 752100966Siwasaki 753100966Siwasaki 754100966Siwasaki/******************************************************************************* 755100966Siwasaki * 756100966Siwasaki * FUNCTION: AcpiDmAscendingOp 757100966Siwasaki * 758100966Siwasaki * PARAMETERS: ASL_WALK_CALLBACK 759100966Siwasaki * 760100966Siwasaki * RETURN: Status 761100966Siwasaki * 762100966Siwasaki * DESCRIPTION: Second visitation of a parse object, during ascent of parse 763100966Siwasaki * tree. Close out any parameter lists and complete the opcode. 764100966Siwasaki * 765100966Siwasaki ******************************************************************************/ 766100966Siwasaki 767151937Sjkimstatic ACPI_STATUS 768100966SiwasakiAcpiDmAscendingOp ( 769100966Siwasaki ACPI_PARSE_OBJECT *Op, 770100966Siwasaki UINT32 Level, 771100966Siwasaki void *Context) 772100966Siwasaki{ 773100966Siwasaki ACPI_OP_WALK_INFO *Info = Context; 774100966Siwasaki 775100966Siwasaki 776100966Siwasaki if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE) 777100966Siwasaki { 778100966Siwasaki /* Ignore this op -- it was handled elsewhere */ 779100966Siwasaki 780100966Siwasaki return (AE_OK); 781100966Siwasaki } 782100966Siwasaki 783100966Siwasaki if ((Level == 0) && (Op->Common.AmlOpcode == AML_SCOPE_OP)) 784100966Siwasaki { 785100966Siwasaki /* Indicates the end of the current descriptor block (table) */ 786100966Siwasaki 787100966Siwasaki AcpiOsPrintf ("}\n\n"); 788100966Siwasaki return (AE_OK); 789100966Siwasaki } 790100966Siwasaki 791100966Siwasaki switch (AcpiDmBlockType (Op)) 792100966Siwasaki { 793100966Siwasaki case BLOCK_PAREN: 794100966Siwasaki 795100966Siwasaki /* Completed an op that has arguments, add closing paren */ 796100966Siwasaki 797100966Siwasaki AcpiOsPrintf (")"); 798100966Siwasaki 799100966Siwasaki /* Could be a nested operator, check if comma required */ 800100966Siwasaki 801100966Siwasaki if (!AcpiDmCommaIfListMember (Op)) 802100966Siwasaki { 803100966Siwasaki if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) && 804100966Siwasaki (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) && 805100966Siwasaki (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP)) 806100966Siwasaki { 807151937Sjkim /* 808151937Sjkim * This is a first-level element of a term list 809151937Sjkim * start a new line 810151937Sjkim */ 811167802Sjkim if (!(Info->Flags & ACPI_PARSEOP_PARAMLIST)) 812167802Sjkim { 813167802Sjkim AcpiOsPrintf ("\n"); 814167802Sjkim } 815100966Siwasaki } 816100966Siwasaki } 817100966Siwasaki break; 818100966Siwasaki 819100966Siwasaki 820100966Siwasaki case BLOCK_BRACE: 821100966Siwasaki case (BLOCK_BRACE | BLOCK_PAREN): 822100966Siwasaki 823100966Siwasaki /* Completed an op that has a term list, add closing brace */ 824100966Siwasaki 825100966Siwasaki if (Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST) 826100966Siwasaki { 827100966Siwasaki AcpiOsPrintf ("}"); 828100966Siwasaki } 829100966Siwasaki else 830100966Siwasaki { 831100966Siwasaki AcpiDmIndent (Level); 832100966Siwasaki AcpiOsPrintf ("}"); 833100966Siwasaki } 834100966Siwasaki 835100966Siwasaki AcpiDmCommaIfListMember (Op); 836100966Siwasaki 837100966Siwasaki if (AcpiDmBlockType (Op->Common.Parent) != BLOCK_PAREN) 838100966Siwasaki { 839100966Siwasaki AcpiOsPrintf ("\n"); 840100966Siwasaki if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST)) 841100966Siwasaki { 842100966Siwasaki if ((Op->Common.AmlOpcode == AML_IF_OP) && 843100966Siwasaki (Op->Common.Next) && 844100966Siwasaki (Op->Common.Next->Common.AmlOpcode == AML_ELSE_OP)) 845100966Siwasaki { 846100966Siwasaki break; 847100966Siwasaki } 848100966Siwasaki 849100966Siwasaki if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) && 850100966Siwasaki (!Op->Common.Next)) 851100966Siwasaki { 852100966Siwasaki break; 853100966Siwasaki } 854100966Siwasaki AcpiOsPrintf ("\n"); 855100966Siwasaki } 856100966Siwasaki } 857100966Siwasaki break; 858100966Siwasaki 859100966Siwasaki 860100966Siwasaki case BLOCK_NONE: 861100966Siwasaki default: 862100966Siwasaki 863100966Siwasaki /* Could be a nested operator, check if comma required */ 864100966Siwasaki 865100966Siwasaki if (!AcpiDmCommaIfListMember (Op)) 866100966Siwasaki { 867100966Siwasaki if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) && 868100966Siwasaki (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) && 869100966Siwasaki (Op->Common.AmlOpcode != AML_INT_BYTELIST_OP)) 870100966Siwasaki { 871151937Sjkim /* 872151937Sjkim * This is a first-level element of a term list 873151937Sjkim * start a new line 874151937Sjkim */ 875100966Siwasaki AcpiOsPrintf ("\n"); 876100966Siwasaki } 877100966Siwasaki } 878100966Siwasaki else if (Op->Common.Parent) 879100966Siwasaki { 880100966Siwasaki switch (Op->Common.Parent->Common.AmlOpcode) 881100966Siwasaki { 882100966Siwasaki case AML_PACKAGE_OP: 883100966Siwasaki case AML_VAR_PACKAGE_OP: 884100966Siwasaki 885100966Siwasaki if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) 886100966Siwasaki { 887100966Siwasaki AcpiOsPrintf ("\n"); 888100966Siwasaki } 889100966Siwasaki break; 890100966Siwasaki 891100966Siwasaki default: 892100966Siwasaki 893100966Siwasaki break; 894100966Siwasaki } 895100966Siwasaki } 896100966Siwasaki break; 897100966Siwasaki } 898100966Siwasaki 899100966Siwasaki if (Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST) 900100966Siwasaki { 901100966Siwasaki if ((Op->Common.Next) && 902100966Siwasaki (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)) 903100966Siwasaki { 904100966Siwasaki return (AE_OK); 905100966Siwasaki } 906100966Siwasaki 907100966Siwasaki /* 908100966Siwasaki * Just completed a parameter node for something like "Buffer (param)". 909100966Siwasaki * Close the paren and open up the term list block with a brace 910100966Siwasaki */ 911100966Siwasaki if (Op->Common.Next) 912100966Siwasaki { 913100966Siwasaki AcpiOsPrintf (")\n"); 914100966Siwasaki AcpiDmIndent (Level - 1); 915100966Siwasaki AcpiOsPrintf ("{\n"); 916100966Siwasaki } 917100966Siwasaki else 918100966Siwasaki { 919151937Sjkim Op->Common.Parent->Common.DisasmFlags |= 920151937Sjkim ACPI_PARSEOP_EMPTY_TERMLIST; 921100966Siwasaki AcpiOsPrintf (") {"); 922100966Siwasaki } 923100966Siwasaki } 924100966Siwasaki 925100966Siwasaki if ((Op->Common.AmlOpcode == AML_NAME_OP) || 926100966Siwasaki (Op->Common.AmlOpcode == AML_RETURN_OP)) 927100966Siwasaki { 928100966Siwasaki Info->Level++; 929100966Siwasaki } 930100966Siwasaki return (AE_OK); 931100966Siwasaki} 932100966Siwasaki 933100966Siwasaki 934100966Siwasaki#endif /* ACPI_DISASSEMBLER */ 935