xref: /freebsd/sys/contrib/dev/acpica/common/dmswitch.c (revision 58308fadece25ae4c12bd2f4dce3d73d9c23be43)
1af051161SJung-uk Kim /******************************************************************************
2af051161SJung-uk Kim  *
3af051161SJung-uk Kim  * Module Name: adwalk - Disassembler routines for switch statements
4af051161SJung-uk Kim  *
5af051161SJung-uk Kim  *****************************************************************************/
6af051161SJung-uk Kim 
7af051161SJung-uk Kim /******************************************************************************
8af051161SJung-uk Kim  *
9af051161SJung-uk Kim  * 1. Copyright Notice
10af051161SJung-uk Kim  *
11*58308fadSJung-uk Kim  * Some or all of this work - Copyright (c) 1999 - 2025, Intel Corp.
12af051161SJung-uk Kim  * All rights reserved.
13af051161SJung-uk Kim  *
14af051161SJung-uk Kim  * 2. License
15af051161SJung-uk Kim  *
16af051161SJung-uk Kim  * 2.1. This is your license from Intel Corp. under its intellectual property
17af051161SJung-uk Kim  * rights. You may have additional license terms from the party that provided
18af051161SJung-uk Kim  * you this software, covering your right to use that party's intellectual
19af051161SJung-uk Kim  * property rights.
20af051161SJung-uk Kim  *
21af051161SJung-uk Kim  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22af051161SJung-uk Kim  * copy of the source code appearing in this file ("Covered Code") an
23af051161SJung-uk Kim  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24af051161SJung-uk Kim  * base code distributed originally by Intel ("Original Intel Code") to copy,
25af051161SJung-uk Kim  * make derivatives, distribute, use and display any portion of the Covered
26af051161SJung-uk Kim  * Code in any form, with the right to sublicense such rights; and
27af051161SJung-uk Kim  *
28af051161SJung-uk Kim  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29af051161SJung-uk Kim  * license (with the right to sublicense), under only those claims of Intel
30af051161SJung-uk Kim  * patents that are infringed by the Original Intel Code, to make, use, sell,
31af051161SJung-uk Kim  * offer to sell, and import the Covered Code and derivative works thereof
32af051161SJung-uk Kim  * solely to the minimum extent necessary to exercise the above copyright
33af051161SJung-uk Kim  * license, and in no event shall the patent license extend to any additions
34af051161SJung-uk Kim  * to or modifications of the Original Intel Code. No other license or right
35af051161SJung-uk Kim  * is granted directly or by implication, estoppel or otherwise;
36af051161SJung-uk Kim  *
37af051161SJung-uk Kim  * The above copyright and patent license is granted only if the following
38af051161SJung-uk Kim  * conditions are met:
39af051161SJung-uk Kim  *
40af051161SJung-uk Kim  * 3. Conditions
41af051161SJung-uk Kim  *
42af051161SJung-uk Kim  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43af051161SJung-uk Kim  * Redistribution of source code of any substantial portion of the Covered
44af051161SJung-uk Kim  * Code or modification with rights to further distribute source must include
45af051161SJung-uk Kim  * the above Copyright Notice, the above License, this list of Conditions,
46af051161SJung-uk Kim  * and the following Disclaimer and Export Compliance provision. In addition,
47af051161SJung-uk Kim  * Licensee must cause all Covered Code to which Licensee contributes to
48af051161SJung-uk Kim  * contain a file documenting the changes Licensee made to create that Covered
49af051161SJung-uk Kim  * Code and the date of any change. Licensee must include in that file the
50af051161SJung-uk Kim  * documentation of any changes made by any predecessor Licensee. Licensee
51af051161SJung-uk Kim  * must include a prominent statement that the modification is derived,
52af051161SJung-uk Kim  * directly or indirectly, from Original Intel Code.
53af051161SJung-uk Kim  *
54af051161SJung-uk Kim  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55af051161SJung-uk Kim  * Redistribution of source code of any substantial portion of the Covered
56af051161SJung-uk Kim  * Code or modification without rights to further distribute source must
57af051161SJung-uk Kim  * include the following Disclaimer and Export Compliance provision in the
58af051161SJung-uk Kim  * documentation and/or other materials provided with distribution. In
59af051161SJung-uk Kim  * addition, Licensee may not authorize further sublicense of source of any
60af051161SJung-uk Kim  * portion of the Covered Code, and must include terms to the effect that the
61af051161SJung-uk Kim  * license from Licensee to its licensee is limited to the intellectual
62af051161SJung-uk Kim  * property embodied in the software Licensee provides to its licensee, and
63af051161SJung-uk Kim  * not to intellectual property embodied in modifications its licensee may
64af051161SJung-uk Kim  * make.
65af051161SJung-uk Kim  *
66af051161SJung-uk Kim  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67af051161SJung-uk Kim  * substantial portion of the Covered Code or modification must reproduce the
68af051161SJung-uk Kim  * above Copyright Notice, and the following Disclaimer and Export Compliance
69af051161SJung-uk Kim  * provision in the documentation and/or other materials provided with the
70af051161SJung-uk Kim  * distribution.
71af051161SJung-uk Kim  *
72af051161SJung-uk Kim  * 3.4. Intel retains all right, title, and interest in and to the Original
73af051161SJung-uk Kim  * Intel Code.
74af051161SJung-uk Kim  *
75af051161SJung-uk Kim  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76af051161SJung-uk Kim  * Intel shall be used in advertising or otherwise to promote the sale, use or
77af051161SJung-uk Kim  * other dealings in products derived from or relating to the Covered Code
78af051161SJung-uk Kim  * without prior written authorization from Intel.
79af051161SJung-uk Kim  *
80af051161SJung-uk Kim  * 4. Disclaimer and Export Compliance
81af051161SJung-uk Kim  *
82af051161SJung-uk Kim  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83af051161SJung-uk Kim  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84af051161SJung-uk Kim  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85af051161SJung-uk Kim  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86af051161SJung-uk Kim  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87af051161SJung-uk Kim  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88af051161SJung-uk Kim  * PARTICULAR PURPOSE.
89af051161SJung-uk Kim  *
90af051161SJung-uk Kim  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91af051161SJung-uk Kim  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92af051161SJung-uk Kim  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93af051161SJung-uk Kim  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94af051161SJung-uk Kim  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95af051161SJung-uk Kim  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96af051161SJung-uk Kim  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97af051161SJung-uk Kim  * LIMITED REMEDY.
98af051161SJung-uk Kim  *
99af051161SJung-uk Kim  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100af051161SJung-uk Kim  * software or system incorporating such software without first obtaining any
101af051161SJung-uk Kim  * required license or other approval from the U. S. Department of Commerce or
102af051161SJung-uk Kim  * any other agency or department of the United States Government. In the
103af051161SJung-uk Kim  * event Licensee exports any such software from the United States or
104af051161SJung-uk Kim  * re-exports any such software from a foreign destination, Licensee shall
105af051161SJung-uk Kim  * ensure that the distribution and export/re-export of the software is in
106af051161SJung-uk Kim  * compliance with all laws, regulations, orders, or other restrictions of the
107af051161SJung-uk Kim  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108af051161SJung-uk Kim  * any of its subsidiaries will export/re-export any technical data, process,
109af051161SJung-uk Kim  * software, or service, directly or indirectly, to any country for which the
110af051161SJung-uk Kim  * United States government or any agency thereof requires an export license,
111af051161SJung-uk Kim  * other governmental approval, or letter of assurance, without first obtaining
112af051161SJung-uk Kim  * such license, approval or letter.
113af051161SJung-uk Kim  *
114af051161SJung-uk Kim  *****************************************************************************
115af051161SJung-uk Kim  *
116af051161SJung-uk Kim  * Alternatively, you may choose to be licensed under the terms of the
117af051161SJung-uk Kim  * following license:
118af051161SJung-uk Kim  *
119af051161SJung-uk Kim  * Redistribution and use in source and binary forms, with or without
120af051161SJung-uk Kim  * modification, are permitted provided that the following conditions
121af051161SJung-uk Kim  * are met:
122af051161SJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
123af051161SJung-uk Kim  *    notice, this list of conditions, and the following disclaimer,
124af051161SJung-uk Kim  *    without modification.
125af051161SJung-uk Kim  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126af051161SJung-uk Kim  *    substantially similar to the "NO WARRANTY" disclaimer below
127af051161SJung-uk Kim  *    ("Disclaimer") and any redistribution must be conditioned upon
128af051161SJung-uk Kim  *    including a substantially similar Disclaimer requirement for further
129af051161SJung-uk Kim  *    binary redistribution.
130af051161SJung-uk Kim  * 3. Neither the names of the above-listed copyright holders nor the names
131af051161SJung-uk Kim  *    of any contributors may be used to endorse or promote products derived
132af051161SJung-uk Kim  *    from this software without specific prior written permission.
133af051161SJung-uk Kim  *
134af051161SJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135af051161SJung-uk Kim  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136af051161SJung-uk Kim  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137af051161SJung-uk Kim  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138af051161SJung-uk Kim  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139af051161SJung-uk Kim  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140af051161SJung-uk Kim  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141af051161SJung-uk Kim  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142af051161SJung-uk Kim  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143af051161SJung-uk Kim  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144af051161SJung-uk Kim  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145af051161SJung-uk Kim  *
146af051161SJung-uk Kim  * Alternatively, you may choose to be licensed under the terms of the
147af051161SJung-uk Kim  * GNU General Public License ("GPL") version 2 as published by the Free
148af051161SJung-uk Kim  * Software Foundation.
149af051161SJung-uk Kim  *
150af051161SJung-uk Kim  *****************************************************************************/
151af051161SJung-uk Kim 
152af051161SJung-uk Kim #include <contrib/dev/acpica/include/acpi.h>
153af051161SJung-uk Kim #include <contrib/dev/acpica/include/accommon.h>
154af051161SJung-uk Kim #include <contrib/dev/acpica/include/acparser.h>
155af051161SJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h>
156af051161SJung-uk Kim #include <contrib/dev/acpica/include/acdisasm.h>
157af051161SJung-uk Kim #include <contrib/dev/acpica/include/acdispat.h>
158af051161SJung-uk Kim #include <contrib/dev/acpica/include/acnamesp.h>
159af051161SJung-uk Kim #include <contrib/dev/acpica/include/acapps.h>
160af051161SJung-uk Kim 
161af051161SJung-uk Kim 
162af051161SJung-uk Kim #define _COMPONENT          ACPI_CA_DISASSEMBLER
163af051161SJung-uk Kim         ACPI_MODULE_NAME    ("dmswitch")
164af051161SJung-uk Kim 
165af051161SJung-uk Kim static BOOLEAN
166af051161SJung-uk Kim AcpiDmIsSwitchBlock (
167af051161SJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
168af051161SJung-uk Kim     char                    **Temp);
169af051161SJung-uk Kim 
170af051161SJung-uk Kim static BOOLEAN
171af051161SJung-uk Kim AcpiDmIsCaseBlock (
172af051161SJung-uk Kim     ACPI_PARSE_OBJECT       *Op);
173af051161SJung-uk Kim 
174af051161SJung-uk Kim 
175af051161SJung-uk Kim /*******************************************************************************
176af051161SJung-uk Kim  *
177af051161SJung-uk Kim  * FUNCTION:    AcpiDmProcessSwitch
178af051161SJung-uk Kim  *
179af051161SJung-uk Kim  * PARAMETERS:  Op              - Object to be examined
180af051161SJung-uk Kim  *
181af051161SJung-uk Kim  * RETURN:      ACPI_STATUS
182af051161SJung-uk Kim  *
183af051161SJung-uk Kim  * DESCRIPTION: Walk function to create a list of all temporary (_T_) objects.
184af051161SJung-uk Kim  *              If a While loop is found that can be converted to a Switch, do
185af051161SJung-uk Kim  *              the conversion, remove the temporary name from the list, and
186af051161SJung-uk Kim  *              mark the parse op with an IGNORE flag.
187af051161SJung-uk Kim  *
188af051161SJung-uk Kim  ******************************************************************************/
189af051161SJung-uk Kim 
190af051161SJung-uk Kim ACPI_STATUS
AcpiDmProcessSwitch(ACPI_PARSE_OBJECT * Op)191af051161SJung-uk Kim AcpiDmProcessSwitch (
192af051161SJung-uk Kim     ACPI_PARSE_OBJECT       *Op)
193af051161SJung-uk Kim {
194af051161SJung-uk Kim     char                    *Temp = NULL;
195af051161SJung-uk Kim     ACPI_PARSE_OBJECT_LIST  *NewTemp;
196af051161SJung-uk Kim     ACPI_PARSE_OBJECT_LIST  *Current;
197af051161SJung-uk Kim     ACPI_PARSE_OBJECT_LIST  *Previous;
198af051161SJung-uk Kim     BOOLEAN                 FoundTemp = FALSE;
199af051161SJung-uk Kim 
200af051161SJung-uk Kim 
201af051161SJung-uk Kim     switch (Op->Common.AmlOpcode)
202af051161SJung-uk Kim     {
203af051161SJung-uk Kim     case AML_NAME_OP:
204af051161SJung-uk Kim 
205af051161SJung-uk Kim         Temp = (char *) (&Op->Named.Name);
206af051161SJung-uk Kim 
207af051161SJung-uk Kim         if (!strncmp(Temp, "_T_", 3))
208af051161SJung-uk Kim         {
209af051161SJung-uk Kim             /* Allocate and init a new Temp List node */
210af051161SJung-uk Kim 
211af051161SJung-uk Kim             NewTemp = ACPI_ALLOCATE_ZEROED (sizeof (ACPI_PARSE_OBJECT_LIST));
212af051161SJung-uk Kim             if (!NewTemp)
213af051161SJung-uk Kim             {
214af051161SJung-uk Kim                 return (AE_NO_MEMORY);
215af051161SJung-uk Kim             }
216af051161SJung-uk Kim 
217af051161SJung-uk Kim             if (AcpiGbl_TempListHead)
218af051161SJung-uk Kim             {
219af051161SJung-uk Kim                 Current = AcpiGbl_TempListHead;
220af051161SJung-uk Kim                 AcpiGbl_TempListHead = NewTemp;
221af051161SJung-uk Kim                 AcpiGbl_TempListHead->Op = Op;
222af051161SJung-uk Kim                 AcpiGbl_TempListHead->Next = Current;
223af051161SJung-uk Kim             }
224af051161SJung-uk Kim             else
225af051161SJung-uk Kim             {
226af051161SJung-uk Kim                 AcpiGbl_TempListHead = NewTemp;
227af051161SJung-uk Kim                 AcpiGbl_TempListHead->Op = Op;
228af051161SJung-uk Kim                 AcpiGbl_TempListHead->Next = NULL;
229af051161SJung-uk Kim             }
230af051161SJung-uk Kim         }
231af051161SJung-uk Kim         break;
232af051161SJung-uk Kim 
233af051161SJung-uk Kim     case AML_WHILE_OP:
234af051161SJung-uk Kim 
235af051161SJung-uk Kim         if (!AcpiDmIsSwitchBlock (Op, &Temp))
236af051161SJung-uk Kim         {
237af051161SJung-uk Kim             break;
238af051161SJung-uk Kim         }
239af051161SJung-uk Kim 
240af051161SJung-uk Kim         /* Found a Switch */
241af051161SJung-uk Kim 
242af051161SJung-uk Kim         Op->Common.DisasmOpcode = ACPI_DASM_SWITCH;
243af051161SJung-uk Kim 
244af051161SJung-uk Kim         Previous = Current = AcpiGbl_TempListHead;
245af051161SJung-uk Kim         while (Current)
246af051161SJung-uk Kim         {
247af051161SJung-uk Kim             /* Note, if we get here Temp is not NULL */
248af051161SJung-uk Kim 
249af051161SJung-uk Kim             if (!strncmp(Temp, (char *) (&Current->Op->Named.Name), 4))
250af051161SJung-uk Kim             {
251af051161SJung-uk Kim                 /* Match found. Ignore disassembly */
252af051161SJung-uk Kim 
253af051161SJung-uk Kim                 Current->Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
254af051161SJung-uk Kim 
255af051161SJung-uk Kim                 /* Remove from list */
256af051161SJung-uk Kim 
257af051161SJung-uk Kim                 if (Current == AcpiGbl_TempListHead)
258af051161SJung-uk Kim                 {
259af051161SJung-uk Kim                     AcpiGbl_TempListHead = Current->Next;
260af051161SJung-uk Kim                 }
261af051161SJung-uk Kim                 else
262af051161SJung-uk Kim                 {
263af051161SJung-uk Kim                     Previous->Next = Current->Next;
264af051161SJung-uk Kim                 }
265af051161SJung-uk Kim 
266af051161SJung-uk Kim                 Current->Op = NULL;
267af051161SJung-uk Kim                 Current->Next = NULL;
268af051161SJung-uk Kim                 ACPI_FREE (Current);
269af051161SJung-uk Kim                 FoundTemp = TRUE;
270af051161SJung-uk Kim                 break;
271af051161SJung-uk Kim             }
272af051161SJung-uk Kim 
273af051161SJung-uk Kim             Previous = Current;
274af051161SJung-uk Kim             Current = Current->Next;
275af051161SJung-uk Kim         }
276af051161SJung-uk Kim 
277af051161SJung-uk Kim         if (!FoundTemp)
278af051161SJung-uk Kim         {
279af051161SJung-uk Kim             fprintf (stderr,
280af051161SJung-uk Kim                 "Warning: Declaration for temp name %.4s not found\n", Temp);
281af051161SJung-uk Kim         }
282af051161SJung-uk Kim         break;
283af051161SJung-uk Kim 
284af051161SJung-uk Kim     default:
285af051161SJung-uk Kim         break;
286af051161SJung-uk Kim     }
287af051161SJung-uk Kim 
288af051161SJung-uk Kim     return (AE_OK);
289af051161SJung-uk Kim }
290af051161SJung-uk Kim 
291af051161SJung-uk Kim 
292af051161SJung-uk Kim /*******************************************************************************
293af051161SJung-uk Kim  *
294af051161SJung-uk Kim  * FUNCTION:    AcpiDmClearTempList
295af051161SJung-uk Kim  *
296af051161SJung-uk Kim  * PARAMETERS:  None
297af051161SJung-uk Kim  *
298af051161SJung-uk Kim  * RETURN:      None
299af051161SJung-uk Kim  *
300af051161SJung-uk Kim  * DESCRIPTION: Removes any remaining temporary objects from global list and
301af051161SJung-uk Kim  *              frees
302af051161SJung-uk Kim  *
303af051161SJung-uk Kim  ******************************************************************************/
304af051161SJung-uk Kim 
305af051161SJung-uk Kim void
AcpiDmClearTempList(void)306af051161SJung-uk Kim AcpiDmClearTempList (
307af051161SJung-uk Kim     void)
308af051161SJung-uk Kim {
309af051161SJung-uk Kim     ACPI_PARSE_OBJECT_LIST      *Current;
310af051161SJung-uk Kim 
311af051161SJung-uk Kim 
312af051161SJung-uk Kim     while (AcpiGbl_TempListHead)
313af051161SJung-uk Kim     {
314af051161SJung-uk Kim         Current = AcpiGbl_TempListHead;
315af051161SJung-uk Kim         AcpiGbl_TempListHead = AcpiGbl_TempListHead->Next;
316af051161SJung-uk Kim         Current->Op = NULL;
317af051161SJung-uk Kim         Current->Next = NULL;
318af051161SJung-uk Kim         ACPI_FREE (Current);
319af051161SJung-uk Kim     }
320af051161SJung-uk Kim }
321af051161SJung-uk Kim 
322af051161SJung-uk Kim 
323af051161SJung-uk Kim /*******************************************************************************
324af051161SJung-uk Kim  *
325af051161SJung-uk Kim  * FUNCTION:    AcpiDmIsSwitchBlock
326af051161SJung-uk Kim  *
327af051161SJung-uk Kim  * PARAMETERS:  Op              - While Object
32890b566fdSJung-uk Kim  *              Temp            - Where the compiler temp name is returned
32990b566fdSJung-uk Kim  *                                  (_T_x)
330af051161SJung-uk Kim  *
331af051161SJung-uk Kim  * RETURN:      TRUE if While block can be converted to a Switch/Case block
332af051161SJung-uk Kim  *
333af051161SJung-uk Kim  * DESCRIPTION: Determines if While block is a Switch/Case statement. Modifies
334af051161SJung-uk Kim  *              parse tree to allow for Switch/Case disassembly during walk.
335af051161SJung-uk Kim  *
336af051161SJung-uk Kim  * EXAMPLE: Example of parse tree to be converted
337af051161SJung-uk Kim  *
338af051161SJung-uk Kim  *    While
339af051161SJung-uk Kim  *        One
340af051161SJung-uk Kim  *        Store
341af051161SJung-uk Kim  *            ByteConst
342af051161SJung-uk Kim  *             -NamePath-
343af051161SJung-uk Kim  *        If
344af051161SJung-uk Kim  *            LEqual
345af051161SJung-uk Kim  *                -NamePath-
346af051161SJung-uk Kim  *                Zero
347af051161SJung-uk Kim  *            Return
348af051161SJung-uk Kim  *                One
349af051161SJung-uk Kim  *        Else
350af051161SJung-uk Kim  *            Return
351af051161SJung-uk Kim  *                WordConst
352af051161SJung-uk Kim  *        Break
353af051161SJung-uk Kim  *
354af051161SJung-uk Kim  ******************************************************************************/
355af051161SJung-uk Kim 
356af051161SJung-uk Kim BOOLEAN
AcpiDmIsSwitchBlock(ACPI_PARSE_OBJECT * Op,char ** Temp)357af051161SJung-uk Kim AcpiDmIsSwitchBlock (
358af051161SJung-uk Kim     ACPI_PARSE_OBJECT       *Op,
359af051161SJung-uk Kim     char                    **Temp)
360af051161SJung-uk Kim {
361af051161SJung-uk Kim     ACPI_PARSE_OBJECT       *OneOp;
362af051161SJung-uk Kim     ACPI_PARSE_OBJECT       *StoreOp;
363af051161SJung-uk Kim     ACPI_PARSE_OBJECT       *NamePathOp;
364af051161SJung-uk Kim     ACPI_PARSE_OBJECT       *PredicateOp;
365af051161SJung-uk Kim     ACPI_PARSE_OBJECT       *CurrentOp;
366af051161SJung-uk Kim     ACPI_PARSE_OBJECT       *TempOp;
367af051161SJung-uk Kim 
368af051161SJung-uk Kim 
369af051161SJung-uk Kim     /* Check for One Op Predicate */
370af051161SJung-uk Kim 
371af051161SJung-uk Kim     OneOp = AcpiPsGetArg (Op, 0);
372af051161SJung-uk Kim     if (!OneOp || (OneOp->Common.AmlOpcode != AML_ONE_OP))
373af051161SJung-uk Kim     {
374af051161SJung-uk Kim         return (FALSE);
375af051161SJung-uk Kim     }
376af051161SJung-uk Kim 
377af051161SJung-uk Kim     /* Check for Store Op */
378af051161SJung-uk Kim 
379af051161SJung-uk Kim     StoreOp = OneOp->Common.Next;
380af051161SJung-uk Kim     if (!StoreOp || (StoreOp->Common.AmlOpcode != AML_STORE_OP))
381af051161SJung-uk Kim     {
382af051161SJung-uk Kim         return (FALSE);
383af051161SJung-uk Kim     }
384af051161SJung-uk Kim 
385af051161SJung-uk Kim     /* Check for Name Op with _T_ string */
386af051161SJung-uk Kim 
387af051161SJung-uk Kim     NamePathOp = AcpiPsGetArg (StoreOp, 1);
388af051161SJung-uk Kim     if (!NamePathOp ||
389af051161SJung-uk Kim         (NamePathOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP))
390af051161SJung-uk Kim     {
391af051161SJung-uk Kim         return (FALSE);
392af051161SJung-uk Kim     }
393af051161SJung-uk Kim 
394af051161SJung-uk Kim     if (strncmp ((char *) (NamePathOp->Common.Value.Name), "_T_", 3))
395af051161SJung-uk Kim     {
396af051161SJung-uk Kim         return (FALSE);
397af051161SJung-uk Kim     }
398af051161SJung-uk Kim 
399af051161SJung-uk Kim     *Temp = (char *) (NamePathOp->Common.Value.Name);
400af051161SJung-uk Kim 
401af051161SJung-uk Kim     /* This is a Switch/Case control block */
402af051161SJung-uk Kim 
403af051161SJung-uk Kim     /* Ignore the One Op Predicate */
404af051161SJung-uk Kim 
405af051161SJung-uk Kim     OneOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
406af051161SJung-uk Kim 
407af051161SJung-uk Kim     /* Ignore the Store Op, but not the children */
408af051161SJung-uk Kim 
409af051161SJung-uk Kim     StoreOp->Common.DisasmOpcode = ACPI_DASM_IGNORE_SINGLE;
410af051161SJung-uk Kim 
411af051161SJung-uk Kim     /*
412af051161SJung-uk Kim      * First arg of Store Op is the Switch condition.
413af051161SJung-uk Kim      * Mark it as a Switch predicate and as a parameter list for paren
414af051161SJung-uk Kim      * closing and correct indentation.
415af051161SJung-uk Kim      */
416af051161SJung-uk Kim     PredicateOp = AcpiPsGetArg (StoreOp, 0);
417af051161SJung-uk Kim     PredicateOp->Common.DisasmOpcode = ACPI_DASM_SWITCH_PREDICATE;
418af051161SJung-uk Kim     PredicateOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
419af051161SJung-uk Kim 
420af051161SJung-uk Kim     /* Ignore the Name Op */
421af051161SJung-uk Kim 
422af051161SJung-uk Kim     NamePathOp->Common.DisasmFlags = ACPI_PARSEOP_IGNORE;
423af051161SJung-uk Kim 
424af051161SJung-uk Kim     /* Remaining opcodes are the Case statements (If/ElseIf's) */
425af051161SJung-uk Kim 
426af051161SJung-uk Kim     CurrentOp = StoreOp->Common.Next;
427af051161SJung-uk Kim     while (AcpiDmIsCaseBlock (CurrentOp))
428af051161SJung-uk Kim     {
429af051161SJung-uk Kim         /* Block is a Case structure */
430af051161SJung-uk Kim 
431af051161SJung-uk Kim         if (CurrentOp->Common.AmlOpcode == AML_ELSE_OP)
432af051161SJung-uk Kim         {
433af051161SJung-uk Kim             /* ElseIf */
434af051161SJung-uk Kim 
435af051161SJung-uk Kim             CurrentOp->Common.DisasmOpcode = ACPI_DASM_CASE;
436af051161SJung-uk Kim             CurrentOp = AcpiPsGetArg (CurrentOp, 0);
437af051161SJung-uk Kim         }
438af051161SJung-uk Kim 
439af051161SJung-uk Kim         /* If */
440af051161SJung-uk Kim 
441af051161SJung-uk Kim         CurrentOp->Common.DisasmOpcode = ACPI_DASM_CASE;
442af051161SJung-uk Kim 
443af051161SJung-uk Kim         /*
444af051161SJung-uk Kim          * Mark the parse tree for Case disassembly. There are two
445af051161SJung-uk Kim          * types of Case statements. The first type of statement begins with
446af051161SJung-uk Kim          * an LEqual. The second starts with an LNot and uses a Match statement
447af051161SJung-uk Kim          * on a Package of constants.
448af051161SJung-uk Kim          */
449af051161SJung-uk Kim         TempOp = AcpiPsGetArg (CurrentOp, 0);
450af051161SJung-uk Kim         switch (TempOp->Common.AmlOpcode)
451af051161SJung-uk Kim         {
452af051161SJung-uk Kim         case (AML_LOGICAL_EQUAL_OP):
453af051161SJung-uk Kim 
454af051161SJung-uk Kim             /* Ignore just the LEqual Op */
455af051161SJung-uk Kim 
456af051161SJung-uk Kim             TempOp->Common.DisasmOpcode = ACPI_DASM_IGNORE_SINGLE;
457af051161SJung-uk Kim 
458af051161SJung-uk Kim             /* Ignore the NamePath Op */
459af051161SJung-uk Kim 
460af051161SJung-uk Kim             TempOp = AcpiPsGetArg (TempOp, 0);
461af051161SJung-uk Kim             TempOp->Common.DisasmFlags = ACPI_PARSEOP_IGNORE;
462af051161SJung-uk Kim 
463af051161SJung-uk Kim             /*
464af051161SJung-uk Kim              * Second arg of LEqual will be the Case predicate.
465af051161SJung-uk Kim              * Mark it as a predicate and also as a parameter list for paren
466af051161SJung-uk Kim              * closing and correct indentation.
467af051161SJung-uk Kim              */
468af051161SJung-uk Kim             PredicateOp = TempOp->Common.Next;
469af051161SJung-uk Kim             PredicateOp->Common.DisasmOpcode = ACPI_DASM_SWITCH_PREDICATE;
470af051161SJung-uk Kim             PredicateOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
471af051161SJung-uk Kim             break;
472af051161SJung-uk Kim 
473af051161SJung-uk Kim         case (AML_LOGICAL_NOT_OP):
474af051161SJung-uk Kim 
475af051161SJung-uk Kim             /*
476af051161SJung-uk Kim              * The Package will be the predicate of the Case statement.
477af051161SJung-uk Kim              * It's under:
478af051161SJung-uk Kim              *            LNOT
479af051161SJung-uk Kim              *                LEQUAL
480af051161SJung-uk Kim              *                    MATCH
481af051161SJung-uk Kim              *                        PACKAGE
482af051161SJung-uk Kim              */
483af051161SJung-uk Kim 
484af051161SJung-uk Kim             /* Get the LEqual Op from LNot */
485af051161SJung-uk Kim 
486af051161SJung-uk Kim             TempOp = AcpiPsGetArg (TempOp, 0);
487af051161SJung-uk Kim 
488af051161SJung-uk Kim             /* Get the Match Op from LEqual */
489af051161SJung-uk Kim 
490af051161SJung-uk Kim             TempOp = AcpiPsGetArg (TempOp, 0);
491af051161SJung-uk Kim 
492af051161SJung-uk Kim             /* Get the Package Op from Match */
493af051161SJung-uk Kim 
494af051161SJung-uk Kim             PredicateOp = AcpiPsGetArg (TempOp, 0);
495af051161SJung-uk Kim 
496af051161SJung-uk Kim             /* Mark as parameter list for paren closing */
497af051161SJung-uk Kim 
498af051161SJung-uk Kim             PredicateOp->Common.DisasmFlags |= ACPI_PARSEOP_PARAMETER_LIST;
499af051161SJung-uk Kim 
500af051161SJung-uk Kim             /*
501af051161SJung-uk Kim              * The Package list would be too deeply indented if we
502af051161SJung-uk Kim              * chose to simply ignore the all the parent opcodes, so
503af051161SJung-uk Kim              * we rearrange the parse tree instead.
504af051161SJung-uk Kim              */
505af051161SJung-uk Kim 
506af051161SJung-uk Kim             /*
507af051161SJung-uk Kim              * Save the second arg of the If/Else Op which is the
508af051161SJung-uk Kim              * block code of code for this Case statement.
509af051161SJung-uk Kim              */
510af051161SJung-uk Kim             TempOp = AcpiPsGetArg (CurrentOp, 1);
511af051161SJung-uk Kim 
512af051161SJung-uk Kim             /*
513af051161SJung-uk Kim              * Move the Package Op to the child (predicate) of the
514af051161SJung-uk Kim              * Case statement.
515af051161SJung-uk Kim              */
516af051161SJung-uk Kim             CurrentOp->Common.Value.Arg = PredicateOp;
517af051161SJung-uk Kim             PredicateOp->Common.Parent = CurrentOp;
518af051161SJung-uk Kim 
519af051161SJung-uk Kim             /* Add the block code */
520af051161SJung-uk Kim 
521af051161SJung-uk Kim             PredicateOp->Common.Next = TempOp;
522af051161SJung-uk Kim             break;
523af051161SJung-uk Kim 
524af051161SJung-uk Kim         default:
525af051161SJung-uk Kim 
526af051161SJung-uk Kim             /* Should never get here */
527af051161SJung-uk Kim             break;
528af051161SJung-uk Kim         }
529af051161SJung-uk Kim 
530af051161SJung-uk Kim         /* Advance to next Case block */
531af051161SJung-uk Kim 
532af051161SJung-uk Kim         CurrentOp = CurrentOp->Common.Next;
533af051161SJung-uk Kim     }
534af051161SJung-uk Kim 
535af051161SJung-uk Kim     /* If CurrentOp is now an Else, then this is a Default block */
536af051161SJung-uk Kim 
537af051161SJung-uk Kim     if (CurrentOp && CurrentOp->Common.AmlOpcode == AML_ELSE_OP)
538af051161SJung-uk Kim     {
539af051161SJung-uk Kim         CurrentOp->Common.DisasmOpcode = ACPI_DASM_DEFAULT;
540af051161SJung-uk Kim     }
541af051161SJung-uk Kim 
542af051161SJung-uk Kim     /*
543af051161SJung-uk Kim      * From the first If advance to the Break op. It's possible to
544af051161SJung-uk Kim      * have an Else (Default) op here when there is only one Case
545af051161SJung-uk Kim      * statement, so check for it.
546af051161SJung-uk Kim      */
547af051161SJung-uk Kim     CurrentOp = StoreOp->Common.Next->Common.Next;
548f1db5ef7SJung-uk Kim     if (!CurrentOp)
549f1db5ef7SJung-uk Kim     {
550f1db5ef7SJung-uk Kim         return (FALSE);
551f1db5ef7SJung-uk Kim     }
552af051161SJung-uk Kim     if (CurrentOp->Common.AmlOpcode == AML_ELSE_OP)
553af051161SJung-uk Kim     {
554af051161SJung-uk Kim         CurrentOp = CurrentOp->Common.Next;
55590b566fdSJung-uk Kim         if (!CurrentOp)
55690b566fdSJung-uk Kim         {
55790b566fdSJung-uk Kim             return (FALSE);
55890b566fdSJung-uk Kim         }
559af051161SJung-uk Kim     }
560af051161SJung-uk Kim 
561af051161SJung-uk Kim     /* Ignore the Break Op */
562af051161SJung-uk Kim 
563af051161SJung-uk Kim     CurrentOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
564af051161SJung-uk Kim     return (TRUE);
565af051161SJung-uk Kim }
566af051161SJung-uk Kim 
567af051161SJung-uk Kim 
568af051161SJung-uk Kim /*******************************************************************************
569af051161SJung-uk Kim  *
570af051161SJung-uk Kim  * FUNCTION:    AcpiDmIsCaseBlock
571af051161SJung-uk Kim  *
572af051161SJung-uk Kim  * PARAMETERS:  Op              - Object to test
573af051161SJung-uk Kim  *
574af051161SJung-uk Kim  * RETURN:      TRUE if Object is beginning of a Case block.
575af051161SJung-uk Kim  *
576af051161SJung-uk Kim  * DESCRIPTION: Determines if an Object is the beginning of a Case block for a
577af051161SJung-uk Kim  *              Switch/Case statement. Parse tree must be one of the following
578af051161SJung-uk Kim  *              forms:
579af051161SJung-uk Kim  *
580af051161SJung-uk Kim  *              Else (Optional)
581af051161SJung-uk Kim  *                  If
582af051161SJung-uk Kim  *                      LEqual
583af051161SJung-uk Kim  *                          -NamePath- _T_x
584af051161SJung-uk Kim  *
585af051161SJung-uk Kim  *              Else (Optional)
586af051161SJung-uk Kim  *                  If
587af051161SJung-uk Kim  *                      LNot
588af051161SJung-uk Kim  *                          LEqual
589af051161SJung-uk Kim  *                              Match
590af051161SJung-uk Kim  *                                  Package
591af051161SJung-uk Kim  *                                      ByteConst
592af051161SJung-uk Kim  *                                      -NamePath- _T_x
593af051161SJung-uk Kim  *
594af051161SJung-uk Kim  ******************************************************************************/
595af051161SJung-uk Kim 
596af051161SJung-uk Kim static BOOLEAN
AcpiDmIsCaseBlock(ACPI_PARSE_OBJECT * Op)597af051161SJung-uk Kim AcpiDmIsCaseBlock (
598af051161SJung-uk Kim     ACPI_PARSE_OBJECT       *Op)
599af051161SJung-uk Kim {
600af051161SJung-uk Kim     ACPI_PARSE_OBJECT       *CurrentOp;
601af051161SJung-uk Kim 
602af051161SJung-uk Kim 
603af051161SJung-uk Kim     if (!Op)
604af051161SJung-uk Kim     {
605af051161SJung-uk Kim         return (FALSE);
606af051161SJung-uk Kim     }
607af051161SJung-uk Kim 
608af051161SJung-uk Kim     /* Look for an If or ElseIf */
609af051161SJung-uk Kim 
610af051161SJung-uk Kim     CurrentOp = Op;
611af051161SJung-uk Kim     if (CurrentOp->Common.AmlOpcode == AML_ELSE_OP)
612af051161SJung-uk Kim     {
613af051161SJung-uk Kim         CurrentOp = AcpiPsGetArg (CurrentOp, 0);
614af051161SJung-uk Kim         if (!CurrentOp)
615af051161SJung-uk Kim         {
616af051161SJung-uk Kim             return (FALSE);
617af051161SJung-uk Kim         }
618af051161SJung-uk Kim     }
619af051161SJung-uk Kim 
620af051161SJung-uk Kim     if (!CurrentOp || CurrentOp->Common.AmlOpcode != AML_IF_OP)
621af051161SJung-uk Kim     {
622af051161SJung-uk Kim         return (FALSE);
623af051161SJung-uk Kim     }
624af051161SJung-uk Kim 
625af051161SJung-uk Kim     /* Child must be LEqual or LNot */
626af051161SJung-uk Kim 
627af051161SJung-uk Kim     CurrentOp = AcpiPsGetArg (CurrentOp, 0);
628af051161SJung-uk Kim     if (!CurrentOp)
629af051161SJung-uk Kim     {
630af051161SJung-uk Kim         return (FALSE);
631af051161SJung-uk Kim     }
632af051161SJung-uk Kim 
633af051161SJung-uk Kim     switch (CurrentOp->Common.AmlOpcode)
634af051161SJung-uk Kim     {
635af051161SJung-uk Kim     case (AML_LOGICAL_EQUAL_OP):
636af051161SJung-uk Kim 
637af051161SJung-uk Kim         /* Next child must be NamePath with string _T_ */
638af051161SJung-uk Kim 
639af051161SJung-uk Kim         CurrentOp = AcpiPsGetArg (CurrentOp, 0);
640af051161SJung-uk Kim         if (!CurrentOp || !CurrentOp->Common.Value.Name ||
641af051161SJung-uk Kim             strncmp(CurrentOp->Common.Value.Name, "_T_", 3))
642af051161SJung-uk Kim         {
643af051161SJung-uk Kim             return (FALSE);
644af051161SJung-uk Kim         }
645af051161SJung-uk Kim         break;
646af051161SJung-uk Kim 
647af051161SJung-uk Kim     case (AML_LOGICAL_NOT_OP):
648af051161SJung-uk Kim 
649af051161SJung-uk Kim         /* Child of LNot must be LEqual op */
650af051161SJung-uk Kim 
651af051161SJung-uk Kim         CurrentOp = AcpiPsGetArg (CurrentOp, 0);
652af051161SJung-uk Kim         if (!CurrentOp || (CurrentOp->Common.AmlOpcode != AML_LOGICAL_EQUAL_OP))
653af051161SJung-uk Kim         {
654af051161SJung-uk Kim             return (FALSE);
655af051161SJung-uk Kim         }
656af051161SJung-uk Kim 
657af051161SJung-uk Kim         /* Child of LNot must be Match op */
658af051161SJung-uk Kim 
659af051161SJung-uk Kim         CurrentOp = AcpiPsGetArg (CurrentOp, 0);
660af051161SJung-uk Kim         if (!CurrentOp || (CurrentOp->Common.AmlOpcode != AML_MATCH_OP))
661af051161SJung-uk Kim         {
662af051161SJung-uk Kim             return (FALSE);
663af051161SJung-uk Kim         }
664af051161SJung-uk Kim 
665af051161SJung-uk Kim         /* First child of Match must be Package op */
666af051161SJung-uk Kim 
667af051161SJung-uk Kim         CurrentOp = AcpiPsGetArg (CurrentOp, 0);
668af051161SJung-uk Kim         if (!CurrentOp || (CurrentOp->Common.AmlOpcode != AML_PACKAGE_OP))
669af051161SJung-uk Kim         {
670af051161SJung-uk Kim             return (FALSE);
671af051161SJung-uk Kim         }
672af051161SJung-uk Kim 
673af051161SJung-uk Kim         /* Third child of Match must be NamePath with string _T_ */
674af051161SJung-uk Kim 
675af051161SJung-uk Kim         CurrentOp = AcpiPsGetArg (CurrentOp->Common.Parent, 2);
676af051161SJung-uk Kim         if (!CurrentOp || !CurrentOp->Common.Value.Name ||
677af051161SJung-uk Kim             strncmp(CurrentOp->Common.Value.Name, "_T_", 3))
678af051161SJung-uk Kim         {
679af051161SJung-uk Kim             return (FALSE);
680af051161SJung-uk Kim         }
681af051161SJung-uk Kim         break;
682af051161SJung-uk Kim 
683af051161SJung-uk Kim     default:
684af051161SJung-uk Kim 
685af051161SJung-uk Kim         return (FALSE);
686af051161SJung-uk Kim     }
687af051161SJung-uk Kim 
688af051161SJung-uk Kim     return (TRUE);
689af051161SJung-uk Kim }
690