xref: /netbsd-src/sys/external/bsd/acpica/dist/disassembler/dmopcode.c (revision 046a29855e04359424fd074e8313af6b6be8cfb6)
128c506b8Sjruoho /*******************************************************************************
228c506b8Sjruoho  *
328c506b8Sjruoho  * Module Name: dmopcode - AML disassembler, specific AML opcodes
428c506b8Sjruoho  *
528c506b8Sjruoho  ******************************************************************************/
628c506b8Sjruoho 
7124f4c82Sjruoho /*
8*046a2985Schristos  * Copyright (C) 2000 - 2023, Intel Corp.
928c506b8Sjruoho  * All rights reserved.
1028c506b8Sjruoho  *
11124f4c82Sjruoho  * Redistribution and use in source and binary forms, with or without
12124f4c82Sjruoho  * modification, are permitted provided that the following conditions
13124f4c82Sjruoho  * are met:
14124f4c82Sjruoho  * 1. Redistributions of source code must retain the above copyright
15124f4c82Sjruoho  *    notice, this list of conditions, and the following disclaimer,
16124f4c82Sjruoho  *    without modification.
17124f4c82Sjruoho  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18124f4c82Sjruoho  *    substantially similar to the "NO WARRANTY" disclaimer below
19124f4c82Sjruoho  *    ("Disclaimer") and any redistribution must be conditioned upon
20124f4c82Sjruoho  *    including a substantially similar Disclaimer requirement for further
21124f4c82Sjruoho  *    binary redistribution.
22124f4c82Sjruoho  * 3. Neither the names of the above-listed copyright holders nor the names
23124f4c82Sjruoho  *    of any contributors may be used to endorse or promote products derived
24124f4c82Sjruoho  *    from this software without specific prior written permission.
2528c506b8Sjruoho  *
26124f4c82Sjruoho  * Alternatively, this software may be distributed under the terms of the
27124f4c82Sjruoho  * GNU General Public License ("GPL") version 2 as published by the Free
28124f4c82Sjruoho  * Software Foundation.
2928c506b8Sjruoho  *
30124f4c82Sjruoho  * NO WARRANTY
31124f4c82Sjruoho  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32124f4c82Sjruoho  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3346a330b4Schristos  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34124f4c82Sjruoho  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35124f4c82Sjruoho  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36124f4c82Sjruoho  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37124f4c82Sjruoho  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38124f4c82Sjruoho  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39124f4c82Sjruoho  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40124f4c82Sjruoho  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41124f4c82Sjruoho  * POSSIBILITY OF SUCH DAMAGES.
42124f4c82Sjruoho  */
4328c506b8Sjruoho 
4428c506b8Sjruoho #include "acpi.h"
4528c506b8Sjruoho #include "accommon.h"
4628c506b8Sjruoho #include "acparser.h"
4728c506b8Sjruoho #include "amlcode.h"
48460301d4Schristos #include "acinterp.h"
49460301d4Schristos #include "acnamesp.h"
50c72da027Schristos #include "acdebug.h"
51835858a6Schristos #include "acconvert.h"
5228c506b8Sjruoho 
5328c506b8Sjruoho 
5428c506b8Sjruoho #define _COMPONENT          ACPI_CA_DEBUGGER
5528c506b8Sjruoho         ACPI_MODULE_NAME    ("dmopcode")
5628c506b8Sjruoho 
57679c17fdSchristos 
5828c506b8Sjruoho /* Local prototypes */
5928c506b8Sjruoho 
6028c506b8Sjruoho static void
6128c506b8Sjruoho AcpiDmMatchKeyword (
6228c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op);
6328c506b8Sjruoho 
6471e38f1dSchristos static void
6571e38f1dSchristos AcpiDmConvertToElseIf (
6671e38f1dSchristos     ACPI_PARSE_OBJECT       *Op);
6771e38f1dSchristos 
68d0e1da26Schristos static void
69d0e1da26Schristos AcpiDmPromoteSubtree (
70d0e1da26Schristos     ACPI_PARSE_OBJECT       *StartOp);
71d0e1da26Schristos 
7228c506b8Sjruoho /*******************************************************************************
7328c506b8Sjruoho  *
74460301d4Schristos  * FUNCTION:    AcpiDmDisplayTargetPathname
75460301d4Schristos  *
76460301d4Schristos  * PARAMETERS:  Op              - Parse object
77460301d4Schristos  *
78460301d4Schristos  * RETURN:      None
79460301d4Schristos  *
80460301d4Schristos  * DESCRIPTION: For AML opcodes that have a target operand, display the full
81460301d4Schristos  *              pathname for the target, in a comment field. Handles Return()
82460301d4Schristos  *              statements also.
83460301d4Schristos  *
84460301d4Schristos  ******************************************************************************/
85460301d4Schristos 
86460301d4Schristos void
AcpiDmDisplayTargetPathname(ACPI_PARSE_OBJECT * Op)87460301d4Schristos AcpiDmDisplayTargetPathname (
88460301d4Schristos     ACPI_PARSE_OBJECT       *Op)
89460301d4Schristos {
90460301d4Schristos     ACPI_PARSE_OBJECT       *NextOp;
91460301d4Schristos     ACPI_PARSE_OBJECT       *PrevOp = NULL;
92460301d4Schristos     char                    *Pathname;
93460301d4Schristos     const ACPI_OPCODE_INFO  *OpInfo;
94460301d4Schristos 
95460301d4Schristos 
96460301d4Schristos     if (Op->Common.AmlOpcode == AML_RETURN_OP)
97460301d4Schristos     {
98460301d4Schristos         PrevOp = Op->Asl.Value.Arg;
99460301d4Schristos     }
100460301d4Schristos     else
101460301d4Schristos     {
102460301d4Schristos         OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
103460301d4Schristos         if (!(OpInfo->Flags & AML_HAS_TARGET))
104460301d4Schristos         {
105460301d4Schristos             return;
106460301d4Schristos         }
107460301d4Schristos 
108460301d4Schristos         /* Target is the last Op in the arg list */
109460301d4Schristos 
110460301d4Schristos         NextOp = Op->Asl.Value.Arg;
111460301d4Schristos         while (NextOp)
112460301d4Schristos         {
113460301d4Schristos             PrevOp = NextOp;
114460301d4Schristos             NextOp = PrevOp->Asl.Next;
115460301d4Schristos         }
116460301d4Schristos     }
117460301d4Schristos 
118460301d4Schristos     if (!PrevOp)
119460301d4Schristos     {
120460301d4Schristos         return;
121460301d4Schristos     }
122460301d4Schristos 
123460301d4Schristos     /* We must have a namepath AML opcode */
124460301d4Schristos 
125460301d4Schristos     if (PrevOp->Asl.AmlOpcode != AML_INT_NAMEPATH_OP)
126460301d4Schristos     {
127460301d4Schristos         return;
128460301d4Schristos     }
129460301d4Schristos 
130460301d4Schristos     /* A null string is the "no target specified" case */
131460301d4Schristos 
132460301d4Schristos     if (!PrevOp->Asl.Value.String)
133460301d4Schristos     {
134460301d4Schristos         return;
135460301d4Schristos     }
136460301d4Schristos 
137460301d4Schristos     /* No node means "unresolved external reference" */
138460301d4Schristos 
139460301d4Schristos     if (!PrevOp->Asl.Node)
140460301d4Schristos     {
141460301d4Schristos         AcpiOsPrintf (" /* External reference */");
142460301d4Schristos         return;
143460301d4Schristos     }
144460301d4Schristos 
145460301d4Schristos     /* Ignore if path is already from the root */
146460301d4Schristos 
147460301d4Schristos     if (*PrevOp->Asl.Value.String == '\\')
148460301d4Schristos     {
149460301d4Schristos         return;
150460301d4Schristos     }
151460301d4Schristos 
152460301d4Schristos     /* Now: we can get the full pathname */
153460301d4Schristos 
154460301d4Schristos     Pathname = AcpiNsGetExternalPathname (PrevOp->Asl.Node);
155460301d4Schristos     if (!Pathname)
156460301d4Schristos     {
157460301d4Schristos         return;
158460301d4Schristos     }
159460301d4Schristos 
160460301d4Schristos     AcpiOsPrintf (" /* %s */", Pathname);
161460301d4Schristos     ACPI_FREE (Pathname);
162460301d4Schristos }
163460301d4Schristos 
164460301d4Schristos 
165460301d4Schristos /*******************************************************************************
166460301d4Schristos  *
167460301d4Schristos  * FUNCTION:    AcpiDmNotifyDescription
168460301d4Schristos  *
169460301d4Schristos  * PARAMETERS:  Op              - Name() parse object
170460301d4Schristos  *
171460301d4Schristos  * RETURN:      None
172460301d4Schristos  *
173460301d4Schristos  * DESCRIPTION: Emit a description comment for the value associated with a
174460301d4Schristos  *              Notify() operator.
175460301d4Schristos  *
176460301d4Schristos  ******************************************************************************/
177460301d4Schristos 
178460301d4Schristos void
AcpiDmNotifyDescription(ACPI_PARSE_OBJECT * Op)179460301d4Schristos AcpiDmNotifyDescription (
180460301d4Schristos     ACPI_PARSE_OBJECT       *Op)
181460301d4Schristos {
182460301d4Schristos     ACPI_PARSE_OBJECT       *NextOp;
183460301d4Schristos     ACPI_NAMESPACE_NODE     *Node;
184460301d4Schristos     UINT8                   NotifyValue;
185460301d4Schristos     UINT8                   Type = ACPI_TYPE_ANY;
186460301d4Schristos 
187460301d4Schristos 
188460301d4Schristos     /* The notify value is the second argument */
189460301d4Schristos 
190460301d4Schristos     NextOp = Op->Asl.Value.Arg;
191460301d4Schristos     NextOp = NextOp->Asl.Next;
192460301d4Schristos 
193460301d4Schristos     switch (NextOp->Common.AmlOpcode)
194460301d4Schristos     {
195460301d4Schristos     case AML_ZERO_OP:
196460301d4Schristos     case AML_ONE_OP:
197460301d4Schristos 
198460301d4Schristos         NotifyValue = (UINT8) NextOp->Common.AmlOpcode;
199460301d4Schristos         break;
200460301d4Schristos 
201460301d4Schristos     case AML_BYTE_OP:
202460301d4Schristos 
203460301d4Schristos         NotifyValue = (UINT8) NextOp->Asl.Value.Integer;
204460301d4Schristos         break;
205460301d4Schristos 
206460301d4Schristos     default:
207460301d4Schristos         return;
208460301d4Schristos     }
209460301d4Schristos 
210460301d4Schristos     /*
211460301d4Schristos      * Attempt to get the namespace node so we can determine the object type.
212460301d4Schristos      * Some notify values are dependent on the object type (Device, Thermal,
213460301d4Schristos      * or Processor).
214460301d4Schristos      */
215460301d4Schristos     Node = Op->Asl.Node;
216460301d4Schristos     if (Node)
217460301d4Schristos     {
218460301d4Schristos         Type = Node->Type;
219460301d4Schristos     }
220460301d4Schristos 
221460301d4Schristos     AcpiOsPrintf (" // %s", AcpiUtGetNotifyName (NotifyValue, Type));
222460301d4Schristos }
223460301d4Schristos 
224460301d4Schristos 
225460301d4Schristos /*******************************************************************************
226460301d4Schristos  *
227ff4a156dSchristos  * FUNCTION:    AcpiDmPredefinedDescription
228ff4a156dSchristos  *
229ff4a156dSchristos  * PARAMETERS:  Op              - Name() parse object
230ff4a156dSchristos  *
231ff4a156dSchristos  * RETURN:      None
232ff4a156dSchristos  *
233ff4a156dSchristos  * DESCRIPTION: Emit a description comment for a predefined ACPI name.
234ff4a156dSchristos  *              Used for iASL compiler only.
235ff4a156dSchristos  *
236ff4a156dSchristos  ******************************************************************************/
237ff4a156dSchristos 
238ff4a156dSchristos void
AcpiDmPredefinedDescription(ACPI_PARSE_OBJECT * Op)239ff4a156dSchristos AcpiDmPredefinedDescription (
240ff4a156dSchristos     ACPI_PARSE_OBJECT       *Op)
241ff4a156dSchristos {
242ff4a156dSchristos #ifdef ACPI_ASL_COMPILER
243ff4a156dSchristos     const AH_PREDEFINED_NAME    *Info;
244ff4a156dSchristos     char                        *NameString;
245ff4a156dSchristos     int                         LastCharIsDigit;
246ff4a156dSchristos     int                         LastCharsAreHex;
247ff4a156dSchristos 
248ff4a156dSchristos 
249ff4a156dSchristos     if (!Op)
250ff4a156dSchristos     {
251ff4a156dSchristos         return;
252ff4a156dSchristos     }
253ff4a156dSchristos 
254ff4a156dSchristos     /* Ensure that the comment field is emitted only once */
255ff4a156dSchristos 
256cfbb7280Schristos     if (Op->Common.DisasmFlags & ACPI_PARSEOP_PREDEFINED_CHECKED)
257ff4a156dSchristos     {
258ff4a156dSchristos         return;
259ff4a156dSchristos     }
260cfbb7280Schristos     Op->Common.DisasmFlags |= ACPI_PARSEOP_PREDEFINED_CHECKED;
261ff4a156dSchristos 
262ff4a156dSchristos     /* Predefined name must start with an underscore */
263ff4a156dSchristos 
264ff4a156dSchristos     NameString = ACPI_CAST_PTR (char, &Op->Named.Name);
265ff4a156dSchristos     if (NameString[0] != '_')
266ff4a156dSchristos     {
267ff4a156dSchristos         return;
268ff4a156dSchristos     }
269ff4a156dSchristos 
270ff4a156dSchristos     /*
271ff4a156dSchristos      * Check for the special ACPI names:
272ff4a156dSchristos      * _ACd, _ALd, _EJd, _Exx, _Lxx, _Qxx, _Wxx, _T_a
273ff4a156dSchristos      * (where d=decimal_digit, x=hex_digit, a=anything)
274ff4a156dSchristos      *
275ff4a156dSchristos      * Convert these to the generic name for table lookup.
276ff4a156dSchristos      * Note: NameString is guaranteed to be upper case here.
277ff4a156dSchristos      */
278ff4a156dSchristos     LastCharIsDigit =
279c72da027Schristos         (isdigit ((int) NameString[3]));    /* d */
280ff4a156dSchristos     LastCharsAreHex =
281c72da027Schristos         (isxdigit ((int) NameString[2]) &&  /* xx */
282c72da027Schristos          isxdigit ((int) NameString[3]));
283ff4a156dSchristos 
284ff4a156dSchristos     switch (NameString[1])
285ff4a156dSchristos     {
286ff4a156dSchristos     case 'A':
287ff4a156dSchristos 
288ff4a156dSchristos         if ((NameString[2] == 'C') && (LastCharIsDigit))
289ff4a156dSchristos         {
290ff4a156dSchristos             NameString = "_ACx";
291ff4a156dSchristos         }
292ff4a156dSchristos         else if ((NameString[2] == 'L') && (LastCharIsDigit))
293ff4a156dSchristos         {
294ff4a156dSchristos             NameString = "_ALx";
295ff4a156dSchristos         }
296ff4a156dSchristos         break;
297ff4a156dSchristos 
298ff4a156dSchristos     case 'E':
299ff4a156dSchristos 
300ff4a156dSchristos         if ((NameString[2] == 'J') && (LastCharIsDigit))
301ff4a156dSchristos         {
302ff4a156dSchristos             NameString = "_EJx";
303ff4a156dSchristos         }
304ff4a156dSchristos         else if (LastCharsAreHex)
305ff4a156dSchristos         {
306ff4a156dSchristos             NameString = "_Exx";
307ff4a156dSchristos         }
308ff4a156dSchristos         break;
309ff4a156dSchristos 
310ff4a156dSchristos     case 'L':
311ff4a156dSchristos 
312ff4a156dSchristos         if (LastCharsAreHex)
313ff4a156dSchristos         {
314ff4a156dSchristos             NameString = "_Lxx";
315ff4a156dSchristos         }
316ff4a156dSchristos         break;
317ff4a156dSchristos 
318ff4a156dSchristos     case 'Q':
319ff4a156dSchristos 
320ff4a156dSchristos         if (LastCharsAreHex)
321ff4a156dSchristos         {
322ff4a156dSchristos             NameString = "_Qxx";
323ff4a156dSchristos         }
324ff4a156dSchristos         break;
325ff4a156dSchristos 
326ff4a156dSchristos     case 'T':
327ff4a156dSchristos 
328ff4a156dSchristos         if (NameString[2] == '_')
329ff4a156dSchristos         {
330ff4a156dSchristos             NameString = "_T_x";
331ff4a156dSchristos         }
332ff4a156dSchristos         break;
333ff4a156dSchristos 
334ff4a156dSchristos     case 'W':
335ff4a156dSchristos 
336ff4a156dSchristos         if (LastCharsAreHex)
337ff4a156dSchristos         {
338ff4a156dSchristos             NameString = "_Wxx";
339ff4a156dSchristos         }
340ff4a156dSchristos         break;
341ff4a156dSchristos 
342ff4a156dSchristos     default:
343ff4a156dSchristos 
344ff4a156dSchristos         break;
345ff4a156dSchristos     }
346ff4a156dSchristos 
347ff4a156dSchristos     /* Match the name in the info table */
348ff4a156dSchristos 
349460301d4Schristos     Info = AcpiAhMatchPredefinedName (NameString);
350460301d4Schristos     if (Info)
351ff4a156dSchristos     {
352ff4a156dSchristos         AcpiOsPrintf ("  // %4.4s: %s",
353ff4a156dSchristos             NameString, ACPI_CAST_PTR (char, Info->Description));
354ff4a156dSchristos     }
355ff4a156dSchristos 
356ff4a156dSchristos #endif
357ff4a156dSchristos     return;
358ff4a156dSchristos }
359ff4a156dSchristos 
360ff4a156dSchristos 
361ff4a156dSchristos /*******************************************************************************
362ff4a156dSchristos  *
363ff4a156dSchristos  * FUNCTION:    AcpiDmFieldPredefinedDescription
364ff4a156dSchristos  *
365ff4a156dSchristos  * PARAMETERS:  Op              - Parse object
366ff4a156dSchristos  *
367ff4a156dSchristos  * RETURN:      None
368ff4a156dSchristos  *
369ff4a156dSchristos  * DESCRIPTION: Emit a description comment for a resource descriptor tag
370ff4a156dSchristos  *              (which is a predefined ACPI name.) Used for iASL compiler only.
371ff4a156dSchristos  *
372ff4a156dSchristos  ******************************************************************************/
373ff4a156dSchristos 
374ff4a156dSchristos void
AcpiDmFieldPredefinedDescription(ACPI_PARSE_OBJECT * Op)375ff4a156dSchristos AcpiDmFieldPredefinedDescription (
376ff4a156dSchristos     ACPI_PARSE_OBJECT       *Op)
377ff4a156dSchristos {
378ff4a156dSchristos #ifdef ACPI_ASL_COMPILER
379ff4a156dSchristos     ACPI_PARSE_OBJECT       *IndexOp;
380ff4a156dSchristos     char                    *Tag;
381ff4a156dSchristos     const ACPI_OPCODE_INFO  *OpInfo;
382ff4a156dSchristos     const AH_PREDEFINED_NAME *Info;
383ff4a156dSchristos 
384ff4a156dSchristos 
385ff4a156dSchristos     if (!Op)
386ff4a156dSchristos     {
387ff4a156dSchristos         return;
388ff4a156dSchristos     }
389ff4a156dSchristos 
390ff4a156dSchristos     /* Ensure that the comment field is emitted only once */
391ff4a156dSchristos 
392cfbb7280Schristos     if (Op->Common.DisasmFlags & ACPI_PARSEOP_PREDEFINED_CHECKED)
393ff4a156dSchristos     {
394ff4a156dSchristos         return;
395ff4a156dSchristos     }
396cfbb7280Schristos     Op->Common.DisasmFlags |= ACPI_PARSEOP_PREDEFINED_CHECKED;
397ff4a156dSchristos 
398ff4a156dSchristos     /*
399ff4a156dSchristos      * Op must be one of the Create* operators: CreateField, CreateBitField,
400ff4a156dSchristos      * CreateByteField, CreateWordField, CreateDwordField, CreateQwordField
401ff4a156dSchristos      */
402ff4a156dSchristos     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
403ff4a156dSchristos     if (!(OpInfo->Flags & AML_CREATE))
404ff4a156dSchristos     {
405ff4a156dSchristos         return;
406ff4a156dSchristos     }
407ff4a156dSchristos 
408ff4a156dSchristos     /* Second argument is the Index argument */
409ff4a156dSchristos 
410ff4a156dSchristos     IndexOp = Op->Common.Value.Arg;
411ff4a156dSchristos     IndexOp = IndexOp->Common.Next;
412ff4a156dSchristos 
413ff4a156dSchristos     /* Index argument must be a namepath */
414ff4a156dSchristos 
415ff4a156dSchristos     if (IndexOp->Common.AmlOpcode != AML_INT_NAMEPATH_OP)
416ff4a156dSchristos     {
417ff4a156dSchristos         return;
418ff4a156dSchristos     }
419ff4a156dSchristos 
420ff4a156dSchristos     /* Major cheat: We previously put the Tag ptr in the Node field */
421ff4a156dSchristos 
422ff4a156dSchristos     Tag = ACPI_CAST_PTR (char, IndexOp->Common.Node);
42389b8eb6cSchristos     if (!Tag || (*Tag == 0))
424ff4a156dSchristos     {
425ff4a156dSchristos         return;
426ff4a156dSchristos     }
427ff4a156dSchristos 
42889b8eb6cSchristos     /* Is the tag a predefined name? */
429ff4a156dSchristos 
430460301d4Schristos     Info = AcpiAhMatchPredefinedName (Tag);
43189b8eb6cSchristos     if (!Info)
432ff4a156dSchristos     {
43389b8eb6cSchristos         /* Not a predefined name (does not start with underscore) */
43489b8eb6cSchristos 
43589b8eb6cSchristos         return;
436ff4a156dSchristos     }
437ff4a156dSchristos 
43889b8eb6cSchristos     AcpiOsPrintf ("  // %4.4s: %s", Tag,
43989b8eb6cSchristos         ACPI_CAST_PTR (char, Info->Description));
44089b8eb6cSchristos 
44189b8eb6cSchristos     /* String contains the prefix path, free it */
442835858a6Schristos 
443835858a6Schristos     ACPI_FREE (IndexOp->Common.Value.String);
44489b8eb6cSchristos     IndexOp->Common.Value.String = NULL;
445ff4a156dSchristos #endif
44689b8eb6cSchristos 
447ff4a156dSchristos     return;
448ff4a156dSchristos }
449ff4a156dSchristos 
450ff4a156dSchristos 
451ff4a156dSchristos /*******************************************************************************
452ff4a156dSchristos  *
45328c506b8Sjruoho  * FUNCTION:    AcpiDmMethodFlags
45428c506b8Sjruoho  *
45528c506b8Sjruoho  * PARAMETERS:  Op              - Method Object to be examined
45628c506b8Sjruoho  *
45728c506b8Sjruoho  * RETURN:      None
45828c506b8Sjruoho  *
45928c506b8Sjruoho  * DESCRIPTION: Decode control method flags
46028c506b8Sjruoho  *
46128c506b8Sjruoho  ******************************************************************************/
46228c506b8Sjruoho 
46328c506b8Sjruoho void
AcpiDmMethodFlags(ACPI_PARSE_OBJECT * Op)46428c506b8Sjruoho AcpiDmMethodFlags (
46528c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op)
46628c506b8Sjruoho {
46728c506b8Sjruoho     UINT32                  Flags;
46828c506b8Sjruoho     UINT32                  Args;
46928c506b8Sjruoho 
47028c506b8Sjruoho 
47128c506b8Sjruoho     /* The next Op contains the flags */
47228c506b8Sjruoho 
47328c506b8Sjruoho     Op = AcpiPsGetDepthNext (NULL, Op);
47428c506b8Sjruoho     Flags = (UINT8) Op->Common.Value.Integer;
47528c506b8Sjruoho     Args = Flags & 0x07;
47628c506b8Sjruoho 
47728c506b8Sjruoho     /* Mark the Op as completed */
47828c506b8Sjruoho 
47928c506b8Sjruoho     Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
48028c506b8Sjruoho 
48128c506b8Sjruoho     /* 1) Method argument count */
48228c506b8Sjruoho 
48328c506b8Sjruoho     AcpiOsPrintf (", %u, ", Args);
48428c506b8Sjruoho 
48528c506b8Sjruoho     /* 2) Serialize rule */
48628c506b8Sjruoho 
48728c506b8Sjruoho     if (!(Flags & 0x08))
48828c506b8Sjruoho     {
48928c506b8Sjruoho         AcpiOsPrintf ("Not");
49028c506b8Sjruoho     }
49128c506b8Sjruoho 
49228c506b8Sjruoho     AcpiOsPrintf ("Serialized");
49328c506b8Sjruoho 
49428c506b8Sjruoho     /* 3) SyncLevel */
49528c506b8Sjruoho 
49628c506b8Sjruoho     if (Flags & 0xF0)
49728c506b8Sjruoho     {
49828c506b8Sjruoho         AcpiOsPrintf (", %u", Flags >> 4);
49928c506b8Sjruoho     }
50028c506b8Sjruoho }
50128c506b8Sjruoho 
50228c506b8Sjruoho 
50328c506b8Sjruoho /*******************************************************************************
50428c506b8Sjruoho  *
50528c506b8Sjruoho  * FUNCTION:    AcpiDmFieldFlags
50628c506b8Sjruoho  *
50728c506b8Sjruoho  * PARAMETERS:  Op              - Field Object to be examined
50828c506b8Sjruoho  *
50928c506b8Sjruoho  * RETURN:      None
51028c506b8Sjruoho  *
51128c506b8Sjruoho  * DESCRIPTION: Decode Field definition flags
51228c506b8Sjruoho  *
51328c506b8Sjruoho  ******************************************************************************/
51428c506b8Sjruoho 
51528c506b8Sjruoho void
AcpiDmFieldFlags(ACPI_PARSE_OBJECT * Op)51628c506b8Sjruoho AcpiDmFieldFlags (
51728c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op)
51828c506b8Sjruoho {
51928c506b8Sjruoho     UINT32                  Flags;
52028c506b8Sjruoho 
52128c506b8Sjruoho 
52228c506b8Sjruoho     Op = Op->Common.Next;
52328c506b8Sjruoho     Flags = (UINT8) Op->Common.Value.Integer;
52428c506b8Sjruoho 
52528c506b8Sjruoho     /* Mark the Op as completed */
52628c506b8Sjruoho 
52728c506b8Sjruoho     Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
52828c506b8Sjruoho 
52928c506b8Sjruoho     AcpiOsPrintf ("%s, ", AcpiGbl_AccessTypes [Flags & 0x07]);
53028c506b8Sjruoho     AcpiOsPrintf ("%s, ", AcpiGbl_LockRule [(Flags & 0x10) >> 4]);
53128c506b8Sjruoho     AcpiOsPrintf ("%s)",  AcpiGbl_UpdateRules [(Flags & 0x60) >> 5]);
53228c506b8Sjruoho }
53328c506b8Sjruoho 
53428c506b8Sjruoho 
53528c506b8Sjruoho /*******************************************************************************
53628c506b8Sjruoho  *
53728c506b8Sjruoho  * FUNCTION:    AcpiDmAddressSpace
53828c506b8Sjruoho  *
53928c506b8Sjruoho  * PARAMETERS:  SpaceId         - ID to be translated
54028c506b8Sjruoho  *
54128c506b8Sjruoho  * RETURN:      None
54228c506b8Sjruoho  *
54328c506b8Sjruoho  * DESCRIPTION: Decode a SpaceId to an AddressSpaceKeyword
54428c506b8Sjruoho  *
54528c506b8Sjruoho  ******************************************************************************/
54628c506b8Sjruoho 
54728c506b8Sjruoho void
AcpiDmAddressSpace(UINT8 SpaceId)54828c506b8Sjruoho AcpiDmAddressSpace (
54928c506b8Sjruoho     UINT8                   SpaceId)
55028c506b8Sjruoho {
55128c506b8Sjruoho 
55228c506b8Sjruoho     if (SpaceId >= ACPI_NUM_PREDEFINED_REGIONS)
55328c506b8Sjruoho     {
55428c506b8Sjruoho         if (SpaceId == 0x7F)
55528c506b8Sjruoho         {
55628c506b8Sjruoho             AcpiOsPrintf ("FFixedHW, ");
55728c506b8Sjruoho         }
55828c506b8Sjruoho         else
55928c506b8Sjruoho         {
56028c506b8Sjruoho             AcpiOsPrintf ("0x%.2X, ", SpaceId);
56128c506b8Sjruoho         }
56228c506b8Sjruoho     }
56328c506b8Sjruoho     else
56428c506b8Sjruoho     {
56528c506b8Sjruoho         AcpiOsPrintf ("%s, ", AcpiGbl_RegionTypes [SpaceId]);
56628c506b8Sjruoho     }
56728c506b8Sjruoho }
56828c506b8Sjruoho 
56928c506b8Sjruoho 
57028c506b8Sjruoho /*******************************************************************************
57128c506b8Sjruoho  *
57228c506b8Sjruoho  * FUNCTION:    AcpiDmRegionFlags
57328c506b8Sjruoho  *
57428c506b8Sjruoho  * PARAMETERS:  Op              - Object to be examined
57528c506b8Sjruoho  *
57628c506b8Sjruoho  * RETURN:      None
57728c506b8Sjruoho  *
57828c506b8Sjruoho  * DESCRIPTION: Decode OperationRegion flags
57928c506b8Sjruoho  *
58028c506b8Sjruoho  ******************************************************************************/
58128c506b8Sjruoho 
58228c506b8Sjruoho void
AcpiDmRegionFlags(ACPI_PARSE_OBJECT * Op)58328c506b8Sjruoho AcpiDmRegionFlags (
58428c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op)
58528c506b8Sjruoho {
58628c506b8Sjruoho 
58728c506b8Sjruoho     /* The next Op contains the SpaceId */
58828c506b8Sjruoho 
58928c506b8Sjruoho     Op = AcpiPsGetDepthNext (NULL, Op);
59028c506b8Sjruoho 
59128c506b8Sjruoho     /* Mark the Op as completed */
59228c506b8Sjruoho 
59328c506b8Sjruoho     Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
59428c506b8Sjruoho 
59528c506b8Sjruoho     AcpiOsPrintf (", ");
59628c506b8Sjruoho     AcpiDmAddressSpace ((UINT8) Op->Common.Value.Integer);
59728c506b8Sjruoho }
59828c506b8Sjruoho 
59928c506b8Sjruoho 
60028c506b8Sjruoho /*******************************************************************************
60128c506b8Sjruoho  *
60228c506b8Sjruoho  * FUNCTION:    AcpiDmMatchOp
60328c506b8Sjruoho  *
60428c506b8Sjruoho  * PARAMETERS:  Op              - Match Object to be examined
60528c506b8Sjruoho  *
60628c506b8Sjruoho  * RETURN:      None
60728c506b8Sjruoho  *
60828c506b8Sjruoho  * DESCRIPTION: Decode Match opcode operands
60928c506b8Sjruoho  *
61028c506b8Sjruoho  ******************************************************************************/
61128c506b8Sjruoho 
61228c506b8Sjruoho void
AcpiDmMatchOp(ACPI_PARSE_OBJECT * Op)61328c506b8Sjruoho AcpiDmMatchOp (
61428c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op)
61528c506b8Sjruoho {
61628c506b8Sjruoho     ACPI_PARSE_OBJECT       *NextOp;
61728c506b8Sjruoho 
61828c506b8Sjruoho 
61928c506b8Sjruoho     NextOp = AcpiPsGetDepthNext (NULL, Op);
62028c506b8Sjruoho     NextOp = NextOp->Common.Next;
62128c506b8Sjruoho 
62228c506b8Sjruoho     if (!NextOp)
62328c506b8Sjruoho     {
62428c506b8Sjruoho         /* Handle partial tree during single-step */
62528c506b8Sjruoho 
62628c506b8Sjruoho         return;
62728c506b8Sjruoho     }
62828c506b8Sjruoho 
62928c506b8Sjruoho     /* Mark the two nodes that contain the encoding for the match keywords */
63028c506b8Sjruoho 
63128c506b8Sjruoho     NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;
63228c506b8Sjruoho 
63328c506b8Sjruoho     NextOp = NextOp->Common.Next;
63428c506b8Sjruoho     NextOp = NextOp->Common.Next;
63528c506b8Sjruoho     NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;
63628c506b8Sjruoho }
63728c506b8Sjruoho 
63828c506b8Sjruoho 
63928c506b8Sjruoho /*******************************************************************************
64028c506b8Sjruoho  *
64128c506b8Sjruoho  * FUNCTION:    AcpiDmMatchKeyword
64228c506b8Sjruoho  *
64328c506b8Sjruoho  * PARAMETERS:  Op              - Match Object to be examined
64428c506b8Sjruoho  *
64528c506b8Sjruoho  * RETURN:      None
64628c506b8Sjruoho  *
64728c506b8Sjruoho  * DESCRIPTION: Decode Match opcode operands
64828c506b8Sjruoho  *
64928c506b8Sjruoho  ******************************************************************************/
65028c506b8Sjruoho 
65128c506b8Sjruoho static void
AcpiDmMatchKeyword(ACPI_PARSE_OBJECT * Op)65228c506b8Sjruoho AcpiDmMatchKeyword (
65328c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op)
65428c506b8Sjruoho {
65528c506b8Sjruoho 
65628c506b8Sjruoho     if (((UINT32) Op->Common.Value.Integer) > ACPI_MAX_MATCH_OPCODE)
65728c506b8Sjruoho     {
65828c506b8Sjruoho         AcpiOsPrintf ("/* Unknown Match Keyword encoding */");
65928c506b8Sjruoho     }
66028c506b8Sjruoho     else
66128c506b8Sjruoho     {
662cfbb7280Schristos         AcpiOsPrintf ("%s",
663cfbb7280Schristos             AcpiGbl_MatchOps[(ACPI_SIZE) Op->Common.Value.Integer]);
66428c506b8Sjruoho     }
66528c506b8Sjruoho }
66628c506b8Sjruoho 
66728c506b8Sjruoho 
66828c506b8Sjruoho /*******************************************************************************
66928c506b8Sjruoho  *
67028c506b8Sjruoho  * FUNCTION:    AcpiDmDisassembleOneOp
67128c506b8Sjruoho  *
67228c506b8Sjruoho  * PARAMETERS:  WalkState           - Current walk info
67328c506b8Sjruoho  *              Info                - Parse tree walk info
67428c506b8Sjruoho  *              Op                  - Op that is to be printed
67528c506b8Sjruoho  *
67628c506b8Sjruoho  * RETURN:      None
67728c506b8Sjruoho  *
67828c506b8Sjruoho  * DESCRIPTION: Disassemble a single AML opcode
67928c506b8Sjruoho  *
68028c506b8Sjruoho  ******************************************************************************/
68128c506b8Sjruoho 
68228c506b8Sjruoho void
AcpiDmDisassembleOneOp(ACPI_WALK_STATE * WalkState,ACPI_OP_WALK_INFO * Info,ACPI_PARSE_OBJECT * Op)68328c506b8Sjruoho AcpiDmDisassembleOneOp (
68428c506b8Sjruoho     ACPI_WALK_STATE         *WalkState,
68528c506b8Sjruoho     ACPI_OP_WALK_INFO       *Info,
68628c506b8Sjruoho     ACPI_PARSE_OBJECT       *Op)
68728c506b8Sjruoho {
68828c506b8Sjruoho     const ACPI_OPCODE_INFO  *OpInfo = NULL;
68928c506b8Sjruoho     UINT32                  Offset;
69028c506b8Sjruoho     UINT32                  Length;
69128c506b8Sjruoho     ACPI_PARSE_OBJECT       *Child;
69228c506b8Sjruoho     ACPI_STATUS             Status;
693ff4a156dSchristos     UINT8                   *Aml;
694460301d4Schristos     const AH_DEVICE_ID      *IdInfo;
69528c506b8Sjruoho 
69628c506b8Sjruoho 
69728c506b8Sjruoho     if (!Op)
69828c506b8Sjruoho     {
69928c506b8Sjruoho         AcpiOsPrintf ("<NULL OP PTR>");
70028c506b8Sjruoho         return;
70128c506b8Sjruoho     }
70228c506b8Sjruoho 
70371e38f1dSchristos     if (Op->Common.DisasmFlags & ACPI_PARSEOP_ELSEIF)
70471e38f1dSchristos     {
70571e38f1dSchristos         return; /* ElseIf macro was already emitted */
70671e38f1dSchristos     }
70771e38f1dSchristos 
70828c506b8Sjruoho     switch (Op->Common.DisasmOpcode)
70928c506b8Sjruoho     {
71028c506b8Sjruoho     case ACPI_DASM_MATCHOP:
71128c506b8Sjruoho 
71228c506b8Sjruoho         AcpiDmMatchKeyword (Op);
71328c506b8Sjruoho         return;
71428c506b8Sjruoho 
71528c506b8Sjruoho     case ACPI_DASM_LNOT_SUFFIX:
716ff4a156dSchristos 
717679c17fdSchristos         if (!AcpiGbl_CstyleDisassembly)
718679c17fdSchristos         {
71928c506b8Sjruoho             switch (Op->Common.AmlOpcode)
72028c506b8Sjruoho             {
721835858a6Schristos             case AML_LOGICAL_EQUAL_OP:
72228c506b8Sjruoho                 AcpiOsPrintf ("LNotEqual");
72328c506b8Sjruoho                 break;
72428c506b8Sjruoho 
725835858a6Schristos             case AML_LOGICAL_GREATER_OP:
72628c506b8Sjruoho                 AcpiOsPrintf ("LLessEqual");
72728c506b8Sjruoho                 break;
72828c506b8Sjruoho 
729835858a6Schristos             case AML_LOGICAL_LESS_OP:
73028c506b8Sjruoho                 AcpiOsPrintf ("LGreaterEqual");
73128c506b8Sjruoho                 break;
73228c506b8Sjruoho 
73328c506b8Sjruoho             default:
73428c506b8Sjruoho                 break;
73528c506b8Sjruoho             }
736679c17fdSchristos         }
737679c17fdSchristos 
73828c506b8Sjruoho         Op->Common.DisasmOpcode = 0;
73928c506b8Sjruoho         Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
74028c506b8Sjruoho         return;
74128c506b8Sjruoho 
74228c506b8Sjruoho     default:
74328c506b8Sjruoho         break;
74428c506b8Sjruoho     }
74528c506b8Sjruoho 
74628c506b8Sjruoho     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
74728c506b8Sjruoho 
74828c506b8Sjruoho     /* The op and arguments */
74928c506b8Sjruoho 
75028c506b8Sjruoho     switch (Op->Common.AmlOpcode)
75128c506b8Sjruoho     {
752835858a6Schristos     case AML_LOGICAL_NOT_OP:
75328c506b8Sjruoho 
75428c506b8Sjruoho         Child = Op->Common.Value.Arg;
755835858a6Schristos         if ((Child->Common.AmlOpcode == AML_LOGICAL_EQUAL_OP) ||
756835858a6Schristos             (Child->Common.AmlOpcode == AML_LOGICAL_GREATER_OP) ||
757835858a6Schristos             (Child->Common.AmlOpcode == AML_LOGICAL_LESS_OP))
75828c506b8Sjruoho         {
75928c506b8Sjruoho             Child->Common.DisasmOpcode = ACPI_DASM_LNOT_SUFFIX;
76028c506b8Sjruoho             Op->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
76128c506b8Sjruoho         }
76228c506b8Sjruoho         else
76328c506b8Sjruoho         {
76428c506b8Sjruoho             AcpiOsPrintf ("%s", OpInfo->Name);
76528c506b8Sjruoho         }
76628c506b8Sjruoho         break;
76728c506b8Sjruoho 
76828c506b8Sjruoho     case AML_BYTE_OP:
76928c506b8Sjruoho 
77028c506b8Sjruoho         AcpiOsPrintf ("0x%2.2X", (UINT32) Op->Common.Value.Integer);
77128c506b8Sjruoho         break;
77228c506b8Sjruoho 
77328c506b8Sjruoho     case AML_WORD_OP:
77428c506b8Sjruoho 
77528c506b8Sjruoho         if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
77628c506b8Sjruoho         {
777460301d4Schristos             AcpiDmDecompressEisaId ((UINT32) Op->Common.Value.Integer);
77828c506b8Sjruoho         }
77928c506b8Sjruoho         else
78028c506b8Sjruoho         {
78128c506b8Sjruoho             AcpiOsPrintf ("0x%4.4X", (UINT32) Op->Common.Value.Integer);
78228c506b8Sjruoho         }
78328c506b8Sjruoho         break;
78428c506b8Sjruoho 
78528c506b8Sjruoho     case AML_DWORD_OP:
78628c506b8Sjruoho 
78728c506b8Sjruoho         if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
78828c506b8Sjruoho         {
789460301d4Schristos             AcpiDmDecompressEisaId ((UINT32) Op->Common.Value.Integer);
79028c506b8Sjruoho         }
79128c506b8Sjruoho         else
79228c506b8Sjruoho         {
79328c506b8Sjruoho             AcpiOsPrintf ("0x%8.8X", (UINT32) Op->Common.Value.Integer);
79428c506b8Sjruoho         }
79528c506b8Sjruoho         break;
79628c506b8Sjruoho 
79728c506b8Sjruoho     case AML_QWORD_OP:
79828c506b8Sjruoho 
79928c506b8Sjruoho         AcpiOsPrintf ("0x%8.8X%8.8X",
80028c506b8Sjruoho             ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
80128c506b8Sjruoho         break;
80228c506b8Sjruoho 
80328c506b8Sjruoho     case AML_STRING_OP:
80428c506b8Sjruoho 
805ff4a156dSchristos         AcpiUtPrintString (Op->Common.Value.String, ACPI_UINT16_MAX);
806460301d4Schristos 
807460301d4Schristos         /* For _HID/_CID strings, attempt to output a descriptive comment */
808460301d4Schristos 
809460301d4Schristos         if (Op->Common.DisasmOpcode == ACPI_DASM_HID_STRING)
810460301d4Schristos         {
811460301d4Schristos             /* If we know about the ID, emit the description */
812460301d4Schristos 
813460301d4Schristos             IdInfo = AcpiAhMatchHardwareId (Op->Common.Value.String);
814460301d4Schristos             if (IdInfo)
815460301d4Schristos             {
816460301d4Schristos                 AcpiOsPrintf (" /* %s */", IdInfo->Description);
817460301d4Schristos             }
818460301d4Schristos         }
81928c506b8Sjruoho         break;
82028c506b8Sjruoho 
82128c506b8Sjruoho     case AML_BUFFER_OP:
82228c506b8Sjruoho         /*
82328c506b8Sjruoho          * Determine the type of buffer. We can have one of the following:
82428c506b8Sjruoho          *
82528c506b8Sjruoho          * 1) ResourceTemplate containing Resource Descriptors.
82628c506b8Sjruoho          * 2) Unicode String buffer
82728c506b8Sjruoho          * 3) ASCII String buffer
82828c506b8Sjruoho          * 4) Raw data buffer (if none of the above)
82928c506b8Sjruoho          *
83028c506b8Sjruoho          * Since there are no special AML opcodes to differentiate these
83128c506b8Sjruoho          * types of buffers, we have to closely look at the data in the
83228c506b8Sjruoho          * buffer to determine the type.
83328c506b8Sjruoho          */
834ff4a156dSchristos         if (!AcpiGbl_NoResourceDisassembly)
835ff4a156dSchristos         {
836ff4a156dSchristos             Status = AcpiDmIsResourceTemplate (WalkState, Op);
83728c506b8Sjruoho             if (ACPI_SUCCESS (Status))
83828c506b8Sjruoho             {
83928c506b8Sjruoho                 Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
84028c506b8Sjruoho                 AcpiOsPrintf ("ResourceTemplate");
84128c506b8Sjruoho                 break;
84228c506b8Sjruoho             }
84328c506b8Sjruoho             else if (Status == AE_AML_NO_RESOURCE_END_TAG)
84428c506b8Sjruoho             {
84571e38f1dSchristos                 AcpiOsPrintf (
84671e38f1dSchristos                     "/**** Is ResourceTemplate, "
84771e38f1dSchristos                     "but EndTag not at buffer end ****/ ");
84828c506b8Sjruoho             }
849ff4a156dSchristos         }
85028c506b8Sjruoho 
851460301d4Schristos         if (AcpiDmIsUuidBuffer (Op))
852460301d4Schristos         {
853460301d4Schristos             Op->Common.DisasmOpcode = ACPI_DASM_UUID;
854460301d4Schristos             AcpiOsPrintf ("ToUUID (");
855460301d4Schristos         }
856460301d4Schristos         else if (AcpiDmIsUnicodeBuffer (Op))
85728c506b8Sjruoho         {
85828c506b8Sjruoho             Op->Common.DisasmOpcode = ACPI_DASM_UNICODE;
85928c506b8Sjruoho             AcpiOsPrintf ("Unicode (");
86028c506b8Sjruoho         }
86128c506b8Sjruoho         else if (AcpiDmIsStringBuffer (Op))
86228c506b8Sjruoho         {
86328c506b8Sjruoho             Op->Common.DisasmOpcode = ACPI_DASM_STRING;
86428c506b8Sjruoho             AcpiOsPrintf ("Buffer");
86528c506b8Sjruoho         }
866ff4a156dSchristos         else if (AcpiDmIsPldBuffer (Op))
867ff4a156dSchristos         {
868ff4a156dSchristos             Op->Common.DisasmOpcode = ACPI_DASM_PLD_METHOD;
869679c17fdSchristos             AcpiOsPrintf ("ToPLD (");
870ff4a156dSchristos         }
87128c506b8Sjruoho         else
87228c506b8Sjruoho         {
87328c506b8Sjruoho             Op->Common.DisasmOpcode = ACPI_DASM_BUFFER;
87428c506b8Sjruoho             AcpiOsPrintf ("Buffer");
87528c506b8Sjruoho         }
87628c506b8Sjruoho         break;
87728c506b8Sjruoho 
87828c506b8Sjruoho     case AML_INT_NAMEPATH_OP:
87928c506b8Sjruoho 
88028c506b8Sjruoho         AcpiDmNamestring (Op->Common.Value.Name);
88128c506b8Sjruoho         break;
88228c506b8Sjruoho 
88328c506b8Sjruoho     case AML_INT_NAMEDFIELD_OP:
88428c506b8Sjruoho 
88528c506b8Sjruoho         Length = AcpiDmDumpName (Op->Named.Name);
886835858a6Schristos 
887835858a6Schristos         AcpiOsPrintf (",");
888835858a6Schristos         ASL_CV_PRINT_ONE_COMMENT (Op, AML_NAMECOMMENT, NULL, 0);
889835858a6Schristos         AcpiOsPrintf ("%*.s  %u", (unsigned) (5 - Length), " ",
89028c506b8Sjruoho             (UINT32) Op->Common.Value.Integer);
891835858a6Schristos 
89228c506b8Sjruoho         AcpiDmCommaIfFieldMember (Op);
89328c506b8Sjruoho 
89428c506b8Sjruoho         Info->BitOffset += (UINT32) Op->Common.Value.Integer;
89528c506b8Sjruoho         break;
89628c506b8Sjruoho 
89728c506b8Sjruoho     case AML_INT_RESERVEDFIELD_OP:
89828c506b8Sjruoho 
89928c506b8Sjruoho         /* Offset() -- Must account for previous offsets */
90028c506b8Sjruoho 
90128c506b8Sjruoho         Offset = (UINT32) Op->Common.Value.Integer;
90228c506b8Sjruoho         Info->BitOffset += Offset;
90328c506b8Sjruoho 
90428c506b8Sjruoho         if (Info->BitOffset % 8 == 0)
90528c506b8Sjruoho         {
90628c506b8Sjruoho             AcpiOsPrintf ("Offset (0x%.2X)", ACPI_DIV_8 (Info->BitOffset));
90728c506b8Sjruoho         }
90828c506b8Sjruoho         else
90928c506b8Sjruoho         {
91028c506b8Sjruoho             AcpiOsPrintf ("    ,   %u", Offset);
91128c506b8Sjruoho         }
91228c506b8Sjruoho 
91328c506b8Sjruoho         AcpiDmCommaIfFieldMember (Op);
91428c506b8Sjruoho         break;
91528c506b8Sjruoho 
91628c506b8Sjruoho     case AML_INT_ACCESSFIELD_OP:
917ff4a156dSchristos     case AML_INT_EXTACCESSFIELD_OP:
91828c506b8Sjruoho 
91928c506b8Sjruoho         AcpiOsPrintf ("AccessAs (%s, ",
920ff4a156dSchristos             AcpiGbl_AccessTypes [(UINT32) (Op->Common.Value.Integer & 0x7)]);
92128c506b8Sjruoho 
922ff4a156dSchristos         AcpiDmDecodeAttribute ((UINT8) (Op->Common.Value.Integer >> 8));
923ff4a156dSchristos 
924ff4a156dSchristos         if (Op->Common.AmlOpcode == AML_INT_EXTACCESSFIELD_OP)
925ff4a156dSchristos         {
92671e38f1dSchristos             AcpiOsPrintf (" (0x%2.2X)", (unsigned)
92771e38f1dSchristos                 ((Op->Common.Value.Integer >> 16) & 0xFF));
928ff4a156dSchristos         }
929ff4a156dSchristos 
93028c506b8Sjruoho         AcpiOsPrintf (")");
93128c506b8Sjruoho         AcpiDmCommaIfFieldMember (Op);
932835858a6Schristos         ASL_CV_PRINT_ONE_COMMENT (Op, AML_COMMENT_END_NODE, NULL, 0);
93328c506b8Sjruoho         break;
93428c506b8Sjruoho 
935ff4a156dSchristos     case AML_INT_CONNECTION_OP:
936ff4a156dSchristos         /*
937ff4a156dSchristos          * Two types of Connection() - one with a buffer object, the
938ff4a156dSchristos          * other with a namestring that points to a buffer object.
939ff4a156dSchristos          */
940ff4a156dSchristos         AcpiOsPrintf ("Connection (");
941ff4a156dSchristos         Child = Op->Common.Value.Arg;
942ff4a156dSchristos 
943ff4a156dSchristos         if (Child->Common.AmlOpcode == AML_INT_BYTELIST_OP)
944ff4a156dSchristos         {
945ff4a156dSchristos             AcpiOsPrintf ("\n");
946ff4a156dSchristos 
947ff4a156dSchristos             Aml = Child->Named.Data;
948ff4a156dSchristos             Length = (UINT32) Child->Common.Value.Integer;
949ff4a156dSchristos 
950ff4a156dSchristos             Info->Level += 1;
951460301d4Schristos             Info->MappingOp = Op;
952ff4a156dSchristos             Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
953460301d4Schristos 
954ff4a156dSchristos             AcpiDmResourceTemplate (Info, Op->Common.Parent, Aml, Length);
955ff4a156dSchristos 
956ff4a156dSchristos             Info->Level -= 1;
957ff4a156dSchristos             AcpiDmIndent (Info->Level);
958ff4a156dSchristos         }
959ff4a156dSchristos         else
960ff4a156dSchristos         {
961ff4a156dSchristos             AcpiDmNamestring (Child->Common.Value.Name);
962ff4a156dSchristos         }
963ff4a156dSchristos 
964ff4a156dSchristos         AcpiOsPrintf (")");
965ff4a156dSchristos         AcpiDmCommaIfFieldMember (Op);
966835858a6Schristos         ASL_CV_PRINT_ONE_COMMENT (Op, AML_COMMENT_END_NODE, NULL, 0);
967835858a6Schristos         ASL_CV_PRINT_ONE_COMMENT (Op, AMLCOMMENT_INLINE, NULL, 0);
968ff4a156dSchristos         AcpiOsPrintf ("\n");
969ff4a156dSchristos 
970ff4a156dSchristos         Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; /* for now, ignore in AcpiDmAscendingOp */
971ff4a156dSchristos         Child->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
972ff4a156dSchristos         break;
97328c506b8Sjruoho 
97428c506b8Sjruoho     case AML_INT_BYTELIST_OP:
97528c506b8Sjruoho 
97628c506b8Sjruoho         AcpiDmByteList (Info, Op);
97728c506b8Sjruoho         break;
97828c506b8Sjruoho 
97928c506b8Sjruoho     case AML_INT_METHODCALL_OP:
98028c506b8Sjruoho 
98128c506b8Sjruoho         Op = AcpiPsGetDepthNext (NULL, Op);
98228c506b8Sjruoho         Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
98328c506b8Sjruoho 
98428c506b8Sjruoho         AcpiDmNamestring (Op->Common.Value.Name);
98528c506b8Sjruoho         break;
98628c506b8Sjruoho 
9870b89cdedSchristos     case AML_WHILE_OP:
9880b89cdedSchristos 
989835858a6Schristos         if (Op->Common.DisasmOpcode == ACPI_DASM_SWITCH)
9900b89cdedSchristos         {
9910b89cdedSchristos             AcpiOsPrintf ("%s", "Switch");
9920b89cdedSchristos             break;
9930b89cdedSchristos         }
9940b89cdedSchristos 
9950b89cdedSchristos         AcpiOsPrintf ("%s", OpInfo->Name);
9960b89cdedSchristos         break;
9970b89cdedSchristos 
9980b89cdedSchristos     case AML_IF_OP:
9990b89cdedSchristos 
10000b89cdedSchristos         if (Op->Common.DisasmOpcode == ACPI_DASM_CASE)
10010b89cdedSchristos         {
10020b89cdedSchristos             AcpiOsPrintf ("%s", "Case");
10030b89cdedSchristos             break;
10040b89cdedSchristos         }
10050b89cdedSchristos 
10060b89cdedSchristos         AcpiOsPrintf ("%s", OpInfo->Name);
10070b89cdedSchristos         break;
10080b89cdedSchristos 
100971e38f1dSchristos     case AML_ELSE_OP:
101071e38f1dSchristos 
101171e38f1dSchristos         AcpiDmConvertToElseIf (Op);
101271e38f1dSchristos         break;
101371e38f1dSchristos 
1014cfbb7280Schristos     case AML_EXTERNAL_OP:
1015cfbb7280Schristos 
1016ae01e9dcSchristos         if (AcpiGbl_DmEmitExternalOpcodes)
1017ae01e9dcSchristos         {
101889b8eb6cSchristos             AcpiDmEmitExternal (Op, AcpiPsGetArg(Op, 0));
1019ae01e9dcSchristos         }
1020cfbb7280Schristos 
1021835858a6Schristos         break;
1022835858a6Schristos 
102328c506b8Sjruoho     default:
102428c506b8Sjruoho 
102528c506b8Sjruoho         /* Just get the opcode name and print it */
102628c506b8Sjruoho 
102728c506b8Sjruoho         AcpiOsPrintf ("%s", OpInfo->Name);
102828c506b8Sjruoho 
102928c506b8Sjruoho 
103028c506b8Sjruoho #ifdef ACPI_DEBUGGER
103128c506b8Sjruoho 
103228c506b8Sjruoho         if ((Op->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP) &&
103328c506b8Sjruoho             (WalkState) &&
103428c506b8Sjruoho             (WalkState->Results) &&
103528c506b8Sjruoho             (WalkState->ResultCount))
103628c506b8Sjruoho         {
1037c72da027Schristos             AcpiDbDecodeInternalObject (
103828c506b8Sjruoho                 WalkState->Results->Results.ObjDesc [
103928c506b8Sjruoho                     (WalkState->ResultCount - 1) %
104028c506b8Sjruoho                         ACPI_RESULTS_FRAME_OBJ_NUM]);
104128c506b8Sjruoho         }
104228c506b8Sjruoho #endif
104328c506b8Sjruoho 
104428c506b8Sjruoho         break;
104528c506b8Sjruoho     }
104628c506b8Sjruoho }
104728c506b8Sjruoho 
104871e38f1dSchristos 
104971e38f1dSchristos /*******************************************************************************
105071e38f1dSchristos  *
105171e38f1dSchristos  * FUNCTION:    AcpiDmConvertToElseIf
105271e38f1dSchristos  *
105371e38f1dSchristos  * PARAMETERS:  OriginalElseOp          - ELSE Object to be examined
105471e38f1dSchristos  *
105571e38f1dSchristos  * RETURN:      None. Emits either an "Else" or an "ElseIf" ASL operator.
105671e38f1dSchristos  *
105771e38f1dSchristos  * DESCRIPTION: Detect and convert an If..Else..If sequence to If..ElseIf
105871e38f1dSchristos  *
105971e38f1dSchristos  * EXAMPLE:
106071e38f1dSchristos  *
106171e38f1dSchristos  * This If..Else..If nested sequence:
106271e38f1dSchristos  *
106371e38f1dSchristos  *        If (Arg0 == 1)
106471e38f1dSchristos  *        {
106571e38f1dSchristos  *            Local0 = 4
106671e38f1dSchristos  *        }
106771e38f1dSchristos  *        Else
106871e38f1dSchristos  *        {
106971e38f1dSchristos  *            If (Arg0 == 2)
107071e38f1dSchristos  *            {
107171e38f1dSchristos  *                Local0 = 5
107271e38f1dSchristos  *            }
107371e38f1dSchristos  *        }
107471e38f1dSchristos  *
107571e38f1dSchristos  * Is converted to this simpler If..ElseIf sequence:
107671e38f1dSchristos  *
107771e38f1dSchristos  *        If (Arg0 == 1)
107871e38f1dSchristos  *        {
107971e38f1dSchristos  *            Local0 = 4
108071e38f1dSchristos  *        }
108171e38f1dSchristos  *        ElseIf (Arg0 == 2)
108271e38f1dSchristos  *        {
108371e38f1dSchristos  *            Local0 = 5
108471e38f1dSchristos  *        }
108571e38f1dSchristos  *
108671e38f1dSchristos  * NOTE: There is no actual ElseIf AML opcode. ElseIf is essentially an ASL
108771e38f1dSchristos  * macro that emits an Else opcode followed by an If opcode. This function
108871e38f1dSchristos  * reverses these AML sequences back to an ElseIf macro where possible. This
108971e38f1dSchristos  * can make the disassembled ASL code simpler and more like the original code.
109071e38f1dSchristos  *
109171e38f1dSchristos  ******************************************************************************/
109271e38f1dSchristos 
109371e38f1dSchristos static void
AcpiDmConvertToElseIf(ACPI_PARSE_OBJECT * OriginalElseOp)109471e38f1dSchristos AcpiDmConvertToElseIf (
109571e38f1dSchristos     ACPI_PARSE_OBJECT       *OriginalElseOp)
109671e38f1dSchristos {
109771e38f1dSchristos     ACPI_PARSE_OBJECT       *IfOp;
109871e38f1dSchristos     ACPI_PARSE_OBJECT       *ElseOp;
109971e38f1dSchristos 
110071e38f1dSchristos 
1101cfbb7280Schristos     /*
1102cfbb7280Schristos      * To be able to perform the conversion, two conditions must be satisfied:
1103cfbb7280Schristos      * 1) The first child of the Else must be an If statement.
1104cfbb7280Schristos      * 2) The If block can only be followed by an Else block and these must
1105cfbb7280Schristos      *    be the only blocks under the original Else.
1106cfbb7280Schristos      */
110771e38f1dSchristos     IfOp = OriginalElseOp->Common.Value.Arg;
1108d0e1da26Schristos 
1109cfbb7280Schristos     if (!IfOp ||
1110cfbb7280Schristos         (IfOp->Common.AmlOpcode != AML_IF_OP) ||
1111cfbb7280Schristos         (IfOp->Asl.Next && (IfOp->Asl.Next->Common.AmlOpcode != AML_ELSE_OP)))
111271e38f1dSchristos     {
1113d0e1da26Schristos         /* Not a proper Else..If sequence, cannot convert to ElseIf */
111471e38f1dSchristos 
11150b89cdedSchristos         if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_DEFAULT)
11160b89cdedSchristos         {
11170b89cdedSchristos             AcpiOsPrintf ("%s", "Default");
11180b89cdedSchristos             return;
11190b89cdedSchristos         }
11200b89cdedSchristos 
112171e38f1dSchristos         AcpiOsPrintf ("%s", "Else");
112271e38f1dSchristos         return;
112371e38f1dSchristos     }
112471e38f1dSchristos 
1125d0e1da26Schristos     /* Cannot have anything following the If...Else block */
1126d0e1da26Schristos 
1127d0e1da26Schristos     ElseOp = IfOp->Common.Next;
1128d0e1da26Schristos     if (ElseOp && ElseOp->Common.Next)
1129d0e1da26Schristos     {
11300b89cdedSchristos         if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_DEFAULT)
11310b89cdedSchristos         {
11320b89cdedSchristos             AcpiOsPrintf ("%s", "Default");
11330b89cdedSchristos             return;
11340b89cdedSchristos         }
11350b89cdedSchristos 
1136d0e1da26Schristos         AcpiOsPrintf ("%s", "Else");
1137d0e1da26Schristos         return;
1138d0e1da26Schristos     }
1139d0e1da26Schristos 
11400b89cdedSchristos     if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_DEFAULT)
11410b89cdedSchristos     {
11420b89cdedSchristos         /*
11430b89cdedSchristos          * There is an ElseIf but in this case the Else is actually
11440b89cdedSchristos          * a Default block for a Switch/Case statement. No conversion.
11450b89cdedSchristos          */
11460b89cdedSchristos         AcpiOsPrintf ("%s", "Default");
11470b89cdedSchristos         return;
11480b89cdedSchristos     }
11490b89cdedSchristos 
11500b89cdedSchristos     if (OriginalElseOp->Common.DisasmOpcode == ACPI_DASM_CASE)
11510b89cdedSchristos     {
11520b89cdedSchristos         /*
11530b89cdedSchristos          * This ElseIf is actually a Case block for a Switch/Case
11540b89cdedSchristos          * statement. Print Case but do not return so that we can
11550b89cdedSchristos          * promote the subtree and keep the indentation level.
11560b89cdedSchristos          */
11570b89cdedSchristos         AcpiOsPrintf ("%s", "Case");
11580b89cdedSchristos     }
11590b89cdedSchristos     else
11600b89cdedSchristos     {
116171e38f1dSchristos        /* Emit ElseIf, mark the IF as now an ELSEIF */
116271e38f1dSchristos 
116371e38f1dSchristos         AcpiOsPrintf ("%s", "ElseIf");
11640b89cdedSchristos     }
11650b89cdedSchristos 
116671e38f1dSchristos     IfOp->Common.DisasmFlags |= ACPI_PARSEOP_ELSEIF;
116771e38f1dSchristos 
116871e38f1dSchristos     /* The IF parent will now be the same as the original ELSE parent */
116971e38f1dSchristos 
117071e38f1dSchristos     IfOp->Common.Parent = OriginalElseOp->Common.Parent;
117171e38f1dSchristos 
117271e38f1dSchristos     /*
117371e38f1dSchristos      * Update the NEXT pointers to restructure the parse tree, essentially
117471e38f1dSchristos      * promoting an If..Else block up to the same level as the original
117571e38f1dSchristos      * Else.
117671e38f1dSchristos      *
117771e38f1dSchristos      * Check if the IF has a corresponding ELSE peer
117871e38f1dSchristos      */
117971e38f1dSchristos     ElseOp = IfOp->Common.Next;
118071e38f1dSchristos     if (ElseOp &&
118171e38f1dSchristos         (ElseOp->Common.AmlOpcode == AML_ELSE_OP))
118271e38f1dSchristos     {
118371e38f1dSchristos         /* If an ELSE matches the IF, promote it also */
118471e38f1dSchristos 
118571e38f1dSchristos         ElseOp->Common.Parent = OriginalElseOp->Common.Parent;
1186d0e1da26Schristos 
1187d0e1da26Schristos         /* Promote the entire block under the ElseIf (All Next OPs) */
1188d0e1da26Schristos 
1189d0e1da26Schristos         AcpiDmPromoteSubtree (OriginalElseOp);
119071e38f1dSchristos     }
119171e38f1dSchristos     else
119271e38f1dSchristos     {
119371e38f1dSchristos         /* Otherwise, set the IF NEXT to the original ELSE NEXT */
119471e38f1dSchristos 
119571e38f1dSchristos         IfOp->Common.Next = OriginalElseOp->Common.Next;
119671e38f1dSchristos     }
119771e38f1dSchristos 
119871e38f1dSchristos     /* Detach the child IF block from the original ELSE */
119971e38f1dSchristos 
120071e38f1dSchristos     OriginalElseOp->Common.Value.Arg = NULL;
120171e38f1dSchristos 
120271e38f1dSchristos     /* Ignore the original ELSE from now on */
120371e38f1dSchristos 
120471e38f1dSchristos     OriginalElseOp->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
120571e38f1dSchristos     OriginalElseOp->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
120671e38f1dSchristos 
120771e38f1dSchristos     /* Insert IF (now ELSEIF) as next peer of the original ELSE */
120871e38f1dSchristos 
120971e38f1dSchristos     OriginalElseOp->Common.Next = IfOp;
121071e38f1dSchristos }
1211d0e1da26Schristos 
1212d0e1da26Schristos 
1213d0e1da26Schristos /*******************************************************************************
1214d0e1da26Schristos  *
1215d0e1da26Schristos  * FUNCTION:    AcpiDmPromoteSubtree
1216d0e1da26Schristos  *
1217d0e1da26Schristos  * PARAMETERS:  StartOpOp           - Original parent of the entire subtree
1218d0e1da26Schristos  *
1219d0e1da26Schristos  * RETURN:      None
1220d0e1da26Schristos  *
1221d0e1da26Schristos  * DESCRIPTION: Promote an entire parse subtree up one level.
1222d0e1da26Schristos  *
1223d0e1da26Schristos  ******************************************************************************/
1224d0e1da26Schristos 
1225d0e1da26Schristos static void
AcpiDmPromoteSubtree(ACPI_PARSE_OBJECT * StartOp)1226d0e1da26Schristos AcpiDmPromoteSubtree (
1227d0e1da26Schristos     ACPI_PARSE_OBJECT       *StartOp)
1228d0e1da26Schristos {
1229d0e1da26Schristos     ACPI_PARSE_OBJECT       *Op;
1230d0e1da26Schristos     ACPI_PARSE_OBJECT       *ParentOp;
1231d0e1da26Schristos 
1232d0e1da26Schristos 
1233d0e1da26Schristos     /* New parent for subtree elements */
1234d0e1da26Schristos 
1235d0e1da26Schristos     ParentOp = StartOp->Common.Parent;
1236d0e1da26Schristos 
1237d0e1da26Schristos     /* First child starts the subtree */
1238d0e1da26Schristos 
1239d0e1da26Schristos     Op = StartOp->Common.Value.Arg;
1240d0e1da26Schristos 
1241d0e1da26Schristos     /* Walk the top-level elements of the subtree */
1242d0e1da26Schristos 
1243d0e1da26Schristos     while (Op)
1244d0e1da26Schristos     {
1245d0e1da26Schristos         Op->Common.Parent = ParentOp;
1246d0e1da26Schristos         if (!Op->Common.Next)
1247d0e1da26Schristos         {
1248d0e1da26Schristos             /* Last Op in list, update its next field */
1249d0e1da26Schristos 
1250d0e1da26Schristos             Op->Common.Next = StartOp->Common.Next;
1251d0e1da26Schristos             break;
1252d0e1da26Schristos         }
1253d0e1da26Schristos         Op = Op->Common.Next;
1254d0e1da26Schristos     }
1255d0e1da26Schristos }
1256