1 /*******************************************************************************
2  *
3  * Module Name: dmutils - AML disassembler utilities
4  *
5  ******************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2015, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #include <contrib/dev/acpica/include/acpi.h>
45 #include <contrib/dev/acpica/include/accommon.h>
46 #include <contrib/dev/acpica/include/amlcode.h>
47 #include <contrib/dev/acpica/include/acdisasm.h>
48 
49 #ifdef ACPI_ASL_COMPILER
50 #include <contrib/dev/acpica/include/acnamesp.h>
51 #endif
52 
53 
54 #define _COMPONENT          ACPI_CA_DEBUGGER
55         ACPI_MODULE_NAME    ("dmutils")
56 
57 
58 /* Data used in keeping track of fields */
59 #if 0
60 const char                      *AcpiGbl_FENames[] =
61 {
62     "skip",
63     "?access?"
64 };              /* FE = Field Element */
65 #endif
66 
67 /* Operators for Match() */
68 
69 const char                      *AcpiGbl_MatchOps[] =
70 {
71     "MTR",
72     "MEQ",
73     "MLE",
74     "MLT",
75     "MGE",
76     "MGT"
77 };
78 
79 /* Access type decoding */
80 
81 const char                      *AcpiGbl_AccessTypes[] =
82 {
83     "AnyAcc",
84     "ByteAcc",
85     "WordAcc",
86     "DWordAcc",
87     "QWordAcc",
88     "BufferAcc",
89     "InvalidAccType",
90     "InvalidAccType"
91 };
92 
93 /* Lock rule decoding */
94 
95 const char                      *AcpiGbl_LockRule[] =
96 {
97     "NoLock",
98     "Lock"
99 };
100 
101 /* Update rule decoding */
102 
103 const char                      *AcpiGbl_UpdateRules[] =
104 {
105     "Preserve",
106     "WriteAsOnes",
107     "WriteAsZeros",
108     "InvalidUpdateRule"
109 };
110 
111 /* Strings used to decode resource descriptors */
112 
113 const char                      *AcpiGbl_WordDecode[] =
114 {
115     "Memory",
116     "IO",
117     "BusNumber",
118     "UnknownResourceType"
119 };
120 
121 const char                      *AcpiGbl_IrqDecode[] =
122 {
123     "IRQNoFlags",
124     "IRQ"
125 };
126 
127 
128 /*******************************************************************************
129  *
130  * FUNCTION:    AcpiDmDecodeAttribute
131  *
132  * PARAMETERS:  Attribute       - Attribute field of AccessAs keyword
133  *
134  * RETURN:      None
135  *
136  * DESCRIPTION: Decode the AccessAs attribute byte. (Mostly SMBus and
137  *              GenericSerialBus stuff.)
138  *
139  ******************************************************************************/
140 
141 void
142 AcpiDmDecodeAttribute (
143     UINT8                   Attribute)
144 {
145 
146     switch (Attribute)
147     {
148     case AML_FIELD_ATTRIB_QUICK:
149 
150         AcpiOsPrintf ("AttribQuick");
151         break;
152 
153     case AML_FIELD_ATTRIB_SEND_RCV:
154 
155         AcpiOsPrintf ("AttribSendReceive");
156         break;
157 
158     case AML_FIELD_ATTRIB_BYTE:
159 
160         AcpiOsPrintf ("AttribByte");
161         break;
162 
163     case AML_FIELD_ATTRIB_WORD:
164 
165         AcpiOsPrintf ("AttribWord");
166         break;
167 
168     case AML_FIELD_ATTRIB_BLOCK:
169 
170         AcpiOsPrintf ("AttribBlock");
171         break;
172 
173     case AML_FIELD_ATTRIB_MULTIBYTE:
174 
175         AcpiOsPrintf ("AttribBytes");
176         break;
177 
178     case AML_FIELD_ATTRIB_WORD_CALL:
179 
180         AcpiOsPrintf ("AttribProcessCall");
181         break;
182 
183     case AML_FIELD_ATTRIB_BLOCK_CALL:
184 
185         AcpiOsPrintf ("AttribBlockProcessCall");
186         break;
187 
188     case AML_FIELD_ATTRIB_RAW_BYTES:
189 
190         AcpiOsPrintf ("AttribRawBytes");
191         break;
192 
193     case AML_FIELD_ATTRIB_RAW_PROCESS:
194 
195         AcpiOsPrintf ("AttribRawProcessBytes");
196         break;
197 
198     default:
199 
200         /* A ByteConst is allowed by the grammar */
201 
202         AcpiOsPrintf ("0x%2.2X", Attribute);
203         break;
204     }
205 }
206 
207 
208 /*******************************************************************************
209  *
210  * FUNCTION:    AcpiDmIndent
211  *
212  * PARAMETERS:  Level               - Current source code indentation level
213  *
214  * RETURN:      None
215  *
216  * DESCRIPTION: Indent 4 spaces per indentation level.
217  *
218  ******************************************************************************/
219 
220 void
221 AcpiDmIndent (
222     UINT32                  Level)
223 {
224 
225     if (!Level)
226     {
227         return;
228     }
229 
230     AcpiOsPrintf ("%*.s", ACPI_MUL_4 (Level), " ");
231 }
232 
233 
234 /*******************************************************************************
235  *
236  * FUNCTION:    AcpiDmCommaIfListMember
237  *
238  * PARAMETERS:  Op              - Current operator/operand
239  *
240  * RETURN:      TRUE if a comma was inserted
241  *
242  * DESCRIPTION: Insert a comma if this Op is a member of an argument list.
243  *
244  ******************************************************************************/
245 
246 BOOLEAN
247 AcpiDmCommaIfListMember (
248     ACPI_PARSE_OBJECT       *Op)
249 {
250 
251     if (!Op->Common.Next)
252     {
253         return (FALSE);
254     }
255 
256     if (AcpiDmListType (Op->Common.Parent) & BLOCK_COMMA_LIST)
257     {
258         /* Exit if Target has been marked IGNORE */
259 
260         if (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_IGNORE)
261         {
262             return (FALSE);
263         }
264 
265         /* Check for a NULL target operand */
266 
267         if ((Op->Common.Next->Common.AmlOpcode == AML_INT_NAMEPATH_OP) &&
268             (!Op->Common.Next->Common.Value.String))
269         {
270             /*
271              * To handle the Divide() case where there are two optional
272              * targets, look ahead one more op. If null, this null target
273              * is the one and only target -- no comma needed. Otherwise,
274              * we need a comma to prepare for the next target.
275              */
276             if (!Op->Common.Next->Common.Next)
277             {
278                 return (FALSE);
279             }
280         }
281 
282         if ((Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST) &&
283             (!(Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST)))
284         {
285             return (FALSE);
286         }
287 
288         /* Emit comma only if this is not a C-style operator */
289 
290         if (!Op->Common.OperatorSymbol)
291         {
292             AcpiOsPrintf (", ");
293         }
294 
295         return (TRUE);
296     }
297 
298     else if ((Op->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST) &&
299              (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMLIST))
300     {
301         AcpiOsPrintf (", ");
302         return (TRUE);
303     }
304 
305     return (FALSE);
306 }
307 
308 
309 /*******************************************************************************
310  *
311  * FUNCTION:    AcpiDmCommaIfFieldMember
312  *
313  * PARAMETERS:  Op              - Current operator/operand
314  *
315  * RETURN:      None
316  *
317  * DESCRIPTION: Insert a comma if this Op is a member of a Field argument list.
318  *
319  ******************************************************************************/
320 
321 void
322 AcpiDmCommaIfFieldMember (
323     ACPI_PARSE_OBJECT       *Op)
324 {
325 
326     if (Op->Common.Next)
327     {
328         AcpiOsPrintf (", ");
329     }
330 }
331