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