xref: /dflybsd-src/sys/contrib/dev/acpica/source/common/dmswitch.c (revision 383048aca08c2de51d27aa8638a36982a0d74550)
11093ca81SSascha Wildner /******************************************************************************
21093ca81SSascha Wildner  *
31093ca81SSascha Wildner  * Module Name: adwalk - Disassembler routines for switch statements
41093ca81SSascha Wildner  *
51093ca81SSascha Wildner  *****************************************************************************/
61093ca81SSascha Wildner 
71093ca81SSascha Wildner /******************************************************************************
81093ca81SSascha Wildner  *
91093ca81SSascha Wildner  * 1. Copyright Notice
101093ca81SSascha Wildner  *
11*383048acSSascha Wildner  * Some or all of this work - Copyright (c) 1999 - 2021, Intel Corp.
121093ca81SSascha Wildner  * All rights reserved.
131093ca81SSascha Wildner  *
141093ca81SSascha Wildner  * 2. License
151093ca81SSascha Wildner  *
161093ca81SSascha Wildner  * 2.1. This is your license from Intel Corp. under its intellectual property
171093ca81SSascha Wildner  * rights. You may have additional license terms from the party that provided
181093ca81SSascha Wildner  * you this software, covering your right to use that party's intellectual
191093ca81SSascha Wildner  * property rights.
201093ca81SSascha Wildner  *
211093ca81SSascha Wildner  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
221093ca81SSascha Wildner  * copy of the source code appearing in this file ("Covered Code") an
231093ca81SSascha Wildner  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
241093ca81SSascha Wildner  * base code distributed originally by Intel ("Original Intel Code") to copy,
251093ca81SSascha Wildner  * make derivatives, distribute, use and display any portion of the Covered
261093ca81SSascha Wildner  * Code in any form, with the right to sublicense such rights; and
271093ca81SSascha Wildner  *
281093ca81SSascha Wildner  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
291093ca81SSascha Wildner  * license (with the right to sublicense), under only those claims of Intel
301093ca81SSascha Wildner  * patents that are infringed by the Original Intel Code, to make, use, sell,
311093ca81SSascha Wildner  * offer to sell, and import the Covered Code and derivative works thereof
321093ca81SSascha Wildner  * solely to the minimum extent necessary to exercise the above copyright
331093ca81SSascha Wildner  * license, and in no event shall the patent license extend to any additions
341093ca81SSascha Wildner  * to or modifications of the Original Intel Code. No other license or right
351093ca81SSascha Wildner  * is granted directly or by implication, estoppel or otherwise;
361093ca81SSascha Wildner  *
371093ca81SSascha Wildner  * The above copyright and patent license is granted only if the following
381093ca81SSascha Wildner  * conditions are met:
391093ca81SSascha Wildner  *
401093ca81SSascha Wildner  * 3. Conditions
411093ca81SSascha Wildner  *
421093ca81SSascha Wildner  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
431093ca81SSascha Wildner  * Redistribution of source code of any substantial portion of the Covered
441093ca81SSascha Wildner  * Code or modification with rights to further distribute source must include
451093ca81SSascha Wildner  * the above Copyright Notice, the above License, this list of Conditions,
461093ca81SSascha Wildner  * and the following Disclaimer and Export Compliance provision. In addition,
471093ca81SSascha Wildner  * Licensee must cause all Covered Code to which Licensee contributes to
481093ca81SSascha Wildner  * contain a file documenting the changes Licensee made to create that Covered
491093ca81SSascha Wildner  * Code and the date of any change. Licensee must include in that file the
501093ca81SSascha Wildner  * documentation of any changes made by any predecessor Licensee. Licensee
511093ca81SSascha Wildner  * must include a prominent statement that the modification is derived,
521093ca81SSascha Wildner  * directly or indirectly, from Original Intel Code.
531093ca81SSascha Wildner  *
541093ca81SSascha Wildner  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
551093ca81SSascha Wildner  * Redistribution of source code of any substantial portion of the Covered
561093ca81SSascha Wildner  * Code or modification without rights to further distribute source must
571093ca81SSascha Wildner  * include the following Disclaimer and Export Compliance provision in the
581093ca81SSascha Wildner  * documentation and/or other materials provided with distribution. In
591093ca81SSascha Wildner  * addition, Licensee may not authorize further sublicense of source of any
601093ca81SSascha Wildner  * portion of the Covered Code, and must include terms to the effect that the
611093ca81SSascha Wildner  * license from Licensee to its licensee is limited to the intellectual
621093ca81SSascha Wildner  * property embodied in the software Licensee provides to its licensee, and
631093ca81SSascha Wildner  * not to intellectual property embodied in modifications its licensee may
641093ca81SSascha Wildner  * make.
651093ca81SSascha Wildner  *
661093ca81SSascha Wildner  * 3.3. Redistribution of Executable. Redistribution in executable form of any
671093ca81SSascha Wildner  * substantial portion of the Covered Code or modification must reproduce the
681093ca81SSascha Wildner  * above Copyright Notice, and the following Disclaimer and Export Compliance
691093ca81SSascha Wildner  * provision in the documentation and/or other materials provided with the
701093ca81SSascha Wildner  * distribution.
711093ca81SSascha Wildner  *
721093ca81SSascha Wildner  * 3.4. Intel retains all right, title, and interest in and to the Original
731093ca81SSascha Wildner  * Intel Code.
741093ca81SSascha Wildner  *
751093ca81SSascha Wildner  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
761093ca81SSascha Wildner  * Intel shall be used in advertising or otherwise to promote the sale, use or
771093ca81SSascha Wildner  * other dealings in products derived from or relating to the Covered Code
781093ca81SSascha Wildner  * without prior written authorization from Intel.
791093ca81SSascha Wildner  *
801093ca81SSascha Wildner  * 4. Disclaimer and Export Compliance
811093ca81SSascha Wildner  *
821093ca81SSascha Wildner  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
831093ca81SSascha Wildner  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
841093ca81SSascha Wildner  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
851093ca81SSascha Wildner  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
861093ca81SSascha Wildner  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
871093ca81SSascha Wildner  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
881093ca81SSascha Wildner  * PARTICULAR PURPOSE.
891093ca81SSascha Wildner  *
901093ca81SSascha Wildner  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
911093ca81SSascha Wildner  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
921093ca81SSascha Wildner  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
931093ca81SSascha Wildner  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
941093ca81SSascha Wildner  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
951093ca81SSascha Wildner  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
961093ca81SSascha Wildner  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
971093ca81SSascha Wildner  * LIMITED REMEDY.
981093ca81SSascha Wildner  *
991093ca81SSascha Wildner  * 4.3. Licensee shall not export, either directly or indirectly, any of this
1001093ca81SSascha Wildner  * software or system incorporating such software without first obtaining any
1011093ca81SSascha Wildner  * required license or other approval from the U. S. Department of Commerce or
1021093ca81SSascha Wildner  * any other agency or department of the United States Government. In the
1031093ca81SSascha Wildner  * event Licensee exports any such software from the United States or
1041093ca81SSascha Wildner  * re-exports any such software from a foreign destination, Licensee shall
1051093ca81SSascha Wildner  * ensure that the distribution and export/re-export of the software is in
1061093ca81SSascha Wildner  * compliance with all laws, regulations, orders, or other restrictions of the
1071093ca81SSascha Wildner  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
1081093ca81SSascha Wildner  * any of its subsidiaries will export/re-export any technical data, process,
1091093ca81SSascha Wildner  * software, or service, directly or indirectly, to any country for which the
1101093ca81SSascha Wildner  * United States government or any agency thereof requires an export license,
1111093ca81SSascha Wildner  * other governmental approval, or letter of assurance, without first obtaining
1121093ca81SSascha Wildner  * such license, approval or letter.
1131093ca81SSascha Wildner  *
1141093ca81SSascha Wildner  *****************************************************************************
1151093ca81SSascha Wildner  *
1161093ca81SSascha Wildner  * Alternatively, you may choose to be licensed under the terms of the
1171093ca81SSascha Wildner  * following license:
1181093ca81SSascha Wildner  *
1191093ca81SSascha Wildner  * Redistribution and use in source and binary forms, with or without
1201093ca81SSascha Wildner  * modification, are permitted provided that the following conditions
1211093ca81SSascha Wildner  * are met:
1221093ca81SSascha Wildner  * 1. Redistributions of source code must retain the above copyright
1231093ca81SSascha Wildner  *    notice, this list of conditions, and the following disclaimer,
1241093ca81SSascha Wildner  *    without modification.
1251093ca81SSascha Wildner  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1261093ca81SSascha Wildner  *    substantially similar to the "NO WARRANTY" disclaimer below
1271093ca81SSascha Wildner  *    ("Disclaimer") and any redistribution must be conditioned upon
1281093ca81SSascha Wildner  *    including a substantially similar Disclaimer requirement for further
1291093ca81SSascha Wildner  *    binary redistribution.
1301093ca81SSascha Wildner  * 3. Neither the names of the above-listed copyright holders nor the names
1311093ca81SSascha Wildner  *    of any contributors may be used to endorse or promote products derived
1321093ca81SSascha Wildner  *    from this software without specific prior written permission.
1331093ca81SSascha Wildner  *
1341093ca81SSascha Wildner  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1351093ca81SSascha Wildner  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1361093ca81SSascha Wildner  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1371093ca81SSascha Wildner  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1381093ca81SSascha Wildner  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1391093ca81SSascha Wildner  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
1401093ca81SSascha Wildner  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
1411093ca81SSascha Wildner  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
1421093ca81SSascha Wildner  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
1431093ca81SSascha Wildner  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
1441093ca81SSascha Wildner  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1451093ca81SSascha Wildner  *
1461093ca81SSascha Wildner  * Alternatively, you may choose to be licensed under the terms of the
1471093ca81SSascha Wildner  * GNU General Public License ("GPL") version 2 as published by the Free
1481093ca81SSascha Wildner  * Software Foundation.
1491093ca81SSascha Wildner  *
1501093ca81SSascha Wildner  *****************************************************************************/
1511093ca81SSascha Wildner 
1521093ca81SSascha Wildner #include "acpi.h"
1531093ca81SSascha Wildner #include "accommon.h"
1541093ca81SSascha Wildner #include "acparser.h"
1551093ca81SSascha Wildner #include "amlcode.h"
1561093ca81SSascha Wildner #include "acdisasm.h"
1571093ca81SSascha Wildner #include "acdispat.h"
1581093ca81SSascha Wildner #include "acnamesp.h"
1591093ca81SSascha Wildner #include "acapps.h"
1601093ca81SSascha Wildner 
1611093ca81SSascha Wildner 
1621093ca81SSascha Wildner #define _COMPONENT          ACPI_CA_DISASSEMBLER
1631093ca81SSascha Wildner         ACPI_MODULE_NAME    ("dmswitch")
1641093ca81SSascha Wildner 
1651093ca81SSascha Wildner static BOOLEAN
1661093ca81SSascha Wildner AcpiDmIsSwitchBlock (
1671093ca81SSascha Wildner     ACPI_PARSE_OBJECT       *Op,
1681093ca81SSascha Wildner     char                    **Temp);
1691093ca81SSascha Wildner 
1701093ca81SSascha Wildner static BOOLEAN
1711093ca81SSascha Wildner AcpiDmIsCaseBlock (
1721093ca81SSascha Wildner     ACPI_PARSE_OBJECT       *Op);
1731093ca81SSascha Wildner 
1741093ca81SSascha Wildner 
1751093ca81SSascha Wildner /*******************************************************************************
1761093ca81SSascha Wildner  *
1771093ca81SSascha Wildner  * FUNCTION:    AcpiDmProcessSwitch
1781093ca81SSascha Wildner  *
1791093ca81SSascha Wildner  * PARAMETERS:  Op              - Object to be examined
1801093ca81SSascha Wildner  *
1811093ca81SSascha Wildner  * RETURN:      ACPI_STATUS
1821093ca81SSascha Wildner  *
1831093ca81SSascha Wildner  * DESCRIPTION: Walk function to create a list of all temporary (_T_) objects.
1841093ca81SSascha Wildner  *              If a While loop is found that can be converted to a Switch, do
1851093ca81SSascha Wildner  *              the conversion, remove the temporary name from the list, and
1861093ca81SSascha Wildner  *              mark the parse op with an IGNORE flag.
1871093ca81SSascha Wildner  *
1881093ca81SSascha Wildner  ******************************************************************************/
1891093ca81SSascha Wildner 
1901093ca81SSascha Wildner ACPI_STATUS
AcpiDmProcessSwitch(ACPI_PARSE_OBJECT * Op)1911093ca81SSascha Wildner AcpiDmProcessSwitch (
1921093ca81SSascha Wildner     ACPI_PARSE_OBJECT       *Op)
1931093ca81SSascha Wildner {
1941093ca81SSascha Wildner     char                    *Temp = NULL;
1951093ca81SSascha Wildner     ACPI_PARSE_OBJECT_LIST  *NewTemp;
1961093ca81SSascha Wildner     ACPI_PARSE_OBJECT_LIST  *Current;
1971093ca81SSascha Wildner     ACPI_PARSE_OBJECT_LIST  *Previous;
1981093ca81SSascha Wildner     BOOLEAN                 FoundTemp = FALSE;
1991093ca81SSascha Wildner 
2001093ca81SSascha Wildner 
2011093ca81SSascha Wildner     switch (Op->Common.AmlOpcode)
2021093ca81SSascha Wildner     {
2031093ca81SSascha Wildner     case AML_NAME_OP:
2041093ca81SSascha Wildner 
2051093ca81SSascha Wildner         Temp = (char *) (&Op->Named.Name);
2061093ca81SSascha Wildner 
2071093ca81SSascha Wildner         if (!strncmp(Temp, "_T_", 3))
2081093ca81SSascha Wildner         {
2091093ca81SSascha Wildner             /* Allocate and init a new Temp List node */
2101093ca81SSascha Wildner 
2111093ca81SSascha Wildner             NewTemp = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PARSE_OBJECT_LIST));
2121093ca81SSascha Wildner             if (!NewTemp)
2131093ca81SSascha Wildner             {
2141093ca81SSascha Wildner                 return (AE_NO_MEMORY);
2151093ca81SSascha Wildner             }
2161093ca81SSascha Wildner 
2171093ca81SSascha Wildner             if (AcpiGbl_TempListHead)
2181093ca81SSascha Wildner             {
2191093ca81SSascha Wildner                 Current = AcpiGbl_TempListHead;
2201093ca81SSascha Wildner                 AcpiGbl_TempListHead = NewTemp;
2211093ca81SSascha Wildner                 AcpiGbl_TempListHead->Op = Op;
2221093ca81SSascha Wildner                 AcpiGbl_TempListHead->Next = Current;
2231093ca81SSascha Wildner             }
2241093ca81SSascha Wildner             else
2251093ca81SSascha Wildner             {
2261093ca81SSascha Wildner                 AcpiGbl_TempListHead = NewTemp;
2271093ca81SSascha Wildner                 AcpiGbl_TempListHead->Op = Op;
2281093ca81SSascha Wildner                 AcpiGbl_TempListHead->Next = NULL;
2291093ca81SSascha Wildner             }
2301093ca81SSascha Wildner         }
2311093ca81SSascha Wildner         break;
2321093ca81SSascha Wildner 
2331093ca81SSascha Wildner     case AML_WHILE_OP:
2341093ca81SSascha Wildner 
2351093ca81SSascha Wildner         if (!AcpiDmIsSwitchBlock (Op, &Temp))
2361093ca81SSascha Wildner         {
2371093ca81SSascha Wildner             break;
2381093ca81SSascha Wildner         }
2391093ca81SSascha Wildner 
2401093ca81SSascha Wildner         /* Found a Switch */
2411093ca81SSascha Wildner 
2421093ca81SSascha Wildner         Op->Common.DisasmOpcode = ACPI_DASM_SWITCH;
2431093ca81SSascha Wildner 
2441093ca81SSascha Wildner         Previous = Current = AcpiGbl_TempListHead;
2451093ca81SSascha Wildner         while (Current)
2461093ca81SSascha Wildner         {
2471093ca81SSascha Wildner             /* Note, if we get here Temp is not NULL */
2481093ca81SSascha Wildner 
2491093ca81SSascha Wildner             if (!strncmp(Temp, (char *) (&Current->Op->Named.Name), 4))
2501093ca81SSascha Wildner             {
2511093ca81SSascha Wildner                 /* Match found. Ignore disassembly */
2521093ca81SSascha Wildner 
2531093ca81SSascha Wildner                 Current->Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
2541093ca81SSascha Wildner 
2551093ca81SSascha Wildner                 /* Remove from list */
2561093ca81SSascha Wildner 
2571093ca81SSascha Wildner                 if (Current == AcpiGbl_TempListHead)
2581093ca81SSascha Wildner                 {
2591093ca81SSascha Wildner                     AcpiGbl_TempListHead = Current->Next;
2601093ca81SSascha Wildner                 }
2611093ca81SSascha Wildner                 else
2621093ca81SSascha Wildner                 {
2631093ca81SSascha Wildner                     Previous->Next = Current->Next;
2641093ca81SSascha Wildner                 }
2651093ca81SSascha Wildner 
2661093ca81SSascha Wildner                 Current->Op = NULL;
2671093ca81SSascha Wildner                 Current->Next = NULL;
2681093ca81SSascha Wildner                 ACPI_FREE (Current);
2691093ca81SSascha Wildner                 FoundTemp = TRUE;
2701093ca81SSascha Wildner                 break;
2711093ca81SSascha Wildner             }
2721093ca81SSascha Wildner 
2731093ca81SSascha Wildner             Previous = Current;
2741093ca81SSascha Wildner             Current = Current->Next;
2751093ca81SSascha Wildner         }
2761093ca81SSascha Wildner 
2771093ca81SSascha Wildner         if (!FoundTemp)
2781093ca81SSascha Wildner         {
2791093ca81SSascha Wildner             fprintf (stderr,
2801093ca81SSascha Wildner                 "Warning: Declaration for temp name %.4s not found\n", Temp);
2811093ca81SSascha Wildner         }
2821093ca81SSascha Wildner         break;
2831093ca81SSascha Wildner 
2841093ca81SSascha Wildner     default:
2851093ca81SSascha Wildner         break;
2861093ca81SSascha Wildner     }
2871093ca81SSascha Wildner 
2881093ca81SSascha Wildner     return (AE_OK);
2891093ca81SSascha Wildner }
2901093ca81SSascha Wildner 
2911093ca81SSascha Wildner 
2921093ca81SSascha Wildner /*******************************************************************************
2931093ca81SSascha Wildner  *
2941093ca81SSascha Wildner  * FUNCTION:    AcpiDmClearTempList
2951093ca81SSascha Wildner  *
2961093ca81SSascha Wildner  * PARAMETERS:  None
2971093ca81SSascha Wildner  *
2981093ca81SSascha Wildner  * RETURN:      None
2991093ca81SSascha Wildner  *
3001093ca81SSascha Wildner  * DESCRIPTION: Removes any remaining temporary objects from global list and
3011093ca81SSascha Wildner  *              frees
3021093ca81SSascha Wildner  *
3031093ca81SSascha Wildner  ******************************************************************************/
3041093ca81SSascha Wildner 
3051093ca81SSascha Wildner void
AcpiDmClearTempList(void)3061093ca81SSascha Wildner AcpiDmClearTempList (
3071093ca81SSascha Wildner     void)
3081093ca81SSascha Wildner {
3091093ca81SSascha Wildner     ACPI_PARSE_OBJECT_LIST      *Current;
3101093ca81SSascha Wildner 
3111093ca81SSascha Wildner 
3121093ca81SSascha Wildner     while (AcpiGbl_TempListHead)
3131093ca81SSascha Wildner     {
3141093ca81SSascha Wildner         Current = AcpiGbl_TempListHead;
3151093ca81SSascha Wildner         AcpiGbl_TempListHead = AcpiGbl_TempListHead->Next;
3161093ca81SSascha Wildner         Current->Op = NULL;
3171093ca81SSascha Wildner         Current->Next = NULL;
3181093ca81SSascha Wildner         ACPI_FREE (Current);
3191093ca81SSascha Wildner     }
3201093ca81SSascha Wildner }
3211093ca81SSascha Wildner 
3221093ca81SSascha Wildner 
3231093ca81SSascha Wildner /*******************************************************************************
3241093ca81SSascha Wildner  *
3251093ca81SSascha Wildner  * FUNCTION:    AcpiDmIsSwitchBlock
3261093ca81SSascha Wildner  *
3271093ca81SSascha Wildner  * PARAMETERS:  Op              - While Object
328ef944814SSascha Wildner  *              Temp            - Where the compiler temp name is returned
329ef944814SSascha Wildner  *                                  (_T_x)
3301093ca81SSascha Wildner  *
3311093ca81SSascha Wildner  * RETURN:      TRUE if While block can be converted to a Switch/Case block
3321093ca81SSascha Wildner  *
3331093ca81SSascha Wildner  * DESCRIPTION: Determines if While block is a Switch/Case statement. Modifies
3341093ca81SSascha Wildner  *              parse tree to allow for Switch/Case disassembly during walk.
3351093ca81SSascha Wildner  *
3361093ca81SSascha Wildner  * EXAMPLE: Example of parse tree to be converted
3371093ca81SSascha Wildner  *
3381093ca81SSascha Wildner  *    While
3391093ca81SSascha Wildner  *        One
3401093ca81SSascha Wildner  *        Store
3411093ca81SSascha Wildner  *            ByteConst
3421093ca81SSascha Wildner  *             -NamePath-
3431093ca81SSascha Wildner  *        If
3441093ca81SSascha Wildner  *            LEqual
3451093ca81SSascha Wildner  *                -NamePath-
3461093ca81SSascha Wildner  *                Zero
3471093ca81SSascha Wildner  *            Return
3481093ca81SSascha Wildner  *                One
3491093ca81SSascha Wildner  *        Else
3501093ca81SSascha Wildner  *            Return
3511093ca81SSascha Wildner  *                WordConst
3521093ca81SSascha Wildner  *        Break
3531093ca81SSascha Wildner  *
3541093ca81SSascha Wildner  ******************************************************************************/
3551093ca81SSascha Wildner 
3561093ca81SSascha Wildner BOOLEAN
AcpiDmIsSwitchBlock(ACPI_PARSE_OBJECT * Op,char ** Temp)3571093ca81SSascha Wildner AcpiDmIsSwitchBlock (
3581093ca81SSascha Wildner     ACPI_PARSE_OBJECT       *Op,
3591093ca81SSascha Wildner     char                    **Temp)
3601093ca81SSascha Wildner {
3611093ca81SSascha Wildner     ACPI_PARSE_OBJECT       *OneOp;
3621093ca81SSascha Wildner     ACPI_PARSE_OBJECT       *StoreOp;
3631093ca81SSascha Wildner     ACPI_PARSE_OBJECT       *NamePathOp;
3641093ca81SSascha Wildner     ACPI_PARSE_OBJECT       *PredicateOp;
3651093ca81SSascha Wildner     ACPI_PARSE_OBJECT       *CurrentOp;
3661093ca81SSascha Wildner     ACPI_PARSE_OBJECT       *TempOp;
3671093ca81SSascha Wildner 
3681093ca81SSascha Wildner 
3691093ca81SSascha Wildner     /* Check for One Op Predicate */
3701093ca81SSascha Wildner 
3711093ca81SSascha Wildner     OneOp = AcpiPsGetArg (Op, 0);
3721093ca81SSascha Wildner     if (!OneOp || (OneOp->Common.AmlOpcode != AML_ONE_OP))
3731093ca81SSascha Wildner     {
3741093ca81SSascha Wildner         return (FALSE);
3751093ca81SSascha Wildner     }
3761093ca81SSascha Wildner 
3771093ca81SSascha Wildner     /* Check for Store Op */
3781093ca81SSascha Wildner 
3791093ca81SSascha Wildner     StoreOp = OneOp->Common.Next;
3801093ca81SSascha Wildner     if (!StoreOp || (StoreOp->Common.AmlOpcode != AML_STORE_OP))
3811093ca81SSascha Wildner     {
3821093ca81SSascha Wildner         return (FALSE);
3831093ca81SSascha Wildner     }
3841093ca81SSascha Wildner 
3851093ca81SSascha Wildner     /* Check for Name Op with _T_ string */
3861093ca81SSascha Wildner 
3871093ca81SSascha Wildner     NamePathOp = AcpiPsGetArg (StoreOp, 1);
3881093ca81SSascha Wildner     if (!NamePathOp ||
3891093ca81SSascha Wildner         (NamePathOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP))
3901093ca81SSascha Wildner     {
3911093ca81SSascha Wildner         return (FALSE);
3921093ca81SSascha Wildner     }
3931093ca81SSascha Wildner 
3941093ca81SSascha Wildner     if (strncmp ((char *) (NamePathOp->Common.Value.Name), "_T_", 3))
3951093ca81SSascha Wildner     {
3961093ca81SSascha Wildner         return (FALSE);
3971093ca81SSascha Wildner     }
3981093ca81SSascha Wildner 
3991093ca81SSascha Wildner     *Temp = (char *) (NamePathOp->Common.Value.Name);
4001093ca81SSascha Wildner 
4011093ca81SSascha Wildner     /* This is a Switch/Case control block */
4021093ca81SSascha Wildner 
4031093ca81SSascha Wildner     /* Ignore the One Op Predicate */
4041093ca81SSascha Wildner 
4051093ca81SSascha Wildner     OneOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
4061093ca81SSascha Wildner 
4071093ca81SSascha Wildner     /* Ignore the Store Op, but not the children */
4081093ca81SSascha Wildner 
4091093ca81SSascha Wildner     StoreOp->Common.DisasmOpcode = ACPI_DASM_IGNORE_SINGLE;
4101093ca81SSascha Wildner 
4111093ca81SSascha Wildner     /*
4121093ca81SSascha Wildner      * First arg of Store Op is the Switch condition.
4131093ca81SSascha Wildner      * Mark it as a Switch predicate and as a parameter list for paren
4141093ca81SSascha Wildner      * closing and correct indentation.
4151093ca81SSascha Wildner      */
4161093ca81SSascha Wildner     PredicateOp = AcpiPsGetArg (StoreOp, 0);
4171093ca81SSascha Wildner     PredicateOp->Common.DisasmOpcode = ACPI_DASM_SWITCH_PREDICATE;
4181093ca81SSascha Wildner     PredicateOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
4191093ca81SSascha Wildner 
4201093ca81SSascha Wildner     /* Ignore the Name Op */
4211093ca81SSascha Wildner 
4221093ca81SSascha Wildner     NamePathOp->Common.DisasmFlags = ACPI_PARSEOP_IGNORE;
4231093ca81SSascha Wildner 
4241093ca81SSascha Wildner     /* Remaining opcodes are the Case statements (If/ElseIf's) */
4251093ca81SSascha Wildner 
4261093ca81SSascha Wildner     CurrentOp = StoreOp->Common.Next;
4271093ca81SSascha Wildner     while (AcpiDmIsCaseBlock (CurrentOp))
4281093ca81SSascha Wildner     {
4291093ca81SSascha Wildner         /* Block is a Case structure */
4301093ca81SSascha Wildner 
4311093ca81SSascha Wildner         if (CurrentOp->Common.AmlOpcode == AML_ELSE_OP)
4321093ca81SSascha Wildner         {
4331093ca81SSascha Wildner             /* ElseIf */
4341093ca81SSascha Wildner 
4351093ca81SSascha Wildner             CurrentOp->Common.DisasmOpcode = ACPI_DASM_CASE;
4361093ca81SSascha Wildner             CurrentOp = AcpiPsGetArg (CurrentOp, 0);
4371093ca81SSascha Wildner         }
4381093ca81SSascha Wildner 
4391093ca81SSascha Wildner         /* If */
4401093ca81SSascha Wildner 
4411093ca81SSascha Wildner         CurrentOp->Common.DisasmOpcode = ACPI_DASM_CASE;
4421093ca81SSascha Wildner 
4431093ca81SSascha Wildner         /*
4441093ca81SSascha Wildner          * Mark the parse tree for Case disassembly. There are two
4451093ca81SSascha Wildner          * types of Case statements. The first type of statement begins with
4461093ca81SSascha Wildner          * an LEqual. The second starts with an LNot and uses a Match statement
4471093ca81SSascha Wildner          * on a Package of constants.
4481093ca81SSascha Wildner          */
4491093ca81SSascha Wildner         TempOp = AcpiPsGetArg (CurrentOp, 0);
4501093ca81SSascha Wildner         switch (TempOp->Common.AmlOpcode)
4511093ca81SSascha Wildner         {
4521093ca81SSascha Wildner         case (AML_LOGICAL_EQUAL_OP):
4531093ca81SSascha Wildner 
4541093ca81SSascha Wildner             /* Ignore just the LEqual Op */
4551093ca81SSascha Wildner 
4561093ca81SSascha Wildner             TempOp->Common.DisasmOpcode = ACPI_DASM_IGNORE_SINGLE;
4571093ca81SSascha Wildner 
4581093ca81SSascha Wildner             /* Ignore the NamePath Op */
4591093ca81SSascha Wildner 
4601093ca81SSascha Wildner             TempOp = AcpiPsGetArg (TempOp, 0);
4611093ca81SSascha Wildner             TempOp->Common.DisasmFlags = ACPI_PARSEOP_IGNORE;
4621093ca81SSascha Wildner 
4631093ca81SSascha Wildner             /*
4641093ca81SSascha Wildner              * Second arg of LEqual will be the Case predicate.
4651093ca81SSascha Wildner              * Mark it as a predicate and also as a parameter list for paren
4661093ca81SSascha Wildner              * closing and correct indentation.
4671093ca81SSascha Wildner              */
4681093ca81SSascha Wildner             PredicateOp = TempOp->Common.Next;
4691093ca81SSascha Wildner             PredicateOp->Common.DisasmOpcode = ACPI_DASM_SWITCH_PREDICATE;
4701093ca81SSascha Wildner             PredicateOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
4711093ca81SSascha Wildner             break;
4721093ca81SSascha Wildner 
4731093ca81SSascha Wildner         case (AML_LOGICAL_NOT_OP):
4741093ca81SSascha Wildner 
4751093ca81SSascha Wildner             /*
4761093ca81SSascha Wildner              * The Package will be the predicate of the Case statement.
4771093ca81SSascha Wildner              * It's under:
4781093ca81SSascha Wildner              *            LNOT
4791093ca81SSascha Wildner              *                LEQUAL
4801093ca81SSascha Wildner              *                    MATCH
4811093ca81SSascha Wildner              *                        PACKAGE
4821093ca81SSascha Wildner              */
4831093ca81SSascha Wildner 
4841093ca81SSascha Wildner             /* Get the LEqual Op from LNot */
4851093ca81SSascha Wildner 
4861093ca81SSascha Wildner             TempOp = AcpiPsGetArg (TempOp, 0);
4871093ca81SSascha Wildner 
4881093ca81SSascha Wildner             /* Get the Match Op from LEqual */
4891093ca81SSascha Wildner 
4901093ca81SSascha Wildner             TempOp = AcpiPsGetArg (TempOp, 0);
4911093ca81SSascha Wildner 
4921093ca81SSascha Wildner             /* Get the Package Op from Match */
4931093ca81SSascha Wildner 
4941093ca81SSascha Wildner             PredicateOp = AcpiPsGetArg (TempOp, 0);
4951093ca81SSascha Wildner 
4961093ca81SSascha Wildner             /* Mark as parameter list for paren closing */
4971093ca81SSascha Wildner 
4981093ca81SSascha Wildner             PredicateOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
4991093ca81SSascha Wildner 
5001093ca81SSascha Wildner             /*
5011093ca81SSascha Wildner              * The Package list would be too deeply indented if we
5021093ca81SSascha Wildner              * chose to simply ignore the all the parent opcodes, so
5031093ca81SSascha Wildner              * we rearrange the parse tree instead.
5041093ca81SSascha Wildner              */
5051093ca81SSascha Wildner 
5061093ca81SSascha Wildner             /*
5071093ca81SSascha Wildner              * Save the second arg of the If/Else Op which is the
5081093ca81SSascha Wildner              * block code of code for this Case statement.
5091093ca81SSascha Wildner              */
5101093ca81SSascha Wildner             TempOp = AcpiPsGetArg (CurrentOp, 1);
5111093ca81SSascha Wildner 
5121093ca81SSascha Wildner             /*
5131093ca81SSascha Wildner              * Move the Package Op to the child (predicate) of the
5141093ca81SSascha Wildner              * Case statement.
5151093ca81SSascha Wildner              */
5161093ca81SSascha Wildner             CurrentOp->Common.Value.Arg = PredicateOp;
5171093ca81SSascha Wildner             PredicateOp->Common.Parent = CurrentOp;
5181093ca81SSascha Wildner 
5191093ca81SSascha Wildner             /* Add the block code */
5201093ca81SSascha Wildner 
5211093ca81SSascha Wildner             PredicateOp->Common.Next = TempOp;
5221093ca81SSascha Wildner             break;
5231093ca81SSascha Wildner 
5241093ca81SSascha Wildner         default:
5251093ca81SSascha Wildner 
5261093ca81SSascha Wildner             /* Should never get here */
5271093ca81SSascha Wildner             break;
5281093ca81SSascha Wildner         }
5291093ca81SSascha Wildner 
5301093ca81SSascha Wildner         /* Advance to next Case block */
5311093ca81SSascha Wildner 
5321093ca81SSascha Wildner         CurrentOp = CurrentOp->Common.Next;
5331093ca81SSascha Wildner     }
5341093ca81SSascha Wildner 
5351093ca81SSascha Wildner     /* If CurrentOp is now an Else, then this is a Default block */
5361093ca81SSascha Wildner 
5371093ca81SSascha Wildner     if (CurrentOp && CurrentOp->Common.AmlOpcode == AML_ELSE_OP)
5381093ca81SSascha Wildner     {
5391093ca81SSascha Wildner         CurrentOp->Common.DisasmOpcode = ACPI_DASM_DEFAULT;
5401093ca81SSascha Wildner     }
5411093ca81SSascha Wildner 
5421093ca81SSascha Wildner     /*
5431093ca81SSascha Wildner      * From the first If advance to the Break op. It's possible to
5441093ca81SSascha Wildner      * have an Else (Default) op here when there is only one Case
5451093ca81SSascha Wildner      * statement, so check for it.
5461093ca81SSascha Wildner      */
5471093ca81SSascha Wildner     CurrentOp = StoreOp->Common.Next->Common.Next;
5487bcb6cafSSascha Wildner     if (!CurrentOp)
5497bcb6cafSSascha Wildner     {
5507bcb6cafSSascha Wildner         return (FALSE);
5517bcb6cafSSascha Wildner     }
5521093ca81SSascha Wildner     if (CurrentOp->Common.AmlOpcode == AML_ELSE_OP)
5531093ca81SSascha Wildner     {
5541093ca81SSascha Wildner         CurrentOp = CurrentOp->Common.Next;
555ef944814SSascha Wildner         if (!CurrentOp)
556ef944814SSascha Wildner         {
557ef944814SSascha Wildner             return (FALSE);
558ef944814SSascha Wildner         }
5591093ca81SSascha Wildner     }
5601093ca81SSascha Wildner 
5611093ca81SSascha Wildner     /* Ignore the Break Op */
5621093ca81SSascha Wildner 
5631093ca81SSascha Wildner     CurrentOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
5641093ca81SSascha Wildner     return (TRUE);
5651093ca81SSascha Wildner }
5661093ca81SSascha Wildner 
5671093ca81SSascha Wildner 
5681093ca81SSascha Wildner /*******************************************************************************
5691093ca81SSascha Wildner  *
5701093ca81SSascha Wildner  * FUNCTION:    AcpiDmIsCaseBlock
5711093ca81SSascha Wildner  *
5721093ca81SSascha Wildner  * PARAMETERS:  Op              - Object to test
5731093ca81SSascha Wildner  *
5741093ca81SSascha Wildner  * RETURN:      TRUE if Object is beginning of a Case block.
5751093ca81SSascha Wildner  *
5761093ca81SSascha Wildner  * DESCRIPTION: Determines if an Object is the beginning of a Case block for a
5771093ca81SSascha Wildner  *              Switch/Case statement. Parse tree must be one of the following
5781093ca81SSascha Wildner  *              forms:
5791093ca81SSascha Wildner  *
5801093ca81SSascha Wildner  *              Else (Optional)
5811093ca81SSascha Wildner  *                  If
5821093ca81SSascha Wildner  *                      LEqual
5831093ca81SSascha Wildner  *                          -NamePath- _T_x
5841093ca81SSascha Wildner  *
5851093ca81SSascha Wildner  *              Else (Optional)
5861093ca81SSascha Wildner  *                  If
5871093ca81SSascha Wildner  *                      LNot
5881093ca81SSascha Wildner  *                          LEqual
5891093ca81SSascha Wildner  *                              Match
5901093ca81SSascha Wildner  *                                  Package
5911093ca81SSascha Wildner  *                                      ByteConst
5921093ca81SSascha Wildner  *                                      -NamePath- _T_x
5931093ca81SSascha Wildner  *
5941093ca81SSascha Wildner  ******************************************************************************/
5951093ca81SSascha Wildner 
5961093ca81SSascha Wildner static BOOLEAN
AcpiDmIsCaseBlock(ACPI_PARSE_OBJECT * Op)5971093ca81SSascha Wildner AcpiDmIsCaseBlock (
5981093ca81SSascha Wildner     ACPI_PARSE_OBJECT       *Op)
5991093ca81SSascha Wildner {
6001093ca81SSascha Wildner     ACPI_PARSE_OBJECT       *CurrentOp;
6011093ca81SSascha Wildner 
6021093ca81SSascha Wildner 
6031093ca81SSascha Wildner     if (!Op)
6041093ca81SSascha Wildner     {
6051093ca81SSascha Wildner         return (FALSE);
6061093ca81SSascha Wildner     }
6071093ca81SSascha Wildner 
6081093ca81SSascha Wildner     /* Look for an If or ElseIf */
6091093ca81SSascha Wildner 
6101093ca81SSascha Wildner     CurrentOp = Op;
6111093ca81SSascha Wildner     if (CurrentOp->Common.AmlOpcode == AML_ELSE_OP)
6121093ca81SSascha Wildner     {
6131093ca81SSascha Wildner         CurrentOp = AcpiPsGetArg (CurrentOp, 0);
6141093ca81SSascha Wildner         if (!CurrentOp)
6151093ca81SSascha Wildner         {
6161093ca81SSascha Wildner             return (FALSE);
6171093ca81SSascha Wildner         }
6181093ca81SSascha Wildner     }
6191093ca81SSascha Wildner 
6201093ca81SSascha Wildner     if (!CurrentOp || CurrentOp->Common.AmlOpcode != AML_IF_OP)
6211093ca81SSascha Wildner     {
6221093ca81SSascha Wildner         return (FALSE);
6231093ca81SSascha Wildner     }
6241093ca81SSascha Wildner 
6251093ca81SSascha Wildner     /* Child must be LEqual or LNot */
6261093ca81SSascha Wildner 
6271093ca81SSascha Wildner     CurrentOp = AcpiPsGetArg (CurrentOp, 0);
6281093ca81SSascha Wildner     if (!CurrentOp)
6291093ca81SSascha Wildner     {
6301093ca81SSascha Wildner         return (FALSE);
6311093ca81SSascha Wildner     }
6321093ca81SSascha Wildner 
6331093ca81SSascha Wildner     switch (CurrentOp->Common.AmlOpcode)
6341093ca81SSascha Wildner     {
6351093ca81SSascha Wildner     case (AML_LOGICAL_EQUAL_OP):
6361093ca81SSascha Wildner 
6371093ca81SSascha Wildner         /* Next child must be NamePath with string _T_ */
6381093ca81SSascha Wildner 
6391093ca81SSascha Wildner         CurrentOp = AcpiPsGetArg (CurrentOp, 0);
6401093ca81SSascha Wildner         if (!CurrentOp || !CurrentOp->Common.Value.Name ||
6411093ca81SSascha Wildner             strncmp(CurrentOp->Common.Value.Name, "_T_", 3))
6421093ca81SSascha Wildner         {
6431093ca81SSascha Wildner             return (FALSE);
6441093ca81SSascha Wildner         }
6451093ca81SSascha Wildner         break;
6461093ca81SSascha Wildner 
6471093ca81SSascha Wildner     case (AML_LOGICAL_NOT_OP):
6481093ca81SSascha Wildner 
6491093ca81SSascha Wildner         /* Child of LNot must be LEqual op */
6501093ca81SSascha Wildner 
6511093ca81SSascha Wildner         CurrentOp = AcpiPsGetArg (CurrentOp, 0);
6521093ca81SSascha Wildner         if (!CurrentOp || (CurrentOp->Common.AmlOpcode != AML_LOGICAL_EQUAL_OP))
6531093ca81SSascha Wildner         {
6541093ca81SSascha Wildner             return (FALSE);
6551093ca81SSascha Wildner         }
6561093ca81SSascha Wildner 
6571093ca81SSascha Wildner         /* Child of LNot must be Match op */
6581093ca81SSascha Wildner 
6591093ca81SSascha Wildner         CurrentOp = AcpiPsGetArg (CurrentOp, 0);
6601093ca81SSascha Wildner         if (!CurrentOp || (CurrentOp->Common.AmlOpcode != AML_MATCH_OP))
6611093ca81SSascha Wildner         {
6621093ca81SSascha Wildner             return (FALSE);
6631093ca81SSascha Wildner         }
6641093ca81SSascha Wildner 
6651093ca81SSascha Wildner         /* First child of Match must be Package op */
6661093ca81SSascha Wildner 
6671093ca81SSascha Wildner         CurrentOp = AcpiPsGetArg (CurrentOp, 0);
6681093ca81SSascha Wildner         if (!CurrentOp || (CurrentOp->Common.AmlOpcode != AML_PACKAGE_OP))
6691093ca81SSascha Wildner         {
6701093ca81SSascha Wildner             return (FALSE);
6711093ca81SSascha Wildner         }
6721093ca81SSascha Wildner 
6731093ca81SSascha Wildner         /* Third child of Match must be NamePath with string _T_ */
6741093ca81SSascha Wildner 
6751093ca81SSascha Wildner         CurrentOp = AcpiPsGetArg (CurrentOp->Common.Parent, 2);
6761093ca81SSascha Wildner         if (!CurrentOp || !CurrentOp->Common.Value.Name ||
6771093ca81SSascha Wildner             strncmp(CurrentOp->Common.Value.Name, "_T_", 3))
6781093ca81SSascha Wildner         {
6791093ca81SSascha Wildner             return (FALSE);
6801093ca81SSascha Wildner         }
6811093ca81SSascha Wildner         break;
6821093ca81SSascha Wildner 
6831093ca81SSascha Wildner     default:
6841093ca81SSascha Wildner 
6851093ca81SSascha Wildner         return (FALSE);
6861093ca81SSascha Wildner     }
6871093ca81SSascha Wildner 
6881093ca81SSascha Wildner     return (TRUE);
6891093ca81SSascha Wildner }
690