Home | History | Annotate | Line # | Download | only in disassembler
dmopcode.c revision 1.1.1.2
      1 /*******************************************************************************
      2  *
      3  * Module Name: dmopcode - AML disassembler, specific AML opcodes
      4  *
      5  ******************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2011, Intel Corp.
      9  * All rights reserved.
     10  *
     11  * Redistribution and use in source and binary forms, with or without
     12  * modification, are permitted provided that the following conditions
     13  * are met:
     14  * 1. Redistributions of source code must retain the above copyright
     15  *    notice, this list of conditions, and the following disclaimer,
     16  *    without modification.
     17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18  *    substantially similar to the "NO WARRANTY" disclaimer below
     19  *    ("Disclaimer") and any redistribution must be conditioned upon
     20  *    including a substantially similar Disclaimer requirement for further
     21  *    binary redistribution.
     22  * 3. Neither the names of the above-listed copyright holders nor the names
     23  *    of any contributors may be used to endorse or promote products derived
     24  *    from this software without specific prior written permission.
     25  *
     26  * Alternatively, this software may be distributed under the terms of the
     27  * GNU General Public License ("GPL") version 2 as published by the Free
     28  * Software Foundation.
     29  *
     30  * NO WARRANTY
     31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41  * POSSIBILITY OF SUCH DAMAGES.
     42  */
     43 
     44 #include "acpi.h"
     45 #include "accommon.h"
     46 #include "acparser.h"
     47 #include "amlcode.h"
     48 #include "acdisasm.h"
     49 
     50 #ifdef ACPI_DISASSEMBLER
     51 
     52 #define _COMPONENT          ACPI_CA_DEBUGGER
     53         ACPI_MODULE_NAME    ("dmopcode")
     54 
     55 /* Local prototypes */
     56 
     57 static void
     58 AcpiDmMatchKeyword (
     59     ACPI_PARSE_OBJECT       *Op);
     60 
     61 
     62 /*******************************************************************************
     63  *
     64  * FUNCTION:    AcpiDmMethodFlags
     65  *
     66  * PARAMETERS:  Op              - Method Object to be examined
     67  *
     68  * RETURN:      None
     69  *
     70  * DESCRIPTION: Decode control method flags
     71  *
     72  ******************************************************************************/
     73 
     74 void
     75 AcpiDmMethodFlags (
     76     ACPI_PARSE_OBJECT       *Op)
     77 {
     78     UINT32                  Flags;
     79     UINT32                  Args;
     80 
     81 
     82     /* The next Op contains the flags */
     83 
     84     Op = AcpiPsGetDepthNext (NULL, Op);
     85     Flags = (UINT8) Op->Common.Value.Integer;
     86     Args = Flags & 0x07;
     87 
     88     /* Mark the Op as completed */
     89 
     90     Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
     91 
     92     /* 1) Method argument count */
     93 
     94     AcpiOsPrintf (", %u, ", Args);
     95 
     96     /* 2) Serialize rule */
     97 
     98     if (!(Flags & 0x08))
     99     {
    100         AcpiOsPrintf ("Not");
    101     }
    102 
    103     AcpiOsPrintf ("Serialized");
    104 
    105     /* 3) SyncLevel */
    106 
    107     if (Flags & 0xF0)
    108     {
    109         AcpiOsPrintf (", %u", Flags >> 4);
    110     }
    111 }
    112 
    113 
    114 /*******************************************************************************
    115  *
    116  * FUNCTION:    AcpiDmFieldFlags
    117  *
    118  * PARAMETERS:  Op              - Field Object to be examined
    119  *
    120  * RETURN:      None
    121  *
    122  * DESCRIPTION: Decode Field definition flags
    123  *
    124  ******************************************************************************/
    125 
    126 void
    127 AcpiDmFieldFlags (
    128     ACPI_PARSE_OBJECT       *Op)
    129 {
    130     UINT32                  Flags;
    131 
    132 
    133     Op = Op->Common.Next;
    134     Flags = (UINT8) Op->Common.Value.Integer;
    135 
    136     /* Mark the Op as completed */
    137 
    138     Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
    139 
    140     AcpiOsPrintf ("%s, ", AcpiGbl_AccessTypes [Flags & 0x07]);
    141     AcpiOsPrintf ("%s, ", AcpiGbl_LockRule [(Flags & 0x10) >> 4]);
    142     AcpiOsPrintf ("%s)",  AcpiGbl_UpdateRules [(Flags & 0x60) >> 5]);
    143 }
    144 
    145 
    146 /*******************************************************************************
    147  *
    148  * FUNCTION:    AcpiDmAddressSpace
    149  *
    150  * PARAMETERS:  SpaceId         - ID to be translated
    151  *
    152  * RETURN:      None
    153  *
    154  * DESCRIPTION: Decode a SpaceId to an AddressSpaceKeyword
    155  *
    156  ******************************************************************************/
    157 
    158 void
    159 AcpiDmAddressSpace (
    160     UINT8                   SpaceId)
    161 {
    162 
    163     if (SpaceId >= ACPI_NUM_PREDEFINED_REGIONS)
    164     {
    165         if (SpaceId == 0x7F)
    166         {
    167             AcpiOsPrintf ("FFixedHW, ");
    168         }
    169         else
    170         {
    171             AcpiOsPrintf ("0x%.2X, ", SpaceId);
    172         }
    173     }
    174     else
    175     {
    176         AcpiOsPrintf ("%s, ", AcpiGbl_RegionTypes [SpaceId]);
    177     }
    178 }
    179 
    180 
    181 /*******************************************************************************
    182  *
    183  * FUNCTION:    AcpiDmRegionFlags
    184  *
    185  * PARAMETERS:  Op              - Object to be examined
    186  *
    187  * RETURN:      None
    188  *
    189  * DESCRIPTION: Decode OperationRegion flags
    190  *
    191  ******************************************************************************/
    192 
    193 void
    194 AcpiDmRegionFlags (
    195     ACPI_PARSE_OBJECT       *Op)
    196 {
    197 
    198 
    199     /* The next Op contains the SpaceId */
    200 
    201     Op = AcpiPsGetDepthNext (NULL, Op);
    202 
    203     /* Mark the Op as completed */
    204 
    205     Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
    206 
    207     AcpiOsPrintf (", ");
    208     AcpiDmAddressSpace ((UINT8) Op->Common.Value.Integer);
    209 }
    210 
    211 
    212 /*******************************************************************************
    213  *
    214  * FUNCTION:    AcpiDmMatchOp
    215  *
    216  * PARAMETERS:  Op              - Match Object to be examined
    217  *
    218  * RETURN:      None
    219  *
    220  * DESCRIPTION: Decode Match opcode operands
    221  *
    222  ******************************************************************************/
    223 
    224 void
    225 AcpiDmMatchOp (
    226     ACPI_PARSE_OBJECT       *Op)
    227 {
    228     ACPI_PARSE_OBJECT       *NextOp;
    229 
    230 
    231     NextOp = AcpiPsGetDepthNext (NULL, Op);
    232     NextOp = NextOp->Common.Next;
    233 
    234     if (!NextOp)
    235     {
    236         /* Handle partial tree during single-step */
    237 
    238         return;
    239     }
    240 
    241     /* Mark the two nodes that contain the encoding for the match keywords */
    242 
    243     NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;
    244 
    245     NextOp = NextOp->Common.Next;
    246     NextOp = NextOp->Common.Next;
    247     NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;
    248 }
    249 
    250 
    251 /*******************************************************************************
    252  *
    253  * FUNCTION:    AcpiDmMatchKeyword
    254  *
    255  * PARAMETERS:  Op              - Match Object to be examined
    256  *
    257  * RETURN:      None
    258  *
    259  * DESCRIPTION: Decode Match opcode operands
    260  *
    261  ******************************************************************************/
    262 
    263 static void
    264 AcpiDmMatchKeyword (
    265     ACPI_PARSE_OBJECT       *Op)
    266 {
    267 
    268 
    269     if (((UINT32) Op->Common.Value.Integer) > ACPI_MAX_MATCH_OPCODE)
    270     {
    271         AcpiOsPrintf ("/* Unknown Match Keyword encoding */");
    272     }
    273     else
    274     {
    275         AcpiOsPrintf ("%s", ACPI_CAST_PTR (char,
    276             AcpiGbl_MatchOps[(ACPI_SIZE) Op->Common.Value.Integer]));
    277     }
    278 }
    279 
    280 
    281 /*******************************************************************************
    282  *
    283  * FUNCTION:    AcpiDmDisassembleOneOp
    284  *
    285  * PARAMETERS:  WalkState           - Current walk info
    286  *              Info                - Parse tree walk info
    287  *              Op                  - Op that is to be printed
    288  *
    289  * RETURN:      None
    290  *
    291  * DESCRIPTION: Disassemble a single AML opcode
    292  *
    293  ******************************************************************************/
    294 
    295 void
    296 AcpiDmDisassembleOneOp (
    297     ACPI_WALK_STATE         *WalkState,
    298     ACPI_OP_WALK_INFO       *Info,
    299     ACPI_PARSE_OBJECT       *Op)
    300 {
    301     const ACPI_OPCODE_INFO  *OpInfo = NULL;
    302     UINT32                  Offset;
    303     UINT32                  Length;
    304     ACPI_PARSE_OBJECT       *Child;
    305     ACPI_STATUS             Status;
    306 
    307 
    308     if (!Op)
    309     {
    310         AcpiOsPrintf ("<NULL OP PTR>");
    311         return;
    312     }
    313 
    314     switch (Op->Common.DisasmOpcode)
    315     {
    316     case ACPI_DASM_MATCHOP:
    317 
    318         AcpiDmMatchKeyword (Op);
    319         return;
    320 
    321     case ACPI_DASM_LNOT_SUFFIX:
    322         switch (Op->Common.AmlOpcode)
    323         {
    324         case AML_LEQUAL_OP:
    325             AcpiOsPrintf ("LNotEqual");
    326             break;
    327 
    328         case AML_LGREATER_OP:
    329             AcpiOsPrintf ("LLessEqual");
    330             break;
    331 
    332         case AML_LLESS_OP:
    333             AcpiOsPrintf ("LGreaterEqual");
    334             break;
    335 
    336         default:
    337             break;
    338         }
    339         Op->Common.DisasmOpcode = 0;
    340         Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
    341         return;
    342 
    343     default:
    344         break;
    345     }
    346 
    347 
    348     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
    349 
    350     /* The op and arguments */
    351 
    352     switch (Op->Common.AmlOpcode)
    353     {
    354     case AML_LNOT_OP:
    355 
    356         Child = Op->Common.Value.Arg;
    357         if ((Child->Common.AmlOpcode == AML_LEQUAL_OP) ||
    358             (Child->Common.AmlOpcode == AML_LGREATER_OP) ||
    359             (Child->Common.AmlOpcode == AML_LLESS_OP))
    360         {
    361             Child->Common.DisasmOpcode = ACPI_DASM_LNOT_SUFFIX;
    362             Op->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
    363         }
    364         else
    365         {
    366             AcpiOsPrintf ("%s", OpInfo->Name);
    367         }
    368         break;
    369 
    370     case AML_BYTE_OP:
    371 
    372         AcpiOsPrintf ("0x%2.2X", (UINT32) Op->Common.Value.Integer);
    373         break;
    374 
    375 
    376     case AML_WORD_OP:
    377 
    378         if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
    379         {
    380             AcpiDmEisaId ((UINT32) Op->Common.Value.Integer);
    381         }
    382         else
    383         {
    384             AcpiOsPrintf ("0x%4.4X", (UINT32) Op->Common.Value.Integer);
    385         }
    386         break;
    387 
    388 
    389     case AML_DWORD_OP:
    390 
    391         if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
    392         {
    393             AcpiDmEisaId ((UINT32) Op->Common.Value.Integer);
    394         }
    395         else
    396         {
    397             AcpiOsPrintf ("0x%8.8X", (UINT32) Op->Common.Value.Integer);
    398         }
    399         break;
    400 
    401 
    402     case AML_QWORD_OP:
    403 
    404         AcpiOsPrintf ("0x%8.8X%8.8X",
    405             ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
    406         break;
    407 
    408 
    409     case AML_STRING_OP:
    410 
    411         AcpiUtPrintString (Op->Common.Value.String, ACPI_UINT8_MAX);
    412         break;
    413 
    414 
    415     case AML_BUFFER_OP:
    416 
    417         /*
    418          * Determine the type of buffer.  We can have one of the following:
    419          *
    420          * 1) ResourceTemplate containing Resource Descriptors.
    421          * 2) Unicode String buffer
    422          * 3) ASCII String buffer
    423          * 4) Raw data buffer (if none of the above)
    424          *
    425          * Since there are no special AML opcodes to differentiate these
    426          * types of buffers, we have to closely look at the data in the
    427          * buffer to determine the type.
    428          */
    429         Status = AcpiDmIsResourceTemplate (Op);
    430         if (ACPI_SUCCESS (Status))
    431         {
    432             Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
    433             AcpiOsPrintf ("ResourceTemplate");
    434             break;
    435         }
    436         else if (Status == AE_AML_NO_RESOURCE_END_TAG)
    437         {
    438             AcpiOsPrintf ("/**** Is ResourceTemplate, but EndTag not at buffer end ****/ ");
    439         }
    440 
    441         if (AcpiDmIsUnicodeBuffer (Op))
    442         {
    443             Op->Common.DisasmOpcode = ACPI_DASM_UNICODE;
    444             AcpiOsPrintf ("Unicode (");
    445         }
    446         else if (AcpiDmIsStringBuffer (Op))
    447         {
    448             Op->Common.DisasmOpcode = ACPI_DASM_STRING;
    449             AcpiOsPrintf ("Buffer");
    450         }
    451         else
    452         {
    453             Op->Common.DisasmOpcode = ACPI_DASM_BUFFER;
    454             AcpiOsPrintf ("Buffer");
    455         }
    456         break;
    457 
    458 
    459     case AML_INT_STATICSTRING_OP:
    460 
    461         if (Op->Common.Value.String)
    462         {
    463             AcpiOsPrintf ("%s", Op->Common.Value.String);
    464         }
    465         else
    466         {
    467             AcpiOsPrintf ("\"<NULL STATIC STRING PTR>\"");
    468         }
    469         break;
    470 
    471 
    472     case AML_INT_NAMEPATH_OP:
    473 
    474         AcpiDmNamestring (Op->Common.Value.Name);
    475         break;
    476 
    477 
    478     case AML_INT_NAMEDFIELD_OP:
    479 
    480         Length = AcpiDmDumpName (Op->Named.Name);
    481         AcpiOsPrintf (",%*.s  %u", (unsigned) (5 - Length), " ",
    482             (UINT32) Op->Common.Value.Integer);
    483         AcpiDmCommaIfFieldMember (Op);
    484 
    485         Info->BitOffset += (UINT32) Op->Common.Value.Integer;
    486         break;
    487 
    488 
    489     case AML_INT_RESERVEDFIELD_OP:
    490 
    491         /* Offset() -- Must account for previous offsets */
    492 
    493         Offset = (UINT32) Op->Common.Value.Integer;
    494         Info->BitOffset += Offset;
    495 
    496         if (Info->BitOffset % 8 == 0)
    497         {
    498             AcpiOsPrintf ("        Offset (0x%.2X)", ACPI_DIV_8 (Info->BitOffset));
    499         }
    500         else
    501         {
    502             AcpiOsPrintf ("    ,   %u", Offset);
    503         }
    504 
    505         AcpiDmCommaIfFieldMember (Op);
    506         break;
    507 
    508 
    509     case AML_INT_ACCESSFIELD_OP:
    510 
    511         AcpiOsPrintf ("        AccessAs (%s, ",
    512             AcpiGbl_AccessTypes [(UINT32) (Op->Common.Value.Integer >> 8) & 0x7]);
    513 
    514         AcpiDmDecodeAttribute ((UINT8) Op->Common.Value.Integer);
    515         AcpiOsPrintf (")");
    516         AcpiDmCommaIfFieldMember (Op);
    517         break;
    518 
    519 
    520     case AML_INT_BYTELIST_OP:
    521 
    522         AcpiDmByteList (Info, Op);
    523         break;
    524 
    525 
    526     case AML_INT_METHODCALL_OP:
    527 
    528         Op = AcpiPsGetDepthNext (NULL, Op);
    529         Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
    530 
    531         AcpiDmNamestring (Op->Common.Value.Name);
    532         break;
    533 
    534 
    535     default:
    536 
    537         /* Just get the opcode name and print it */
    538 
    539         AcpiOsPrintf ("%s", OpInfo->Name);
    540 
    541 
    542 #ifdef ACPI_DEBUGGER
    543 
    544         if ((Op->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP) &&
    545             (WalkState) &&
    546             (WalkState->Results) &&
    547             (WalkState->ResultCount))
    548         {
    549             AcpiDmDecodeInternalObject (
    550                 WalkState->Results->Results.ObjDesc [
    551                     (WalkState->ResultCount - 1) %
    552                         ACPI_RESULTS_FRAME_OBJ_NUM]);
    553         }
    554 #endif
    555 
    556         break;
    557     }
    558 }
    559 
    560 #endif  /* ACPI_DISASSEMBLER */
    561