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