1/*******************************************************************************
2 *
3 * Module Name: dmutils - AML disassembler utilities
4 *
5 ******************************************************************************/
6
7/*
8 * Copyright (C) 2000 - 2016, 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
60const char                      *AcpiGbl_FENames[] =
61{
62    "skip",
63    "?access?"
64};              /* FE = Field Element */
65#endif
66
67/* Operators for Match() */
68
69const char                      *AcpiGbl_MatchOps[] =
70{
71    "MTR",
72    "MEQ",
73    "MLE",
74    "MLT",
75    "MGE",
76    "MGT"
77};
78
79/* Access type decoding */
80
81const 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
95const char                      *AcpiGbl_LockRule[] =
96{
97    "NoLock",
98    "Lock"
99};
100
101/* Update rule decoding */
102
103const char                      *AcpiGbl_UpdateRules[] =
104{
105    "Preserve",
106    "WriteAsOnes",
107    "WriteAsZeros",
108    "InvalidUpdateRule"
109};
110
111/* Strings used to decode resource descriptors */
112
113const char                      *AcpiGbl_WordDecode[] =
114{
115    "Memory",
116    "IO",
117    "BusNumber",
118    "UnknownResourceType"
119};
120
121const 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
141void
142AcpiDmDecodeAttribute (
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
220void
221AcpiDmIndent (
222    UINT32                  Level)
223{
224
225    if (!Level)
226    {
227        return;
228    }
229
230    AcpiOsPrintf ("%*.s", (Level * 4), " ");
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
246BOOLEAN
247AcpiDmCommaIfListMember (
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_PARAMETER_LIST) &&
283            (!(Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST)))
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_PARAMETER_LIST) &&
299             (Op->Common.Next->Common.DisasmFlags & ACPI_PARSEOP_PARAMETER_LIST))
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
321void
322AcpiDmCommaIfFieldMember (
323    ACPI_PARSE_OBJECT       *Op)
324{
325
326    if (Op->Common.Next)
327    {
328        AcpiOsPrintf (", ");
329    }
330}
331