Path: blob/main/sys/contrib/dev/acpica/components/disassembler/dmwalk.c
48524 views
/*******************************************************************************1*2* Module Name: dmwalk - AML disassembly tree walk3*4******************************************************************************/56/******************************************************************************7*8* 1. Copyright Notice9*10* Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.11* All rights reserved.12*13* 2. License14*15* 2.1. This is your license from Intel Corp. under its intellectual property16* rights. You may have additional license terms from the party that provided17* you this software, covering your right to use that party's intellectual18* property rights.19*20* 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a21* copy of the source code appearing in this file ("Covered Code") an22* irrevocable, perpetual, worldwide license under Intel's copyrights in the23* base code distributed originally by Intel ("Original Intel Code") to copy,24* make derivatives, distribute, use and display any portion of the Covered25* Code in any form, with the right to sublicense such rights; and26*27* 2.3. Intel grants Licensee a non-exclusive and non-transferable patent28* license (with the right to sublicense), under only those claims of Intel29* patents that are infringed by the Original Intel Code, to make, use, sell,30* offer to sell, and import the Covered Code and derivative works thereof31* solely to the minimum extent necessary to exercise the above copyright32* license, and in no event shall the patent license extend to any additions33* to or modifications of the Original Intel Code. No other license or right34* is granted directly or by implication, estoppel or otherwise;35*36* The above copyright and patent license is granted only if the following37* conditions are met:38*39* 3. Conditions40*41* 3.1. Redistribution of Source with Rights to Further Distribute Source.42* Redistribution of source code of any substantial portion of the Covered43* Code or modification with rights to further distribute source must include44* the above Copyright Notice, the above License, this list of Conditions,45* and the following Disclaimer and Export Compliance provision. In addition,46* Licensee must cause all Covered Code to which Licensee contributes to47* contain a file documenting the changes Licensee made to create that Covered48* Code and the date of any change. Licensee must include in that file the49* documentation of any changes made by any predecessor Licensee. Licensee50* must include a prominent statement that the modification is derived,51* directly or indirectly, from Original Intel Code.52*53* 3.2. Redistribution of Source with no Rights to Further Distribute Source.54* Redistribution of source code of any substantial portion of the Covered55* Code or modification without rights to further distribute source must56* include the following Disclaimer and Export Compliance provision in the57* documentation and/or other materials provided with distribution. In58* addition, Licensee may not authorize further sublicense of source of any59* portion of the Covered Code, and must include terms to the effect that the60* license from Licensee to its licensee is limited to the intellectual61* property embodied in the software Licensee provides to its licensee, and62* not to intellectual property embodied in modifications its licensee may63* make.64*65* 3.3. Redistribution of Executable. Redistribution in executable form of any66* substantial portion of the Covered Code or modification must reproduce the67* above Copyright Notice, and the following Disclaimer and Export Compliance68* provision in the documentation and/or other materials provided with the69* distribution.70*71* 3.4. Intel retains all right, title, and interest in and to the Original72* Intel Code.73*74* 3.5. Neither the name Intel nor any other trademark owned or controlled by75* Intel shall be used in advertising or otherwise to promote the sale, use or76* other dealings in products derived from or relating to the Covered Code77* without prior written authorization from Intel.78*79* 4. Disclaimer and Export Compliance80*81* 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED82* HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE83* IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,84* INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY85* UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY86* IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A87* PARTICULAR PURPOSE.88*89* 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES90* OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR91* COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,92* SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY93* CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL94* HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS95* SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY96* LIMITED REMEDY.97*98* 4.3. Licensee shall not export, either directly or indirectly, any of this99* software or system incorporating such software without first obtaining any100* required license or other approval from the U. S. Department of Commerce or101* any other agency or department of the United States Government. In the102* event Licensee exports any such software from the United States or103* re-exports any such software from a foreign destination, Licensee shall104* ensure that the distribution and export/re-export of the software is in105* compliance with all laws, regulations, orders, or other restrictions of the106* U.S. Export Administration Regulations. Licensee agrees that neither it nor107* any of its subsidiaries will export/re-export any technical data, process,108* software, or service, directly or indirectly, to any country for which the109* United States government or any agency thereof requires an export license,110* other governmental approval, or letter of assurance, without first obtaining111* such license, approval or letter.112*113*****************************************************************************114*115* Alternatively, you may choose to be licensed under the terms of the116* following license:117*118* Redistribution and use in source and binary forms, with or without119* modification, are permitted provided that the following conditions120* are met:121* 1. Redistributions of source code must retain the above copyright122* notice, this list of conditions, and the following disclaimer,123* without modification.124* 2. Redistributions in binary form must reproduce at minimum a disclaimer125* substantially similar to the "NO WARRANTY" disclaimer below126* ("Disclaimer") and any redistribution must be conditioned upon127* including a substantially similar Disclaimer requirement for further128* binary redistribution.129* 3. Neither the names of the above-listed copyright holders nor the names130* of any contributors may be used to endorse or promote products derived131* from this software without specific prior written permission.132*133* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS134* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT135* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR136* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT137* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,138* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT139* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,140* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY141* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT142* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE143* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.144*145* Alternatively, you may choose to be licensed under the terms of the146* GNU General Public License ("GPL") version 2 as published by the Free147* Software Foundation.148*149*****************************************************************************/150151#include <contrib/dev/acpica/include/acpi.h>152#include <contrib/dev/acpica/include/accommon.h>153#include <contrib/dev/acpica/include/acparser.h>154#include <contrib/dev/acpica/include/amlcode.h>155#include <contrib/dev/acpica/include/acdebug.h>156#include <contrib/dev/acpica/include/acconvert.h>157158159#define _COMPONENT ACPI_CA_DEBUGGER160ACPI_MODULE_NAME ("dmwalk")161162163/* Stub for non-compiler code */164165#ifndef ACPI_ASL_COMPILER166void167AcpiDmEmitExternals (168void)169{170return;171}172173void174AcpiDmEmitExternal (175ACPI_PARSE_OBJECT *NameOp,176ACPI_PARSE_OBJECT *TypeOp)177{178return;179}180#endif181182/* Local prototypes */183184static ACPI_STATUS185AcpiDmDescendingOp (186ACPI_PARSE_OBJECT *Op,187UINT32 Level,188void *Context);189190static ACPI_STATUS191AcpiDmAscendingOp (192ACPI_PARSE_OBJECT *Op,193UINT32 Level,194void *Context);195196197/*******************************************************************************198*199* FUNCTION: AcpiDmDisassemble200*201* PARAMETERS: WalkState - Current state202* Origin - Starting object203* NumOpcodes - Max number of opcodes to be displayed204*205* RETURN: None206*207* DESCRIPTION: Disassemble parser object and its children. This is the208* main entry point of the disassembler.209*210******************************************************************************/211212void213AcpiDmDisassemble (214ACPI_WALK_STATE *WalkState,215ACPI_PARSE_OBJECT *Origin,216UINT32 NumOpcodes)217{218ACPI_PARSE_OBJECT *Op = Origin;219ACPI_OP_WALK_INFO Info;220221222if (!Op)223{224return;225}226227memset (&Info, 0, sizeof (ACPI_OP_WALK_INFO));228Info.WalkState = WalkState;229Info.StartAml = Op->Common.Aml - sizeof (ACPI_TABLE_HEADER);230Info.AmlOffset = Op->Common.Aml - Info.StartAml;231232AcpiDmWalkParseTree (Op, AcpiDmDescendingOp, AcpiDmAscendingOp, &Info);233return;234}235236237/*******************************************************************************238*239* FUNCTION: AcpiDmWalkParseTree240*241* PARAMETERS: Op - Root Op object242* DescendingCallback - Called during tree descent243* AscendingCallback - Called during tree ascent244* Context - To be passed to the callbacks245*246* RETURN: Status from callback(s)247*248* DESCRIPTION: Walk the entire parse tree.249*250******************************************************************************/251252void253AcpiDmWalkParseTree (254ACPI_PARSE_OBJECT *Op,255ASL_WALK_CALLBACK DescendingCallback,256ASL_WALK_CALLBACK AscendingCallback,257void *Context)258{259BOOLEAN NodePreviouslyVisited;260ACPI_PARSE_OBJECT *StartOp = Op;261ACPI_STATUS Status;262ACPI_PARSE_OBJECT *Next;263ACPI_OP_WALK_INFO *Info = Context;264265266Info->Level = 0;267NodePreviouslyVisited = FALSE;268269while (Op)270{271if (NodePreviouslyVisited)272{273if (AscendingCallback)274{275Status = AscendingCallback (Op, Info->Level, Context);276if (ACPI_FAILURE (Status))277{278return;279}280}281}282else283{284/* Let the callback process the node */285286Status = DescendingCallback (Op, Info->Level, Context);287if (ACPI_SUCCESS (Status))288{289/* Visit children first, once */290291Next = AcpiPsGetArg (Op, 0);292if (Next)293{294Info->Level++;295Op = Next;296continue;297}298}299else if (Status != AE_CTRL_DEPTH)300{301/* Exit immediately on any error */302303return;304}305}306307/* Terminate walk at start op */308309if (Op == StartOp)310{311break;312}313314/* No more children, re-visit this node */315316if (!NodePreviouslyVisited)317{318NodePreviouslyVisited = TRUE;319continue;320}321322/* No more children, visit peers */323324if (Op->Common.Next)325{326Op = Op->Common.Next;327NodePreviouslyVisited = FALSE;328}329else330{331/* No peers, re-visit parent */332333if (Info->Level != 0 )334{335Info->Level--;336}337338Op = Op->Common.Parent;339NodePreviouslyVisited = TRUE;340}341}342343/* If we get here, the walk completed with no errors */344345return;346}347348349/*******************************************************************************350*351* FUNCTION: AcpiDmBlockType352*353* PARAMETERS: Op - Object to be examined354*355* RETURN: BlockType - not a block, parens, braces, or even both.356*357* DESCRIPTION: Type of block for this op (parens or braces)358*359******************************************************************************/360361UINT32362AcpiDmBlockType (363ACPI_PARSE_OBJECT *Op)364{365const ACPI_OPCODE_INFO *OpInfo;366367368if (!Op)369{370return (BLOCK_NONE);371}372373switch (Op->Common.AmlOpcode)374{375case AML_ELSE_OP:376377return (BLOCK_BRACE);378379case AML_METHOD_OP:380case AML_DEVICE_OP:381case AML_SCOPE_OP:382case AML_PROCESSOR_OP:383case AML_POWER_RESOURCE_OP:384case AML_THERMAL_ZONE_OP:385case AML_IF_OP:386case AML_WHILE_OP:387case AML_FIELD_OP:388case AML_INDEX_FIELD_OP:389case AML_BANK_FIELD_OP:390391return (BLOCK_PAREN | BLOCK_BRACE);392393case AML_BUFFER_OP:394395if ((Op->Common.DisasmOpcode == ACPI_DASM_UNICODE) ||396(Op->Common.DisasmOpcode == ACPI_DASM_UUID) ||397(Op->Common.DisasmOpcode == ACPI_DASM_PLD_METHOD))398{399return (BLOCK_NONE);400}401402ACPI_FALLTHROUGH;403404case AML_PACKAGE_OP:405case AML_VARIABLE_PACKAGE_OP:406407return (BLOCK_PAREN | BLOCK_BRACE);408409case AML_EVENT_OP:410411return (BLOCK_PAREN);412413case AML_INT_METHODCALL_OP:414415if (Op->Common.Parent &&416((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) ||417(Op->Common.Parent->Common.AmlOpcode == AML_VARIABLE_PACKAGE_OP)))418{419/* This is a reference to a method, not an invocation */420421return (BLOCK_NONE);422}423424ACPI_FALLTHROUGH;425426default:427428OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);429if (OpInfo->Flags & AML_HAS_ARGS)430{431return (BLOCK_PAREN);432}433434return (BLOCK_NONE);435}436}437438439/*******************************************************************************440*441* FUNCTION: AcpiDmListType442*443* PARAMETERS: Op - Object to be examined444*445* RETURN: ListType - has commas or not.446*447* DESCRIPTION: Type of block for this op (parens or braces)448*449******************************************************************************/450451UINT32452AcpiDmListType (453ACPI_PARSE_OBJECT *Op)454{455const ACPI_OPCODE_INFO *OpInfo;456457458if (!Op)459{460return (BLOCK_NONE);461}462463switch (Op->Common.AmlOpcode)464{465466case AML_ELSE_OP:467case AML_METHOD_OP:468case AML_DEVICE_OP:469case AML_SCOPE_OP:470case AML_POWER_RESOURCE_OP:471case AML_PROCESSOR_OP:472case AML_THERMAL_ZONE_OP:473case AML_IF_OP:474case AML_WHILE_OP:475case AML_FIELD_OP:476case AML_INDEX_FIELD_OP:477case AML_BANK_FIELD_OP:478479return (BLOCK_NONE);480481case AML_BUFFER_OP:482case AML_PACKAGE_OP:483case AML_VARIABLE_PACKAGE_OP:484485return (BLOCK_COMMA_LIST);486487default:488489OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);490if (OpInfo->Flags & AML_HAS_ARGS)491{492return (BLOCK_COMMA_LIST);493}494495return (BLOCK_NONE);496}497}498499500/*******************************************************************************501*502* FUNCTION: AcpiDmDescendingOp503*504* PARAMETERS: ASL_WALK_CALLBACK505*506* RETURN: Status507*508* DESCRIPTION: First visitation of a parse object during tree descent.509* Decode opcode name and begin parameter list(s), if any.510*511******************************************************************************/512513static ACPI_STATUS514AcpiDmDescendingOp (515ACPI_PARSE_OBJECT *Op,516UINT32 Level,517void *Context)518{519ACPI_OP_WALK_INFO *Info = Context;520const ACPI_OPCODE_INFO *OpInfo;521UINT32 Name;522ACPI_PARSE_OBJECT *NextOp;523ACPI_PARSE_OBJECT *NextOp2;524UINT32 AmlOffset;525526527/* Determine which file this parse node is contained in. */528529if (AcpiGbl_CaptureComments)530{531ASL_CV_LABEL_FILENODE (Op);532533if (Level != 0 && ASL_CV_FILE_HAS_SWITCHED (Op))534{535ASL_CV_SWITCH_FILES (Level, Op);536}537538/* If this parse node has regular comments, print them here. */539540ASL_CV_PRINT_ONE_COMMENT (Op, AML_COMMENT_STANDARD, NULL, Level);541}542543OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);544545/* Listing support to dump the AML code after the ASL statement */546547if (AcpiGbl_DmOpt_Listing)548{549/* We only care about these classes of objects */550551if ((OpInfo->Class == AML_CLASS_NAMED_OBJECT) ||552(OpInfo->Class == AML_CLASS_CONTROL) ||553(OpInfo->Class == AML_CLASS_CREATE) ||554((OpInfo->Class == AML_CLASS_EXECUTE) && (!Op->Common.Next)))555{556if (AcpiGbl_DmOpt_Listing && Info->PreviousAml)557{558/* Dump the AML byte code for the previous Op */559560if (Op->Common.Aml > Info->PreviousAml)561{562AcpiOsPrintf ("\n");563AcpiUtDumpBuffer (564(Info->StartAml + Info->AmlOffset),565(Op->Common.Aml - Info->PreviousAml),566DB_BYTE_DISPLAY, Info->AmlOffset);567AcpiOsPrintf ("\n");568}569570Info->AmlOffset = (Op->Common.Aml - Info->StartAml);571}572573Info->PreviousAml = Op->Common.Aml;574}575}576577if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)578{579/* Ignore this op -- it was handled elsewhere */580581return (AE_CTRL_DEPTH);582}583584if (Op->Common.DisasmOpcode == ACPI_DASM_IGNORE_SINGLE)585{586/* Ignore this op, but not it's children */587588return (AE_OK);589}590591if (Op->Common.AmlOpcode == AML_IF_OP)592{593NextOp = AcpiPsGetDepthNext (NULL, Op);594if (NextOp)595{596NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;597598/* Don't emit the actual embedded externals unless asked */599600if (!AcpiGbl_DmEmitExternalOpcodes)601{602/*603* A Zero predicate indicates the possibility of one or more604* External() opcodes within the If() block.605*/606if (NextOp->Common.AmlOpcode == AML_ZERO_OP)607{608NextOp2 = NextOp->Common.Next;609610if (NextOp2 &&611(NextOp2->Common.AmlOpcode == AML_EXTERNAL_OP))612{613/* Ignore the If 0 block and all children */614615Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;616return (AE_CTRL_DEPTH);617}618}619}620}621}622623/* Level 0 is at the Definition Block level */624625if (Level == 0)626{627/* In verbose mode, print the AML offset, opcode and depth count */628629if (Info->WalkState)630{631AmlOffset = (UINT32) ACPI_PTR_DIFF (Op->Common.Aml,632Info->WalkState->ParserState.AmlStart);633if (AcpiGbl_DmOpt_Verbose)634{635if (AcpiGbl_CmSingleStep)636{637AcpiOsPrintf ("%5.5X/%4.4X: ",638AmlOffset, (UINT32) Op->Common.AmlOpcode);639}640else641{642AcpiOsPrintf ("AML Offset %5.5X, Opcode %4.4X: ",643AmlOffset, (UINT32) Op->Common.AmlOpcode);644}645}646}647648if (Op->Common.AmlOpcode == AML_SCOPE_OP)649{650/* This is the beginning of the Definition Block */651652AcpiOsPrintf ("{\n");653654/* Emit all External() declarations here */655656if (!AcpiGbl_DmEmitExternalOpcodes)657{658AcpiDmEmitExternals ();659}660661return (AE_OK);662}663}664else if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&665(!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST)) &&666(!(Op->Common.DisasmFlags & ACPI_PARSEOP_ELSEIF)) &&667(Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))668{669/*670* This is a first-level element of a term list,671* indent a new line672*/673switch (Op->Common.AmlOpcode)674{675case AML_NOOP_OP:676/*677* Optionally just ignore this opcode. Some tables use678* NoOp opcodes for "padding" out packages that the BIOS679* changes dynamically. This can leave hundreds or680* thousands of NoOp opcodes that if disassembled,681* cannot be compiled because they are syntactically682* incorrect.683*/684if (AcpiGbl_IgnoreNoopOperator)685{686Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;687return (AE_OK);688}689690ACPI_FALLTHROUGH;691692default:693694AcpiDmIndent (Level);695break;696}697698Info->LastLevel = Level;699Info->Count = 0;700}701702/*703* This is an inexpensive mechanism to try and keep lines from getting704* too long. When the limit is hit, start a new line at the previous705* indent plus one. A better but more expensive mechanism would be to706* keep track of the current column.707*/708Info->Count++;709if (Info->Count /* +Info->LastLevel */ > 12)710{711Info->Count = 0;712AcpiOsPrintf ("\n");713AcpiDmIndent (Info->LastLevel + 1);714}715716/* If ASL+ is enabled, check for a C-style operator */717718if (AcpiDmCheckForSymbolicOpcode (Op, Info))719{720return (AE_OK);721}722723/* Print the opcode name */724725AcpiDmDisassembleOneOp (NULL, Info, Op);726727if ((Op->Common.DisasmOpcode == ACPI_DASM_LNOT_PREFIX) ||728(Op->Common.AmlOpcode == AML_INT_CONNECTION_OP))729{730return (AE_OK);731}732733if ((Op->Common.AmlOpcode == AML_NAME_OP) ||734(Op->Common.AmlOpcode == AML_RETURN_OP))735{736Info->Level--;737}738739if (Op->Common.AmlOpcode == AML_EXTERNAL_OP)740{741Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;742return (AE_CTRL_DEPTH);743}744745/* Start the opcode argument list if necessary */746747if ((OpInfo->Flags & AML_HAS_ARGS) ||748(Op->Common.AmlOpcode == AML_EVENT_OP))749{750/* This opcode has an argument list */751752if (AcpiDmBlockType (Op) & BLOCK_PAREN)753{754AcpiOsPrintf (" (");755if (!(AcpiDmBlockType (Op) & BLOCK_BRACE))756{757ASL_CV_PRINT_ONE_COMMENT (Op, AMLCOMMENT_INLINE, " ", 0);758}759}760761/* If this is a named opcode, print the associated name value */762763if (OpInfo->Flags & AML_NAMED)764{765switch (Op->Common.AmlOpcode)766{767case AML_ALIAS_OP:768769NextOp = AcpiPsGetDepthNext (NULL, Op);770NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;771AcpiDmNamestring (NextOp->Common.Value.Name);772AcpiOsPrintf (", ");773774ACPI_FALLTHROUGH;775776default:777778Name = AcpiPsGetName (Op);779if (Op->Named.Path)780{781AcpiDmNamestring (Op->Named.Path);782}783else784{785AcpiDmDumpName (Name);786}787788if (Op->Common.AmlOpcode != AML_INT_NAMEDFIELD_OP)789{790if (AcpiGbl_DmOpt_Verbose)791{792(void) AcpiPsDisplayObjectPathname (NULL, Op);793}794}795break;796}797798switch (Op->Common.AmlOpcode)799{800case AML_METHOD_OP:801802AcpiDmMethodFlags (Op);803ASL_CV_CLOSE_PAREN (Op, Level);804805/* Emit description comment for Method() with a predefined ACPI name */806807AcpiDmPredefinedDescription (Op);808break;809810case AML_NAME_OP:811812/* Check for _HID and related EISAID() */813814AcpiDmCheckForHardwareId (Op);815AcpiOsPrintf (", ");816ASL_CV_PRINT_ONE_COMMENT (Op, AML_NAMECOMMENT, NULL, 0);817break;818819case AML_REGION_OP:820821AcpiDmRegionFlags (Op);822break;823824case AML_POWER_RESOURCE_OP:825826/* Mark the next two Ops as part of the parameter list */827828AcpiOsPrintf (", ");829NextOp = AcpiPsGetDepthNext (NULL, Op);830NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;831832NextOp = NextOp->Common.Next;833NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;834return (AE_OK);835836case AML_PROCESSOR_OP:837838/* Mark the next three Ops as part of the parameter list */839840AcpiOsPrintf (", ");841NextOp = AcpiPsGetDepthNext (NULL, Op);842NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;843844NextOp = NextOp->Common.Next;845NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;846847NextOp = NextOp->Common.Next;848NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;849return (AE_OK);850851case AML_MUTEX_OP:852case AML_DATA_REGION_OP:853854AcpiOsPrintf (", ");855return (AE_OK);856857case AML_EVENT_OP:858case AML_ALIAS_OP:859860return (AE_OK);861862case AML_SCOPE_OP:863case AML_DEVICE_OP:864case AML_THERMAL_ZONE_OP:865866ASL_CV_CLOSE_PAREN (Op, Level);867break;868869default:870871AcpiOsPrintf ("*** Unhandled named opcode %X\n",872Op->Common.AmlOpcode);873break;874}875}876877else switch (Op->Common.AmlOpcode)878{879case AML_FIELD_OP:880case AML_BANK_FIELD_OP:881case AML_INDEX_FIELD_OP:882883Info->BitOffset = 0;884885/* Name of the parent OperationRegion */886887NextOp = AcpiPsGetDepthNext (NULL, Op);888AcpiDmNamestring (NextOp->Common.Value.Name);889AcpiOsPrintf (", ");890NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;891892switch (Op->Common.AmlOpcode)893{894case AML_BANK_FIELD_OP:895896/* Namestring - Bank Name */897898NextOp = AcpiPsGetDepthNext (NULL, NextOp);899AcpiDmNamestring (NextOp->Common.Value.Name);900NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;901AcpiOsPrintf (", ");902903/*904* Bank Value. This is a TermArg in the middle of the parameter905* list, must handle it here.906*907* Disassemble the TermArg parse tree. ACPI_PARSEOP_PARAMETER_LIST908* eliminates newline in the output.909*/910NextOp = NextOp->Common.Next;911912Info->Flags = ACPI_PARSEOP_PARAMETER_LIST;913AcpiDmWalkParseTree (NextOp, AcpiDmDescendingOp,914AcpiDmAscendingOp, Info);915Info->Flags = 0;916Info->Level = Level;917918NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;919AcpiOsPrintf (", ");920break;921922case AML_INDEX_FIELD_OP:923924/* Namestring - Data Name */925926NextOp = AcpiPsGetDepthNext (NULL, NextOp);927AcpiDmNamestring (NextOp->Common.Value.Name);928AcpiOsPrintf (", ");929NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;930break;931932default:933934break;935}936937AcpiDmFieldFlags (NextOp);938break;939940case AML_BUFFER_OP:941942/* The next op is the size parameter */943944NextOp = AcpiPsGetDepthNext (NULL, Op);945if (!NextOp)946{947/* Single-step support */948949return (AE_OK);950}951952if (Op->Common.DisasmOpcode == ACPI_DASM_RESOURCE)953{954/*955* We have a resource list. Don't need to output956* the buffer size Op. Open up a new block957*/958NextOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;959ASL_CV_CLOSE_PAREN (Op, Level);960961if (Op->Asl.Parent->Common.AmlOpcode == AML_NAME_OP)962{963/*964* Emit description comment showing the full ACPI name965* of the ResourceTemplate only if it was defined using a966* Name statement.967*/968AcpiDmPredefinedDescription (Op->Asl.Parent);969}970971AcpiOsPrintf ("\n");972AcpiDmIndent (Info->Level);973AcpiOsPrintf ("{\n");974return (AE_OK);975}976977/* Normal Buffer, mark size as in the parameter list */978979NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;980return (AE_OK);981982case AML_IF_OP:983case AML_VARIABLE_PACKAGE_OP:984case AML_WHILE_OP:985986/* The next op is the size or predicate parameter */987988NextOp = AcpiPsGetDepthNext (NULL, Op);989if (NextOp)990{991NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;992}993return (AE_OK);994995case AML_PACKAGE_OP:996997/* The next op is the size parameter */998999NextOp = AcpiPsGetDepthNext (NULL, Op);1000if (NextOp)1001{1002NextOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;1003}1004return (AE_OK);10051006case AML_MATCH_OP:10071008AcpiDmMatchOp (Op);1009break;10101011default:10121013break;1014}10151016if (AcpiDmBlockType (Op) & BLOCK_BRACE)1017{1018AcpiOsPrintf ("\n");1019AcpiDmIndent (Level);1020AcpiOsPrintf ("{\n");1021}1022}10231024return (AE_OK);1025}102610271028/*******************************************************************************1029*1030* FUNCTION: AcpiDmAscendingOp1031*1032* PARAMETERS: ASL_WALK_CALLBACK1033*1034* RETURN: Status1035*1036* DESCRIPTION: Second visitation of a parse object, during ascent of parse1037* tree. Close out any parameter lists and complete the opcode.1038*1039******************************************************************************/10401041static ACPI_STATUS1042AcpiDmAscendingOp (1043ACPI_PARSE_OBJECT *Op,1044UINT32 Level,1045void *Context)1046{1047ACPI_OP_WALK_INFO *Info = Context;1048ACPI_PARSE_OBJECT *ParentOp;104910501051/* Point the Op's filename pointer to the proper file */10521053if (AcpiGbl_CaptureComments)1054{1055ASL_CV_LABEL_FILENODE (Op);10561057/* Switch the output of these files if necessary */10581059if (ASL_CV_FILE_HAS_SWITCHED (Op))1060{1061ASL_CV_SWITCH_FILES (Level, Op);1062}1063}10641065if (Op->Common.DisasmFlags & ACPI_PARSEOP_IGNORE ||1066Op->Common.DisasmOpcode == ACPI_DASM_IGNORE_SINGLE)1067{1068/* Ignore this op -- it was handled elsewhere */10691070return (AE_OK);1071}10721073if ((Level == 0) && (Op->Common.AmlOpcode == AML_SCOPE_OP))1074{1075/* Indicates the end of the current descriptor block (table) */10761077ASL_CV_CLOSE_BRACE (Op, Level);10781079/* Print any comments that are at the end of the file here */10801081if (AcpiGbl_CaptureComments && AcpiGbl_LastListHead)1082{1083AcpiOsPrintf ("\n");1084ASL_CV_PRINT_ONE_COMMENT_LIST (AcpiGbl_LastListHead, 0);1085}1086AcpiOsPrintf ("\n\n");10871088return (AE_OK);1089}10901091switch (AcpiDmBlockType (Op))1092{1093case BLOCK_PAREN:10941095/* Completed an op that has arguments, add closing paren if needed */10961097AcpiDmCloseOperator (Op);10981099if (Op->Common.AmlOpcode == AML_NAME_OP)1100{1101/* Emit description comment for Name() with a predefined ACPI name */11021103AcpiDmPredefinedDescription (Op);1104}1105else1106{1107/* For Create* operators, attempt to emit resource tag description */11081109AcpiDmFieldPredefinedDescription (Op);1110}11111112/* Decode Notify() values */11131114if (Op->Common.AmlOpcode == AML_NOTIFY_OP)1115{1116AcpiDmNotifyDescription (Op);1117}11181119AcpiDmDisplayTargetPathname (Op);11201121/* Could be a nested operator, check if comma required */11221123if (!AcpiDmCommaIfListMember (Op))1124{1125if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&1126(!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST)) &&1127(Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))1128{1129/*1130* This is a first-level element of a term list1131* start a new line1132*/1133if (!(Info->Flags & ACPI_PARSEOP_PARAMETER_LIST))1134{1135AcpiOsPrintf ("\n");1136}1137}1138}1139break;11401141case BLOCK_BRACE:1142case (BLOCK_BRACE | BLOCK_PAREN):11431144/* Completed an op that has a term list, add closing brace */11451146if (Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST)1147{1148ASL_CV_CLOSE_BRACE (Op, Level);1149}1150else1151{1152AcpiDmIndent (Level);1153ASL_CV_CLOSE_BRACE (Op, Level);1154}11551156AcpiDmCommaIfListMember (Op);11571158if (AcpiDmBlockType (Op->Common.Parent) != BLOCK_PAREN)1159{1160AcpiOsPrintf ("\n");1161if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_EMPTY_TERMLIST))1162{1163if ((Op->Common.AmlOpcode == AML_IF_OP) &&1164(Op->Common.Next) &&1165(Op->Common.Next->Common.AmlOpcode == AML_ELSE_OP))1166{1167break;1168}11691170if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&1171(!Op->Common.Next))1172{1173break;1174}1175AcpiOsPrintf ("\n");1176}1177}1178break;11791180case BLOCK_NONE:1181default:11821183/* Could be a nested operator, check if comma required */11841185if (!AcpiDmCommaIfListMember (Op))1186{1187if ((AcpiDmBlockType (Op->Common.Parent) & BLOCK_BRACE) &&1188(!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST)) &&1189(Op->Common.AmlOpcode != AML_INT_BYTELIST_OP))1190{1191/*1192* This is a first-level element of a term list1193* start a new line1194*/1195AcpiOsPrintf ("\n");1196}1197}1198else if (Op->Common.Parent)1199{1200switch (Op->Common.Parent->Common.AmlOpcode)1201{1202case AML_PACKAGE_OP:1203case AML_VARIABLE_PACKAGE_OP:12041205if (!(Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST))1206{1207AcpiOsPrintf ("\n");1208}1209break;12101211default:12121213break;1214}1215}1216break;1217}12181219if (Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST)1220{1221if ((Op->Common.Next) &&1222(Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST))1223{1224return (AE_OK);1225}12261227/*1228* The parent Op is guaranteed to be valid because of the flag1229* ACPI_PARSEOP_PARAMETER_LIST -- which means that this op is part of1230* a parameter list and thus has a valid parent.1231*/1232ParentOp = Op->Common.Parent;12331234/*1235* Just completed a parameter node for something like "Buffer (param)".1236* Close the paren and open up the term list block with a brace.1237*1238* Switch predicates don't have a Next node but require a closing paren1239* and opening brace.1240*/1241if (Op->Common.Next || Op->Common.DisasmOpcode == ACPI_DASM_SWITCH_PREDICATE)1242{1243ASL_CV_CLOSE_PAREN (Op, Level);12441245/*1246* Emit a description comment for a Name() operator that is a1247* predefined ACPI name. Must check the grandparent.1248*/1249ParentOp = ParentOp->Common.Parent;1250if (ParentOp &&1251(ParentOp->Asl.AmlOpcode == AML_NAME_OP))1252{1253AcpiDmPredefinedDescription (ParentOp);1254}12551256/* Correct the indentation level for Switch and Case predicates */12571258if (Op->Common.DisasmOpcode == ACPI_DASM_SWITCH_PREDICATE)1259{1260--Level;1261}12621263AcpiOsPrintf ("\n");1264AcpiDmIndent (Level - 1);1265AcpiOsPrintf ("{\n");1266}1267else1268{1269ParentOp->Common.DisasmFlags |= ACPI_PARSEOP_EMPTY_TERMLIST;1270ASL_CV_CLOSE_PAREN (Op, Level);1271AcpiOsPrintf ("{");1272}1273}12741275if ((Op->Common.AmlOpcode == AML_NAME_OP) ||1276(Op->Common.AmlOpcode == AML_RETURN_OP))1277{1278Info->Level++;1279}12801281/*1282* For ASL+, check for and emit a C-style symbol. If valid, the1283* symbol string has been deferred until after the first operand1284*/1285if (AcpiGbl_CstyleDisassembly)1286{1287if (Op->Asl.OperatorSymbol)1288{1289AcpiOsPrintf ("%s", Op->Asl.OperatorSymbol);1290Op->Asl.OperatorSymbol = NULL;1291}1292}12931294return (AE_OK);1295}129612971298