10d02842fSSascha Wildner /*******************************************************************************
20d02842fSSascha Wildner *
30d02842fSSascha Wildner * Module Name: dmopcode - AML disassembler, specific AML opcodes
40d02842fSSascha Wildner *
50d02842fSSascha Wildner ******************************************************************************/
60d02842fSSascha Wildner
7b4315fc7SSascha Wildner /******************************************************************************
8b4315fc7SSascha Wildner *
9b4315fc7SSascha Wildner * 1. Copyright Notice
10b4315fc7SSascha Wildner *
11*383048acSSascha Wildner * Some or all of this work - Copyright (c) 1999 - 2021, Intel Corp.
120d02842fSSascha Wildner * All rights reserved.
130d02842fSSascha Wildner *
14b4315fc7SSascha Wildner * 2. License
15b4315fc7SSascha Wildner *
16b4315fc7SSascha Wildner * 2.1. This is your license from Intel Corp. under its intellectual property
17b4315fc7SSascha Wildner * rights. You may have additional license terms from the party that provided
18b4315fc7SSascha Wildner * you this software, covering your right to use that party's intellectual
19b4315fc7SSascha Wildner * property rights.
20b4315fc7SSascha Wildner *
21b4315fc7SSascha Wildner * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22b4315fc7SSascha Wildner * copy of the source code appearing in this file ("Covered Code") an
23b4315fc7SSascha Wildner * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24b4315fc7SSascha Wildner * base code distributed originally by Intel ("Original Intel Code") to copy,
25b4315fc7SSascha Wildner * make derivatives, distribute, use and display any portion of the Covered
26b4315fc7SSascha Wildner * Code in any form, with the right to sublicense such rights; and
27b4315fc7SSascha Wildner *
28b4315fc7SSascha Wildner * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29b4315fc7SSascha Wildner * license (with the right to sublicense), under only those claims of Intel
30b4315fc7SSascha Wildner * patents that are infringed by the Original Intel Code, to make, use, sell,
31b4315fc7SSascha Wildner * offer to sell, and import the Covered Code and derivative works thereof
32b4315fc7SSascha Wildner * solely to the minimum extent necessary to exercise the above copyright
33b4315fc7SSascha Wildner * license, and in no event shall the patent license extend to any additions
34b4315fc7SSascha Wildner * to or modifications of the Original Intel Code. No other license or right
35b4315fc7SSascha Wildner * is granted directly or by implication, estoppel or otherwise;
36b4315fc7SSascha Wildner *
37b4315fc7SSascha Wildner * The above copyright and patent license is granted only if the following
38b4315fc7SSascha Wildner * conditions are met:
39b4315fc7SSascha Wildner *
40b4315fc7SSascha Wildner * 3. Conditions
41b4315fc7SSascha Wildner *
42b4315fc7SSascha Wildner * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43b4315fc7SSascha Wildner * Redistribution of source code of any substantial portion of the Covered
44b4315fc7SSascha Wildner * Code or modification with rights to further distribute source must include
45b4315fc7SSascha Wildner * the above Copyright Notice, the above License, this list of Conditions,
46b4315fc7SSascha Wildner * and the following Disclaimer and Export Compliance provision. In addition,
47b4315fc7SSascha Wildner * Licensee must cause all Covered Code to which Licensee contributes to
48b4315fc7SSascha Wildner * contain a file documenting the changes Licensee made to create that Covered
49b4315fc7SSascha Wildner * Code and the date of any change. Licensee must include in that file the
50b4315fc7SSascha Wildner * documentation of any changes made by any predecessor Licensee. Licensee
51b4315fc7SSascha Wildner * must include a prominent statement that the modification is derived,
52b4315fc7SSascha Wildner * directly or indirectly, from Original Intel Code.
53b4315fc7SSascha Wildner *
54b4315fc7SSascha Wildner * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55b4315fc7SSascha Wildner * Redistribution of source code of any substantial portion of the Covered
56b4315fc7SSascha Wildner * Code or modification without rights to further distribute source must
57b4315fc7SSascha Wildner * include the following Disclaimer and Export Compliance provision in the
58b4315fc7SSascha Wildner * documentation and/or other materials provided with distribution. In
59b4315fc7SSascha Wildner * addition, Licensee may not authorize further sublicense of source of any
60b4315fc7SSascha Wildner * portion of the Covered Code, and must include terms to the effect that the
61b4315fc7SSascha Wildner * license from Licensee to its licensee is limited to the intellectual
62b4315fc7SSascha Wildner * property embodied in the software Licensee provides to its licensee, and
63b4315fc7SSascha Wildner * not to intellectual property embodied in modifications its licensee may
64b4315fc7SSascha Wildner * make.
65b4315fc7SSascha Wildner *
66b4315fc7SSascha Wildner * 3.3. Redistribution of Executable. Redistribution in executable form of any
67b4315fc7SSascha Wildner * substantial portion of the Covered Code or modification must reproduce the
68b4315fc7SSascha Wildner * above Copyright Notice, and the following Disclaimer and Export Compliance
69b4315fc7SSascha Wildner * provision in the documentation and/or other materials provided with the
70b4315fc7SSascha Wildner * distribution.
71b4315fc7SSascha Wildner *
72b4315fc7SSascha Wildner * 3.4. Intel retains all right, title, and interest in and to the Original
73b4315fc7SSascha Wildner * Intel Code.
74b4315fc7SSascha Wildner *
75b4315fc7SSascha Wildner * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76b4315fc7SSascha Wildner * Intel shall be used in advertising or otherwise to promote the sale, use or
77b4315fc7SSascha Wildner * other dealings in products derived from or relating to the Covered Code
78b4315fc7SSascha Wildner * without prior written authorization from Intel.
79b4315fc7SSascha Wildner *
80b4315fc7SSascha Wildner * 4. Disclaimer and Export Compliance
81b4315fc7SSascha Wildner *
82b4315fc7SSascha Wildner * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83b4315fc7SSascha Wildner * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84b4315fc7SSascha Wildner * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85b4315fc7SSascha Wildner * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86b4315fc7SSascha Wildner * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87b4315fc7SSascha Wildner * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88b4315fc7SSascha Wildner * PARTICULAR PURPOSE.
89b4315fc7SSascha Wildner *
90b4315fc7SSascha Wildner * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91b4315fc7SSascha Wildner * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92b4315fc7SSascha Wildner * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93b4315fc7SSascha Wildner * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94b4315fc7SSascha Wildner * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95b4315fc7SSascha Wildner * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96b4315fc7SSascha Wildner * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97b4315fc7SSascha Wildner * LIMITED REMEDY.
98b4315fc7SSascha Wildner *
99b4315fc7SSascha Wildner * 4.3. Licensee shall not export, either directly or indirectly, any of this
100b4315fc7SSascha Wildner * software or system incorporating such software without first obtaining any
101b4315fc7SSascha Wildner * required license or other approval from the U. S. Department of Commerce or
102b4315fc7SSascha Wildner * any other agency or department of the United States Government. In the
103b4315fc7SSascha Wildner * event Licensee exports any such software from the United States or
104b4315fc7SSascha Wildner * re-exports any such software from a foreign destination, Licensee shall
105b4315fc7SSascha Wildner * ensure that the distribution and export/re-export of the software is in
106b4315fc7SSascha Wildner * compliance with all laws, regulations, orders, or other restrictions of the
107b4315fc7SSascha Wildner * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108b4315fc7SSascha Wildner * any of its subsidiaries will export/re-export any technical data, process,
109b4315fc7SSascha Wildner * software, or service, directly or indirectly, to any country for which the
110b4315fc7SSascha Wildner * United States government or any agency thereof requires an export license,
111b4315fc7SSascha Wildner * other governmental approval, or letter of assurance, without first obtaining
112b4315fc7SSascha Wildner * such license, approval or letter.
113b4315fc7SSascha Wildner *
114b4315fc7SSascha Wildner *****************************************************************************
115b4315fc7SSascha Wildner *
116b4315fc7SSascha Wildner * Alternatively, you may choose to be licensed under the terms of the
117b4315fc7SSascha Wildner * following license:
118b4315fc7SSascha Wildner *
1190d02842fSSascha Wildner * Redistribution and use in source and binary forms, with or without
1200d02842fSSascha Wildner * modification, are permitted provided that the following conditions
1210d02842fSSascha Wildner * are met:
1220d02842fSSascha Wildner * 1. Redistributions of source code must retain the above copyright
1230d02842fSSascha Wildner * notice, this list of conditions, and the following disclaimer,
1240d02842fSSascha Wildner * without modification.
1250d02842fSSascha Wildner * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1260d02842fSSascha Wildner * substantially similar to the "NO WARRANTY" disclaimer below
1270d02842fSSascha Wildner * ("Disclaimer") and any redistribution must be conditioned upon
1280d02842fSSascha Wildner * including a substantially similar Disclaimer requirement for further
1290d02842fSSascha Wildner * binary redistribution.
1300d02842fSSascha Wildner * 3. Neither the names of the above-listed copyright holders nor the names
1310d02842fSSascha Wildner * of any contributors may be used to endorse or promote products derived
1320d02842fSSascha Wildner * from this software without specific prior written permission.
1330d02842fSSascha Wildner *
134b4315fc7SSascha Wildner * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135b4315fc7SSascha Wildner * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136b4315fc7SSascha Wildner * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137b4315fc7SSascha Wildner * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138b4315fc7SSascha Wildner * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139b4315fc7SSascha Wildner * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140b4315fc7SSascha Wildner * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141b4315fc7SSascha Wildner * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142b4315fc7SSascha Wildner * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143b4315fc7SSascha Wildner * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144b4315fc7SSascha Wildner * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145b4315fc7SSascha Wildner *
146b4315fc7SSascha Wildner * Alternatively, you may choose to be licensed under the terms of the
1470d02842fSSascha Wildner * GNU General Public License ("GPL") version 2 as published by the Free
1480d02842fSSascha Wildner * Software Foundation.
1490d02842fSSascha Wildner *
150b4315fc7SSascha Wildner *****************************************************************************/
1510d02842fSSascha Wildner
1520d02842fSSascha Wildner #include "acpi.h"
1530d02842fSSascha Wildner #include "accommon.h"
1540d02842fSSascha Wildner #include "acparser.h"
1550d02842fSSascha Wildner #include "amlcode.h"
156d4972a9cSSascha Wildner #include "acinterp.h"
157d4972a9cSSascha Wildner #include "acnamesp.h"
158267c04fdSSascha Wildner #include "acdebug.h"
159d638c6eeSSascha Wildner #include "acconvert.h"
1600d02842fSSascha Wildner
1610d02842fSSascha Wildner #ifdef ACPI_DISASSEMBLER
1620d02842fSSascha Wildner
1630d02842fSSascha Wildner #define _COMPONENT ACPI_CA_DEBUGGER
1640d02842fSSascha Wildner ACPI_MODULE_NAME ("dmopcode")
1650d02842fSSascha Wildner
1662e2672b8SSascha Wildner
1670d02842fSSascha Wildner /* Local prototypes */
1680d02842fSSascha Wildner
1690d02842fSSascha Wildner static void
1700d02842fSSascha Wildner AcpiDmMatchKeyword (
1710d02842fSSascha Wildner ACPI_PARSE_OBJECT *Op);
1720d02842fSSascha Wildner
173f5f76cf2SSascha Wildner static void
174f5f76cf2SSascha Wildner AcpiDmConvertToElseIf (
175f5f76cf2SSascha Wildner ACPI_PARSE_OBJECT *Op);
176f5f76cf2SSascha Wildner
17796f24602SSascha Wildner static void
17896f24602SSascha Wildner AcpiDmPromoteSubtree (
17996f24602SSascha Wildner ACPI_PARSE_OBJECT *StartOp);
18096f24602SSascha Wildner
1810d02842fSSascha Wildner /*******************************************************************************
1820d02842fSSascha Wildner *
183d4972a9cSSascha Wildner * FUNCTION: AcpiDmDisplayTargetPathname
184d4972a9cSSascha Wildner *
185d4972a9cSSascha Wildner * PARAMETERS: Op - Parse object
186d4972a9cSSascha Wildner *
187d4972a9cSSascha Wildner * RETURN: None
188d4972a9cSSascha Wildner *
189d4972a9cSSascha Wildner * DESCRIPTION: For AML opcodes that have a target operand, display the full
190d4972a9cSSascha Wildner * pathname for the target, in a comment field. Handles Return()
191d4972a9cSSascha Wildner * statements also.
192d4972a9cSSascha Wildner *
193d4972a9cSSascha Wildner ******************************************************************************/
194d4972a9cSSascha Wildner
195d4972a9cSSascha Wildner void
AcpiDmDisplayTargetPathname(ACPI_PARSE_OBJECT * Op)196d4972a9cSSascha Wildner AcpiDmDisplayTargetPathname (
197d4972a9cSSascha Wildner ACPI_PARSE_OBJECT *Op)
198d4972a9cSSascha Wildner {
199d4972a9cSSascha Wildner ACPI_PARSE_OBJECT *NextOp;
200d4972a9cSSascha Wildner ACPI_PARSE_OBJECT *PrevOp = NULL;
201d4972a9cSSascha Wildner char *Pathname;
202d4972a9cSSascha Wildner const ACPI_OPCODE_INFO *OpInfo;
203d4972a9cSSascha Wildner
204d4972a9cSSascha Wildner
205d4972a9cSSascha Wildner if (Op->Common.AmlOpcode == AML_RETURN_OP)
206d4972a9cSSascha Wildner {
207d4972a9cSSascha Wildner PrevOp = Op->Asl.Value.Arg;
208d4972a9cSSascha Wildner }
209d4972a9cSSascha Wildner else
210d4972a9cSSascha Wildner {
211d4972a9cSSascha Wildner OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
212d4972a9cSSascha Wildner if (!(OpInfo->Flags & AML_HAS_TARGET))
213d4972a9cSSascha Wildner {
214d4972a9cSSascha Wildner return;
215d4972a9cSSascha Wildner }
216d4972a9cSSascha Wildner
217d4972a9cSSascha Wildner /* Target is the last Op in the arg list */
218d4972a9cSSascha Wildner
219d4972a9cSSascha Wildner NextOp = Op->Asl.Value.Arg;
220d4972a9cSSascha Wildner while (NextOp)
221d4972a9cSSascha Wildner {
222d4972a9cSSascha Wildner PrevOp = NextOp;
223d4972a9cSSascha Wildner NextOp = PrevOp->Asl.Next;
224d4972a9cSSascha Wildner }
225d4972a9cSSascha Wildner }
226d4972a9cSSascha Wildner
227d4972a9cSSascha Wildner if (!PrevOp)
228d4972a9cSSascha Wildner {
229d4972a9cSSascha Wildner return;
230d4972a9cSSascha Wildner }
231d4972a9cSSascha Wildner
232d4972a9cSSascha Wildner /* We must have a namepath AML opcode */
233d4972a9cSSascha Wildner
234d4972a9cSSascha Wildner if (PrevOp->Asl.AmlOpcode != AML_INT_NAMEPATH_OP)
235d4972a9cSSascha Wildner {
236d4972a9cSSascha Wildner return;
237d4972a9cSSascha Wildner }
238d4972a9cSSascha Wildner
239d4972a9cSSascha Wildner /* A null string is the "no target specified" case */
240d4972a9cSSascha Wildner
241d4972a9cSSascha Wildner if (!PrevOp->Asl.Value.String)
242d4972a9cSSascha Wildner {
243d4972a9cSSascha Wildner return;
244d4972a9cSSascha Wildner }
245d4972a9cSSascha Wildner
246d4972a9cSSascha Wildner /* No node means "unresolved external reference" */
247d4972a9cSSascha Wildner
248d4972a9cSSascha Wildner if (!PrevOp->Asl.Node)
249d4972a9cSSascha Wildner {
250d4972a9cSSascha Wildner AcpiOsPrintf (" /* External reference */");
251d4972a9cSSascha Wildner return;
252d4972a9cSSascha Wildner }
253d4972a9cSSascha Wildner
254d4972a9cSSascha Wildner /* Ignore if path is already from the root */
255d4972a9cSSascha Wildner
256d4972a9cSSascha Wildner if (*PrevOp->Asl.Value.String == '\\')
257d4972a9cSSascha Wildner {
258d4972a9cSSascha Wildner return;
259d4972a9cSSascha Wildner }
260d4972a9cSSascha Wildner
261d4972a9cSSascha Wildner /* Now: we can get the full pathname */
262d4972a9cSSascha Wildner
263d4972a9cSSascha Wildner Pathname = AcpiNsGetExternalPathname (PrevOp->Asl.Node);
264d4972a9cSSascha Wildner if (!Pathname)
265d4972a9cSSascha Wildner {
266d4972a9cSSascha Wildner return;
267d4972a9cSSascha Wildner }
268d4972a9cSSascha Wildner
269d4972a9cSSascha Wildner AcpiOsPrintf (" /* %s */", Pathname);
270d4972a9cSSascha Wildner ACPI_FREE (Pathname);
271d4972a9cSSascha Wildner }
272d4972a9cSSascha Wildner
273d4972a9cSSascha Wildner
274d4972a9cSSascha Wildner /*******************************************************************************
275d4972a9cSSascha Wildner *
276d4972a9cSSascha Wildner * FUNCTION: AcpiDmNotifyDescription
277d4972a9cSSascha Wildner *
278d4972a9cSSascha Wildner * PARAMETERS: Op - Name() parse object
279d4972a9cSSascha Wildner *
280d4972a9cSSascha Wildner * RETURN: None
281d4972a9cSSascha Wildner *
282d4972a9cSSascha Wildner * DESCRIPTION: Emit a description comment for the value associated with a
283d4972a9cSSascha Wildner * Notify() operator.
284d4972a9cSSascha Wildner *
285d4972a9cSSascha Wildner ******************************************************************************/
286d4972a9cSSascha Wildner
287d4972a9cSSascha Wildner void
AcpiDmNotifyDescription(ACPI_PARSE_OBJECT * Op)288d4972a9cSSascha Wildner AcpiDmNotifyDescription (
289d4972a9cSSascha Wildner ACPI_PARSE_OBJECT *Op)
290d4972a9cSSascha Wildner {
291d4972a9cSSascha Wildner ACPI_PARSE_OBJECT *NextOp;
292d4972a9cSSascha Wildner ACPI_NAMESPACE_NODE *Node;
293d4972a9cSSascha Wildner UINT8 NotifyValue;
294d4972a9cSSascha Wildner UINT8 Type = ACPI_TYPE_ANY;
295d4972a9cSSascha Wildner
296d4972a9cSSascha Wildner
297d4972a9cSSascha Wildner /* The notify value is the second argument */
298d4972a9cSSascha Wildner
299d4972a9cSSascha Wildner NextOp = Op->Asl.Value.Arg;
300d4972a9cSSascha Wildner NextOp = NextOp->Asl.Next;
301d4972a9cSSascha Wildner
302d4972a9cSSascha Wildner switch (NextOp->Common.AmlOpcode)
303d4972a9cSSascha Wildner {
304d4972a9cSSascha Wildner case AML_ZERO_OP:
305d4972a9cSSascha Wildner case AML_ONE_OP:
306d4972a9cSSascha Wildner
307d4972a9cSSascha Wildner NotifyValue = (UINT8) NextOp->Common.AmlOpcode;
308d4972a9cSSascha Wildner break;
309d4972a9cSSascha Wildner
310d4972a9cSSascha Wildner case AML_BYTE_OP:
311d4972a9cSSascha Wildner
312d4972a9cSSascha Wildner NotifyValue = (UINT8) NextOp->Asl.Value.Integer;
313d4972a9cSSascha Wildner break;
314d4972a9cSSascha Wildner
315d4972a9cSSascha Wildner default:
316d4972a9cSSascha Wildner return;
317d4972a9cSSascha Wildner }
318d4972a9cSSascha Wildner
319d4972a9cSSascha Wildner /*
320d4972a9cSSascha Wildner * Attempt to get the namespace node so we can determine the object type.
321d4972a9cSSascha Wildner * Some notify values are dependent on the object type (Device, Thermal,
322d4972a9cSSascha Wildner * or Processor).
323d4972a9cSSascha Wildner */
324d4972a9cSSascha Wildner Node = Op->Asl.Node;
325d4972a9cSSascha Wildner if (Node)
326d4972a9cSSascha Wildner {
327d4972a9cSSascha Wildner Type = Node->Type;
328d4972a9cSSascha Wildner }
329d4972a9cSSascha Wildner
330d4972a9cSSascha Wildner AcpiOsPrintf (" // %s", AcpiUtGetNotifyName (NotifyValue, Type));
331d4972a9cSSascha Wildner }
332d4972a9cSSascha Wildner
333d4972a9cSSascha Wildner
334d4972a9cSSascha Wildner /*******************************************************************************
335d4972a9cSSascha Wildner *
3360d02842fSSascha Wildner * FUNCTION: AcpiDmPredefinedDescription
3370d02842fSSascha Wildner *
3380d02842fSSascha Wildner * PARAMETERS: Op - Name() parse object
3390d02842fSSascha Wildner *
3400d02842fSSascha Wildner * RETURN: None
3410d02842fSSascha Wildner *
3420d02842fSSascha Wildner * DESCRIPTION: Emit a description comment for a predefined ACPI name.
3430d02842fSSascha Wildner * Used for iASL compiler only.
3440d02842fSSascha Wildner *
3450d02842fSSascha Wildner ******************************************************************************/
3460d02842fSSascha Wildner
3470d02842fSSascha Wildner void
AcpiDmPredefinedDescription(ACPI_PARSE_OBJECT * Op)3480d02842fSSascha Wildner AcpiDmPredefinedDescription (
3490d02842fSSascha Wildner ACPI_PARSE_OBJECT *Op)
3500d02842fSSascha Wildner {
3510d02842fSSascha Wildner #ifdef ACPI_ASL_COMPILER
3520d02842fSSascha Wildner const AH_PREDEFINED_NAME *Info;
3530d02842fSSascha Wildner char *NameString;
3540d02842fSSascha Wildner int LastCharIsDigit;
3550d02842fSSascha Wildner int LastCharsAreHex;
3560d02842fSSascha Wildner
3570d02842fSSascha Wildner
3580d02842fSSascha Wildner if (!Op)
3590d02842fSSascha Wildner {
3600d02842fSSascha Wildner return;
3610d02842fSSascha Wildner }
3620d02842fSSascha Wildner
3630d02842fSSascha Wildner /* Ensure that the comment field is emitted only once */
3640d02842fSSascha Wildner
3650d27ae55SSascha Wildner if (Op->Common.DisasmFlags & ACPI_PARSEOP_PREDEFINED_CHECKED)
3660d02842fSSascha Wildner {
3670d02842fSSascha Wildner return;
3680d02842fSSascha Wildner }
3690d27ae55SSascha Wildner Op->Common.DisasmFlags |= ACPI_PARSEOP_PREDEFINED_CHECKED;
3700d02842fSSascha Wildner
3710d02842fSSascha Wildner /* Predefined name must start with an underscore */
3720d02842fSSascha Wildner
3730d02842fSSascha Wildner NameString = ACPI_CAST_PTR (char, &Op->Named.Name);
3740d02842fSSascha Wildner if (NameString[0] != '_')
3750d02842fSSascha Wildner {
3760d02842fSSascha Wildner return;
3770d02842fSSascha Wildner }
3780d02842fSSascha Wildner
3790d02842fSSascha Wildner /*
3800d02842fSSascha Wildner * Check for the special ACPI names:
3810d02842fSSascha Wildner * _ACd, _ALd, _EJd, _Exx, _Lxx, _Qxx, _Wxx, _T_a
3820d02842fSSascha Wildner * (where d=decimal_digit, x=hex_digit, a=anything)
3830d02842fSSascha Wildner *
3840d02842fSSascha Wildner * Convert these to the generic name for table lookup.
3850d02842fSSascha Wildner * Note: NameString is guaranteed to be upper case here.
3860d02842fSSascha Wildner */
3870d02842fSSascha Wildner LastCharIsDigit =
38825ca8c79SSascha Wildner (isdigit ((int) NameString[3])); /* d */
3890d02842fSSascha Wildner LastCharsAreHex =
39025ca8c79SSascha Wildner (isxdigit ((int) NameString[2]) && /* xx */
39125ca8c79SSascha Wildner isxdigit ((int) NameString[3]));
3920d02842fSSascha Wildner
3930d02842fSSascha Wildner switch (NameString[1])
3940d02842fSSascha Wildner {
3950d02842fSSascha Wildner case 'A':
3960d02842fSSascha Wildner
3970d02842fSSascha Wildner if ((NameString[2] == 'C') && (LastCharIsDigit))
3980d02842fSSascha Wildner {
3990d02842fSSascha Wildner NameString = "_ACx";
4000d02842fSSascha Wildner }
4010d02842fSSascha Wildner else if ((NameString[2] == 'L') && (LastCharIsDigit))
4020d02842fSSascha Wildner {
4030d02842fSSascha Wildner NameString = "_ALx";
4040d02842fSSascha Wildner }
4050d02842fSSascha Wildner break;
4060d02842fSSascha Wildner
4070d02842fSSascha Wildner case 'E':
4080d02842fSSascha Wildner
4090d02842fSSascha Wildner if ((NameString[2] == 'J') && (LastCharIsDigit))
4100d02842fSSascha Wildner {
4110d02842fSSascha Wildner NameString = "_EJx";
4120d02842fSSascha Wildner }
4130d02842fSSascha Wildner else if (LastCharsAreHex)
4140d02842fSSascha Wildner {
4150d02842fSSascha Wildner NameString = "_Exx";
4160d02842fSSascha Wildner }
4170d02842fSSascha Wildner break;
4180d02842fSSascha Wildner
4190d02842fSSascha Wildner case 'L':
4200d02842fSSascha Wildner
4210d02842fSSascha Wildner if (LastCharsAreHex)
4220d02842fSSascha Wildner {
4230d02842fSSascha Wildner NameString = "_Lxx";
4240d02842fSSascha Wildner }
4250d02842fSSascha Wildner break;
4260d02842fSSascha Wildner
4270d02842fSSascha Wildner case 'Q':
4280d02842fSSascha Wildner
4290d02842fSSascha Wildner if (LastCharsAreHex)
4300d02842fSSascha Wildner {
4310d02842fSSascha Wildner NameString = "_Qxx";
4320d02842fSSascha Wildner }
4330d02842fSSascha Wildner break;
4340d02842fSSascha Wildner
4350d02842fSSascha Wildner case 'T':
4360d02842fSSascha Wildner
4370d02842fSSascha Wildner if (NameString[2] == '_')
4380d02842fSSascha Wildner {
4390d02842fSSascha Wildner NameString = "_T_x";
4400d02842fSSascha Wildner }
4410d02842fSSascha Wildner break;
4420d02842fSSascha Wildner
4430d02842fSSascha Wildner case 'W':
4440d02842fSSascha Wildner
4450d02842fSSascha Wildner if (LastCharsAreHex)
4460d02842fSSascha Wildner {
4470d02842fSSascha Wildner NameString = "_Wxx";
4480d02842fSSascha Wildner }
4490d02842fSSascha Wildner break;
4500d02842fSSascha Wildner
4510d02842fSSascha Wildner default:
4520d02842fSSascha Wildner
4530d02842fSSascha Wildner break;
4540d02842fSSascha Wildner }
4550d02842fSSascha Wildner
4560d02842fSSascha Wildner /* Match the name in the info table */
4570d02842fSSascha Wildner
458d4972a9cSSascha Wildner Info = AcpiAhMatchPredefinedName (NameString);
459d4972a9cSSascha Wildner if (Info)
4600d02842fSSascha Wildner {
4610d02842fSSascha Wildner AcpiOsPrintf (" // %4.4s: %s",
4620d02842fSSascha Wildner NameString, ACPI_CAST_PTR (char, Info->Description));
4630d02842fSSascha Wildner }
4640d02842fSSascha Wildner
4650d02842fSSascha Wildner #endif
4660d02842fSSascha Wildner return;
4670d02842fSSascha Wildner }
4680d02842fSSascha Wildner
4690d02842fSSascha Wildner
4700d02842fSSascha Wildner /*******************************************************************************
4710d02842fSSascha Wildner *
4720d02842fSSascha Wildner * FUNCTION: AcpiDmFieldPredefinedDescription
4730d02842fSSascha Wildner *
4740d02842fSSascha Wildner * PARAMETERS: Op - Parse object
4750d02842fSSascha Wildner *
4760d02842fSSascha Wildner * RETURN: None
4770d02842fSSascha Wildner *
4780d02842fSSascha Wildner * DESCRIPTION: Emit a description comment for a resource descriptor tag
4790d02842fSSascha Wildner * (which is a predefined ACPI name.) Used for iASL compiler only.
4800d02842fSSascha Wildner *
4810d02842fSSascha Wildner ******************************************************************************/
4820d02842fSSascha Wildner
4830d02842fSSascha Wildner void
AcpiDmFieldPredefinedDescription(ACPI_PARSE_OBJECT * Op)4840d02842fSSascha Wildner AcpiDmFieldPredefinedDescription (
4850d02842fSSascha Wildner ACPI_PARSE_OBJECT *Op)
4860d02842fSSascha Wildner {
4870d02842fSSascha Wildner #ifdef ACPI_ASL_COMPILER
4880d02842fSSascha Wildner ACPI_PARSE_OBJECT *IndexOp;
4890d02842fSSascha Wildner char *Tag;
4900d02842fSSascha Wildner const ACPI_OPCODE_INFO *OpInfo;
4910d02842fSSascha Wildner const AH_PREDEFINED_NAME *Info;
4920d02842fSSascha Wildner
4930d02842fSSascha Wildner
4940d02842fSSascha Wildner if (!Op)
4950d02842fSSascha Wildner {
4960d02842fSSascha Wildner return;
4970d02842fSSascha Wildner }
4980d02842fSSascha Wildner
4990d02842fSSascha Wildner /* Ensure that the comment field is emitted only once */
5000d02842fSSascha Wildner
5010d27ae55SSascha Wildner if (Op->Common.DisasmFlags & ACPI_PARSEOP_PREDEFINED_CHECKED)
5020d02842fSSascha Wildner {
5030d02842fSSascha Wildner return;
5040d02842fSSascha Wildner }
5050d27ae55SSascha Wildner Op->Common.DisasmFlags |= ACPI_PARSEOP_PREDEFINED_CHECKED;
5060d02842fSSascha Wildner
5070d02842fSSascha Wildner /*
5080d02842fSSascha Wildner * Op must be one of the Create* operators: CreateField, CreateBitField,
5090d02842fSSascha Wildner * CreateByteField, CreateWordField, CreateDwordField, CreateQwordField
5100d02842fSSascha Wildner */
5110d02842fSSascha Wildner OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
5120d02842fSSascha Wildner if (!(OpInfo->Flags & AML_CREATE))
5130d02842fSSascha Wildner {
5140d02842fSSascha Wildner return;
5150d02842fSSascha Wildner }
5160d02842fSSascha Wildner
5170d02842fSSascha Wildner /* Second argument is the Index argument */
5180d02842fSSascha Wildner
5190d02842fSSascha Wildner IndexOp = Op->Common.Value.Arg;
5200d02842fSSascha Wildner IndexOp = IndexOp->Common.Next;
5210d02842fSSascha Wildner
5220d02842fSSascha Wildner /* Index argument must be a namepath */
5230d02842fSSascha Wildner
5240d02842fSSascha Wildner if (IndexOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP)
5250d02842fSSascha Wildner {
5260d02842fSSascha Wildner return;
5270d02842fSSascha Wildner }
5280d02842fSSascha Wildner
5290d02842fSSascha Wildner /* Major cheat: We previously put the Tag ptr in the Node field */
5300d02842fSSascha Wildner
5310d02842fSSascha Wildner Tag = ACPI_CAST_PTR (char, IndexOp->Common.Node);
5321093ca81SSascha Wildner if (!Tag || (*Tag == 0))
5330d02842fSSascha Wildner {
5340d02842fSSascha Wildner return;
5350d02842fSSascha Wildner }
5360d02842fSSascha Wildner
5371093ca81SSascha Wildner /* Is the tag a predefined name? */
5380d02842fSSascha Wildner
539d4972a9cSSascha Wildner Info = AcpiAhMatchPredefinedName (Tag);
5401093ca81SSascha Wildner if (!Info)
5410d02842fSSascha Wildner {
5421093ca81SSascha Wildner /* Not a predefined name (does not start with underscore) */
5431093ca81SSascha Wildner
5441093ca81SSascha Wildner return;
5450d02842fSSascha Wildner }
5460d02842fSSascha Wildner
5471093ca81SSascha Wildner AcpiOsPrintf (" // %4.4s: %s", Tag,
5481093ca81SSascha Wildner ACPI_CAST_PTR (char, Info->Description));
5491093ca81SSascha Wildner
5501093ca81SSascha Wildner /* String contains the prefix path, free it */
551b4315fc7SSascha Wildner
552b4315fc7SSascha Wildner ACPI_FREE (IndexOp->Common.Value.String);
5531093ca81SSascha Wildner IndexOp->Common.Value.String = NULL;
5540d02842fSSascha Wildner #endif
5551093ca81SSascha Wildner
5560d02842fSSascha Wildner return;
5570d02842fSSascha Wildner }
5580d02842fSSascha Wildner
5590d02842fSSascha Wildner
5600d02842fSSascha Wildner /*******************************************************************************
5610d02842fSSascha Wildner *
5620d02842fSSascha Wildner * FUNCTION: AcpiDmMethodFlags
5630d02842fSSascha Wildner *
5640d02842fSSascha Wildner * PARAMETERS: Op - Method Object to be examined
5650d02842fSSascha Wildner *
5660d02842fSSascha Wildner * RETURN: None
5670d02842fSSascha Wildner *
5680d02842fSSascha Wildner * DESCRIPTION: Decode control method flags
5690d02842fSSascha Wildner *
5700d02842fSSascha Wildner ******************************************************************************/
5710d02842fSSascha Wildner
5720d02842fSSascha Wildner void
AcpiDmMethodFlags(ACPI_PARSE_OBJECT * Op)5730d02842fSSascha Wildner AcpiDmMethodFlags (
5740d02842fSSascha Wildner ACPI_PARSE_OBJECT *Op)
5750d02842fSSascha Wildner {
5760d02842fSSascha Wildner UINT32 Flags;
5770d02842fSSascha Wildner UINT32 Args;
5780d02842fSSascha Wildner
5790d02842fSSascha Wildner
5800d02842fSSascha Wildner /* The next Op contains the flags */
5810d02842fSSascha Wildner
5820d02842fSSascha Wildner Op = AcpiPsGetDepthNext (NULL, Op);
5830d02842fSSascha Wildner Flags = (UINT8) Op->Common.Value.Integer;
5840d02842fSSascha Wildner Args = Flags & 0x07;
5850d02842fSSascha Wildner
5860d02842fSSascha Wildner /* Mark the Op as completed */
5870d02842fSSascha Wildner
5880d02842fSSascha Wildner Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
5890d02842fSSascha Wildner
5900d02842fSSascha Wildner /* 1) Method argument count */
5910d02842fSSascha Wildner
5920d02842fSSascha Wildner AcpiOsPrintf (", %u, ", Args);
5930d02842fSSascha Wildner
5940d02842fSSascha Wildner /* 2) Serialize rule */
5950d02842fSSascha Wildner
5960d02842fSSascha Wildner if (!(Flags & 0x08))
5970d02842fSSascha Wildner {
5980d02842fSSascha Wildner AcpiOsPrintf ("Not");
5990d02842fSSascha Wildner }
6000d02842fSSascha Wildner
6010d02842fSSascha Wildner AcpiOsPrintf ("Serialized");
6020d02842fSSascha Wildner
6030d02842fSSascha Wildner /* 3) SyncLevel */
6040d02842fSSascha Wildner
6050d02842fSSascha Wildner if (Flags & 0xF0)
6060d02842fSSascha Wildner {
6070d02842fSSascha Wildner AcpiOsPrintf (", %u", Flags >> 4);
6080d02842fSSascha Wildner }
6090d02842fSSascha Wildner }
6100d02842fSSascha Wildner
6110d02842fSSascha Wildner
6120d02842fSSascha Wildner /*******************************************************************************
6130d02842fSSascha Wildner *
6140d02842fSSascha Wildner * FUNCTION: AcpiDmFieldFlags
6150d02842fSSascha Wildner *
6160d02842fSSascha Wildner * PARAMETERS: Op - Field Object to be examined
6170d02842fSSascha Wildner *
6180d02842fSSascha Wildner * RETURN: None
6190d02842fSSascha Wildner *
6200d02842fSSascha Wildner * DESCRIPTION: Decode Field definition flags
6210d02842fSSascha Wildner *
6220d02842fSSascha Wildner ******************************************************************************/
6230d02842fSSascha Wildner
6240d02842fSSascha Wildner void
AcpiDmFieldFlags(ACPI_PARSE_OBJECT * Op)6250d02842fSSascha Wildner AcpiDmFieldFlags (
6260d02842fSSascha Wildner ACPI_PARSE_OBJECT *Op)
6270d02842fSSascha Wildner {
6280d02842fSSascha Wildner UINT32 Flags;
6290d02842fSSascha Wildner
6300d02842fSSascha Wildner
6310d02842fSSascha Wildner Op = Op->Common.Next;
6320d02842fSSascha Wildner Flags = (UINT8) Op->Common.Value.Integer;
6330d02842fSSascha Wildner
6340d02842fSSascha Wildner /* Mark the Op as completed */
6350d02842fSSascha Wildner
6360d02842fSSascha Wildner Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
6370d02842fSSascha Wildner
6380d02842fSSascha Wildner AcpiOsPrintf ("%s, ", AcpiGbl_AccessTypes [Flags & 0x07]);
6390d02842fSSascha Wildner AcpiOsPrintf ("%s, ", AcpiGbl_LockRule [(Flags & 0x10) >> 4]);
6400d02842fSSascha Wildner AcpiOsPrintf ("%s)", AcpiGbl_UpdateRules [(Flags & 0x60) >> 5]);
6410d02842fSSascha Wildner }
6420d02842fSSascha Wildner
6430d02842fSSascha Wildner
6440d02842fSSascha Wildner /*******************************************************************************
6450d02842fSSascha Wildner *
6460d02842fSSascha Wildner * FUNCTION: AcpiDmAddressSpace
6470d02842fSSascha Wildner *
6480d02842fSSascha Wildner * PARAMETERS: SpaceId - ID to be translated
6490d02842fSSascha Wildner *
6500d02842fSSascha Wildner * RETURN: None
6510d02842fSSascha Wildner *
6520d02842fSSascha Wildner * DESCRIPTION: Decode a SpaceId to an AddressSpaceKeyword
6530d02842fSSascha Wildner *
6540d02842fSSascha Wildner ******************************************************************************/
6550d02842fSSascha Wildner
6560d02842fSSascha Wildner void
AcpiDmAddressSpace(UINT8 SpaceId)6570d02842fSSascha Wildner AcpiDmAddressSpace (
6580d02842fSSascha Wildner UINT8 SpaceId)
6590d02842fSSascha Wildner {
6600d02842fSSascha Wildner
6610d02842fSSascha Wildner if (SpaceId >= ACPI_NUM_PREDEFINED_REGIONS)
6620d02842fSSascha Wildner {
6630d02842fSSascha Wildner if (SpaceId == 0x7F)
6640d02842fSSascha Wildner {
6650d02842fSSascha Wildner AcpiOsPrintf ("FFixedHW, ");
6660d02842fSSascha Wildner }
6670d02842fSSascha Wildner else
6680d02842fSSascha Wildner {
6690d02842fSSascha Wildner AcpiOsPrintf ("0x%.2X, ", SpaceId);
6700d02842fSSascha Wildner }
6710d02842fSSascha Wildner }
6720d02842fSSascha Wildner else
6730d02842fSSascha Wildner {
6740d02842fSSascha Wildner AcpiOsPrintf ("%s, ", AcpiGbl_RegionTypes [SpaceId]);
6750d02842fSSascha Wildner }
6760d02842fSSascha Wildner }
6770d02842fSSascha Wildner
6780d02842fSSascha Wildner
6790d02842fSSascha Wildner /*******************************************************************************
6800d02842fSSascha Wildner *
6810d02842fSSascha Wildner * FUNCTION: AcpiDmRegionFlags
6820d02842fSSascha Wildner *
6830d02842fSSascha Wildner * PARAMETERS: Op - Object to be examined
6840d02842fSSascha Wildner *
6850d02842fSSascha Wildner * RETURN: None
6860d02842fSSascha Wildner *
6870d02842fSSascha Wildner * DESCRIPTION: Decode OperationRegion flags
6880d02842fSSascha Wildner *
6890d02842fSSascha Wildner ******************************************************************************/
6900d02842fSSascha Wildner
6910d02842fSSascha Wildner void
AcpiDmRegionFlags(ACPI_PARSE_OBJECT * Op)6920d02842fSSascha Wildner AcpiDmRegionFlags (
6930d02842fSSascha Wildner ACPI_PARSE_OBJECT *Op)
6940d02842fSSascha Wildner {
6950d02842fSSascha Wildner
6960d02842fSSascha Wildner /* The next Op contains the SpaceId */
6970d02842fSSascha Wildner
6980d02842fSSascha Wildner Op = AcpiPsGetDepthNext (NULL, Op);
6990d02842fSSascha Wildner
7000d02842fSSascha Wildner /* Mark the Op as completed */
7010d02842fSSascha Wildner
7020d02842fSSascha Wildner Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
7030d02842fSSascha Wildner
7040d02842fSSascha Wildner AcpiOsPrintf (", ");
7050d02842fSSascha Wildner AcpiDmAddressSpace ((UINT8) Op->Common.Value.Integer);
7060d02842fSSascha Wildner }
7070d02842fSSascha Wildner
7080d02842fSSascha Wildner
7090d02842fSSascha Wildner /*******************************************************************************
7100d02842fSSascha Wildner *
7110d02842fSSascha Wildner * FUNCTION: AcpiDmMatchOp
7120d02842fSSascha Wildner *
7130d02842fSSascha Wildner * PARAMETERS: Op - Match Object to be examined
7140d02842fSSascha Wildner *
7150d02842fSSascha Wildner * RETURN: None
7160d02842fSSascha Wildner *
7170d02842fSSascha Wildner * DESCRIPTION: Decode Match opcode operands
7180d02842fSSascha Wildner *
7190d02842fSSascha Wildner ******************************************************************************/
7200d02842fSSascha Wildner
7210d02842fSSascha Wildner void
AcpiDmMatchOp(ACPI_PARSE_OBJECT * Op)7220d02842fSSascha Wildner AcpiDmMatchOp (
7230d02842fSSascha Wildner ACPI_PARSE_OBJECT *Op)
7240d02842fSSascha Wildner {
7250d02842fSSascha Wildner ACPI_PARSE_OBJECT *NextOp;
7260d02842fSSascha Wildner
7270d02842fSSascha Wildner
7280d02842fSSascha Wildner NextOp = AcpiPsGetDepthNext (NULL, Op);
7290d02842fSSascha Wildner NextOp = NextOp->Common.Next;
7300d02842fSSascha Wildner
7310d02842fSSascha Wildner if (!NextOp)
7320d02842fSSascha Wildner {
7330d02842fSSascha Wildner /* Handle partial tree during single-step */
7340d02842fSSascha Wildner
7350d02842fSSascha Wildner return;
7360d02842fSSascha Wildner }
7370d02842fSSascha Wildner
7380d02842fSSascha Wildner /* Mark the two nodes that contain the encoding for the match keywords */
7390d02842fSSascha Wildner
7400d02842fSSascha Wildner NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;
7410d02842fSSascha Wildner
7420d02842fSSascha Wildner NextOp = NextOp->Common.Next;
7430d02842fSSascha Wildner NextOp = NextOp->Common.Next;
7440d02842fSSascha Wildner NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;
7450d02842fSSascha Wildner }
7460d02842fSSascha Wildner
7470d02842fSSascha Wildner
7480d02842fSSascha Wildner /*******************************************************************************
7490d02842fSSascha Wildner *
7500d02842fSSascha Wildner * FUNCTION: AcpiDmMatchKeyword
7510d02842fSSascha Wildner *
7520d02842fSSascha Wildner * PARAMETERS: Op - Match Object to be examined
7530d02842fSSascha Wildner *
7540d02842fSSascha Wildner * RETURN: None
7550d02842fSSascha Wildner *
7560d02842fSSascha Wildner * DESCRIPTION: Decode Match opcode operands
7570d02842fSSascha Wildner *
7580d02842fSSascha Wildner ******************************************************************************/
7590d02842fSSascha Wildner
7600d02842fSSascha Wildner static void
AcpiDmMatchKeyword(ACPI_PARSE_OBJECT * Op)7610d02842fSSascha Wildner AcpiDmMatchKeyword (
7620d02842fSSascha Wildner ACPI_PARSE_OBJECT *Op)
7630d02842fSSascha Wildner {
7640d02842fSSascha Wildner
7650d02842fSSascha Wildner if (((UINT32) Op->Common.Value.Integer) > ACPI_MAX_MATCH_OPCODE)
7660d02842fSSascha Wildner {
7670d02842fSSascha Wildner AcpiOsPrintf ("/* Unknown Match Keyword encoding */");
7680d02842fSSascha Wildner }
7690d02842fSSascha Wildner else
7700d02842fSSascha Wildner {
7712ffe9f16SSascha Wildner AcpiOsPrintf ("%s",
7722ffe9f16SSascha Wildner AcpiGbl_MatchOps[(ACPI_SIZE) Op->Common.Value.Integer]);
7730d02842fSSascha Wildner }
7740d02842fSSascha Wildner }
7750d02842fSSascha Wildner
7760d02842fSSascha Wildner
7770d02842fSSascha Wildner /*******************************************************************************
7780d02842fSSascha Wildner *
7790d02842fSSascha Wildner * FUNCTION: AcpiDmDisassembleOneOp
7800d02842fSSascha Wildner *
7810d02842fSSascha Wildner * PARAMETERS: WalkState - Current walk info
7820d02842fSSascha Wildner * Info - Parse tree walk info
7830d02842fSSascha Wildner * Op - Op that is to be printed
7840d02842fSSascha Wildner *
7850d02842fSSascha Wildner * RETURN: None
7860d02842fSSascha Wildner *
7870d02842fSSascha Wildner * DESCRIPTION: Disassemble a single AML opcode
7880d02842fSSascha Wildner *
7890d02842fSSascha Wildner ******************************************************************************/
7900d02842fSSascha Wildner
7910d02842fSSascha Wildner void
AcpiDmDisassembleOneOp(ACPI_WALK_STATE * WalkState,ACPI_OP_WALK_INFO * Info,ACPI_PARSE_OBJECT * Op)7920d02842fSSascha Wildner AcpiDmDisassembleOneOp (
7930d02842fSSascha Wildner ACPI_WALK_STATE *WalkState,
7940d02842fSSascha Wildner ACPI_OP_WALK_INFO *Info,
7950d02842fSSascha Wildner ACPI_PARSE_OBJECT *Op)
7960d02842fSSascha Wildner {
7970d02842fSSascha Wildner const ACPI_OPCODE_INFO *OpInfo = NULL;
7980d02842fSSascha Wildner UINT32 Offset;
7990d02842fSSascha Wildner UINT32 Length;
8000d02842fSSascha Wildner ACPI_PARSE_OBJECT *Child;
8010d02842fSSascha Wildner ACPI_STATUS Status;
8020d02842fSSascha Wildner UINT8 *Aml;
803d4972a9cSSascha Wildner const AH_DEVICE_ID *IdInfo;
8040d02842fSSascha Wildner
8050d02842fSSascha Wildner
8060d02842fSSascha Wildner if (!Op)
8070d02842fSSascha Wildner {
8080d02842fSSascha Wildner AcpiOsPrintf ("<NULL OP PTR>");
8090d02842fSSascha Wildner return;
8100d02842fSSascha Wildner }
8110d02842fSSascha Wildner
812f5f76cf2SSascha Wildner if (Op->Common.DisasmFlags & ACPI_PARSEOP_ELSEIF)
813f5f76cf2SSascha Wildner {
814f5f76cf2SSascha Wildner return; /* ElseIf macro was already emitted */
815f5f76cf2SSascha Wildner }
816f5f76cf2SSascha Wildner
8170d02842fSSascha Wildner switch (Op->Common.DisasmOpcode)
8180d02842fSSascha Wildner {
8190d02842fSSascha Wildner case ACPI_DASM_MATCHOP:
8200d02842fSSascha Wildner
8210d02842fSSascha Wildner AcpiDmMatchKeyword (Op);
8220d02842fSSascha Wildner return;
8230d02842fSSascha Wildner
8240d02842fSSascha Wildner case ACPI_DASM_LNOT_SUFFIX:
8250d02842fSSascha Wildner
8262e2672b8SSascha Wildner if (!AcpiGbl_CstyleDisassembly)
8272e2672b8SSascha Wildner {
8280d02842fSSascha Wildner switch (Op->Common.AmlOpcode)
8290d02842fSSascha Wildner {
830d638c6eeSSascha Wildner case AML_LOGICAL_EQUAL_OP:
8310d02842fSSascha Wildner AcpiOsPrintf ("LNotEqual");
8320d02842fSSascha Wildner break;
8330d02842fSSascha Wildner
834d638c6eeSSascha Wildner case AML_LOGICAL_GREATER_OP:
8350d02842fSSascha Wildner AcpiOsPrintf ("LLessEqual");
8360d02842fSSascha Wildner break;
8370d02842fSSascha Wildner
838d638c6eeSSascha Wildner case AML_LOGICAL_LESS_OP:
8390d02842fSSascha Wildner AcpiOsPrintf ("LGreaterEqual");
8400d02842fSSascha Wildner break;
8410d02842fSSascha Wildner
8420d02842fSSascha Wildner default:
8430d02842fSSascha Wildner break;
8440d02842fSSascha Wildner }
8452e2672b8SSascha Wildner }
8462e2672b8SSascha Wildner
8470d02842fSSascha Wildner Op->Common.DisasmOpcode = 0;
8480d02842fSSascha Wildner Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
8490d02842fSSascha Wildner return;
8500d02842fSSascha Wildner
8510d02842fSSascha Wildner default:
8520d02842fSSascha Wildner break;
8530d02842fSSascha Wildner }
8540d02842fSSascha Wildner
8550d02842fSSascha Wildner OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
8560d02842fSSascha Wildner
8570d02842fSSascha Wildner /* The op and arguments */
8580d02842fSSascha Wildner
8590d02842fSSascha Wildner switch (Op->Common.AmlOpcode)
8600d02842fSSascha Wildner {
861d638c6eeSSascha Wildner case AML_LOGICAL_NOT_OP:
8620d02842fSSascha Wildner
8630d02842fSSascha Wildner Child = Op->Common.Value.Arg;
864d638c6eeSSascha Wildner if ((Child->Common.AmlOpcode == AML_LOGICAL_EQUAL_OP) ||
865d638c6eeSSascha Wildner (Child->Common.AmlOpcode == AML_LOGICAL_GREATER_OP) ||
866d638c6eeSSascha Wildner (Child->Common.AmlOpcode == AML_LOGICAL_LESS_OP))
8670d02842fSSascha Wildner {
8680d02842fSSascha Wildner Child->Common.DisasmOpcode = ACPI_DASM_LNOT_SUFFIX;
8690d02842fSSascha Wildner Op->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
8700d02842fSSascha Wildner }
8710d02842fSSascha Wildner else
8720d02842fSSascha Wildner {
8730d02842fSSascha Wildner AcpiOsPrintf ("%s", OpInfo->Name);
8740d02842fSSascha Wildner }
8750d02842fSSascha Wildner break;
8760d02842fSSascha Wildner
8770d02842fSSascha Wildner case AML_BYTE_OP:
8780d02842fSSascha Wildner
8790d02842fSSascha Wildner AcpiOsPrintf ("0x%2.2X", (UINT32) Op->Common.Value.Integer);
8800d02842fSSascha Wildner break;
8810d02842fSSascha Wildner
8820d02842fSSascha Wildner case AML_WORD_OP:
8830d02842fSSascha Wildner
8840d02842fSSascha Wildner if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
8850d02842fSSascha Wildner {
886d4972a9cSSascha Wildner AcpiDmDecompressEisaId ((UINT32) Op->Common.Value.Integer);
8870d02842fSSascha Wildner }
8880d02842fSSascha Wildner else
8890d02842fSSascha Wildner {
8900d02842fSSascha Wildner AcpiOsPrintf ("0x%4.4X", (UINT32) Op->Common.Value.Integer);
8910d02842fSSascha Wildner }
8920d02842fSSascha Wildner break;
8930d02842fSSascha Wildner
8940d02842fSSascha Wildner case AML_DWORD_OP:
8950d02842fSSascha Wildner
8960d02842fSSascha Wildner if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
8970d02842fSSascha Wildner {
898d4972a9cSSascha Wildner AcpiDmDecompressEisaId ((UINT32) Op->Common.Value.Integer);
8990d02842fSSascha Wildner }
9000d02842fSSascha Wildner else
9010d02842fSSascha Wildner {
9020d02842fSSascha Wildner AcpiOsPrintf ("0x%8.8X", (UINT32) Op->Common.Value.Integer);
9030d02842fSSascha Wildner }
9040d02842fSSascha Wildner break;
9050d02842fSSascha Wildner
9060d02842fSSascha Wildner case AML_QWORD_OP:
9070d02842fSSascha Wildner
9080d02842fSSascha Wildner AcpiOsPrintf ("0x%8.8X%8.8X",
9090d02842fSSascha Wildner ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
9100d02842fSSascha Wildner break;
9110d02842fSSascha Wildner
9120d02842fSSascha Wildner case AML_STRING_OP:
9130d02842fSSascha Wildner
9140d02842fSSascha Wildner AcpiUtPrintString (Op->Common.Value.String, ACPI_UINT16_MAX);
915d4972a9cSSascha Wildner
916d4972a9cSSascha Wildner /* For _HID/_CID strings, attempt to output a descriptive comment */
917d4972a9cSSascha Wildner
918d4972a9cSSascha Wildner if (Op->Common.DisasmOpcode == ACPI_DASM_HID_STRING)
919d4972a9cSSascha Wildner {
920d4972a9cSSascha Wildner /* If we know about the ID, emit the description */
921d4972a9cSSascha Wildner
922d4972a9cSSascha Wildner IdInfo = AcpiAhMatchHardwareId (Op->Common.Value.String);
923d4972a9cSSascha Wildner if (IdInfo)
924d4972a9cSSascha Wildner {
925d4972a9cSSascha Wildner AcpiOsPrintf (" /* %s */", IdInfo->Description);
926d4972a9cSSascha Wildner }
927d4972a9cSSascha Wildner }
9280d02842fSSascha Wildner break;
9290d02842fSSascha Wildner
9300d02842fSSascha Wildner case AML_BUFFER_OP:
9310d02842fSSascha Wildner /*
9320d02842fSSascha Wildner * Determine the type of buffer. We can have one of the following:
9330d02842fSSascha Wildner *
9340d02842fSSascha Wildner * 1) ResourceTemplate containing Resource Descriptors.
9350d02842fSSascha Wildner * 2) Unicode String buffer
9360d02842fSSascha Wildner * 3) ASCII String buffer
9370d02842fSSascha Wildner * 4) Raw data buffer (if none of the above)
9380d02842fSSascha Wildner *
9390d02842fSSascha Wildner * Since there are no special AML opcodes to differentiate these
9400d02842fSSascha Wildner * types of buffers, we have to closely look at the data in the
9410d02842fSSascha Wildner * buffer to determine the type.
9420d02842fSSascha Wildner */
9430d02842fSSascha Wildner if (!AcpiGbl_NoResourceDisassembly)
9440d02842fSSascha Wildner {
9450d02842fSSascha Wildner Status = AcpiDmIsResourceTemplate (WalkState, Op);
9460d02842fSSascha Wildner if (ACPI_SUCCESS (Status))
9470d02842fSSascha Wildner {
9480d02842fSSascha Wildner Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
9490d02842fSSascha Wildner AcpiOsPrintf ("ResourceTemplate");
9500d02842fSSascha Wildner break;
9510d02842fSSascha Wildner }
9520d02842fSSascha Wildner else if (Status == AE_AML_NO_RESOURCE_END_TAG)
9530d02842fSSascha Wildner {
954820c5b08SSascha Wildner AcpiOsPrintf (
955820c5b08SSascha Wildner "/**** Is ResourceTemplate, "
956820c5b08SSascha Wildner "but EndTag not at buffer end ****/ ");
9570d02842fSSascha Wildner }
9580d02842fSSascha Wildner }
9590d02842fSSascha Wildner
960066b6da2SSascha Wildner if (AcpiDmIsUuidBuffer (Op))
961066b6da2SSascha Wildner {
962066b6da2SSascha Wildner Op->Common.DisasmOpcode = ACPI_DASM_UUID;
963066b6da2SSascha Wildner AcpiOsPrintf ("ToUUID (");
964066b6da2SSascha Wildner }
965066b6da2SSascha Wildner else if (AcpiDmIsUnicodeBuffer (Op))
9660d02842fSSascha Wildner {
9670d02842fSSascha Wildner Op->Common.DisasmOpcode = ACPI_DASM_UNICODE;
9680d02842fSSascha Wildner AcpiOsPrintf ("Unicode (");
9690d02842fSSascha Wildner }
9700d02842fSSascha Wildner else if (AcpiDmIsStringBuffer (Op))
9710d02842fSSascha Wildner {
9720d02842fSSascha Wildner Op->Common.DisasmOpcode = ACPI_DASM_STRING;
9730d02842fSSascha Wildner AcpiOsPrintf ("Buffer");
9740d02842fSSascha Wildner }
9750d02842fSSascha Wildner else if (AcpiDmIsPldBuffer (Op))
9760d02842fSSascha Wildner {
9770d02842fSSascha Wildner Op->Common.DisasmOpcode = ACPI_DASM_PLD_METHOD;
9782e2672b8SSascha Wildner AcpiOsPrintf ("ToPLD (");
9790d02842fSSascha Wildner }
9800d02842fSSascha Wildner else
9810d02842fSSascha Wildner {
9820d02842fSSascha Wildner Op->Common.DisasmOpcode = ACPI_DASM_BUFFER;
9830d02842fSSascha Wildner AcpiOsPrintf ("Buffer");
9840d02842fSSascha Wildner }
9850d02842fSSascha Wildner break;
9860d02842fSSascha Wildner
9870d02842fSSascha Wildner case AML_INT_NAMEPATH_OP:
9880d02842fSSascha Wildner
9890d02842fSSascha Wildner AcpiDmNamestring (Op->Common.Value.Name);
9900d02842fSSascha Wildner break;
9910d02842fSSascha Wildner
9920d02842fSSascha Wildner case AML_INT_NAMEDFIELD_OP:
9930d02842fSSascha Wildner
9940d02842fSSascha Wildner Length = AcpiDmDumpName (Op->Named.Name);
995d638c6eeSSascha Wildner
996d638c6eeSSascha Wildner AcpiOsPrintf (",");
997d638c6eeSSascha Wildner ASL_CV_PRINT_ONE_COMMENT (Op, AML_NAMECOMMENT, NULL, 0);
998d638c6eeSSascha Wildner AcpiOsPrintf ("%*.s %u", (unsigned) (5 - Length), " ",
9990d02842fSSascha Wildner (UINT32) Op->Common.Value.Integer);
1000d638c6eeSSascha Wildner
10010d02842fSSascha Wildner AcpiDmCommaIfFieldMember (Op);
10020d02842fSSascha Wildner
10030d02842fSSascha Wildner Info->BitOffset += (UINT32) Op->Common.Value.Integer;
10040d02842fSSascha Wildner break;
10050d02842fSSascha Wildner
10060d02842fSSascha Wildner case AML_INT_RESERVEDFIELD_OP:
10070d02842fSSascha Wildner
10080d02842fSSascha Wildner /* Offset() -- Must account for previous offsets */
10090d02842fSSascha Wildner
10100d02842fSSascha Wildner Offset = (UINT32) Op->Common.Value.Integer;
10110d02842fSSascha Wildner Info->BitOffset += Offset;
10120d02842fSSascha Wildner
10130d02842fSSascha Wildner if (Info->BitOffset % 8 == 0)
10140d02842fSSascha Wildner {
10150d02842fSSascha Wildner AcpiOsPrintf ("Offset (0x%.2X)", ACPI_DIV_8 (Info->BitOffset));
10160d02842fSSascha Wildner }
10170d02842fSSascha Wildner else
10180d02842fSSascha Wildner {
10190d02842fSSascha Wildner AcpiOsPrintf (" , %u", Offset);
10200d02842fSSascha Wildner }
10210d02842fSSascha Wildner
10220d02842fSSascha Wildner AcpiDmCommaIfFieldMember (Op);
10230d02842fSSascha Wildner break;
10240d02842fSSascha Wildner
10250d02842fSSascha Wildner case AML_INT_ACCESSFIELD_OP:
10260d02842fSSascha Wildner case AML_INT_EXTACCESSFIELD_OP:
10270d02842fSSascha Wildner
10280d02842fSSascha Wildner AcpiOsPrintf ("AccessAs (%s, ",
10290d02842fSSascha Wildner AcpiGbl_AccessTypes [(UINT32) (Op->Common.Value.Integer & 0x7)]);
10300d02842fSSascha Wildner
10310d02842fSSascha Wildner AcpiDmDecodeAttribute ((UINT8) (Op->Common.Value.Integer >> 8));
10320d02842fSSascha Wildner
10330d02842fSSascha Wildner if (Op->Common.AmlOpcode == AML_INT_EXTACCESSFIELD_OP)
10340d02842fSSascha Wildner {
1035820c5b08SSascha Wildner AcpiOsPrintf (" (0x%2.2X)", (unsigned)
1036820c5b08SSascha Wildner ((Op->Common.Value.Integer >> 16) & 0xFF));
10370d02842fSSascha Wildner }
10380d02842fSSascha Wildner
10390d02842fSSascha Wildner AcpiOsPrintf (")");
10400d02842fSSascha Wildner AcpiDmCommaIfFieldMember (Op);
1041d638c6eeSSascha Wildner ASL_CV_PRINT_ONE_COMMENT (Op, AML_COMMENT_END_NODE, NULL, 0);
10420d02842fSSascha Wildner break;
10430d02842fSSascha Wildner
10440d02842fSSascha Wildner case AML_INT_CONNECTION_OP:
10450d02842fSSascha Wildner /*
10460d02842fSSascha Wildner * Two types of Connection() - one with a buffer object, the
10470d02842fSSascha Wildner * other with a namestring that points to a buffer object.
10480d02842fSSascha Wildner */
10490d02842fSSascha Wildner AcpiOsPrintf ("Connection (");
10500d02842fSSascha Wildner Child = Op->Common.Value.Arg;
10510d02842fSSascha Wildner
10520d02842fSSascha Wildner if (Child->Common.AmlOpcode == AML_INT_BYTELIST_OP)
10530d02842fSSascha Wildner {
10540d02842fSSascha Wildner AcpiOsPrintf ("\n");
10550d02842fSSascha Wildner
10560d02842fSSascha Wildner Aml = Child->Named.Data;
10570d02842fSSascha Wildner Length = (UINT32) Child->Common.Value.Integer;
10580d02842fSSascha Wildner
10590d02842fSSascha Wildner Info->Level += 1;
10602e2672b8SSascha Wildner Info->MappingOp = Op;
10610d02842fSSascha Wildner Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
10622e2672b8SSascha Wildner
10630d02842fSSascha Wildner AcpiDmResourceTemplate (Info, Op->Common.Parent, Aml, Length);
10640d02842fSSascha Wildner
10650d02842fSSascha Wildner Info->Level -= 1;
10660d02842fSSascha Wildner AcpiDmIndent (Info->Level);
10670d02842fSSascha Wildner }
10680d02842fSSascha Wildner else
10690d02842fSSascha Wildner {
10700d02842fSSascha Wildner AcpiDmNamestring (Child->Common.Value.Name);
10710d02842fSSascha Wildner }
10720d02842fSSascha Wildner
10730d02842fSSascha Wildner AcpiOsPrintf (")");
10740d02842fSSascha Wildner AcpiDmCommaIfFieldMember (Op);
1075d638c6eeSSascha Wildner ASL_CV_PRINT_ONE_COMMENT (Op, AML_COMMENT_END_NODE, NULL, 0);
1076d638c6eeSSascha Wildner ASL_CV_PRINT_ONE_COMMENT (Op, AMLCOMMENT_INLINE, NULL, 0);
10770d02842fSSascha Wildner AcpiOsPrintf ("\n");
10780d02842fSSascha Wildner
10790d02842fSSascha Wildner Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; /* for now, ignore in AcpiDmAscendingOp */
10800d02842fSSascha Wildner Child->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
10810d02842fSSascha Wildner break;
10820d02842fSSascha Wildner
10830d02842fSSascha Wildner case AML_INT_BYTELIST_OP:
10840d02842fSSascha Wildner
10850d02842fSSascha Wildner AcpiDmByteList (Info, Op);
10860d02842fSSascha Wildner break;
10870d02842fSSascha Wildner
10880d02842fSSascha Wildner case AML_INT_METHODCALL_OP:
10890d02842fSSascha Wildner
10900d02842fSSascha Wildner Op = AcpiPsGetDepthNext (NULL, Op);
10910d02842fSSascha Wildner Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
10920d02842fSSascha Wildner
10930d02842fSSascha Wildner AcpiDmNamestring (Op->Common.Value.Name);
10940d02842fSSascha Wildner break;
10950d02842fSSascha Wildner
109638b5d46cSSascha Wildner case AML_WHILE_OP:
109738b5d46cSSascha Wildner
1098d638c6eeSSascha Wildner if (Op->Common.DisasmOpcode == ACPI_DASM_SWITCH)
109938b5d46cSSascha Wildner {
110038b5d46cSSascha Wildner AcpiOsPrintf ("%s", "Switch");
110138b5d46cSSascha Wildner break;
110238b5d46cSSascha Wildner }
110338b5d46cSSascha Wildner
110438b5d46cSSascha Wildner AcpiOsPrintf ("%s", OpInfo->Name);
110538b5d46cSSascha Wildner break;
110638b5d46cSSascha Wildner
110738b5d46cSSascha Wildner case AML_IF_OP:
110838b5d46cSSascha Wildner
110938b5d46cSSascha Wildner if (Op->Common.DisasmOpcode == ACPI_DASM_CASE)
111038b5d46cSSascha Wildner {
111138b5d46cSSascha Wildner AcpiOsPrintf ("%s", "Case");
111238b5d46cSSascha Wildner break;
111338b5d46cSSascha Wildner }
111438b5d46cSSascha Wildner
111538b5d46cSSascha Wildner AcpiOsPrintf ("%s", OpInfo->Name);
111638b5d46cSSascha Wildner break;
111738b5d46cSSascha Wildner
1118f5f76cf2SSascha Wildner case AML_ELSE_OP:
1119f5f76cf2SSascha Wildner
1120f5f76cf2SSascha Wildner AcpiDmConvertToElseIf (Op);
1121f5f76cf2SSascha Wildner break;
1122f5f76cf2SSascha Wildner
11237c9678bcSSascha Wildner case AML_EXTERNAL_OP:
11247c9678bcSSascha Wildner
11252adac2b8SSascha Wildner if (AcpiGbl_DmEmitExternalOpcodes)
11262adac2b8SSascha Wildner {
11271093ca81SSascha Wildner AcpiDmEmitExternal (Op, AcpiPsGetArg(Op, 0));
11282adac2b8SSascha Wildner }
11297c9678bcSSascha Wildner
1130d638c6eeSSascha Wildner break;
1131d638c6eeSSascha Wildner
11320d02842fSSascha Wildner default:
11330d02842fSSascha Wildner
11340d02842fSSascha Wildner /* Just get the opcode name and print it */
11350d02842fSSascha Wildner
11360d02842fSSascha Wildner AcpiOsPrintf ("%s", OpInfo->Name);
11370d02842fSSascha Wildner
11380d02842fSSascha Wildner
11390d02842fSSascha Wildner #ifdef ACPI_DEBUGGER
11400d02842fSSascha Wildner
11410d02842fSSascha Wildner if ((Op->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP) &&
11420d02842fSSascha Wildner (WalkState) &&
11430d02842fSSascha Wildner (WalkState->Results) &&
11440d02842fSSascha Wildner (WalkState->ResultCount))
11450d02842fSSascha Wildner {
1146267c04fdSSascha Wildner AcpiDbDecodeInternalObject (
11470d02842fSSascha Wildner WalkState->Results->Results.ObjDesc [
11480d02842fSSascha Wildner (WalkState->ResultCount - 1) %
11490d02842fSSascha Wildner ACPI_RESULTS_FRAME_OBJ_NUM]);
11500d02842fSSascha Wildner }
11510d02842fSSascha Wildner #endif
11520d02842fSSascha Wildner
11530d02842fSSascha Wildner break;
11540d02842fSSascha Wildner }
11550d02842fSSascha Wildner }
11560d02842fSSascha Wildner
1157f5f76cf2SSascha Wildner
1158f5f76cf2SSascha Wildner /*******************************************************************************
1159f5f76cf2SSascha Wildner *
1160f5f76cf2SSascha Wildner * FUNCTION: AcpiDmConvertToElseIf
1161f5f76cf2SSascha Wildner *
1162f5f76cf2SSascha Wildner * PARAMETERS: OriginalElseOp - ELSE Object to be examined
1163f5f76cf2SSascha Wildner *
1164f5f76cf2SSascha Wildner * RETURN: None. Emits either an "Else" or an "ElseIf" ASL operator.
1165f5f76cf2SSascha Wildner *
1166f5f76cf2SSascha Wildner * DESCRIPTION: Detect and convert an If..Else..If sequence to If..ElseIf
1167f5f76cf2SSascha Wildner *
1168f5f76cf2SSascha Wildner * EXAMPLE:
1169f5f76cf2SSascha Wildner *
1170f5f76cf2SSascha Wildner * This If..Else..If nested sequence:
1171f5f76cf2SSascha Wildner *
1172f5f76cf2SSascha Wildner * If (Arg0 == 1)
1173f5f76cf2SSascha Wildner * {
1174f5f76cf2SSascha Wildner * Local0 = 4
1175f5f76cf2SSascha Wildner * }
1176f5f76cf2SSascha Wildner * Else
1177f5f76cf2SSascha Wildner * {
1178f5f76cf2SSascha Wildner * If (Arg0 == 2)
1179f5f76cf2SSascha Wildner * {
1180f5f76cf2SSascha Wildner * Local0 = 5
1181f5f76cf2SSascha Wildner * }
1182f5f76cf2SSascha Wildner * }
1183f5f76cf2SSascha Wildner *
1184f5f76cf2SSascha Wildner * Is converted to this simpler If..ElseIf sequence:
1185f5f76cf2SSascha Wildner *
1186f5f76cf2SSascha Wildner * If (Arg0 == 1)
1187f5f76cf2SSascha Wildner * {
1188f5f76cf2SSascha Wildner * Local0 = 4
1189f5f76cf2SSascha Wildner * }
1190f5f76cf2SSascha Wildner * ElseIf (Arg0 == 2)
1191f5f76cf2SSascha Wildner * {
1192f5f76cf2SSascha Wildner * Local0 = 5
1193f5f76cf2SSascha Wildner * }
1194f5f76cf2SSascha Wildner *
1195f5f76cf2SSascha Wildner * NOTE: There is no actual ElseIf AML opcode. ElseIf is essentially an ASL
1196f5f76cf2SSascha Wildner * macro that emits an Else opcode followed by an If opcode. This function
1197f5f76cf2SSascha Wildner * reverses these AML sequences back to an ElseIf macro where possible. This
1198f5f76cf2SSascha Wildner * can make the disassembled ASL code simpler and more like the original code.
1199f5f76cf2SSascha Wildner *
1200f5f76cf2SSascha Wildner ******************************************************************************/
1201f5f76cf2SSascha Wildner
1202f5f76cf2SSascha Wildner static void
AcpiDmConvertToElseIf(ACPI_PARSE_OBJECT * OriginalElseOp)1203f5f76cf2SSascha Wildner AcpiDmConvertToElseIf (
1204f5f76cf2SSascha Wildner ACPI_PARSE_OBJECT *OriginalElseOp)
1205f5f76cf2SSascha Wildner {
1206f5f76cf2SSascha Wildner ACPI_PARSE_OBJECT *IfOp;
1207f5f76cf2SSascha Wildner ACPI_PARSE_OBJECT *ElseOp;
1208f5f76cf2SSascha Wildner
1209f5f76cf2SSascha Wildner
12100d27ae55SSascha Wildner /*
12110d27ae55SSascha Wildner * To be able to perform the conversion, two conditions must be satisfied:
12120d27ae55SSascha Wildner * 1) The first child of the Else must be an If statement.
12130d27ae55SSascha Wildner * 2) The If block can only be followed by an Else block and these must
12140d27ae55SSascha Wildner * be the only blocks under the original Else.
12150d27ae55SSascha Wildner */
1216f5f76cf2SSascha Wildner IfOp = OriginalElseOp->Common.Value.Arg;
121796f24602SSascha Wildner
12180d27ae55SSascha Wildner if (!IfOp ||
12190d27ae55SSascha Wildner (IfOp->Common.AmlOpcode != AML_IF_OP) ||
12200d27ae55SSascha Wildner (IfOp->Asl.Next && (IfOp->Asl.Next->Common.AmlOpcode != AML_ELSE_OP)))
1221f5f76cf2SSascha Wildner {
122296f24602SSascha Wildner /* Not a proper Else..If sequence, cannot convert to ElseIf */
1223f5f76cf2SSascha Wildner
122438b5d46cSSascha Wildner if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_DEFAULT)
122538b5d46cSSascha Wildner {
122638b5d46cSSascha Wildner AcpiOsPrintf ("%s", "Default");
122738b5d46cSSascha Wildner return;
122838b5d46cSSascha Wildner }
122938b5d46cSSascha Wildner
1230f5f76cf2SSascha Wildner AcpiOsPrintf ("%s", "Else");
1231f5f76cf2SSascha Wildner return;
1232f5f76cf2SSascha Wildner }
1233f5f76cf2SSascha Wildner
123496f24602SSascha Wildner /* Cannot have anything following the If...Else block */
123596f24602SSascha Wildner
123696f24602SSascha Wildner ElseOp = IfOp->Common.Next;
123796f24602SSascha Wildner if (ElseOp && ElseOp->Common.Next)
123896f24602SSascha Wildner {
123938b5d46cSSascha Wildner if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_DEFAULT)
124038b5d46cSSascha Wildner {
124138b5d46cSSascha Wildner AcpiOsPrintf ("%s", "Default");
124238b5d46cSSascha Wildner return;
124338b5d46cSSascha Wildner }
124438b5d46cSSascha Wildner
124596f24602SSascha Wildner AcpiOsPrintf ("%s", "Else");
124696f24602SSascha Wildner return;
124796f24602SSascha Wildner }
124896f24602SSascha Wildner
124938b5d46cSSascha Wildner if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_DEFAULT)
125038b5d46cSSascha Wildner {
125138b5d46cSSascha Wildner /*
125238b5d46cSSascha Wildner * There is an ElseIf but in this case the Else is actually
125338b5d46cSSascha Wildner * a Default block for a Switch/Case statement. No conversion.
125438b5d46cSSascha Wildner */
125538b5d46cSSascha Wildner AcpiOsPrintf ("%s", "Default");
125638b5d46cSSascha Wildner return;
125738b5d46cSSascha Wildner }
125838b5d46cSSascha Wildner
125938b5d46cSSascha Wildner if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_CASE)
126038b5d46cSSascha Wildner {
126138b5d46cSSascha Wildner /*
126238b5d46cSSascha Wildner * This ElseIf is actually a Case block for a Switch/Case
126338b5d46cSSascha Wildner * statement. Print Case but do not return so that we can
126438b5d46cSSascha Wildner * promote the subtree and keep the indentation level.
126538b5d46cSSascha Wildner */
126638b5d46cSSascha Wildner AcpiOsPrintf ("%s", "Case");
126738b5d46cSSascha Wildner }
126838b5d46cSSascha Wildner else
126938b5d46cSSascha Wildner {
1270f5f76cf2SSascha Wildner /* Emit ElseIf, mark the IF as now an ELSEIF */
1271f5f76cf2SSascha Wildner
1272f5f76cf2SSascha Wildner AcpiOsPrintf ("%s", "ElseIf");
127338b5d46cSSascha Wildner }
127438b5d46cSSascha Wildner
1275f5f76cf2SSascha Wildner IfOp->Common.DisasmFlags |= ACPI_PARSEOP_ELSEIF;
1276f5f76cf2SSascha Wildner
1277f5f76cf2SSascha Wildner /* The IF parent will now be the same as the original ELSE parent */
1278f5f76cf2SSascha Wildner
1279f5f76cf2SSascha Wildner IfOp->Common.Parent = OriginalElseOp->Common.Parent;
1280f5f76cf2SSascha Wildner
1281f5f76cf2SSascha Wildner /*
1282f5f76cf2SSascha Wildner * Update the NEXT pointers to restructure the parse tree, essentially
1283f5f76cf2SSascha Wildner * promoting an If..Else block up to the same level as the original
1284f5f76cf2SSascha Wildner * Else.
1285f5f76cf2SSascha Wildner *
1286f5f76cf2SSascha Wildner * Check if the IF has a corresponding ELSE peer
1287f5f76cf2SSascha Wildner */
1288f5f76cf2SSascha Wildner ElseOp = IfOp->Common.Next;
1289f5f76cf2SSascha Wildner if (ElseOp &&
1290f5f76cf2SSascha Wildner (ElseOp->Common.AmlOpcode == AML_ELSE_OP))
1291f5f76cf2SSascha Wildner {
1292f5f76cf2SSascha Wildner /* If an ELSE matches the IF, promote it also */
1293f5f76cf2SSascha Wildner
1294f5f76cf2SSascha Wildner ElseOp->Common.Parent = OriginalElseOp->Common.Parent;
129596f24602SSascha Wildner
129696f24602SSascha Wildner /* Promote the entire block under the ElseIf (All Next OPs) */
129796f24602SSascha Wildner
129896f24602SSascha Wildner AcpiDmPromoteSubtree (OriginalElseOp);
1299f5f76cf2SSascha Wildner }
1300f5f76cf2SSascha Wildner else
1301f5f76cf2SSascha Wildner {
1302f5f76cf2SSascha Wildner /* Otherwise, set the IF NEXT to the original ELSE NEXT */
1303f5f76cf2SSascha Wildner
1304f5f76cf2SSascha Wildner IfOp->Common.Next = OriginalElseOp->Common.Next;
1305f5f76cf2SSascha Wildner }
1306f5f76cf2SSascha Wildner
1307f5f76cf2SSascha Wildner /* Detach the child IF block from the original ELSE */
1308f5f76cf2SSascha Wildner
1309f5f76cf2SSascha Wildner OriginalElseOp->Common.Value.Arg = NULL;
1310f5f76cf2SSascha Wildner
1311f5f76cf2SSascha Wildner /* Ignore the original ELSE from now on */
1312f5f76cf2SSascha Wildner
1313f5f76cf2SSascha Wildner OriginalElseOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
1314f5f76cf2SSascha Wildner OriginalElseOp->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
1315f5f76cf2SSascha Wildner
1316f5f76cf2SSascha Wildner /* Insert IF (now ELSEIF) as next peer of the original ELSE */
1317f5f76cf2SSascha Wildner
1318f5f76cf2SSascha Wildner OriginalElseOp->Common.Next = IfOp;
1319f5f76cf2SSascha Wildner }
1320f5f76cf2SSascha Wildner
132196f24602SSascha Wildner
132296f24602SSascha Wildner /*******************************************************************************
132396f24602SSascha Wildner *
132496f24602SSascha Wildner * FUNCTION: AcpiDmPromoteSubtree
132596f24602SSascha Wildner *
132696f24602SSascha Wildner * PARAMETERS: StartOpOp - Original parent of the entire subtree
132796f24602SSascha Wildner *
132896f24602SSascha Wildner * RETURN: None
132996f24602SSascha Wildner *
133096f24602SSascha Wildner * DESCRIPTION: Promote an entire parse subtree up one level.
133196f24602SSascha Wildner *
133296f24602SSascha Wildner ******************************************************************************/
133396f24602SSascha Wildner
133496f24602SSascha Wildner static void
AcpiDmPromoteSubtree(ACPI_PARSE_OBJECT * StartOp)133596f24602SSascha Wildner AcpiDmPromoteSubtree (
133696f24602SSascha Wildner ACPI_PARSE_OBJECT *StartOp)
133796f24602SSascha Wildner {
133896f24602SSascha Wildner ACPI_PARSE_OBJECT *Op;
133996f24602SSascha Wildner ACPI_PARSE_OBJECT *ParentOp;
134096f24602SSascha Wildner
134196f24602SSascha Wildner
134296f24602SSascha Wildner /* New parent for subtree elements */
134396f24602SSascha Wildner
134496f24602SSascha Wildner ParentOp = StartOp->Common.Parent;
134596f24602SSascha Wildner
134696f24602SSascha Wildner /* First child starts the subtree */
134796f24602SSascha Wildner
134896f24602SSascha Wildner Op = StartOp->Common.Value.Arg;
134996f24602SSascha Wildner
135096f24602SSascha Wildner /* Walk the top-level elements of the subtree */
135196f24602SSascha Wildner
135296f24602SSascha Wildner while (Op)
135396f24602SSascha Wildner {
135496f24602SSascha Wildner Op->Common.Parent = ParentOp;
135596f24602SSascha Wildner if (!Op->Common.Next)
135696f24602SSascha Wildner {
135796f24602SSascha Wildner /* Last Op in list, update its next field */
135896f24602SSascha Wildner
135996f24602SSascha Wildner Op->Common.Next = StartOp->Common.Next;
136096f24602SSascha Wildner break;
136196f24602SSascha Wildner }
136296f24602SSascha Wildner Op = Op->Common.Next;
136396f24602SSascha Wildner }
136496f24602SSascha Wildner }
136596f24602SSascha Wildner
13660d02842fSSascha Wildner #endif /* ACPI_DISASSEMBLER */
1367