Home | History | Annotate | Line # | Download | only in disassembler
dmopcode.c revision 1.1.1.11.4.1
      1           1.1    jruoho /*******************************************************************************
      2           1.1    jruoho  *
      3           1.1    jruoho  * Module Name: dmopcode - AML disassembler, specific AML opcodes
      4           1.1    jruoho  *
      5           1.1    jruoho  ******************************************************************************/
      6           1.1    jruoho 
      7       1.1.1.2    jruoho /*
      8      1.1.1.11  christos  * Copyright (C) 2000 - 2017, Intel Corp.
      9           1.1    jruoho  * All rights reserved.
     10           1.1    jruoho  *
     11       1.1.1.2    jruoho  * Redistribution and use in source and binary forms, with or without
     12       1.1.1.2    jruoho  * modification, are permitted provided that the following conditions
     13       1.1.1.2    jruoho  * are met:
     14       1.1.1.2    jruoho  * 1. Redistributions of source code must retain the above copyright
     15       1.1.1.2    jruoho  *    notice, this list of conditions, and the following disclaimer,
     16       1.1.1.2    jruoho  *    without modification.
     17       1.1.1.2    jruoho  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
     18       1.1.1.2    jruoho  *    substantially similar to the "NO WARRANTY" disclaimer below
     19       1.1.1.2    jruoho  *    ("Disclaimer") and any redistribution must be conditioned upon
     20       1.1.1.2    jruoho  *    including a substantially similar Disclaimer requirement for further
     21       1.1.1.2    jruoho  *    binary redistribution.
     22       1.1.1.2    jruoho  * 3. Neither the names of the above-listed copyright holders nor the names
     23       1.1.1.2    jruoho  *    of any contributors may be used to endorse or promote products derived
     24       1.1.1.2    jruoho  *    from this software without specific prior written permission.
     25       1.1.1.2    jruoho  *
     26       1.1.1.2    jruoho  * Alternatively, this software may be distributed under the terms of the
     27       1.1.1.2    jruoho  * GNU General Public License ("GPL") version 2 as published by the Free
     28       1.1.1.2    jruoho  * Software Foundation.
     29       1.1.1.2    jruoho  *
     30       1.1.1.2    jruoho  * NO WARRANTY
     31       1.1.1.2    jruoho  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     32       1.1.1.2    jruoho  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     33       1.1.1.2    jruoho  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
     34       1.1.1.2    jruoho  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     35       1.1.1.2    jruoho  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     36       1.1.1.2    jruoho  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     37       1.1.1.2    jruoho  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     38       1.1.1.2    jruoho  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
     39       1.1.1.2    jruoho  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
     40       1.1.1.2    jruoho  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     41       1.1.1.2    jruoho  * POSSIBILITY OF SUCH DAMAGES.
     42       1.1.1.2    jruoho  */
     43           1.1    jruoho 
     44           1.1    jruoho #include "acpi.h"
     45           1.1    jruoho #include "accommon.h"
     46           1.1    jruoho #include "acparser.h"
     47           1.1    jruoho #include "amlcode.h"
     48       1.1.1.4  christos #include "acinterp.h"
     49       1.1.1.4  christos #include "acnamesp.h"
     50       1.1.1.6  christos #include "acdebug.h"
     51  1.1.1.11.4.1  pgoyette #include "acconvert.h"
     52           1.1    jruoho 
     53           1.1    jruoho 
     54           1.1    jruoho #define _COMPONENT          ACPI_CA_DEBUGGER
     55           1.1    jruoho         ACPI_MODULE_NAME    ("dmopcode")
     56           1.1    jruoho 
     57       1.1.1.5  christos 
     58           1.1    jruoho /* Local prototypes */
     59           1.1    jruoho 
     60           1.1    jruoho static void
     61           1.1    jruoho AcpiDmMatchKeyword (
     62           1.1    jruoho     ACPI_PARSE_OBJECT       *Op);
     63           1.1    jruoho 
     64       1.1.1.7  christos static void
     65       1.1.1.7  christos AcpiDmConvertToElseIf (
     66       1.1.1.7  christos     ACPI_PARSE_OBJECT       *Op);
     67       1.1.1.7  christos 
     68      1.1.1.10  christos static void
     69      1.1.1.10  christos AcpiDmPromoteSubtree (
     70      1.1.1.10  christos     ACPI_PARSE_OBJECT       *StartOp);
     71      1.1.1.10  christos 
     72      1.1.1.11  christos static BOOLEAN
     73      1.1.1.11  christos AcpiDmIsSwitchBlock (
     74  1.1.1.11.4.1  pgoyette     ACPI_PARSE_OBJECT       *Op,
     75  1.1.1.11.4.1  pgoyette     char                    *Temp);
     76      1.1.1.11  christos 
     77      1.1.1.11  christos static BOOLEAN
     78      1.1.1.11  christos AcpiDmIsCaseBlock (
     79      1.1.1.11  christos     ACPI_PARSE_OBJECT       *Op);
     80           1.1    jruoho 
     81           1.1    jruoho /*******************************************************************************
     82           1.1    jruoho  *
     83       1.1.1.4  christos  * FUNCTION:    AcpiDmDisplayTargetPathname
     84       1.1.1.4  christos  *
     85       1.1.1.4  christos  * PARAMETERS:  Op              - Parse object
     86       1.1.1.4  christos  *
     87       1.1.1.4  christos  * RETURN:      None
     88       1.1.1.4  christos  *
     89       1.1.1.4  christos  * DESCRIPTION: For AML opcodes that have a target operand, display the full
     90       1.1.1.4  christos  *              pathname for the target, in a comment field. Handles Return()
     91       1.1.1.4  christos  *              statements also.
     92       1.1.1.4  christos  *
     93       1.1.1.4  christos  ******************************************************************************/
     94       1.1.1.4  christos 
     95       1.1.1.4  christos void
     96       1.1.1.4  christos AcpiDmDisplayTargetPathname (
     97       1.1.1.4  christos     ACPI_PARSE_OBJECT       *Op)
     98       1.1.1.4  christos {
     99       1.1.1.4  christos     ACPI_PARSE_OBJECT       *NextOp;
    100       1.1.1.4  christos     ACPI_PARSE_OBJECT       *PrevOp = NULL;
    101       1.1.1.4  christos     char                    *Pathname;
    102       1.1.1.4  christos     const ACPI_OPCODE_INFO  *OpInfo;
    103       1.1.1.4  christos 
    104       1.1.1.4  christos 
    105       1.1.1.4  christos     if (Op->Common.AmlOpcode == AML_RETURN_OP)
    106       1.1.1.4  christos     {
    107       1.1.1.4  christos         PrevOp = Op->Asl.Value.Arg;
    108       1.1.1.4  christos     }
    109       1.1.1.4  christos     else
    110       1.1.1.4  christos     {
    111       1.1.1.4  christos         OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
    112       1.1.1.4  christos         if (!(OpInfo->Flags & AML_HAS_TARGET))
    113       1.1.1.4  christos         {
    114       1.1.1.4  christos             return;
    115       1.1.1.4  christos         }
    116       1.1.1.4  christos 
    117       1.1.1.4  christos         /* Target is the last Op in the arg list */
    118       1.1.1.4  christos 
    119       1.1.1.4  christos         NextOp = Op->Asl.Value.Arg;
    120       1.1.1.4  christos         while (NextOp)
    121       1.1.1.4  christos         {
    122       1.1.1.4  christos             PrevOp = NextOp;
    123       1.1.1.4  christos             NextOp = PrevOp->Asl.Next;
    124       1.1.1.4  christos         }
    125       1.1.1.4  christos     }
    126       1.1.1.4  christos 
    127       1.1.1.4  christos     if (!PrevOp)
    128       1.1.1.4  christos     {
    129       1.1.1.4  christos         return;
    130       1.1.1.4  christos     }
    131       1.1.1.4  christos 
    132       1.1.1.4  christos     /* We must have a namepath AML opcode */
    133       1.1.1.4  christos 
    134       1.1.1.4  christos     if (PrevOp->Asl.AmlOpcode != AML_INT_NAMEPATH_OP)
    135       1.1.1.4  christos     {
    136       1.1.1.4  christos         return;
    137       1.1.1.4  christos     }
    138       1.1.1.4  christos 
    139       1.1.1.4  christos     /* A null string is the "no target specified" case */
    140       1.1.1.4  christos 
    141       1.1.1.4  christos     if (!PrevOp->Asl.Value.String)
    142       1.1.1.4  christos     {
    143       1.1.1.4  christos         return;
    144       1.1.1.4  christos     }
    145       1.1.1.4  christos 
    146       1.1.1.4  christos     /* No node means "unresolved external reference" */
    147       1.1.1.4  christos 
    148       1.1.1.4  christos     if (!PrevOp->Asl.Node)
    149       1.1.1.4  christos     {
    150       1.1.1.4  christos         AcpiOsPrintf (" /* External reference */");
    151       1.1.1.4  christos         return;
    152       1.1.1.4  christos     }
    153       1.1.1.4  christos 
    154       1.1.1.4  christos     /* Ignore if path is already from the root */
    155       1.1.1.4  christos 
    156       1.1.1.4  christos     if (*PrevOp->Asl.Value.String == '\\')
    157       1.1.1.4  christos     {
    158       1.1.1.4  christos         return;
    159       1.1.1.4  christos     }
    160       1.1.1.4  christos 
    161       1.1.1.4  christos     /* Now: we can get the full pathname */
    162       1.1.1.4  christos 
    163       1.1.1.4  christos     Pathname = AcpiNsGetExternalPathname (PrevOp->Asl.Node);
    164       1.1.1.4  christos     if (!Pathname)
    165       1.1.1.4  christos     {
    166       1.1.1.4  christos         return;
    167       1.1.1.4  christos     }
    168       1.1.1.4  christos 
    169       1.1.1.4  christos     AcpiOsPrintf (" /* %s */", Pathname);
    170       1.1.1.4  christos     ACPI_FREE (Pathname);
    171       1.1.1.4  christos }
    172       1.1.1.4  christos 
    173       1.1.1.4  christos 
    174       1.1.1.4  christos /*******************************************************************************
    175       1.1.1.4  christos  *
    176       1.1.1.4  christos  * FUNCTION:    AcpiDmNotifyDescription
    177       1.1.1.4  christos  *
    178       1.1.1.4  christos  * PARAMETERS:  Op              - Name() parse object
    179       1.1.1.4  christos  *
    180       1.1.1.4  christos  * RETURN:      None
    181       1.1.1.4  christos  *
    182       1.1.1.4  christos  * DESCRIPTION: Emit a description comment for the value associated with a
    183       1.1.1.4  christos  *              Notify() operator.
    184       1.1.1.4  christos  *
    185       1.1.1.4  christos  ******************************************************************************/
    186       1.1.1.4  christos 
    187       1.1.1.4  christos void
    188       1.1.1.4  christos AcpiDmNotifyDescription (
    189       1.1.1.4  christos     ACPI_PARSE_OBJECT       *Op)
    190       1.1.1.4  christos {
    191       1.1.1.4  christos     ACPI_PARSE_OBJECT       *NextOp;
    192       1.1.1.4  christos     ACPI_NAMESPACE_NODE     *Node;
    193       1.1.1.4  christos     UINT8                   NotifyValue;
    194       1.1.1.4  christos     UINT8                   Type = ACPI_TYPE_ANY;
    195       1.1.1.4  christos 
    196       1.1.1.4  christos 
    197       1.1.1.4  christos     /* The notify value is the second argument */
    198       1.1.1.4  christos 
    199       1.1.1.4  christos     NextOp = Op->Asl.Value.Arg;
    200       1.1.1.4  christos     NextOp = NextOp->Asl.Next;
    201       1.1.1.4  christos 
    202       1.1.1.4  christos     switch (NextOp->Common.AmlOpcode)
    203       1.1.1.4  christos     {
    204       1.1.1.4  christos     case AML_ZERO_OP:
    205       1.1.1.4  christos     case AML_ONE_OP:
    206       1.1.1.4  christos 
    207       1.1.1.4  christos         NotifyValue = (UINT8) NextOp->Common.AmlOpcode;
    208       1.1.1.4  christos         break;
    209       1.1.1.4  christos 
    210       1.1.1.4  christos     case AML_BYTE_OP:
    211       1.1.1.4  christos 
    212       1.1.1.4  christos         NotifyValue = (UINT8) NextOp->Asl.Value.Integer;
    213       1.1.1.4  christos         break;
    214       1.1.1.4  christos 
    215       1.1.1.4  christos     default:
    216       1.1.1.4  christos         return;
    217       1.1.1.4  christos     }
    218       1.1.1.4  christos 
    219       1.1.1.4  christos     /*
    220       1.1.1.4  christos      * Attempt to get the namespace node so we can determine the object type.
    221       1.1.1.4  christos      * Some notify values are dependent on the object type (Device, Thermal,
    222       1.1.1.4  christos      * or Processor).
    223       1.1.1.4  christos      */
    224       1.1.1.4  christos     Node = Op->Asl.Node;
    225       1.1.1.4  christos     if (Node)
    226       1.1.1.4  christos     {
    227       1.1.1.4  christos         Type = Node->Type;
    228       1.1.1.4  christos     }
    229       1.1.1.4  christos 
    230       1.1.1.4  christos     AcpiOsPrintf (" // %s", AcpiUtGetNotifyName (NotifyValue, Type));
    231       1.1.1.4  christos }
    232       1.1.1.4  christos 
    233       1.1.1.4  christos 
    234       1.1.1.4  christos /*******************************************************************************
    235       1.1.1.4  christos  *
    236       1.1.1.3  christos  * FUNCTION:    AcpiDmPredefinedDescription
    237       1.1.1.3  christos  *
    238       1.1.1.3  christos  * PARAMETERS:  Op              - Name() parse object
    239       1.1.1.3  christos  *
    240       1.1.1.3  christos  * RETURN:      None
    241       1.1.1.3  christos  *
    242       1.1.1.3  christos  * DESCRIPTION: Emit a description comment for a predefined ACPI name.
    243       1.1.1.3  christos  *              Used for iASL compiler only.
    244       1.1.1.3  christos  *
    245       1.1.1.3  christos  ******************************************************************************/
    246       1.1.1.3  christos 
    247       1.1.1.3  christos void
    248       1.1.1.3  christos AcpiDmPredefinedDescription (
    249       1.1.1.3  christos     ACPI_PARSE_OBJECT       *Op)
    250       1.1.1.3  christos {
    251       1.1.1.3  christos #ifdef ACPI_ASL_COMPILER
    252       1.1.1.3  christos     const AH_PREDEFINED_NAME    *Info;
    253       1.1.1.3  christos     char                        *NameString;
    254       1.1.1.3  christos     int                         LastCharIsDigit;
    255       1.1.1.3  christos     int                         LastCharsAreHex;
    256       1.1.1.3  christos 
    257       1.1.1.3  christos 
    258       1.1.1.3  christos     if (!Op)
    259       1.1.1.3  christos     {
    260       1.1.1.3  christos         return;
    261       1.1.1.3  christos     }
    262       1.1.1.3  christos 
    263       1.1.1.3  christos     /* Ensure that the comment field is emitted only once */
    264       1.1.1.3  christos 
    265       1.1.1.8  christos     if (Op->Common.DisasmFlags & ACPI_PARSEOP_PREDEFINED_CHECKED)
    266       1.1.1.3  christos     {
    267       1.1.1.3  christos         return;
    268       1.1.1.3  christos     }
    269       1.1.1.8  christos     Op->Common.DisasmFlags |= ACPI_PARSEOP_PREDEFINED_CHECKED;
    270       1.1.1.3  christos 
    271       1.1.1.3  christos     /* Predefined name must start with an underscore */
    272       1.1.1.3  christos 
    273       1.1.1.3  christos     NameString = ACPI_CAST_PTR (char, &Op->Named.Name);
    274       1.1.1.3  christos     if (NameString[0] != '_')
    275       1.1.1.3  christos     {
    276       1.1.1.3  christos         return;
    277       1.1.1.3  christos     }
    278       1.1.1.3  christos 
    279       1.1.1.3  christos     /*
    280       1.1.1.3  christos      * Check for the special ACPI names:
    281       1.1.1.3  christos      * _ACd, _ALd, _EJd, _Exx, _Lxx, _Qxx, _Wxx, _T_a
    282       1.1.1.3  christos      * (where d=decimal_digit, x=hex_digit, a=anything)
    283       1.1.1.3  christos      *
    284       1.1.1.3  christos      * Convert these to the generic name for table lookup.
    285       1.1.1.3  christos      * Note: NameString is guaranteed to be upper case here.
    286       1.1.1.3  christos      */
    287       1.1.1.3  christos     LastCharIsDigit =
    288       1.1.1.6  christos         (isdigit ((int) NameString[3]));    /* d */
    289       1.1.1.3  christos     LastCharsAreHex =
    290       1.1.1.6  christos         (isxdigit ((int) NameString[2]) &&  /* xx */
    291       1.1.1.6  christos          isxdigit ((int) NameString[3]));
    292       1.1.1.3  christos 
    293       1.1.1.3  christos     switch (NameString[1])
    294       1.1.1.3  christos     {
    295       1.1.1.3  christos     case 'A':
    296       1.1.1.3  christos 
    297       1.1.1.3  christos         if ((NameString[2] == 'C') && (LastCharIsDigit))
    298       1.1.1.3  christos         {
    299       1.1.1.3  christos             NameString = "_ACx";
    300       1.1.1.3  christos         }
    301       1.1.1.3  christos         else if ((NameString[2] == 'L') && (LastCharIsDigit))
    302       1.1.1.3  christos         {
    303       1.1.1.3  christos             NameString = "_ALx";
    304       1.1.1.3  christos         }
    305       1.1.1.3  christos         break;
    306       1.1.1.3  christos 
    307       1.1.1.3  christos     case 'E':
    308       1.1.1.3  christos 
    309       1.1.1.3  christos         if ((NameString[2] == 'J') && (LastCharIsDigit))
    310       1.1.1.3  christos         {
    311       1.1.1.3  christos             NameString = "_EJx";
    312       1.1.1.3  christos         }
    313       1.1.1.3  christos         else if (LastCharsAreHex)
    314       1.1.1.3  christos         {
    315       1.1.1.3  christos             NameString = "_Exx";
    316       1.1.1.3  christos         }
    317       1.1.1.3  christos         break;
    318       1.1.1.3  christos 
    319       1.1.1.3  christos     case 'L':
    320       1.1.1.3  christos 
    321       1.1.1.3  christos         if (LastCharsAreHex)
    322       1.1.1.3  christos         {
    323       1.1.1.3  christos             NameString = "_Lxx";
    324       1.1.1.3  christos         }
    325       1.1.1.3  christos         break;
    326       1.1.1.3  christos 
    327       1.1.1.3  christos     case 'Q':
    328       1.1.1.3  christos 
    329       1.1.1.3  christos         if (LastCharsAreHex)
    330       1.1.1.3  christos         {
    331       1.1.1.3  christos             NameString = "_Qxx";
    332       1.1.1.3  christos         }
    333       1.1.1.3  christos         break;
    334       1.1.1.3  christos 
    335       1.1.1.3  christos     case 'T':
    336       1.1.1.3  christos 
    337       1.1.1.3  christos         if (NameString[2] == '_')
    338       1.1.1.3  christos         {
    339       1.1.1.3  christos             NameString = "_T_x";
    340       1.1.1.3  christos         }
    341       1.1.1.3  christos         break;
    342       1.1.1.3  christos 
    343       1.1.1.3  christos     case 'W':
    344       1.1.1.3  christos 
    345       1.1.1.3  christos         if (LastCharsAreHex)
    346       1.1.1.3  christos         {
    347       1.1.1.3  christos             NameString = "_Wxx";
    348       1.1.1.3  christos         }
    349       1.1.1.3  christos         break;
    350       1.1.1.3  christos 
    351       1.1.1.3  christos     default:
    352       1.1.1.3  christos 
    353       1.1.1.3  christos         break;
    354       1.1.1.3  christos     }
    355       1.1.1.3  christos 
    356       1.1.1.3  christos     /* Match the name in the info table */
    357       1.1.1.3  christos 
    358       1.1.1.4  christos     Info = AcpiAhMatchPredefinedName (NameString);
    359       1.1.1.4  christos     if (Info)
    360       1.1.1.3  christos     {
    361       1.1.1.4  christos         AcpiOsPrintf ("  // %4.4s: %s",
    362       1.1.1.4  christos             NameString, ACPI_CAST_PTR (char, Info->Description));
    363       1.1.1.3  christos     }
    364       1.1.1.3  christos 
    365       1.1.1.3  christos #endif
    366       1.1.1.3  christos     return;
    367       1.1.1.3  christos }
    368       1.1.1.3  christos 
    369       1.1.1.3  christos 
    370       1.1.1.3  christos /*******************************************************************************
    371       1.1.1.3  christos  *
    372       1.1.1.3  christos  * FUNCTION:    AcpiDmFieldPredefinedDescription
    373       1.1.1.3  christos  *
    374       1.1.1.3  christos  * PARAMETERS:  Op              - Parse object
    375       1.1.1.3  christos  *
    376       1.1.1.3  christos  * RETURN:      None
    377       1.1.1.3  christos  *
    378       1.1.1.3  christos  * DESCRIPTION: Emit a description comment for a resource descriptor tag
    379       1.1.1.3  christos  *              (which is a predefined ACPI name.) Used for iASL compiler only.
    380       1.1.1.3  christos  *
    381       1.1.1.3  christos  ******************************************************************************/
    382       1.1.1.3  christos 
    383       1.1.1.3  christos void
    384       1.1.1.3  christos AcpiDmFieldPredefinedDescription (
    385       1.1.1.3  christos     ACPI_PARSE_OBJECT       *Op)
    386       1.1.1.3  christos {
    387       1.1.1.3  christos #ifdef ACPI_ASL_COMPILER
    388       1.1.1.3  christos     ACPI_PARSE_OBJECT       *IndexOp;
    389       1.1.1.3  christos     char                    *Tag;
    390       1.1.1.3  christos     const ACPI_OPCODE_INFO  *OpInfo;
    391       1.1.1.3  christos     const AH_PREDEFINED_NAME *Info;
    392       1.1.1.3  christos 
    393       1.1.1.3  christos 
    394       1.1.1.3  christos     if (!Op)
    395       1.1.1.3  christos     {
    396       1.1.1.3  christos         return;
    397       1.1.1.3  christos     }
    398       1.1.1.3  christos 
    399       1.1.1.3  christos     /* Ensure that the comment field is emitted only once */
    400       1.1.1.3  christos 
    401       1.1.1.8  christos     if (Op->Common.DisasmFlags & ACPI_PARSEOP_PREDEFINED_CHECKED)
    402       1.1.1.3  christos     {
    403       1.1.1.3  christos         return;
    404       1.1.1.3  christos     }
    405       1.1.1.8  christos     Op->Common.DisasmFlags |= ACPI_PARSEOP_PREDEFINED_CHECKED;
    406       1.1.1.3  christos 
    407       1.1.1.3  christos     /*
    408       1.1.1.3  christos      * Op must be one of the Create* operators: CreateField, CreateBitField,
    409       1.1.1.3  christos      * CreateByteField, CreateWordField, CreateDwordField, CreateQwordField
    410       1.1.1.3  christos      */
    411       1.1.1.3  christos     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
    412       1.1.1.3  christos     if (!(OpInfo->Flags & AML_CREATE))
    413       1.1.1.3  christos     {
    414       1.1.1.3  christos         return;
    415       1.1.1.3  christos     }
    416       1.1.1.3  christos 
    417       1.1.1.3  christos     /* Second argument is the Index argument */
    418       1.1.1.3  christos 
    419       1.1.1.3  christos     IndexOp = Op->Common.Value.Arg;
    420       1.1.1.3  christos     IndexOp = IndexOp->Common.Next;
    421       1.1.1.3  christos 
    422       1.1.1.3  christos     /* Index argument must be a namepath */
    423       1.1.1.3  christos 
    424       1.1.1.3  christos     if (IndexOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP)
    425       1.1.1.3  christos     {
    426       1.1.1.3  christos         return;
    427       1.1.1.3  christos     }
    428       1.1.1.3  christos 
    429       1.1.1.3  christos     /* Major cheat: We previously put the Tag ptr in the Node field */
    430       1.1.1.3  christos 
    431       1.1.1.3  christos     Tag = ACPI_CAST_PTR (char, IndexOp->Common.Node);
    432       1.1.1.3  christos     if (!Tag)
    433       1.1.1.3  christos     {
    434       1.1.1.3  christos         return;
    435       1.1.1.3  christos     }
    436       1.1.1.3  christos 
    437       1.1.1.3  christos     /* Match the name in the info table */
    438       1.1.1.3  christos 
    439       1.1.1.4  christos     Info = AcpiAhMatchPredefinedName (Tag);
    440       1.1.1.4  christos     if (Info)
    441       1.1.1.3  christos     {
    442       1.1.1.4  christos         AcpiOsPrintf ("  // %4.4s: %s", Tag,
    443       1.1.1.4  christos             ACPI_CAST_PTR (char, Info->Description));
    444       1.1.1.3  christos     }
    445       1.1.1.3  christos 
    446  1.1.1.11.4.1  pgoyette     /* AML buffer (String) was allocated in AcpiGetTagPathname */
    447  1.1.1.11.4.1  pgoyette 
    448  1.1.1.11.4.1  pgoyette     ACPI_FREE (IndexOp->Common.Value.String);
    449  1.1.1.11.4.1  pgoyette 
    450       1.1.1.3  christos #endif
    451       1.1.1.3  christos     return;
    452       1.1.1.3  christos }
    453       1.1.1.3  christos 
    454       1.1.1.3  christos 
    455       1.1.1.3  christos /*******************************************************************************
    456       1.1.1.3  christos  *
    457           1.1    jruoho  * FUNCTION:    AcpiDmMethodFlags
    458           1.1    jruoho  *
    459           1.1    jruoho  * PARAMETERS:  Op              - Method Object to be examined
    460           1.1    jruoho  *
    461           1.1    jruoho  * RETURN:      None
    462           1.1    jruoho  *
    463           1.1    jruoho  * DESCRIPTION: Decode control method flags
    464           1.1    jruoho  *
    465           1.1    jruoho  ******************************************************************************/
    466           1.1    jruoho 
    467           1.1    jruoho void
    468           1.1    jruoho AcpiDmMethodFlags (
    469           1.1    jruoho     ACPI_PARSE_OBJECT       *Op)
    470           1.1    jruoho {
    471           1.1    jruoho     UINT32                  Flags;
    472           1.1    jruoho     UINT32                  Args;
    473           1.1    jruoho 
    474           1.1    jruoho 
    475           1.1    jruoho     /* The next Op contains the flags */
    476           1.1    jruoho 
    477           1.1    jruoho     Op = AcpiPsGetDepthNext (NULL, Op);
    478           1.1    jruoho     Flags = (UINT8) Op->Common.Value.Integer;
    479           1.1    jruoho     Args = Flags & 0x07;
    480           1.1    jruoho 
    481           1.1    jruoho     /* Mark the Op as completed */
    482           1.1    jruoho 
    483           1.1    jruoho     Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
    484           1.1    jruoho 
    485           1.1    jruoho     /* 1) Method argument count */
    486           1.1    jruoho 
    487           1.1    jruoho     AcpiOsPrintf (", %u, ", Args);
    488           1.1    jruoho 
    489           1.1    jruoho     /* 2) Serialize rule */
    490           1.1    jruoho 
    491           1.1    jruoho     if (!(Flags & 0x08))
    492           1.1    jruoho     {
    493           1.1    jruoho         AcpiOsPrintf ("Not");
    494           1.1    jruoho     }
    495           1.1    jruoho 
    496           1.1    jruoho     AcpiOsPrintf ("Serialized");
    497           1.1    jruoho 
    498           1.1    jruoho     /* 3) SyncLevel */
    499           1.1    jruoho 
    500           1.1    jruoho     if (Flags & 0xF0)
    501           1.1    jruoho     {
    502           1.1    jruoho         AcpiOsPrintf (", %u", Flags >> 4);
    503           1.1    jruoho     }
    504           1.1    jruoho }
    505           1.1    jruoho 
    506           1.1    jruoho 
    507           1.1    jruoho /*******************************************************************************
    508           1.1    jruoho  *
    509           1.1    jruoho  * FUNCTION:    AcpiDmFieldFlags
    510           1.1    jruoho  *
    511           1.1    jruoho  * PARAMETERS:  Op              - Field Object to be examined
    512           1.1    jruoho  *
    513           1.1    jruoho  * RETURN:      None
    514           1.1    jruoho  *
    515           1.1    jruoho  * DESCRIPTION: Decode Field definition flags
    516           1.1    jruoho  *
    517           1.1    jruoho  ******************************************************************************/
    518           1.1    jruoho 
    519           1.1    jruoho void
    520           1.1    jruoho AcpiDmFieldFlags (
    521           1.1    jruoho     ACPI_PARSE_OBJECT       *Op)
    522           1.1    jruoho {
    523           1.1    jruoho     UINT32                  Flags;
    524           1.1    jruoho 
    525           1.1    jruoho 
    526           1.1    jruoho     Op = Op->Common.Next;
    527           1.1    jruoho     Flags = (UINT8) Op->Common.Value.Integer;
    528           1.1    jruoho 
    529           1.1    jruoho     /* Mark the Op as completed */
    530           1.1    jruoho 
    531           1.1    jruoho     Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
    532           1.1    jruoho 
    533           1.1    jruoho     AcpiOsPrintf ("%s, ", AcpiGbl_AccessTypes [Flags & 0x07]);
    534           1.1    jruoho     AcpiOsPrintf ("%s, ", AcpiGbl_LockRule [(Flags & 0x10) >> 4]);
    535           1.1    jruoho     AcpiOsPrintf ("%s)",  AcpiGbl_UpdateRules [(Flags & 0x60) >> 5]);
    536           1.1    jruoho }
    537           1.1    jruoho 
    538           1.1    jruoho 
    539           1.1    jruoho /*******************************************************************************
    540           1.1    jruoho  *
    541           1.1    jruoho  * FUNCTION:    AcpiDmAddressSpace
    542           1.1    jruoho  *
    543           1.1    jruoho  * PARAMETERS:  SpaceId         - ID to be translated
    544           1.1    jruoho  *
    545           1.1    jruoho  * RETURN:      None
    546           1.1    jruoho  *
    547           1.1    jruoho  * DESCRIPTION: Decode a SpaceId to an AddressSpaceKeyword
    548           1.1    jruoho  *
    549           1.1    jruoho  ******************************************************************************/
    550           1.1    jruoho 
    551           1.1    jruoho void
    552           1.1    jruoho AcpiDmAddressSpace (
    553           1.1    jruoho     UINT8                   SpaceId)
    554           1.1    jruoho {
    555           1.1    jruoho 
    556           1.1    jruoho     if (SpaceId >= ACPI_NUM_PREDEFINED_REGIONS)
    557           1.1    jruoho     {
    558           1.1    jruoho         if (SpaceId == 0x7F)
    559           1.1    jruoho         {
    560           1.1    jruoho             AcpiOsPrintf ("FFixedHW, ");
    561           1.1    jruoho         }
    562           1.1    jruoho         else
    563           1.1    jruoho         {
    564           1.1    jruoho             AcpiOsPrintf ("0x%.2X, ", SpaceId);
    565           1.1    jruoho         }
    566           1.1    jruoho     }
    567           1.1    jruoho     else
    568           1.1    jruoho     {
    569           1.1    jruoho         AcpiOsPrintf ("%s, ", AcpiGbl_RegionTypes [SpaceId]);
    570           1.1    jruoho     }
    571           1.1    jruoho }
    572           1.1    jruoho 
    573           1.1    jruoho 
    574           1.1    jruoho /*******************************************************************************
    575           1.1    jruoho  *
    576           1.1    jruoho  * FUNCTION:    AcpiDmRegionFlags
    577           1.1    jruoho  *
    578           1.1    jruoho  * PARAMETERS:  Op              - Object to be examined
    579           1.1    jruoho  *
    580           1.1    jruoho  * RETURN:      None
    581           1.1    jruoho  *
    582           1.1    jruoho  * DESCRIPTION: Decode OperationRegion flags
    583           1.1    jruoho  *
    584           1.1    jruoho  ******************************************************************************/
    585           1.1    jruoho 
    586           1.1    jruoho void
    587           1.1    jruoho AcpiDmRegionFlags (
    588           1.1    jruoho     ACPI_PARSE_OBJECT       *Op)
    589           1.1    jruoho {
    590           1.1    jruoho 
    591           1.1    jruoho     /* The next Op contains the SpaceId */
    592           1.1    jruoho 
    593           1.1    jruoho     Op = AcpiPsGetDepthNext (NULL, Op);
    594           1.1    jruoho 
    595           1.1    jruoho     /* Mark the Op as completed */
    596           1.1    jruoho 
    597           1.1    jruoho     Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
    598           1.1    jruoho 
    599           1.1    jruoho     AcpiOsPrintf (", ");
    600           1.1    jruoho     AcpiDmAddressSpace ((UINT8) Op->Common.Value.Integer);
    601           1.1    jruoho }
    602           1.1    jruoho 
    603           1.1    jruoho 
    604           1.1    jruoho /*******************************************************************************
    605           1.1    jruoho  *
    606           1.1    jruoho  * FUNCTION:    AcpiDmMatchOp
    607           1.1    jruoho  *
    608           1.1    jruoho  * PARAMETERS:  Op              - Match Object to be examined
    609           1.1    jruoho  *
    610           1.1    jruoho  * RETURN:      None
    611           1.1    jruoho  *
    612           1.1    jruoho  * DESCRIPTION: Decode Match opcode operands
    613           1.1    jruoho  *
    614           1.1    jruoho  ******************************************************************************/
    615           1.1    jruoho 
    616           1.1    jruoho void
    617           1.1    jruoho AcpiDmMatchOp (
    618           1.1    jruoho     ACPI_PARSE_OBJECT       *Op)
    619           1.1    jruoho {
    620           1.1    jruoho     ACPI_PARSE_OBJECT       *NextOp;
    621           1.1    jruoho 
    622           1.1    jruoho 
    623           1.1    jruoho     NextOp = AcpiPsGetDepthNext (NULL, Op);
    624           1.1    jruoho     NextOp = NextOp->Common.Next;
    625           1.1    jruoho 
    626           1.1    jruoho     if (!NextOp)
    627           1.1    jruoho     {
    628           1.1    jruoho         /* Handle partial tree during single-step */
    629           1.1    jruoho 
    630           1.1    jruoho         return;
    631           1.1    jruoho     }
    632           1.1    jruoho 
    633           1.1    jruoho     /* Mark the two nodes that contain the encoding for the match keywords */
    634           1.1    jruoho 
    635           1.1    jruoho     NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;
    636           1.1    jruoho 
    637           1.1    jruoho     NextOp = NextOp->Common.Next;
    638           1.1    jruoho     NextOp = NextOp->Common.Next;
    639           1.1    jruoho     NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;
    640           1.1    jruoho }
    641           1.1    jruoho 
    642           1.1    jruoho 
    643           1.1    jruoho /*******************************************************************************
    644           1.1    jruoho  *
    645           1.1    jruoho  * FUNCTION:    AcpiDmMatchKeyword
    646           1.1    jruoho  *
    647           1.1    jruoho  * PARAMETERS:  Op              - Match Object to be examined
    648           1.1    jruoho  *
    649           1.1    jruoho  * RETURN:      None
    650           1.1    jruoho  *
    651           1.1    jruoho  * DESCRIPTION: Decode Match opcode operands
    652           1.1    jruoho  *
    653           1.1    jruoho  ******************************************************************************/
    654           1.1    jruoho 
    655           1.1    jruoho static void
    656           1.1    jruoho AcpiDmMatchKeyword (
    657           1.1    jruoho     ACPI_PARSE_OBJECT       *Op)
    658           1.1    jruoho {
    659           1.1    jruoho 
    660           1.1    jruoho     if (((UINT32) Op->Common.Value.Integer) > ACPI_MAX_MATCH_OPCODE)
    661           1.1    jruoho     {
    662           1.1    jruoho         AcpiOsPrintf ("/* Unknown Match Keyword encoding */");
    663           1.1    jruoho     }
    664           1.1    jruoho     else
    665           1.1    jruoho     {
    666       1.1.1.8  christos         AcpiOsPrintf ("%s",
    667       1.1.1.8  christos             AcpiGbl_MatchOps[(ACPI_SIZE) Op->Common.Value.Integer]);
    668           1.1    jruoho     }
    669           1.1    jruoho }
    670           1.1    jruoho 
    671           1.1    jruoho 
    672           1.1    jruoho /*******************************************************************************
    673           1.1    jruoho  *
    674           1.1    jruoho  * FUNCTION:    AcpiDmDisassembleOneOp
    675           1.1    jruoho  *
    676           1.1    jruoho  * PARAMETERS:  WalkState           - Current walk info
    677           1.1    jruoho  *              Info                - Parse tree walk info
    678           1.1    jruoho  *              Op                  - Op that is to be printed
    679           1.1    jruoho  *
    680           1.1    jruoho  * RETURN:      None
    681           1.1    jruoho  *
    682           1.1    jruoho  * DESCRIPTION: Disassemble a single AML opcode
    683           1.1    jruoho  *
    684           1.1    jruoho  ******************************************************************************/
    685           1.1    jruoho 
    686           1.1    jruoho void
    687           1.1    jruoho AcpiDmDisassembleOneOp (
    688           1.1    jruoho     ACPI_WALK_STATE         *WalkState,
    689           1.1    jruoho     ACPI_OP_WALK_INFO       *Info,
    690           1.1    jruoho     ACPI_PARSE_OBJECT       *Op)
    691           1.1    jruoho {
    692           1.1    jruoho     const ACPI_OPCODE_INFO  *OpInfo = NULL;
    693           1.1    jruoho     UINT32                  Offset;
    694           1.1    jruoho     UINT32                  Length;
    695           1.1    jruoho     ACPI_PARSE_OBJECT       *Child;
    696           1.1    jruoho     ACPI_STATUS             Status;
    697       1.1.1.3  christos     UINT8                   *Aml;
    698       1.1.1.4  christos     const AH_DEVICE_ID      *IdInfo;
    699           1.1    jruoho 
    700           1.1    jruoho 
    701           1.1    jruoho     if (!Op)
    702           1.1    jruoho     {
    703           1.1    jruoho         AcpiOsPrintf ("<NULL OP PTR>");
    704           1.1    jruoho         return;
    705           1.1    jruoho     }
    706           1.1    jruoho 
    707       1.1.1.7  christos     if (Op->Common.DisasmFlags & ACPI_PARSEOP_ELSEIF)
    708       1.1.1.7  christos     {
    709       1.1.1.7  christos         return; /* ElseIf macro was already emitted */
    710       1.1.1.7  christos     }
    711       1.1.1.7  christos 
    712           1.1    jruoho     switch (Op->Common.DisasmOpcode)
    713           1.1    jruoho     {
    714           1.1    jruoho     case ACPI_DASM_MATCHOP:
    715           1.1    jruoho 
    716           1.1    jruoho         AcpiDmMatchKeyword (Op);
    717           1.1    jruoho         return;
    718           1.1    jruoho 
    719           1.1    jruoho     case ACPI_DASM_LNOT_SUFFIX:
    720       1.1.1.3  christos 
    721       1.1.1.5  christos         if (!AcpiGbl_CstyleDisassembly)
    722           1.1    jruoho         {
    723       1.1.1.5  christos             switch (Op->Common.AmlOpcode)
    724       1.1.1.5  christos             {
    725  1.1.1.11.4.1  pgoyette             case AML_LOGICAL_EQUAL_OP:
    726       1.1.1.5  christos                 AcpiOsPrintf ("LNotEqual");
    727       1.1.1.5  christos                 break;
    728       1.1.1.3  christos 
    729  1.1.1.11.4.1  pgoyette             case AML_LOGICAL_GREATER_OP:
    730       1.1.1.5  christos                 AcpiOsPrintf ("LLessEqual");
    731       1.1.1.5  christos                 break;
    732           1.1    jruoho 
    733  1.1.1.11.4.1  pgoyette             case AML_LOGICAL_LESS_OP:
    734       1.1.1.5  christos                 AcpiOsPrintf ("LGreaterEqual");
    735       1.1.1.5  christos                 break;
    736       1.1.1.3  christos 
    737       1.1.1.5  christos             default:
    738       1.1.1.5  christos                 break;
    739       1.1.1.5  christos             }
    740           1.1    jruoho         }
    741       1.1.1.5  christos 
    742           1.1    jruoho         Op->Common.DisasmOpcode = 0;
    743           1.1    jruoho         Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
    744           1.1    jruoho         return;
    745           1.1    jruoho 
    746           1.1    jruoho     default:
    747           1.1    jruoho         break;
    748           1.1    jruoho     }
    749           1.1    jruoho 
    750           1.1    jruoho     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
    751           1.1    jruoho 
    752           1.1    jruoho     /* The op and arguments */
    753           1.1    jruoho 
    754           1.1    jruoho     switch (Op->Common.AmlOpcode)
    755           1.1    jruoho     {
    756  1.1.1.11.4.1  pgoyette     case AML_LOGICAL_NOT_OP:
    757           1.1    jruoho 
    758           1.1    jruoho         Child = Op->Common.Value.Arg;
    759  1.1.1.11.4.1  pgoyette         if ((Child->Common.AmlOpcode == AML_LOGICAL_EQUAL_OP) ||
    760  1.1.1.11.4.1  pgoyette             (Child->Common.AmlOpcode == AML_LOGICAL_GREATER_OP) ||
    761  1.1.1.11.4.1  pgoyette             (Child->Common.AmlOpcode == AML_LOGICAL_LESS_OP))
    762           1.1    jruoho         {
    763           1.1    jruoho             Child->Common.DisasmOpcode = ACPI_DASM_LNOT_SUFFIX;
    764           1.1    jruoho             Op->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
    765           1.1    jruoho         }
    766           1.1    jruoho         else
    767           1.1    jruoho         {
    768           1.1    jruoho             AcpiOsPrintf ("%s", OpInfo->Name);
    769           1.1    jruoho         }
    770           1.1    jruoho         break;
    771           1.1    jruoho 
    772           1.1    jruoho     case AML_BYTE_OP:
    773           1.1    jruoho 
    774           1.1    jruoho         AcpiOsPrintf ("0x%2.2X", (UINT32) Op->Common.Value.Integer);
    775           1.1    jruoho         break;
    776           1.1    jruoho 
    777           1.1    jruoho     case AML_WORD_OP:
    778           1.1    jruoho 
    779           1.1    jruoho         if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
    780           1.1    jruoho         {
    781       1.1.1.4  christos             AcpiDmDecompressEisaId ((UINT32) Op->Common.Value.Integer);
    782           1.1    jruoho         }
    783           1.1    jruoho         else
    784           1.1    jruoho         {
    785           1.1    jruoho             AcpiOsPrintf ("0x%4.4X", (UINT32) Op->Common.Value.Integer);
    786           1.1    jruoho         }
    787           1.1    jruoho         break;
    788           1.1    jruoho 
    789           1.1    jruoho     case AML_DWORD_OP:
    790           1.1    jruoho 
    791           1.1    jruoho         if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
    792           1.1    jruoho         {
    793       1.1.1.4  christos             AcpiDmDecompressEisaId ((UINT32) Op->Common.Value.Integer);
    794           1.1    jruoho         }
    795           1.1    jruoho         else
    796           1.1    jruoho         {
    797           1.1    jruoho             AcpiOsPrintf ("0x%8.8X", (UINT32) Op->Common.Value.Integer);
    798           1.1    jruoho         }
    799           1.1    jruoho         break;
    800           1.1    jruoho 
    801           1.1    jruoho     case AML_QWORD_OP:
    802           1.1    jruoho 
    803           1.1    jruoho         AcpiOsPrintf ("0x%8.8X%8.8X",
    804           1.1    jruoho             ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
    805           1.1    jruoho         break;
    806           1.1    jruoho 
    807           1.1    jruoho     case AML_STRING_OP:
    808           1.1    jruoho 
    809       1.1.1.3  christos         AcpiUtPrintString (Op->Common.Value.String, ACPI_UINT16_MAX);
    810       1.1.1.4  christos 
    811       1.1.1.4  christos         /* For _HID/_CID strings, attempt to output a descriptive comment */
    812       1.1.1.4  christos 
    813       1.1.1.4  christos         if (Op->Common.DisasmOpcode == ACPI_DASM_HID_STRING)
    814       1.1.1.4  christos         {
    815       1.1.1.4  christos             /* If we know about the ID, emit the description */
    816       1.1.1.4  christos 
    817       1.1.1.4  christos             IdInfo = AcpiAhMatchHardwareId (Op->Common.Value.String);
    818       1.1.1.4  christos             if (IdInfo)
    819       1.1.1.4  christos             {
    820       1.1.1.4  christos                 AcpiOsPrintf (" /* %s */", IdInfo->Description);
    821       1.1.1.4  christos             }
    822       1.1.1.4  christos         }
    823           1.1    jruoho         break;
    824           1.1    jruoho 
    825           1.1    jruoho     case AML_BUFFER_OP:
    826           1.1    jruoho         /*
    827       1.1.1.3  christos          * Determine the type of buffer. We can have one of the following:
    828           1.1    jruoho          *
    829           1.1    jruoho          * 1) ResourceTemplate containing Resource Descriptors.
    830           1.1    jruoho          * 2) Unicode String buffer
    831           1.1    jruoho          * 3) ASCII String buffer
    832           1.1    jruoho          * 4) Raw data buffer (if none of the above)
    833           1.1    jruoho          *
    834           1.1    jruoho          * Since there are no special AML opcodes to differentiate these
    835           1.1    jruoho          * types of buffers, we have to closely look at the data in the
    836           1.1    jruoho          * buffer to determine the type.
    837           1.1    jruoho          */
    838       1.1.1.3  christos         if (!AcpiGbl_NoResourceDisassembly)
    839           1.1    jruoho         {
    840       1.1.1.3  christos             Status = AcpiDmIsResourceTemplate (WalkState, Op);
    841       1.1.1.3  christos             if (ACPI_SUCCESS (Status))
    842       1.1.1.3  christos             {
    843       1.1.1.3  christos                 Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
    844       1.1.1.3  christos                 AcpiOsPrintf ("ResourceTemplate");
    845       1.1.1.3  christos                 break;
    846       1.1.1.3  christos             }
    847       1.1.1.3  christos             else if (Status == AE_AML_NO_RESOURCE_END_TAG)
    848       1.1.1.3  christos             {
    849       1.1.1.7  christos                 AcpiOsPrintf (
    850       1.1.1.7  christos                     "/**** Is ResourceTemplate, "
    851       1.1.1.7  christos                     "but EndTag not at buffer end ****/ ");
    852       1.1.1.3  christos             }
    853           1.1    jruoho         }
    854           1.1    jruoho 
    855       1.1.1.4  christos         if (AcpiDmIsUuidBuffer (Op))
    856       1.1.1.4  christos         {
    857       1.1.1.4  christos             Op->Common.DisasmOpcode = ACPI_DASM_UUID;
    858       1.1.1.4  christos             AcpiOsPrintf ("ToUUID (");
    859       1.1.1.4  christos         }
    860       1.1.1.4  christos         else if (AcpiDmIsUnicodeBuffer (Op))
    861           1.1    jruoho         {
    862           1.1    jruoho             Op->Common.DisasmOpcode = ACPI_DASM_UNICODE;
    863           1.1    jruoho             AcpiOsPrintf ("Unicode (");
    864           1.1    jruoho         }
    865           1.1    jruoho         else if (AcpiDmIsStringBuffer (Op))
    866           1.1    jruoho         {
    867           1.1    jruoho             Op->Common.DisasmOpcode = ACPI_DASM_STRING;
    868           1.1    jruoho             AcpiOsPrintf ("Buffer");
    869           1.1    jruoho         }
    870       1.1.1.3  christos         else if (AcpiDmIsPldBuffer (Op))
    871       1.1.1.3  christos         {
    872       1.1.1.3  christos             Op->Common.DisasmOpcode = ACPI_DASM_PLD_METHOD;
    873       1.1.1.5  christos             AcpiOsPrintf ("ToPLD (");
    874       1.1.1.3  christos         }
    875           1.1    jruoho         else
    876           1.1    jruoho         {
    877           1.1    jruoho             Op->Common.DisasmOpcode = ACPI_DASM_BUFFER;
    878           1.1    jruoho             AcpiOsPrintf ("Buffer");
    879           1.1    jruoho         }
    880           1.1    jruoho         break;
    881           1.1    jruoho 
    882           1.1    jruoho     case AML_INT_NAMEPATH_OP:
    883           1.1    jruoho 
    884           1.1    jruoho         AcpiDmNamestring (Op->Common.Value.Name);
    885           1.1    jruoho         break;
    886           1.1    jruoho 
    887           1.1    jruoho     case AML_INT_NAMEDFIELD_OP:
    888           1.1    jruoho 
    889           1.1    jruoho         Length = AcpiDmDumpName (Op->Named.Name);
    890  1.1.1.11.4.1  pgoyette 
    891  1.1.1.11.4.1  pgoyette         AcpiOsPrintf (",");
    892  1.1.1.11.4.1  pgoyette         ASL_CV_PRINT_ONE_COMMENT (Op, AML_NAMECOMMENT, NULL, 0);
    893  1.1.1.11.4.1  pgoyette         AcpiOsPrintf ("%*.s  %u", (unsigned) (5 - Length), " ",
    894           1.1    jruoho             (UINT32) Op->Common.Value.Integer);
    895  1.1.1.11.4.1  pgoyette 
    896           1.1    jruoho         AcpiDmCommaIfFieldMember (Op);
    897           1.1    jruoho 
    898           1.1    jruoho         Info->BitOffset += (UINT32) Op->Common.Value.Integer;
    899           1.1    jruoho         break;
    900           1.1    jruoho 
    901           1.1    jruoho     case AML_INT_RESERVEDFIELD_OP:
    902           1.1    jruoho 
    903           1.1    jruoho         /* Offset() -- Must account for previous offsets */
    904           1.1    jruoho 
    905           1.1    jruoho         Offset = (UINT32) Op->Common.Value.Integer;
    906           1.1    jruoho         Info->BitOffset += Offset;
    907           1.1    jruoho 
    908           1.1    jruoho         if (Info->BitOffset % 8 == 0)
    909           1.1    jruoho         {
    910       1.1.1.3  christos             AcpiOsPrintf ("Offset (0x%.2X)", ACPI_DIV_8 (Info->BitOffset));
    911           1.1    jruoho         }
    912           1.1    jruoho         else
    913           1.1    jruoho         {
    914           1.1    jruoho             AcpiOsPrintf ("    ,   %u", Offset);
    915           1.1    jruoho         }
    916           1.1    jruoho 
    917           1.1    jruoho         AcpiDmCommaIfFieldMember (Op);
    918           1.1    jruoho         break;
    919           1.1    jruoho 
    920           1.1    jruoho     case AML_INT_ACCESSFIELD_OP:
    921       1.1.1.3  christos     case AML_INT_EXTACCESSFIELD_OP:
    922       1.1.1.3  christos 
    923       1.1.1.3  christos         AcpiOsPrintf ("AccessAs (%s, ",
    924       1.1.1.3  christos             AcpiGbl_AccessTypes [(UINT32) (Op->Common.Value.Integer & 0x7)]);
    925       1.1.1.3  christos 
    926       1.1.1.3  christos         AcpiDmDecodeAttribute ((UINT8) (Op->Common.Value.Integer >> 8));
    927           1.1    jruoho 
    928       1.1.1.3  christos         if (Op->Common.AmlOpcode == AML_INT_EXTACCESSFIELD_OP)
    929       1.1.1.3  christos         {
    930       1.1.1.7  christos             AcpiOsPrintf (" (0x%2.2X)", (unsigned)
    931       1.1.1.7  christos                 ((Op->Common.Value.Integer >> 16) & 0xFF));
    932       1.1.1.3  christos         }
    933           1.1    jruoho 
    934           1.1    jruoho         AcpiOsPrintf (")");
    935           1.1    jruoho         AcpiDmCommaIfFieldMember (Op);
    936  1.1.1.11.4.1  pgoyette         ASL_CV_PRINT_ONE_COMMENT (Op, AML_COMMENT_END_NODE, NULL, 0);
    937           1.1    jruoho         break;
    938           1.1    jruoho 
    939       1.1.1.3  christos     case AML_INT_CONNECTION_OP:
    940       1.1.1.3  christos         /*
    941       1.1.1.3  christos          * Two types of Connection() - one with a buffer object, the
    942       1.1.1.3  christos          * other with a namestring that points to a buffer object.
    943       1.1.1.3  christos          */
    944       1.1.1.3  christos         AcpiOsPrintf ("Connection (");
    945       1.1.1.3  christos         Child = Op->Common.Value.Arg;
    946       1.1.1.3  christos 
    947       1.1.1.3  christos         if (Child->Common.AmlOpcode == AML_INT_BYTELIST_OP)
    948       1.1.1.3  christos         {
    949       1.1.1.3  christos             AcpiOsPrintf ("\n");
    950       1.1.1.3  christos 
    951       1.1.1.3  christos             Aml = Child->Named.Data;
    952       1.1.1.3  christos             Length = (UINT32) Child->Common.Value.Integer;
    953       1.1.1.3  christos 
    954       1.1.1.3  christos             Info->Level += 1;
    955       1.1.1.4  christos             Info->MappingOp = Op;
    956       1.1.1.3  christos             Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
    957       1.1.1.4  christos 
    958       1.1.1.3  christos             AcpiDmResourceTemplate (Info, Op->Common.Parent, Aml, Length);
    959       1.1.1.3  christos 
    960       1.1.1.3  christos             Info->Level -= 1;
    961       1.1.1.3  christos             AcpiDmIndent (Info->Level);
    962       1.1.1.3  christos         }
    963       1.1.1.3  christos         else
    964       1.1.1.3  christos         {
    965       1.1.1.3  christos             AcpiDmNamestring (Child->Common.Value.Name);
    966       1.1.1.3  christos         }
    967       1.1.1.3  christos 
    968       1.1.1.3  christos         AcpiOsPrintf (")");
    969       1.1.1.3  christos         AcpiDmCommaIfFieldMember (Op);
    970  1.1.1.11.4.1  pgoyette         ASL_CV_PRINT_ONE_COMMENT (Op, AML_COMMENT_END_NODE, NULL, 0);
    971  1.1.1.11.4.1  pgoyette         ASL_CV_PRINT_ONE_COMMENT (Op, AMLCOMMENT_INLINE, NULL, 0);
    972       1.1.1.3  christos         AcpiOsPrintf ("\n");
    973       1.1.1.3  christos 
    974       1.1.1.3  christos         Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; /* for now, ignore in AcpiDmAscendingOp */
    975       1.1.1.3  christos         Child->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
    976       1.1.1.3  christos         break;
    977           1.1    jruoho 
    978           1.1    jruoho     case AML_INT_BYTELIST_OP:
    979           1.1    jruoho 
    980           1.1    jruoho         AcpiDmByteList (Info, Op);
    981           1.1    jruoho         break;
    982           1.1    jruoho 
    983           1.1    jruoho     case AML_INT_METHODCALL_OP:
    984           1.1    jruoho 
    985           1.1    jruoho         Op = AcpiPsGetDepthNext (NULL, Op);
    986           1.1    jruoho         Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
    987           1.1    jruoho 
    988           1.1    jruoho         AcpiDmNamestring (Op->Common.Value.Name);
    989           1.1    jruoho         break;
    990           1.1    jruoho 
    991      1.1.1.11  christos     case AML_WHILE_OP:
    992      1.1.1.11  christos 
    993  1.1.1.11.4.1  pgoyette         if (Op->Common.DisasmOpcode == ACPI_DASM_SWITCH)
    994      1.1.1.11  christos         {
    995      1.1.1.11  christos             AcpiOsPrintf ("%s", "Switch");
    996      1.1.1.11  christos             break;
    997      1.1.1.11  christos         }
    998      1.1.1.11  christos 
    999      1.1.1.11  christos         AcpiOsPrintf ("%s", OpInfo->Name);
   1000      1.1.1.11  christos         break;
   1001      1.1.1.11  christos 
   1002      1.1.1.11  christos     case AML_IF_OP:
   1003      1.1.1.11  christos 
   1004      1.1.1.11  christos         if (Op->Common.DisasmOpcode == ACPI_DASM_CASE)
   1005      1.1.1.11  christos         {
   1006      1.1.1.11  christos             AcpiOsPrintf ("%s", "Case");
   1007      1.1.1.11  christos             break;
   1008      1.1.1.11  christos         }
   1009      1.1.1.11  christos 
   1010      1.1.1.11  christos         AcpiOsPrintf ("%s", OpInfo->Name);
   1011      1.1.1.11  christos         break;
   1012      1.1.1.11  christos 
   1013       1.1.1.7  christos     case AML_ELSE_OP:
   1014       1.1.1.7  christos 
   1015       1.1.1.7  christos         AcpiDmConvertToElseIf (Op);
   1016       1.1.1.7  christos         break;
   1017       1.1.1.7  christos 
   1018       1.1.1.8  christos     case AML_EXTERNAL_OP:
   1019       1.1.1.8  christos 
   1020       1.1.1.9  christos         if (AcpiGbl_DmEmitExternalOpcodes)
   1021       1.1.1.9  christos         {
   1022  1.1.1.11.4.1  pgoyette             AcpiDmEmitExternal (AcpiPsGetArg(Op, 0),
   1023  1.1.1.11.4.1  pgoyette                 AcpiPsGetArg(Op, 1));
   1024       1.1.1.9  christos             break;
   1025       1.1.1.9  christos         }
   1026       1.1.1.8  christos 
   1027  1.1.1.11.4.1  pgoyette         break;
   1028  1.1.1.11.4.1  pgoyette 
   1029           1.1    jruoho     default:
   1030           1.1    jruoho 
   1031           1.1    jruoho         /* Just get the opcode name and print it */
   1032           1.1    jruoho 
   1033           1.1    jruoho         AcpiOsPrintf ("%s", OpInfo->Name);
   1034           1.1    jruoho 
   1035           1.1    jruoho 
   1036           1.1    jruoho #ifdef ACPI_DEBUGGER
   1037           1.1    jruoho 
   1038           1.1    jruoho         if ((Op->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP) &&
   1039           1.1    jruoho             (WalkState) &&
   1040           1.1    jruoho             (WalkState->Results) &&
   1041           1.1    jruoho             (WalkState->ResultCount))
   1042           1.1    jruoho         {
   1043       1.1.1.6  christos             AcpiDbDecodeInternalObject (
   1044           1.1    jruoho                 WalkState->Results->Results.ObjDesc [
   1045           1.1    jruoho                     (WalkState->ResultCount - 1) %
   1046           1.1    jruoho                         ACPI_RESULTS_FRAME_OBJ_NUM]);
   1047           1.1    jruoho         }
   1048           1.1    jruoho #endif
   1049           1.1    jruoho 
   1050           1.1    jruoho         break;
   1051           1.1    jruoho     }
   1052           1.1    jruoho }
   1053           1.1    jruoho 
   1054       1.1.1.7  christos 
   1055       1.1.1.7  christos /*******************************************************************************
   1056       1.1.1.7  christos  *
   1057       1.1.1.7  christos  * FUNCTION:    AcpiDmConvertToElseIf
   1058       1.1.1.7  christos  *
   1059       1.1.1.7  christos  * PARAMETERS:  OriginalElseOp          - ELSE Object to be examined
   1060       1.1.1.7  christos  *
   1061       1.1.1.7  christos  * RETURN:      None. Emits either an "Else" or an "ElseIf" ASL operator.
   1062       1.1.1.7  christos  *
   1063       1.1.1.7  christos  * DESCRIPTION: Detect and convert an If..Else..If sequence to If..ElseIf
   1064       1.1.1.7  christos  *
   1065       1.1.1.7  christos  * EXAMPLE:
   1066       1.1.1.7  christos  *
   1067       1.1.1.7  christos  * This If..Else..If nested sequence:
   1068       1.1.1.7  christos  *
   1069       1.1.1.7  christos  *        If (Arg0 == 1)
   1070       1.1.1.7  christos  *        {
   1071       1.1.1.7  christos  *            Local0 = 4
   1072       1.1.1.7  christos  *        }
   1073       1.1.1.7  christos  *        Else
   1074       1.1.1.7  christos  *        {
   1075       1.1.1.7  christos  *            If (Arg0 == 2)
   1076       1.1.1.7  christos  *            {
   1077       1.1.1.7  christos  *                Local0 = 5
   1078       1.1.1.7  christos  *            }
   1079       1.1.1.7  christos  *        }
   1080       1.1.1.7  christos  *
   1081       1.1.1.7  christos  * Is converted to this simpler If..ElseIf sequence:
   1082       1.1.1.7  christos  *
   1083       1.1.1.7  christos  *        If (Arg0 == 1)
   1084       1.1.1.7  christos  *        {
   1085       1.1.1.7  christos  *            Local0 = 4
   1086       1.1.1.7  christos  *        }
   1087       1.1.1.7  christos  *        ElseIf (Arg0 == 2)
   1088       1.1.1.7  christos  *        {
   1089       1.1.1.7  christos  *            Local0 = 5
   1090       1.1.1.7  christos  *        }
   1091       1.1.1.7  christos  *
   1092       1.1.1.7  christos  * NOTE: There is no actual ElseIf AML opcode. ElseIf is essentially an ASL
   1093       1.1.1.7  christos  * macro that emits an Else opcode followed by an If opcode. This function
   1094       1.1.1.7  christos  * reverses these AML sequences back to an ElseIf macro where possible. This
   1095       1.1.1.7  christos  * can make the disassembled ASL code simpler and more like the original code.
   1096       1.1.1.7  christos  *
   1097       1.1.1.7  christos  ******************************************************************************/
   1098       1.1.1.7  christos 
   1099       1.1.1.7  christos static void
   1100       1.1.1.7  christos AcpiDmConvertToElseIf (
   1101       1.1.1.7  christos     ACPI_PARSE_OBJECT       *OriginalElseOp)
   1102       1.1.1.7  christos {
   1103       1.1.1.7  christos     ACPI_PARSE_OBJECT       *IfOp;
   1104       1.1.1.7  christos     ACPI_PARSE_OBJECT       *ElseOp;
   1105       1.1.1.7  christos 
   1106       1.1.1.7  christos 
   1107       1.1.1.8  christos     /*
   1108       1.1.1.8  christos      * To be able to perform the conversion, two conditions must be satisfied:
   1109       1.1.1.8  christos      * 1) The first child of the Else must be an If statement.
   1110       1.1.1.8  christos      * 2) The If block can only be followed by an Else block and these must
   1111       1.1.1.8  christos      *    be the only blocks under the original Else.
   1112       1.1.1.8  christos      */
   1113       1.1.1.7  christos     IfOp = OriginalElseOp->Common.Value.Arg;
   1114      1.1.1.10  christos 
   1115       1.1.1.8  christos     if (!IfOp ||
   1116       1.1.1.8  christos         (IfOp->Common.AmlOpcode != AML_IF_OP) ||
   1117       1.1.1.8  christos         (IfOp->Asl.Next && (IfOp->Asl.Next->Common.AmlOpcode != AML_ELSE_OP)))
   1118       1.1.1.7  christos     {
   1119      1.1.1.10  christos         /* Not a proper Else..If sequence, cannot convert to ElseIf */
   1120      1.1.1.10  christos 
   1121      1.1.1.11  christos         if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_DEFAULT)
   1122      1.1.1.11  christos         {
   1123      1.1.1.11  christos             AcpiOsPrintf ("%s", "Default");
   1124      1.1.1.11  christos             return;
   1125      1.1.1.11  christos         }
   1126      1.1.1.11  christos 
   1127      1.1.1.10  christos         AcpiOsPrintf ("%s", "Else");
   1128      1.1.1.10  christos         return;
   1129      1.1.1.10  christos     }
   1130      1.1.1.10  christos 
   1131      1.1.1.10  christos     /* Cannot have anything following the If...Else block */
   1132       1.1.1.7  christos 
   1133      1.1.1.10  christos     ElseOp = IfOp->Common.Next;
   1134      1.1.1.10  christos     if (ElseOp && ElseOp->Common.Next)
   1135      1.1.1.10  christos     {
   1136      1.1.1.11  christos         if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_DEFAULT)
   1137      1.1.1.11  christos         {
   1138      1.1.1.11  christos             AcpiOsPrintf ("%s", "Default");
   1139      1.1.1.11  christos             return;
   1140      1.1.1.11  christos         }
   1141      1.1.1.11  christos 
   1142       1.1.1.7  christos         AcpiOsPrintf ("%s", "Else");
   1143       1.1.1.7  christos         return;
   1144       1.1.1.7  christos     }
   1145       1.1.1.7  christos 
   1146      1.1.1.11  christos     if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_DEFAULT)
   1147      1.1.1.11  christos     {
   1148      1.1.1.11  christos         /*
   1149      1.1.1.11  christos          * There is an ElseIf but in this case the Else is actually
   1150      1.1.1.11  christos          * a Default block for a Switch/Case statement. No conversion.
   1151      1.1.1.11  christos          */
   1152      1.1.1.11  christos         AcpiOsPrintf ("%s", "Default");
   1153      1.1.1.11  christos         return;
   1154      1.1.1.11  christos     }
   1155      1.1.1.11  christos 
   1156      1.1.1.11  christos     if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_CASE)
   1157      1.1.1.11  christos     {
   1158      1.1.1.11  christos         /*
   1159      1.1.1.11  christos          * This ElseIf is actually a Case block for a Switch/Case
   1160      1.1.1.11  christos          * statement. Print Case but do not return so that we can
   1161      1.1.1.11  christos          * promote the subtree and keep the indentation level.
   1162      1.1.1.11  christos          */
   1163      1.1.1.11  christos         AcpiOsPrintf ("%s", "Case");
   1164      1.1.1.11  christos     }
   1165      1.1.1.11  christos     else
   1166      1.1.1.11  christos     {
   1167      1.1.1.11  christos        /* Emit ElseIf, mark the IF as now an ELSEIF */
   1168      1.1.1.11  christos 
   1169      1.1.1.11  christos         AcpiOsPrintf ("%s", "ElseIf");
   1170      1.1.1.11  christos     }
   1171       1.1.1.7  christos 
   1172       1.1.1.7  christos     IfOp->Common.DisasmFlags |= ACPI_PARSEOP_ELSEIF;
   1173       1.1.1.7  christos 
   1174       1.1.1.7  christos     /* The IF parent will now be the same as the original ELSE parent */
   1175       1.1.1.7  christos 
   1176       1.1.1.7  christos     IfOp->Common.Parent = OriginalElseOp->Common.Parent;
   1177       1.1.1.7  christos 
   1178       1.1.1.7  christos     /*
   1179       1.1.1.7  christos      * Update the NEXT pointers to restructure the parse tree, essentially
   1180       1.1.1.7  christos      * promoting an If..Else block up to the same level as the original
   1181       1.1.1.7  christos      * Else.
   1182       1.1.1.7  christos      *
   1183       1.1.1.7  christos      * Check if the IF has a corresponding ELSE peer
   1184       1.1.1.7  christos      */
   1185       1.1.1.7  christos     ElseOp = IfOp->Common.Next;
   1186       1.1.1.7  christos     if (ElseOp &&
   1187       1.1.1.7  christos         (ElseOp->Common.AmlOpcode == AML_ELSE_OP))
   1188       1.1.1.7  christos     {
   1189       1.1.1.7  christos         /* If an ELSE matches the IF, promote it also */
   1190       1.1.1.7  christos 
   1191       1.1.1.7  christos         ElseOp->Common.Parent = OriginalElseOp->Common.Parent;
   1192      1.1.1.10  christos 
   1193      1.1.1.10  christos         /* Promote the entire block under the ElseIf (All Next OPs) */
   1194      1.1.1.10  christos 
   1195      1.1.1.10  christos         AcpiDmPromoteSubtree (OriginalElseOp);
   1196       1.1.1.7  christos     }
   1197       1.1.1.7  christos     else
   1198       1.1.1.7  christos     {
   1199       1.1.1.7  christos         /* Otherwise, set the IF NEXT to the original ELSE NEXT */
   1200       1.1.1.7  christos 
   1201       1.1.1.7  christos         IfOp->Common.Next = OriginalElseOp->Common.Next;
   1202       1.1.1.7  christos     }
   1203       1.1.1.7  christos 
   1204       1.1.1.7  christos     /* Detach the child IF block from the original ELSE */
   1205       1.1.1.7  christos 
   1206       1.1.1.7  christos     OriginalElseOp->Common.Value.Arg = NULL;
   1207       1.1.1.7  christos 
   1208       1.1.1.7  christos     /* Ignore the original ELSE from now on */
   1209       1.1.1.7  christos 
   1210       1.1.1.7  christos     OriginalElseOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
   1211       1.1.1.7  christos     OriginalElseOp->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
   1212       1.1.1.7  christos 
   1213       1.1.1.7  christos     /* Insert IF (now ELSEIF) as next peer of the original ELSE */
   1214       1.1.1.7  christos 
   1215       1.1.1.7  christos     OriginalElseOp->Common.Next = IfOp;
   1216       1.1.1.7  christos }
   1217      1.1.1.10  christos 
   1218      1.1.1.10  christos 
   1219      1.1.1.10  christos /*******************************************************************************
   1220      1.1.1.10  christos  *
   1221      1.1.1.10  christos  * FUNCTION:    AcpiDmPromoteSubtree
   1222      1.1.1.10  christos  *
   1223      1.1.1.10  christos  * PARAMETERS:  StartOpOp           - Original parent of the entire subtree
   1224      1.1.1.10  christos  *
   1225      1.1.1.10  christos  * RETURN:      None
   1226      1.1.1.10  christos  *
   1227      1.1.1.10  christos  * DESCRIPTION: Promote an entire parse subtree up one level.
   1228      1.1.1.10  christos  *
   1229      1.1.1.10  christos  ******************************************************************************/
   1230      1.1.1.10  christos 
   1231      1.1.1.10  christos static void
   1232      1.1.1.10  christos AcpiDmPromoteSubtree (
   1233      1.1.1.10  christos     ACPI_PARSE_OBJECT       *StartOp)
   1234      1.1.1.10  christos {
   1235      1.1.1.10  christos     ACPI_PARSE_OBJECT       *Op;
   1236      1.1.1.10  christos     ACPI_PARSE_OBJECT       *ParentOp;
   1237      1.1.1.10  christos 
   1238      1.1.1.10  christos 
   1239      1.1.1.10  christos     /* New parent for subtree elements */
   1240      1.1.1.10  christos 
   1241      1.1.1.10  christos     ParentOp = StartOp->Common.Parent;
   1242      1.1.1.10  christos 
   1243      1.1.1.10  christos     /* First child starts the subtree */
   1244      1.1.1.10  christos 
   1245      1.1.1.10  christos     Op = StartOp->Common.Value.Arg;
   1246      1.1.1.10  christos 
   1247      1.1.1.10  christos     /* Walk the top-level elements of the subtree */
   1248      1.1.1.10  christos 
   1249      1.1.1.10  christos     while (Op)
   1250      1.1.1.10  christos     {
   1251      1.1.1.10  christos         Op->Common.Parent = ParentOp;
   1252      1.1.1.10  christos         if (!Op->Common.Next)
   1253      1.1.1.10  christos         {
   1254      1.1.1.10  christos             /* Last Op in list, update its next field */
   1255      1.1.1.10  christos 
   1256      1.1.1.10  christos             Op->Common.Next = StartOp->Common.Next;
   1257      1.1.1.10  christos             break;
   1258      1.1.1.10  christos         }
   1259      1.1.1.10  christos         Op = Op->Common.Next;
   1260      1.1.1.10  christos     }
   1261      1.1.1.10  christos }
   1262      1.1.1.11  christos 
   1263      1.1.1.11  christos /*******************************************************************************
   1264      1.1.1.11  christos  *
   1265      1.1.1.11  christos  * FUNCTION:    AcpiDmIsTempName
   1266      1.1.1.11  christos  *
   1267      1.1.1.11  christos  * PARAMETERS:  Op              - Object to be examined
   1268      1.1.1.11  christos  *
   1269  1.1.1.11.4.1  pgoyette  * RETURN:      TRUE if object is a temporary (_T_x) name for a matching While
   1270  1.1.1.11.4.1  pgoyette  *              loop that can be converted to a Switch.
   1271      1.1.1.11  christos  *
   1272  1.1.1.11.4.1  pgoyette  * DESCRIPTION: _T_X objects are only used for Switch statements. If a temporary
   1273  1.1.1.11.4.1  pgoyette  *              name exists, search the siblings for a matching While (One) loop
   1274  1.1.1.11.4.1  pgoyette  *              that can be converted to a Switch. Return TRUE if a match was
   1275  1.1.1.11.4.1  pgoyette  *              found, FALSE otherwise.
   1276      1.1.1.11  christos  *
   1277      1.1.1.11  christos  ******************************************************************************/
   1278      1.1.1.11  christos 
   1279      1.1.1.11  christos BOOLEAN
   1280      1.1.1.11  christos AcpiDmIsTempName (
   1281      1.1.1.11  christos     ACPI_PARSE_OBJECT       *Op)
   1282      1.1.1.11  christos {
   1283  1.1.1.11.4.1  pgoyette     ACPI_PARSE_OBJECT       *CurrentOp;
   1284      1.1.1.11  christos     char                    *Temp;
   1285      1.1.1.11  christos 
   1286      1.1.1.11  christos     if (Op->Common.AmlOpcode != AML_NAME_OP)
   1287      1.1.1.11  christos     {
   1288      1.1.1.11  christos         return (FALSE);
   1289      1.1.1.11  christos     }
   1290      1.1.1.11  christos 
   1291      1.1.1.11  christos     Temp = (char *)(Op->Common.Aml);
   1292      1.1.1.11  christos     ++Temp;
   1293      1.1.1.11  christos 
   1294      1.1.1.11  christos     if (strncmp(Temp, "_T_", 3))
   1295      1.1.1.11  christos     {
   1296      1.1.1.11  christos         return (FALSE);
   1297      1.1.1.11  christos     }
   1298      1.1.1.11  christos 
   1299  1.1.1.11.4.1  pgoyette     CurrentOp = Op->Common.Next;
   1300  1.1.1.11.4.1  pgoyette     while (CurrentOp)
   1301  1.1.1.11.4.1  pgoyette     {
   1302  1.1.1.11.4.1  pgoyette         if (CurrentOp->Common.AmlOpcode == AML_WHILE_OP &&
   1303  1.1.1.11.4.1  pgoyette             AcpiDmIsSwitchBlock(CurrentOp, Temp))
   1304  1.1.1.11.4.1  pgoyette         {
   1305  1.1.1.11.4.1  pgoyette             Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
   1306  1.1.1.11.4.1  pgoyette             CurrentOp->Common.DisasmOpcode = ACPI_DASM_SWITCH;
   1307      1.1.1.11  christos 
   1308  1.1.1.11.4.1  pgoyette             return (TRUE);
   1309  1.1.1.11.4.1  pgoyette         }
   1310  1.1.1.11.4.1  pgoyette         CurrentOp = CurrentOp->Common.Next;
   1311  1.1.1.11.4.1  pgoyette     }
   1312      1.1.1.11  christos 
   1313  1.1.1.11.4.1  pgoyette     return (FALSE);
   1314      1.1.1.11  christos }
   1315      1.1.1.11  christos 
   1316      1.1.1.11  christos /*******************************************************************************
   1317      1.1.1.11  christos  *
   1318      1.1.1.11  christos  * FUNCTION:    AcpiDmIsSwitchBlock
   1319      1.1.1.11  christos  *
   1320      1.1.1.11  christos  * PARAMETERS:  Op              - While Object
   1321      1.1.1.11  christos  *
   1322      1.1.1.11  christos  * RETURN:      TRUE if While block can be converted to a Switch/Case block
   1323      1.1.1.11  christos  *
   1324      1.1.1.11  christos  * DESCRIPTION: Determines if While block is a Switch/Case statement. Modifies
   1325      1.1.1.11  christos  *              parse tree to allow for Switch/Case disassembly during walk.
   1326      1.1.1.11  christos  *
   1327      1.1.1.11  christos  * EXAMPLE: Example of parse tree to be converted
   1328      1.1.1.11  christos  *
   1329      1.1.1.11  christos  *    While
   1330      1.1.1.11  christos  *        One
   1331      1.1.1.11  christos  *        Store
   1332      1.1.1.11  christos  *            ByteConst
   1333      1.1.1.11  christos  *             -NamePath-
   1334      1.1.1.11  christos  *        If
   1335      1.1.1.11  christos  *            LEqual
   1336      1.1.1.11  christos  *                -NamePath-
   1337      1.1.1.11  christos  *                Zero
   1338      1.1.1.11  christos  *            Return
   1339      1.1.1.11  christos  *                One
   1340      1.1.1.11  christos  *        Else
   1341      1.1.1.11  christos  *            Return
   1342      1.1.1.11  christos  *                WordConst
   1343      1.1.1.11  christos  *        Break
   1344      1.1.1.11  christos  *
   1345      1.1.1.11  christos  ******************************************************************************/
   1346      1.1.1.11  christos 
   1347      1.1.1.11  christos static BOOLEAN
   1348      1.1.1.11  christos AcpiDmIsSwitchBlock (
   1349  1.1.1.11.4.1  pgoyette     ACPI_PARSE_OBJECT       *Op,
   1350  1.1.1.11.4.1  pgoyette     char                    *Temp)
   1351      1.1.1.11  christos {
   1352      1.1.1.11  christos     ACPI_PARSE_OBJECT       *OneOp;
   1353      1.1.1.11  christos     ACPI_PARSE_OBJECT       *StoreOp;
   1354      1.1.1.11  christos     ACPI_PARSE_OBJECT       *NamePathOp;
   1355      1.1.1.11  christos     ACPI_PARSE_OBJECT       *PredicateOp;
   1356      1.1.1.11  christos     ACPI_PARSE_OBJECT       *CurrentOp;
   1357      1.1.1.11  christos     ACPI_PARSE_OBJECT       *TempOp;
   1358      1.1.1.11  christos 
   1359      1.1.1.11  christos     /* Check for One Op Predicate */
   1360      1.1.1.11  christos 
   1361      1.1.1.11  christos     OneOp = AcpiPsGetArg (Op, 0);
   1362      1.1.1.11  christos     if (!OneOp || (OneOp->Common.AmlOpcode != AML_ONE_OP))
   1363      1.1.1.11  christos     {
   1364      1.1.1.11  christos         return (FALSE);
   1365      1.1.1.11  christos     }
   1366      1.1.1.11  christos 
   1367      1.1.1.11  christos     /* Check for Store Op */
   1368      1.1.1.11  christos 
   1369      1.1.1.11  christos     StoreOp = OneOp->Common.Next;
   1370      1.1.1.11  christos     if (!StoreOp || (StoreOp->Common.AmlOpcode != AML_STORE_OP))
   1371      1.1.1.11  christos     {
   1372      1.1.1.11  christos         return (FALSE);
   1373      1.1.1.11  christos     }
   1374      1.1.1.11  christos 
   1375      1.1.1.11  christos     /* Check for Name Op with _T_ string */
   1376      1.1.1.11  christos 
   1377      1.1.1.11  christos     NamePathOp = AcpiPsGetArg (StoreOp, 1);
   1378      1.1.1.11  christos     if (!NamePathOp || (NamePathOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP))
   1379      1.1.1.11  christos     {
   1380      1.1.1.11  christos         return (FALSE);
   1381      1.1.1.11  christos     }
   1382      1.1.1.11  christos 
   1383  1.1.1.11.4.1  pgoyette     if (strncmp((char *)(NamePathOp->Common.Aml), Temp, 4))
   1384      1.1.1.11  christos     {
   1385      1.1.1.11  christos         return (FALSE);
   1386      1.1.1.11  christos     }
   1387      1.1.1.11  christos 
   1388      1.1.1.11  christos     /* This is a Switch/Case control block */
   1389      1.1.1.11  christos 
   1390      1.1.1.11  christos     /* Ignore the One Op Predicate */
   1391      1.1.1.11  christos 
   1392      1.1.1.11  christos     OneOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
   1393      1.1.1.11  christos 
   1394      1.1.1.11  christos     /* Ignore the Store Op, but not the children */
   1395      1.1.1.11  christos 
   1396      1.1.1.11  christos     StoreOp->Common.DisasmOpcode = ACPI_DASM_IGNORE_SINGLE;
   1397      1.1.1.11  christos 
   1398      1.1.1.11  christos     /*
   1399      1.1.1.11  christos      * First arg of Store Op is the Switch condition.
   1400      1.1.1.11  christos      * Mark it as a Switch predicate and as a parameter list for paren
   1401      1.1.1.11  christos      * closing and correct indentation.
   1402      1.1.1.11  christos      */
   1403      1.1.1.11  christos     PredicateOp = AcpiPsGetArg (StoreOp, 0);
   1404      1.1.1.11  christos     PredicateOp->Common.DisasmOpcode = ACPI_DASM_SWITCH_PREDICATE;
   1405      1.1.1.11  christos     PredicateOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
   1406      1.1.1.11  christos 
   1407      1.1.1.11  christos     /* Ignore the Name Op */
   1408      1.1.1.11  christos 
   1409      1.1.1.11  christos     NamePathOp->Common.DisasmFlags = ACPI_PARSEOP_IGNORE;
   1410      1.1.1.11  christos 
   1411      1.1.1.11  christos     /* Remaining opcodes are the Case statements (If/ElseIf's) */
   1412      1.1.1.11  christos 
   1413      1.1.1.11  christos     CurrentOp = StoreOp->Common.Next;
   1414      1.1.1.11  christos     while (AcpiDmIsCaseBlock (CurrentOp))
   1415      1.1.1.11  christos     {
   1416      1.1.1.11  christos         /* Block is a Case structure */
   1417      1.1.1.11  christos 
   1418      1.1.1.11  christos         if (CurrentOp->Common.AmlOpcode == AML_ELSE_OP)
   1419      1.1.1.11  christos         {
   1420      1.1.1.11  christos             /* ElseIf */
   1421      1.1.1.11  christos 
   1422      1.1.1.11  christos             CurrentOp->Common.DisasmOpcode = ACPI_DASM_CASE;
   1423      1.1.1.11  christos             CurrentOp = AcpiPsGetArg (CurrentOp, 0);
   1424      1.1.1.11  christos         }
   1425      1.1.1.11  christos 
   1426      1.1.1.11  christos         /* If */
   1427      1.1.1.11  christos 
   1428      1.1.1.11  christos         CurrentOp->Common.DisasmOpcode = ACPI_DASM_CASE;
   1429      1.1.1.11  christos 
   1430      1.1.1.11  christos         /*
   1431      1.1.1.11  christos          * Mark the parse tree for Case disassembly. There are two
   1432      1.1.1.11  christos          * types of Case statements. The first type of statement begins with
   1433      1.1.1.11  christos          * an LEqual. The second starts with an LNot and uses a Match statement
   1434      1.1.1.11  christos          * on a Package of constants.
   1435      1.1.1.11  christos          */
   1436      1.1.1.11  christos         TempOp = AcpiPsGetArg (CurrentOp, 0);
   1437      1.1.1.11  christos         switch (TempOp->Common.AmlOpcode)
   1438      1.1.1.11  christos         {
   1439  1.1.1.11.4.1  pgoyette             case (AML_LOGICAL_EQUAL_OP):
   1440      1.1.1.11  christos 
   1441      1.1.1.11  christos                 /* Ignore just the LEqual Op */
   1442      1.1.1.11  christos 
   1443      1.1.1.11  christos                 TempOp->Common.DisasmOpcode = ACPI_DASM_IGNORE_SINGLE;
   1444      1.1.1.11  christos 
   1445      1.1.1.11  christos                 /* Ignore the NamePath Op */
   1446      1.1.1.11  christos 
   1447      1.1.1.11  christos                 TempOp = AcpiPsGetArg (TempOp, 0);
   1448      1.1.1.11  christos                 TempOp->Common.DisasmFlags = ACPI_PARSEOP_IGNORE;
   1449      1.1.1.11  christos 
   1450      1.1.1.11  christos                 /*
   1451      1.1.1.11  christos                  * Second arg of LEqual will be the Case predicate.
   1452      1.1.1.11  christos                  * Mark it as a predicate and also as a parameter list for paren
   1453      1.1.1.11  christos                  * closing and correct indentation.
   1454      1.1.1.11  christos                  */
   1455      1.1.1.11  christos                 PredicateOp = TempOp->Common.Next;
   1456      1.1.1.11  christos                 PredicateOp->Common.DisasmOpcode = ACPI_DASM_SWITCH_PREDICATE;
   1457      1.1.1.11  christos                 PredicateOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
   1458      1.1.1.11  christos 
   1459      1.1.1.11  christos                 break;
   1460      1.1.1.11  christos 
   1461  1.1.1.11.4.1  pgoyette             case (AML_LOGICAL_NOT_OP):
   1462      1.1.1.11  christos 
   1463      1.1.1.11  christos                 /*
   1464      1.1.1.11  christos                  * The Package will be the predicate of the Case statement.
   1465      1.1.1.11  christos                  * It's under:
   1466      1.1.1.11  christos                  *            LNOT
   1467      1.1.1.11  christos                  *                LEQUAL
   1468      1.1.1.11  christos                  *                    MATCH
   1469      1.1.1.11  christos                  *                        PACKAGE
   1470      1.1.1.11  christos                  */
   1471      1.1.1.11  christos 
   1472      1.1.1.11  christos                 /* Get the LEqual Op from LNot */
   1473      1.1.1.11  christos 
   1474      1.1.1.11  christos                 TempOp = AcpiPsGetArg (TempOp, 0);
   1475      1.1.1.11  christos 
   1476      1.1.1.11  christos                 /* Get the Match Op from LEqual */
   1477      1.1.1.11  christos 
   1478      1.1.1.11  christos                 TempOp = AcpiPsGetArg (TempOp, 0);
   1479      1.1.1.11  christos 
   1480      1.1.1.11  christos                 /* Get the Package Op from Match */
   1481      1.1.1.11  christos 
   1482      1.1.1.11  christos                 PredicateOp = AcpiPsGetArg (TempOp, 0);
   1483      1.1.1.11  christos 
   1484      1.1.1.11  christos                 /* Mark as parameter list for paren closing */
   1485      1.1.1.11  christos 
   1486      1.1.1.11  christos                 PredicateOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
   1487      1.1.1.11  christos 
   1488      1.1.1.11  christos                 /*
   1489      1.1.1.11  christos                  * The Package list would be too deeply indented if we
   1490      1.1.1.11  christos                  * chose to simply ignore the all the parent opcodes, so
   1491      1.1.1.11  christos                  * we rearrange the parse tree instead.
   1492      1.1.1.11  christos                  */
   1493      1.1.1.11  christos 
   1494      1.1.1.11  christos                 /*
   1495      1.1.1.11  christos                  * Save the second arg of the If/Else Op which is the
   1496      1.1.1.11  christos                  * block code of code for this Case statement.
   1497      1.1.1.11  christos                  */
   1498      1.1.1.11  christos                 TempOp = AcpiPsGetArg (CurrentOp, 1);
   1499      1.1.1.11  christos 
   1500      1.1.1.11  christos                 /*
   1501      1.1.1.11  christos                  * Move the Package Op to the child (predicate) of the
   1502      1.1.1.11  christos                  * Case statement.
   1503      1.1.1.11  christos                  */
   1504      1.1.1.11  christos                 CurrentOp->Common.Value.Arg = PredicateOp;
   1505      1.1.1.11  christos                 PredicateOp->Common.Parent = CurrentOp;
   1506      1.1.1.11  christos 
   1507      1.1.1.11  christos                 /* Add the block code */
   1508      1.1.1.11  christos 
   1509      1.1.1.11  christos                 PredicateOp->Common.Next = TempOp;
   1510      1.1.1.11  christos 
   1511      1.1.1.11  christos                 break;
   1512      1.1.1.11  christos 
   1513      1.1.1.11  christos             default:
   1514      1.1.1.11  christos 
   1515      1.1.1.11  christos                 /* Should never get here */
   1516      1.1.1.11  christos 
   1517      1.1.1.11  christos                 break;
   1518      1.1.1.11  christos         }
   1519      1.1.1.11  christos 
   1520      1.1.1.11  christos         /* Advance to next Case block */
   1521      1.1.1.11  christos 
   1522      1.1.1.11  christos         CurrentOp = CurrentOp->Common.Next;
   1523      1.1.1.11  christos     }
   1524      1.1.1.11  christos 
   1525      1.1.1.11  christos     /* If CurrentOp is now an Else, then this is a Default block */
   1526      1.1.1.11  christos 
   1527      1.1.1.11  christos     if (CurrentOp && CurrentOp->Common.AmlOpcode == AML_ELSE_OP)
   1528      1.1.1.11  christos     {
   1529      1.1.1.11  christos         CurrentOp->Common.DisasmOpcode = ACPI_DASM_DEFAULT;
   1530      1.1.1.11  christos     }
   1531      1.1.1.11  christos 
   1532      1.1.1.11  christos     /*
   1533      1.1.1.11  christos      * From the first If advance to the Break op. It's possible to
   1534      1.1.1.11  christos      * have an Else (Default) op here when there is only one Case
   1535      1.1.1.11  christos      * statement, so check for it.
   1536      1.1.1.11  christos      */
   1537      1.1.1.11  christos     CurrentOp = StoreOp->Common.Next->Common.Next;
   1538      1.1.1.11  christos     if (CurrentOp->Common.AmlOpcode == AML_ELSE_OP)
   1539      1.1.1.11  christos     {
   1540      1.1.1.11  christos         CurrentOp = CurrentOp->Common.Next;
   1541      1.1.1.11  christos     }
   1542      1.1.1.11  christos 
   1543      1.1.1.11  christos     /* Ignore the Break Op */
   1544      1.1.1.11  christos 
   1545      1.1.1.11  christos     CurrentOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
   1546      1.1.1.11  christos 
   1547      1.1.1.11  christos     return (TRUE);
   1548      1.1.1.11  christos }
   1549      1.1.1.11  christos 
   1550      1.1.1.11  christos /*******************************************************************************
   1551      1.1.1.11  christos  *
   1552      1.1.1.11  christos  * FUNCTION:    AcpiDmIsCaseBlock
   1553      1.1.1.11  christos  *
   1554      1.1.1.11  christos  * PARAMETERS:  Op              - Object to test
   1555      1.1.1.11  christos  *
   1556      1.1.1.11  christos  * RETURN:      TRUE if Object is beginning of a Case block.
   1557      1.1.1.11  christos  *
   1558      1.1.1.11  christos  * DESCRIPTION: Determines if an Object is the beginning of a Case block for a
   1559      1.1.1.11  christos  *              Switch/Case statement. Parse tree must be one of the following
   1560      1.1.1.11  christos  *              forms:
   1561      1.1.1.11  christos  *
   1562      1.1.1.11  christos  *              Else (Optional)
   1563      1.1.1.11  christos  *                  If
   1564      1.1.1.11  christos  *                      LEqual
   1565      1.1.1.11  christos  *                          -NamePath- _T_x
   1566      1.1.1.11  christos  *
   1567      1.1.1.11  christos  *              Else (Optional)
   1568      1.1.1.11  christos  *                  If
   1569      1.1.1.11  christos  *                      LNot
   1570      1.1.1.11  christos  *                          LEqual
   1571      1.1.1.11  christos  *                              Match
   1572      1.1.1.11  christos  *                                  Package
   1573      1.1.1.11  christos  *                                      ByteConst
   1574      1.1.1.11  christos  *                                      -NamePath- _T_x
   1575      1.1.1.11  christos  *
   1576      1.1.1.11  christos  ******************************************************************************/
   1577      1.1.1.11  christos 
   1578      1.1.1.11  christos static BOOLEAN
   1579      1.1.1.11  christos AcpiDmIsCaseBlock (
   1580      1.1.1.11  christos     ACPI_PARSE_OBJECT       *Op)
   1581      1.1.1.11  christos {
   1582      1.1.1.11  christos     ACPI_PARSE_OBJECT       *CurrentOp;
   1583      1.1.1.11  christos 
   1584      1.1.1.11  christos     if (!Op)
   1585      1.1.1.11  christos     {
   1586      1.1.1.11  christos         return (FALSE);
   1587      1.1.1.11  christos     }
   1588      1.1.1.11  christos 
   1589      1.1.1.11  christos     /* Look for an If or ElseIf */
   1590      1.1.1.11  christos 
   1591      1.1.1.11  christos     CurrentOp = Op;
   1592      1.1.1.11  christos     if (CurrentOp->Common.AmlOpcode == AML_ELSE_OP)
   1593      1.1.1.11  christos     {
   1594      1.1.1.11  christos         CurrentOp = AcpiPsGetArg (CurrentOp, 0);
   1595      1.1.1.11  christos         if (!CurrentOp)
   1596      1.1.1.11  christos         {
   1597      1.1.1.11  christos             return (FALSE);
   1598      1.1.1.11  christos         }
   1599      1.1.1.11  christos     }
   1600      1.1.1.11  christos 
   1601      1.1.1.11  christos     if (!CurrentOp || CurrentOp->Common.AmlOpcode != AML_IF_OP)
   1602      1.1.1.11  christos     {
   1603      1.1.1.11  christos         return (FALSE);
   1604      1.1.1.11  christos     }
   1605      1.1.1.11  christos 
   1606      1.1.1.11  christos     /* Child must be LEqual or LNot */
   1607      1.1.1.11  christos 
   1608      1.1.1.11  christos     CurrentOp = AcpiPsGetArg (CurrentOp, 0);
   1609      1.1.1.11  christos     if (!CurrentOp)
   1610      1.1.1.11  christos     {
   1611      1.1.1.11  christos         return (FALSE);
   1612      1.1.1.11  christos     }
   1613      1.1.1.11  christos 
   1614      1.1.1.11  christos     switch (CurrentOp->Common.AmlOpcode)
   1615      1.1.1.11  christos     {
   1616  1.1.1.11.4.1  pgoyette         case (AML_LOGICAL_EQUAL_OP):
   1617      1.1.1.11  christos 
   1618      1.1.1.11  christos             /* Next child must be NamePath with string _T_ */
   1619      1.1.1.11  christos 
   1620      1.1.1.11  christos             CurrentOp = AcpiPsGetArg (CurrentOp, 0);
   1621      1.1.1.11  christos             if (!CurrentOp || !CurrentOp->Common.Value.Name ||
   1622      1.1.1.11  christos                 strncmp(CurrentOp->Common.Value.Name, "_T_", 3))
   1623      1.1.1.11  christos             {
   1624      1.1.1.11  christos                 return (FALSE);
   1625      1.1.1.11  christos             }
   1626      1.1.1.11  christos 
   1627      1.1.1.11  christos             break;
   1628      1.1.1.11  christos 
   1629  1.1.1.11.4.1  pgoyette         case (AML_LOGICAL_NOT_OP):
   1630      1.1.1.11  christos 
   1631      1.1.1.11  christos             /* Child of LNot must be LEqual op */
   1632      1.1.1.11  christos 
   1633      1.1.1.11  christos             CurrentOp = AcpiPsGetArg (CurrentOp, 0);
   1634  1.1.1.11.4.1  pgoyette             if (!CurrentOp || (CurrentOp->Common.AmlOpcode != AML_LOGICAL_EQUAL_OP))
   1635      1.1.1.11  christos             {
   1636      1.1.1.11  christos                 return (FALSE);
   1637      1.1.1.11  christos             }
   1638      1.1.1.11  christos 
   1639      1.1.1.11  christos             /* Child of LNot must be Match op */
   1640      1.1.1.11  christos 
   1641      1.1.1.11  christos             CurrentOp = AcpiPsGetArg (CurrentOp, 0);
   1642      1.1.1.11  christos             if (!CurrentOp || (CurrentOp->Common.AmlOpcode != AML_MATCH_OP))
   1643      1.1.1.11  christos             {
   1644      1.1.1.11  christos                 return (FALSE);
   1645      1.1.1.11  christos             }
   1646      1.1.1.11  christos 
   1647      1.1.1.11  christos             /* First child of Match must be Package op */
   1648      1.1.1.11  christos 
   1649      1.1.1.11  christos             CurrentOp = AcpiPsGetArg (CurrentOp, 0);
   1650      1.1.1.11  christos             if (!CurrentOp || (CurrentOp->Common.AmlOpcode != AML_PACKAGE_OP))
   1651      1.1.1.11  christos             {
   1652      1.1.1.11  christos                 return (FALSE);
   1653      1.1.1.11  christos             }
   1654      1.1.1.11  christos 
   1655      1.1.1.11  christos             /* Third child of Match must be NamePath with string _T_ */
   1656      1.1.1.11  christos 
   1657      1.1.1.11  christos             CurrentOp = AcpiPsGetArg (CurrentOp->Common.Parent, 2);
   1658      1.1.1.11  christos             if (!CurrentOp || !CurrentOp->Common.Value.Name ||
   1659      1.1.1.11  christos                 strncmp(CurrentOp->Common.Value.Name, "_T_", 3))
   1660      1.1.1.11  christos             {
   1661      1.1.1.11  christos                 return (FALSE);
   1662      1.1.1.11  christos             }
   1663      1.1.1.11  christos 
   1664      1.1.1.11  christos             break;
   1665      1.1.1.11  christos 
   1666      1.1.1.11  christos         default:
   1667      1.1.1.11  christos 
   1668      1.1.1.11  christos             return (FALSE);
   1669      1.1.1.11  christos     }
   1670      1.1.1.11  christos 
   1671      1.1.1.11  christos     return (TRUE);
   1672      1.1.1.11  christos }
   1673