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