Path: blob/main/sys/contrib/dev/acpica/components/disassembler/dmopcode.c
48524 views
/*******************************************************************************1*2* Module Name: dmopcode - AML disassembler, specific AML opcodes3*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/acinterp.h>156#include <contrib/dev/acpica/include/acnamesp.h>157#include <contrib/dev/acpica/include/acdebug.h>158#include <contrib/dev/acpica/include/acconvert.h>159160161#define _COMPONENT ACPI_CA_DEBUGGER162ACPI_MODULE_NAME ("dmopcode")163164165/* Local prototypes */166167static void168AcpiDmMatchKeyword (169ACPI_PARSE_OBJECT *Op);170171static void172AcpiDmConvertToElseIf (173ACPI_PARSE_OBJECT *Op);174175static void176AcpiDmPromoteSubtree (177ACPI_PARSE_OBJECT *StartOp);178179/*******************************************************************************180*181* FUNCTION: AcpiDmDisplayTargetPathname182*183* PARAMETERS: Op - Parse object184*185* RETURN: None186*187* DESCRIPTION: For AML opcodes that have a target operand, display the full188* pathname for the target, in a comment field. Handles Return()189* statements also.190*191******************************************************************************/192193void194AcpiDmDisplayTargetPathname (195ACPI_PARSE_OBJECT *Op)196{197ACPI_PARSE_OBJECT *NextOp;198ACPI_PARSE_OBJECT *PrevOp = NULL;199char *Pathname;200const ACPI_OPCODE_INFO *OpInfo;201202203if (Op->Common.AmlOpcode == AML_RETURN_OP)204{205PrevOp = Op->Asl.Value.Arg;206}207else208{209OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);210if (!(OpInfo->Flags & AML_HAS_TARGET))211{212return;213}214215/* Target is the last Op in the arg list */216217NextOp = Op->Asl.Value.Arg;218while (NextOp)219{220PrevOp = NextOp;221NextOp = PrevOp->Asl.Next;222}223}224225if (!PrevOp)226{227return;228}229230/* We must have a namepath AML opcode */231232if (PrevOp->Asl.AmlOpcode != AML_INT_NAMEPATH_OP)233{234return;235}236237/* A null string is the "no target specified" case */238239if (!PrevOp->Asl.Value.String)240{241return;242}243244/* No node means "unresolved external reference" */245246if (!PrevOp->Asl.Node)247{248AcpiOsPrintf (" /* External reference */");249return;250}251252/* Ignore if path is already from the root */253254if (*PrevOp->Asl.Value.String == '\\')255{256return;257}258259/* Now: we can get the full pathname */260261Pathname = AcpiNsGetExternalPathname (PrevOp->Asl.Node);262if (!Pathname)263{264return;265}266267AcpiOsPrintf (" /* %s */", Pathname);268ACPI_FREE (Pathname);269}270271272/*******************************************************************************273*274* FUNCTION: AcpiDmNotifyDescription275*276* PARAMETERS: Op - Name() parse object277*278* RETURN: None279*280* DESCRIPTION: Emit a description comment for the value associated with a281* Notify() operator.282*283******************************************************************************/284285void286AcpiDmNotifyDescription (287ACPI_PARSE_OBJECT *Op)288{289ACPI_PARSE_OBJECT *NextOp;290ACPI_NAMESPACE_NODE *Node;291UINT8 NotifyValue;292UINT8 Type = ACPI_TYPE_ANY;293294295/* The notify value is the second argument */296297NextOp = Op->Asl.Value.Arg;298NextOp = NextOp->Asl.Next;299300switch (NextOp->Common.AmlOpcode)301{302case AML_ZERO_OP:303case AML_ONE_OP:304305NotifyValue = (UINT8) NextOp->Common.AmlOpcode;306break;307308case AML_BYTE_OP:309310NotifyValue = (UINT8) NextOp->Asl.Value.Integer;311break;312313default:314return;315}316317/*318* Attempt to get the namespace node so we can determine the object type.319* Some notify values are dependent on the object type (Device, Thermal,320* or Processor).321*/322Node = Op->Asl.Node;323if (Node)324{325Type = Node->Type;326}327328AcpiOsPrintf (" // %s", AcpiUtGetNotifyName (NotifyValue, Type));329}330331332/*******************************************************************************333*334* FUNCTION: AcpiDmPredefinedDescription335*336* PARAMETERS: Op - Name() parse object337*338* RETURN: None339*340* DESCRIPTION: Emit a description comment for a predefined ACPI name.341* Used for iASL compiler only.342*343******************************************************************************/344345void346AcpiDmPredefinedDescription (347ACPI_PARSE_OBJECT *Op)348{349#ifdef ACPI_ASL_COMPILER350const AH_PREDEFINED_NAME *Info;351char *NameString;352int LastCharIsDigit;353int LastCharsAreHex;354355356if (!Op)357{358return;359}360361/* Ensure that the comment field is emitted only once */362363if (Op->Common.DisasmFlags & ACPI_PARSEOP_PREDEFINED_CHECKED)364{365return;366}367Op->Common.DisasmFlags |= ACPI_PARSEOP_PREDEFINED_CHECKED;368369/* Predefined name must start with an underscore */370371NameString = ACPI_CAST_PTR (char, &Op->Named.Name);372if (NameString[0] != '_')373{374return;375}376377/*378* Check for the special ACPI names:379* _ACd, _ALd, _EJd, _Exx, _Lxx, _Qxx, _Wxx, _T_a380* (where d=decimal_digit, x=hex_digit, a=anything)381*382* Convert these to the generic name for table lookup.383* Note: NameString is guaranteed to be upper case here.384*/385LastCharIsDigit =386(isdigit ((int) NameString[3])); /* d */387LastCharsAreHex =388(isxdigit ((int) NameString[2]) && /* xx */389isxdigit ((int) NameString[3]));390391switch (NameString[1])392{393case 'A':394395if ((NameString[2] == 'C') && (LastCharIsDigit))396{397NameString = "_ACx";398}399else if ((NameString[2] == 'L') && (LastCharIsDigit))400{401NameString = "_ALx";402}403break;404405case 'E':406407if ((NameString[2] == 'J') && (LastCharIsDigit))408{409NameString = "_EJx";410}411else if (LastCharsAreHex)412{413NameString = "_Exx";414}415break;416417case 'L':418419if (LastCharsAreHex)420{421NameString = "_Lxx";422}423break;424425case 'Q':426427if (LastCharsAreHex)428{429NameString = "_Qxx";430}431break;432433case 'T':434435if (NameString[2] == '_')436{437NameString = "_T_x";438}439break;440441case 'W':442443if (LastCharsAreHex)444{445NameString = "_Wxx";446}447break;448449default:450451break;452}453454/* Match the name in the info table */455456Info = AcpiAhMatchPredefinedName (NameString);457if (Info)458{459AcpiOsPrintf (" // %4.4s: %s",460NameString, ACPI_CAST_PTR (char, Info->Description));461}462463#endif464return;465}466467468/*******************************************************************************469*470* FUNCTION: AcpiDmFieldPredefinedDescription471*472* PARAMETERS: Op - Parse object473*474* RETURN: None475*476* DESCRIPTION: Emit a description comment for a resource descriptor tag477* (which is a predefined ACPI name.) Used for iASL compiler only.478*479******************************************************************************/480481void482AcpiDmFieldPredefinedDescription (483ACPI_PARSE_OBJECT *Op)484{485#ifdef ACPI_ASL_COMPILER486ACPI_PARSE_OBJECT *IndexOp;487char *Tag;488const ACPI_OPCODE_INFO *OpInfo;489const AH_PREDEFINED_NAME *Info;490491492if (!Op)493{494return;495}496497/* Ensure that the comment field is emitted only once */498499if (Op->Common.DisasmFlags & ACPI_PARSEOP_PREDEFINED_CHECKED)500{501return;502}503Op->Common.DisasmFlags |= ACPI_PARSEOP_PREDEFINED_CHECKED;504505/*506* Op must be one of the Create* operators: CreateField, CreateBitField,507* CreateByteField, CreateWordField, CreateDwordField, CreateQwordField508*/509OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);510if (!(OpInfo->Flags & AML_CREATE))511{512return;513}514515/* Second argument is the Index argument */516517IndexOp = Op->Common.Value.Arg;518IndexOp = IndexOp->Common.Next;519520/* Index argument must be a namepath */521522if (IndexOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP)523{524return;525}526527/* Major cheat: We previously put the Tag ptr in the Node field */528529Tag = ACPI_CAST_PTR (char, IndexOp->Common.Node);530if (!Tag || (*Tag == 0))531{532return;533}534535/* Is the tag a predefined name? */536537Info = AcpiAhMatchPredefinedName (Tag);538if (!Info)539{540/* Not a predefined name (does not start with underscore) */541542return;543}544545AcpiOsPrintf (" // %4.4s: %s", Tag,546ACPI_CAST_PTR (char, Info->Description));547548/* String contains the prefix path, free it */549550ACPI_FREE (IndexOp->Common.Value.String);551IndexOp->Common.Value.String = NULL;552#endif553554return;555}556557558/*******************************************************************************559*560* FUNCTION: AcpiDmMethodFlags561*562* PARAMETERS: Op - Method Object to be examined563*564* RETURN: None565*566* DESCRIPTION: Decode control method flags567*568******************************************************************************/569570void571AcpiDmMethodFlags (572ACPI_PARSE_OBJECT *Op)573{574UINT32 Flags;575UINT32 Args;576577578/* The next Op contains the flags */579580Op = AcpiPsGetDepthNext (NULL, Op);581Flags = (UINT8) Op->Common.Value.Integer;582Args = Flags & 0x07;583584/* Mark the Op as completed */585586Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;587588/* 1) Method argument count */589590AcpiOsPrintf (", %u, ", Args);591592/* 2) Serialize rule */593594if (!(Flags & 0x08))595{596AcpiOsPrintf ("Not");597}598599AcpiOsPrintf ("Serialized");600601/* 3) SyncLevel */602603if (Flags & 0xF0)604{605AcpiOsPrintf (", %u", Flags >> 4);606}607}608609610/*******************************************************************************611*612* FUNCTION: AcpiDmFieldFlags613*614* PARAMETERS: Op - Field Object to be examined615*616* RETURN: None617*618* DESCRIPTION: Decode Field definition flags619*620******************************************************************************/621622void623AcpiDmFieldFlags (624ACPI_PARSE_OBJECT *Op)625{626UINT32 Flags;627628629Op = Op->Common.Next;630Flags = (UINT8) Op->Common.Value.Integer;631632/* Mark the Op as completed */633634Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;635636AcpiOsPrintf ("%s, ", AcpiGbl_AccessTypes [Flags & 0x07]);637AcpiOsPrintf ("%s, ", AcpiGbl_LockRule [(Flags & 0x10) >> 4]);638AcpiOsPrintf ("%s)", AcpiGbl_UpdateRules [(Flags & 0x60) >> 5]);639}640641642/*******************************************************************************643*644* FUNCTION: AcpiDmAddressSpace645*646* PARAMETERS: SpaceId - ID to be translated647*648* RETURN: None649*650* DESCRIPTION: Decode a SpaceId to an AddressSpaceKeyword651*652******************************************************************************/653654void655AcpiDmAddressSpace (656UINT8 SpaceId)657{658659if (SpaceId >= ACPI_NUM_PREDEFINED_REGIONS)660{661if (SpaceId == 0x7F)662{663AcpiOsPrintf ("FFixedHW, ");664}665else666{667AcpiOsPrintf ("0x%.2X, ", SpaceId);668}669}670else671{672AcpiOsPrintf ("%s, ", AcpiGbl_RegionTypes [SpaceId]);673}674}675676677/*******************************************************************************678*679* FUNCTION: AcpiDmRegionFlags680*681* PARAMETERS: Op - Object to be examined682*683* RETURN: None684*685* DESCRIPTION: Decode OperationRegion flags686*687******************************************************************************/688689void690AcpiDmRegionFlags (691ACPI_PARSE_OBJECT *Op)692{693694/* The next Op contains the SpaceId */695696Op = AcpiPsGetDepthNext (NULL, Op);697698/* Mark the Op as completed */699700Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;701702AcpiOsPrintf (", ");703AcpiDmAddressSpace ((UINT8) Op->Common.Value.Integer);704}705706707/*******************************************************************************708*709* FUNCTION: AcpiDmMatchOp710*711* PARAMETERS: Op - Match Object to be examined712*713* RETURN: None714*715* DESCRIPTION: Decode Match opcode operands716*717******************************************************************************/718719void720AcpiDmMatchOp (721ACPI_PARSE_OBJECT *Op)722{723ACPI_PARSE_OBJECT *NextOp;724725726NextOp = AcpiPsGetDepthNext (NULL, Op);727NextOp = NextOp->Common.Next;728729if (!NextOp)730{731/* Handle partial tree during single-step */732733return;734}735736/* Mark the two nodes that contain the encoding for the match keywords */737738NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;739740NextOp = NextOp->Common.Next;741NextOp = NextOp->Common.Next;742NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;743}744745746/*******************************************************************************747*748* FUNCTION: AcpiDmMatchKeyword749*750* PARAMETERS: Op - Match Object to be examined751*752* RETURN: None753*754* DESCRIPTION: Decode Match opcode operands755*756******************************************************************************/757758static void759AcpiDmMatchKeyword (760ACPI_PARSE_OBJECT *Op)761{762763if (((UINT32) Op->Common.Value.Integer) > ACPI_MAX_MATCH_OPCODE)764{765AcpiOsPrintf ("/* Unknown Match Keyword encoding */");766}767else768{769AcpiOsPrintf ("%s",770AcpiGbl_MatchOps[(ACPI_SIZE) Op->Common.Value.Integer]);771}772}773774775/*******************************************************************************776*777* FUNCTION: AcpiDmDisassembleOneOp778*779* PARAMETERS: WalkState - Current walk info780* Info - Parse tree walk info781* Op - Op that is to be printed782*783* RETURN: None784*785* DESCRIPTION: Disassemble a single AML opcode786*787******************************************************************************/788789void790AcpiDmDisassembleOneOp (791ACPI_WALK_STATE *WalkState,792ACPI_OP_WALK_INFO *Info,793ACPI_PARSE_OBJECT *Op)794{795const ACPI_OPCODE_INFO *OpInfo = NULL;796UINT32 Offset;797UINT32 Length;798ACPI_PARSE_OBJECT *Child;799ACPI_STATUS Status;800UINT8 *Aml;801const AH_DEVICE_ID *IdInfo;802803804if (!Op)805{806AcpiOsPrintf ("<NULL OP PTR>");807return;808}809810if (Op->Common.DisasmFlags & ACPI_PARSEOP_ELSEIF)811{812return; /* ElseIf macro was already emitted */813}814815switch (Op->Common.DisasmOpcode)816{817case ACPI_DASM_MATCHOP:818819AcpiDmMatchKeyword (Op);820return;821822case ACPI_DASM_LNOT_SUFFIX:823824if (!AcpiGbl_CstyleDisassembly)825{826switch (Op->Common.AmlOpcode)827{828case AML_LOGICAL_EQUAL_OP:829AcpiOsPrintf ("LNotEqual");830break;831832case AML_LOGICAL_GREATER_OP:833AcpiOsPrintf ("LLessEqual");834break;835836case AML_LOGICAL_LESS_OP:837AcpiOsPrintf ("LGreaterEqual");838break;839840default:841break;842}843}844845Op->Common.DisasmOpcode = 0;846Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;847return;848849default:850break;851}852853OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);854855/* The op and arguments */856857switch (Op->Common.AmlOpcode)858{859case AML_LOGICAL_NOT_OP:860861Child = Op->Common.Value.Arg;862if ((Child->Common.AmlOpcode == AML_LOGICAL_EQUAL_OP) ||863(Child->Common.AmlOpcode == AML_LOGICAL_GREATER_OP) ||864(Child->Common.AmlOpcode == AML_LOGICAL_LESS_OP))865{866Child->Common.DisasmOpcode = ACPI_DASM_LNOT_SUFFIX;867Op->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;868}869else870{871AcpiOsPrintf ("%s", OpInfo->Name);872}873break;874875case AML_BYTE_OP:876877AcpiOsPrintf ("0x%2.2X", (UINT32) Op->Common.Value.Integer);878break;879880case AML_WORD_OP:881882if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)883{884AcpiDmDecompressEisaId ((UINT32) Op->Common.Value.Integer);885}886else887{888AcpiOsPrintf ("0x%4.4X", (UINT32) Op->Common.Value.Integer);889}890break;891892case AML_DWORD_OP:893894if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)895{896AcpiDmDecompressEisaId ((UINT32) Op->Common.Value.Integer);897}898else899{900AcpiOsPrintf ("0x%8.8X", (UINT32) Op->Common.Value.Integer);901}902break;903904case AML_QWORD_OP:905906AcpiOsPrintf ("0x%8.8X%8.8X",907ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));908break;909910case AML_STRING_OP:911912AcpiUtPrintString (Op->Common.Value.String, ACPI_UINT16_MAX);913914/* For _HID/_CID strings, attempt to output a descriptive comment */915916if (Op->Common.DisasmOpcode == ACPI_DASM_HID_STRING)917{918/* If we know about the ID, emit the description */919920IdInfo = AcpiAhMatchHardwareId (Op->Common.Value.String);921if (IdInfo)922{923AcpiOsPrintf (" /* %s */", IdInfo->Description);924}925}926break;927928case AML_BUFFER_OP:929/*930* Determine the type of buffer. We can have one of the following:931*932* 1) ResourceTemplate containing Resource Descriptors.933* 2) Unicode String buffer934* 3) ASCII String buffer935* 4) Raw data buffer (if none of the above)936*937* Since there are no special AML opcodes to differentiate these938* types of buffers, we have to closely look at the data in the939* buffer to determine the type.940*/941if (!AcpiGbl_NoResourceDisassembly)942{943Status = AcpiDmIsResourceTemplate (WalkState, Op);944if (ACPI_SUCCESS (Status))945{946Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;947AcpiOsPrintf ("ResourceTemplate");948break;949}950else if (Status == AE_AML_NO_RESOURCE_END_TAG)951{952AcpiOsPrintf (953"/**** Is ResourceTemplate, "954"but EndTag not at buffer end ****/ ");955}956}957958if (AcpiDmIsUuidBuffer (Op))959{960Op->Common.DisasmOpcode = ACPI_DASM_UUID;961AcpiOsPrintf ("ToUUID (");962}963else if (AcpiDmIsUnicodeBuffer (Op))964{965Op->Common.DisasmOpcode = ACPI_DASM_UNICODE;966AcpiOsPrintf ("Unicode (");967}968else if (AcpiDmIsStringBuffer (Op))969{970Op->Common.DisasmOpcode = ACPI_DASM_STRING;971AcpiOsPrintf ("Buffer");972}973else if (AcpiDmIsPldBuffer (Op))974{975Op->Common.DisasmOpcode = ACPI_DASM_PLD_METHOD;976AcpiOsPrintf ("ToPLD (");977}978else979{980Op->Common.DisasmOpcode = ACPI_DASM_BUFFER;981AcpiOsPrintf ("Buffer");982}983break;984985case AML_INT_NAMEPATH_OP:986987AcpiDmNamestring (Op->Common.Value.Name);988break;989990case AML_INT_NAMEDFIELD_OP:991992Length = AcpiDmDumpName (Op->Named.Name);993994AcpiOsPrintf (",");995ASL_CV_PRINT_ONE_COMMENT (Op, AML_NAMECOMMENT, NULL, 0);996AcpiOsPrintf ("%*.s %u", (unsigned) (5 - Length), " ",997(UINT32) Op->Common.Value.Integer);998999AcpiDmCommaIfFieldMember (Op);10001001Info->BitOffset += (UINT32) Op->Common.Value.Integer;1002break;10031004case AML_INT_RESERVEDFIELD_OP:10051006/* Offset() -- Must account for previous offsets */10071008Offset = (UINT32) Op->Common.Value.Integer;1009Info->BitOffset += Offset;10101011if (Info->BitOffset % 8 == 0)1012{1013AcpiOsPrintf ("Offset (0x%.2X)", ACPI_DIV_8 (Info->BitOffset));1014}1015else1016{1017AcpiOsPrintf (" , %u", Offset);1018}10191020AcpiDmCommaIfFieldMember (Op);1021break;10221023case AML_INT_ACCESSFIELD_OP:1024case AML_INT_EXTACCESSFIELD_OP:10251026AcpiOsPrintf ("AccessAs (%s, ",1027AcpiGbl_AccessTypes [(UINT32) (Op->Common.Value.Integer & 0x7)]);10281029AcpiDmDecodeAttribute ((UINT8) (Op->Common.Value.Integer >> 8));10301031if (Op->Common.AmlOpcode == AML_INT_EXTACCESSFIELD_OP)1032{1033AcpiOsPrintf (" (0x%2.2X)", (unsigned)1034((Op->Common.Value.Integer >> 16) & 0xFF));1035}10361037AcpiOsPrintf (")");1038AcpiDmCommaIfFieldMember (Op);1039ASL_CV_PRINT_ONE_COMMENT (Op, AML_COMMENT_END_NODE, NULL, 0);1040break;10411042case AML_INT_CONNECTION_OP:1043/*1044* Two types of Connection() - one with a buffer object, the1045* other with a namestring that points to a buffer object.1046*/1047AcpiOsPrintf ("Connection (");1048Child = Op->Common.Value.Arg;10491050if (Child->Common.AmlOpcode == AML_INT_BYTELIST_OP)1051{1052AcpiOsPrintf ("\n");10531054Aml = Child->Named.Data;1055Length = (UINT32) Child->Common.Value.Integer;10561057Info->Level += 1;1058Info->MappingOp = Op;1059Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;10601061AcpiDmResourceTemplate (Info, Op->Common.Parent, Aml, Length);10621063Info->Level -= 1;1064AcpiDmIndent (Info->Level);1065}1066else1067{1068AcpiDmNamestring (Child->Common.Value.Name);1069}10701071AcpiOsPrintf (")");1072AcpiDmCommaIfFieldMember (Op);1073ASL_CV_PRINT_ONE_COMMENT (Op, AML_COMMENT_END_NODE, NULL, 0);1074ASL_CV_PRINT_ONE_COMMENT (Op, AMLCOMMENT_INLINE, NULL, 0);1075AcpiOsPrintf ("\n");10761077Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; /* for now, ignore in AcpiDmAscendingOp */1078Child->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;1079break;10801081case AML_INT_BYTELIST_OP:10821083AcpiDmByteList (Info, Op);1084break;10851086case AML_INT_METHODCALL_OP:10871088Op = AcpiPsGetDepthNext (NULL, Op);1089Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;10901091AcpiDmNamestring (Op->Common.Value.Name);1092break;10931094case AML_WHILE_OP:10951096if (Op->Common.DisasmOpcode == ACPI_DASM_SWITCH)1097{1098AcpiOsPrintf ("%s", "Switch");1099break;1100}11011102AcpiOsPrintf ("%s", OpInfo->Name);1103break;11041105case AML_IF_OP:11061107if (Op->Common.DisasmOpcode == ACPI_DASM_CASE)1108{1109AcpiOsPrintf ("%s", "Case");1110break;1111}11121113AcpiOsPrintf ("%s", OpInfo->Name);1114break;11151116case AML_ELSE_OP:11171118AcpiDmConvertToElseIf (Op);1119break;11201121case AML_EXTERNAL_OP:11221123if (AcpiGbl_DmEmitExternalOpcodes)1124{1125AcpiDmEmitExternal (Op, AcpiPsGetArg(Op, 0));1126}11271128break;11291130default:11311132/* Just get the opcode name and print it */11331134AcpiOsPrintf ("%s", OpInfo->Name);113511361137#ifdef ACPI_DEBUGGER11381139if ((Op->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP) &&1140(WalkState) &&1141(WalkState->Results) &&1142(WalkState->ResultCount))1143{1144AcpiDbDecodeInternalObject (1145WalkState->Results->Results.ObjDesc [1146(WalkState->ResultCount - 1) %1147ACPI_RESULTS_FRAME_OBJ_NUM]);1148}1149#endif11501151break;1152}1153}115411551156/*******************************************************************************1157*1158* FUNCTION: AcpiDmConvertToElseIf1159*1160* PARAMETERS: OriginalElseOp - ELSE Object to be examined1161*1162* RETURN: None. Emits either an "Else" or an "ElseIf" ASL operator.1163*1164* DESCRIPTION: Detect and convert an If..Else..If sequence to If..ElseIf1165*1166* EXAMPLE:1167*1168* This If..Else..If nested sequence:1169*1170* If (Arg0 == 1)1171* {1172* Local0 = 41173* }1174* Else1175* {1176* If (Arg0 == 2)1177* {1178* Local0 = 51179* }1180* }1181*1182* Is converted to this simpler If..ElseIf sequence:1183*1184* If (Arg0 == 1)1185* {1186* Local0 = 41187* }1188* ElseIf (Arg0 == 2)1189* {1190* Local0 = 51191* }1192*1193* NOTE: There is no actual ElseIf AML opcode. ElseIf is essentially an ASL1194* macro that emits an Else opcode followed by an If opcode. This function1195* reverses these AML sequences back to an ElseIf macro where possible. This1196* can make the disassembled ASL code simpler and more like the original code.1197*1198******************************************************************************/11991200static void1201AcpiDmConvertToElseIf (1202ACPI_PARSE_OBJECT *OriginalElseOp)1203{1204ACPI_PARSE_OBJECT *IfOp;1205ACPI_PARSE_OBJECT *ElseOp;120612071208/*1209* To be able to perform the conversion, two conditions must be satisfied:1210* 1) The first child of the Else must be an If statement.1211* 2) The If block can only be followed by an Else block and these must1212* be the only blocks under the original Else.1213*/1214IfOp = OriginalElseOp->Common.Value.Arg;12151216if (!IfOp ||1217(IfOp->Common.AmlOpcode != AML_IF_OP) ||1218(IfOp->Asl.Next && (IfOp->Asl.Next->Common.AmlOpcode != AML_ELSE_OP)))1219{1220/* Not a proper Else..If sequence, cannot convert to ElseIf */12211222if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_DEFAULT)1223{1224AcpiOsPrintf ("%s", "Default");1225return;1226}12271228AcpiOsPrintf ("%s", "Else");1229return;1230}12311232/* Cannot have anything following the If...Else block */12331234ElseOp = IfOp->Common.Next;1235if (ElseOp && ElseOp->Common.Next)1236{1237if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_DEFAULT)1238{1239AcpiOsPrintf ("%s", "Default");1240return;1241}12421243AcpiOsPrintf ("%s", "Else");1244return;1245}12461247if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_DEFAULT)1248{1249/*1250* There is an ElseIf but in this case the Else is actually1251* a Default block for a Switch/Case statement. No conversion.1252*/1253AcpiOsPrintf ("%s", "Default");1254return;1255}12561257if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_CASE)1258{1259/*1260* This ElseIf is actually a Case block for a Switch/Case1261* statement. Print Case but do not return so that we can1262* promote the subtree and keep the indentation level.1263*/1264AcpiOsPrintf ("%s", "Case");1265}1266else1267{1268/* Emit ElseIf, mark the IF as now an ELSEIF */12691270AcpiOsPrintf ("%s", "ElseIf");1271}12721273IfOp->Common.DisasmFlags |= ACPI_PARSEOP_ELSEIF;12741275/* The IF parent will now be the same as the original ELSE parent */12761277IfOp->Common.Parent = OriginalElseOp->Common.Parent;12781279/*1280* Update the NEXT pointers to restructure the parse tree, essentially1281* promoting an If..Else block up to the same level as the original1282* Else.1283*1284* Check if the IF has a corresponding ELSE peer1285*/1286ElseOp = IfOp->Common.Next;1287if (ElseOp &&1288(ElseOp->Common.AmlOpcode == AML_ELSE_OP))1289{1290/* If an ELSE matches the IF, promote it also */12911292ElseOp->Common.Parent = OriginalElseOp->Common.Parent;12931294/* Promote the entire block under the ElseIf (All Next OPs) */12951296AcpiDmPromoteSubtree (OriginalElseOp);1297}1298else1299{1300/* Otherwise, set the IF NEXT to the original ELSE NEXT */13011302IfOp->Common.Next = OriginalElseOp->Common.Next;1303}13041305/* Detach the child IF block from the original ELSE */13061307OriginalElseOp->Common.Value.Arg = NULL;13081309/* Ignore the original ELSE from now on */13101311OriginalElseOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;1312OriginalElseOp->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;13131314/* Insert IF (now ELSEIF) as next peer of the original ELSE */13151316OriginalElseOp->Common.Next = IfOp;1317}131813191320/*******************************************************************************1321*1322* FUNCTION: AcpiDmPromoteSubtree1323*1324* PARAMETERS: StartOpOp - Original parent of the entire subtree1325*1326* RETURN: None1327*1328* DESCRIPTION: Promote an entire parse subtree up one level.1329*1330******************************************************************************/13311332static void1333AcpiDmPromoteSubtree (1334ACPI_PARSE_OBJECT *StartOp)1335{1336ACPI_PARSE_OBJECT *Op;1337ACPI_PARSE_OBJECT *ParentOp;133813391340/* New parent for subtree elements */13411342ParentOp = StartOp->Common.Parent;13431344/* First child starts the subtree */13451346Op = StartOp->Common.Value.Arg;13471348/* Walk the top-level elements of the subtree */13491350while (Op)1351{1352Op->Common.Parent = ParentOp;1353if (!Op->Common.Next)1354{1355/* Last Op in list, update its next field */13561357Op->Common.Next = StartOp->Common.Next;1358break;1359}1360Op = Op->Common.Next;1361}1362}136313641365