xref: /titanic_50/usr/src/uts/intel/io/acpica/disassembler/dmopcode.c (revision 45818ee124adeaaf947698996b4f4c722afc6d1f)
1 /*******************************************************************************
2  *
3  * Module Name: dmopcode - AML disassembler, specific AML opcodes
4  *
5  ******************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2011, 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 "acpi.h"
45 #include "accommon.h"
46 #include "acparser.h"
47 #include "amlcode.h"
48 #include "acdisasm.h"
49 
50 #ifdef ACPI_DISASSEMBLER
51 
52 #define _COMPONENT          ACPI_CA_DEBUGGER
53         ACPI_MODULE_NAME    ("dmopcode")
54 
55 /* Local prototypes */
56 
57 static void
58 AcpiDmMatchKeyword (
59     ACPI_PARSE_OBJECT       *Op);
60 
61 
62 /*******************************************************************************
63  *
64  * FUNCTION:    AcpiDmMethodFlags
65  *
66  * PARAMETERS:  Op              - Method Object to be examined
67  *
68  * RETURN:      None
69  *
70  * DESCRIPTION: Decode control method flags
71  *
72  ******************************************************************************/
73 
74 void
75 AcpiDmMethodFlags (
76     ACPI_PARSE_OBJECT       *Op)
77 {
78     UINT32                  Flags;
79     UINT32                  Args;
80 
81 
82     /* The next Op contains the flags */
83 
84     Op = AcpiPsGetDepthNext (NULL, Op);
85     Flags = (UINT8) Op->Common.Value.Integer;
86     Args = Flags & 0x07;
87 
88     /* Mark the Op as completed */
89 
90     Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
91 
92     /* 1) Method argument count */
93 
94     AcpiOsPrintf (", %u, ", Args);
95 
96     /* 2) Serialize rule */
97 
98     if (!(Flags & 0x08))
99     {
100         AcpiOsPrintf ("Not");
101     }
102 
103     AcpiOsPrintf ("Serialized");
104 
105     /* 3) SyncLevel */
106 
107     if (Flags & 0xF0)
108     {
109         AcpiOsPrintf (", %u", Flags >> 4);
110     }
111 }
112 
113 
114 /*******************************************************************************
115  *
116  * FUNCTION:    AcpiDmFieldFlags
117  *
118  * PARAMETERS:  Op              - Field Object to be examined
119  *
120  * RETURN:      None
121  *
122  * DESCRIPTION: Decode Field definition flags
123  *
124  ******************************************************************************/
125 
126 void
127 AcpiDmFieldFlags (
128     ACPI_PARSE_OBJECT       *Op)
129 {
130     UINT32                  Flags;
131 
132 
133     Op = Op->Common.Next;
134     Flags = (UINT8) Op->Common.Value.Integer;
135 
136     /* Mark the Op as completed */
137 
138     Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
139 
140     AcpiOsPrintf ("%s, ", AcpiGbl_AccessTypes [Flags & 0x07]);
141     AcpiOsPrintf ("%s, ", AcpiGbl_LockRule [(Flags & 0x10) >> 4]);
142     AcpiOsPrintf ("%s)",  AcpiGbl_UpdateRules [(Flags & 0x60) >> 5]);
143 }
144 
145 
146 /*******************************************************************************
147  *
148  * FUNCTION:    AcpiDmAddressSpace
149  *
150  * PARAMETERS:  SpaceId         - ID to be translated
151  *
152  * RETURN:      None
153  *
154  * DESCRIPTION: Decode a SpaceId to an AddressSpaceKeyword
155  *
156  ******************************************************************************/
157 
158 void
159 AcpiDmAddressSpace (
160     UINT8                   SpaceId)
161 {
162 
163     if (SpaceId >= ACPI_NUM_PREDEFINED_REGIONS)
164     {
165         if (SpaceId == 0x7F)
166         {
167             AcpiOsPrintf ("FFixedHW, ");
168         }
169         else
170         {
171             AcpiOsPrintf ("0x%.2X, ", SpaceId);
172         }
173     }
174     else
175     {
176         AcpiOsPrintf ("%s, ", AcpiGbl_RegionTypes [SpaceId]);
177     }
178 }
179 
180 
181 /*******************************************************************************
182  *
183  * FUNCTION:    AcpiDmRegionFlags
184  *
185  * PARAMETERS:  Op              - Object to be examined
186  *
187  * RETURN:      None
188  *
189  * DESCRIPTION: Decode OperationRegion flags
190  *
191  ******************************************************************************/
192 
193 void
194 AcpiDmRegionFlags (
195     ACPI_PARSE_OBJECT       *Op)
196 {
197 
198 
199     /* The next Op contains the SpaceId */
200 
201     Op = AcpiPsGetDepthNext (NULL, Op);
202 
203     /* Mark the Op as completed */
204 
205     Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
206 
207     AcpiOsPrintf (", ");
208     AcpiDmAddressSpace ((UINT8) Op->Common.Value.Integer);
209 }
210 
211 
212 /*******************************************************************************
213  *
214  * FUNCTION:    AcpiDmMatchOp
215  *
216  * PARAMETERS:  Op              - Match Object to be examined
217  *
218  * RETURN:      None
219  *
220  * DESCRIPTION: Decode Match opcode operands
221  *
222  ******************************************************************************/
223 
224 void
225 AcpiDmMatchOp (
226     ACPI_PARSE_OBJECT       *Op)
227 {
228     ACPI_PARSE_OBJECT       *NextOp;
229 
230 
231     NextOp = AcpiPsGetDepthNext (NULL, Op);
232     NextOp = NextOp->Common.Next;
233 
234     if (!NextOp)
235     {
236         /* Handle partial tree during single-step */
237 
238         return;
239     }
240 
241     /* Mark the two nodes that contain the encoding for the match keywords */
242 
243     NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;
244 
245     NextOp = NextOp->Common.Next;
246     NextOp = NextOp->Common.Next;
247     NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;
248 }
249 
250 
251 /*******************************************************************************
252  *
253  * FUNCTION:    AcpiDmMatchKeyword
254  *
255  * PARAMETERS:  Op              - Match Object to be examined
256  *
257  * RETURN:      None
258  *
259  * DESCRIPTION: Decode Match opcode operands
260  *
261  ******************************************************************************/
262 
263 static void
264 AcpiDmMatchKeyword (
265     ACPI_PARSE_OBJECT       *Op)
266 {
267 
268 
269     if (((UINT32) Op->Common.Value.Integer) > ACPI_MAX_MATCH_OPCODE)
270     {
271         AcpiOsPrintf ("/* Unknown Match Keyword encoding */");
272     }
273     else
274     {
275         AcpiOsPrintf ("%s", ACPI_CAST_PTR (char,
276             AcpiGbl_MatchOps[(ACPI_SIZE) Op->Common.Value.Integer]));
277     }
278 }
279 
280 
281 /*******************************************************************************
282  *
283  * FUNCTION:    AcpiDmDisassembleOneOp
284  *
285  * PARAMETERS:  WalkState           - Current walk info
286  *              Info                - Parse tree walk info
287  *              Op                  - Op that is to be printed
288  *
289  * RETURN:      None
290  *
291  * DESCRIPTION: Disassemble a single AML opcode
292  *
293  ******************************************************************************/
294 
295 void
296 AcpiDmDisassembleOneOp (
297     ACPI_WALK_STATE         *WalkState,
298     ACPI_OP_WALK_INFO       *Info,
299     ACPI_PARSE_OBJECT       *Op)
300 {
301     const ACPI_OPCODE_INFO  *OpInfo = NULL;
302     UINT32                  Offset;
303     UINT32                  Length;
304     ACPI_PARSE_OBJECT       *Child;
305     ACPI_STATUS             Status;
306 
307 
308     if (!Op)
309     {
310         AcpiOsPrintf ("<NULL OP PTR>");
311         return;
312     }
313 
314     switch (Op->Common.DisasmOpcode)
315     {
316     case ACPI_DASM_MATCHOP:
317 
318         AcpiDmMatchKeyword (Op);
319         return;
320 
321     case ACPI_DASM_LNOT_SUFFIX:
322         switch (Op->Common.AmlOpcode)
323         {
324         case AML_LEQUAL_OP:
325             AcpiOsPrintf ("LNotEqual");
326             break;
327 
328         case AML_LGREATER_OP:
329             AcpiOsPrintf ("LLessEqual");
330             break;
331 
332         case AML_LLESS_OP:
333             AcpiOsPrintf ("LGreaterEqual");
334             break;
335 
336         default:
337             break;
338         }
339         Op->Common.DisasmOpcode = 0;
340         Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
341         return;
342 
343     default:
344         break;
345     }
346 
347 
348     OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
349 
350     /* The op and arguments */
351 
352     switch (Op->Common.AmlOpcode)
353     {
354     case AML_LNOT_OP:
355 
356         Child = Op->Common.Value.Arg;
357         if ((Child->Common.AmlOpcode == AML_LEQUAL_OP) ||
358             (Child->Common.AmlOpcode == AML_LGREATER_OP) ||
359             (Child->Common.AmlOpcode == AML_LLESS_OP))
360         {
361             Child->Common.DisasmOpcode = ACPI_DASM_LNOT_SUFFIX;
362             Op->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
363         }
364         else
365         {
366             AcpiOsPrintf ("%s", OpInfo->Name);
367         }
368         break;
369 
370     case AML_BYTE_OP:
371 
372         AcpiOsPrintf ("0x%2.2X", (UINT32) Op->Common.Value.Integer);
373         break;
374 
375 
376     case AML_WORD_OP:
377 
378         if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
379         {
380             AcpiDmEisaId ((UINT32) Op->Common.Value.Integer);
381         }
382         else
383         {
384             AcpiOsPrintf ("0x%4.4X", (UINT32) Op->Common.Value.Integer);
385         }
386         break;
387 
388 
389     case AML_DWORD_OP:
390 
391         if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
392         {
393             AcpiDmEisaId ((UINT32) Op->Common.Value.Integer);
394         }
395         else
396         {
397             AcpiOsPrintf ("0x%8.8X", (UINT32) Op->Common.Value.Integer);
398         }
399         break;
400 
401 
402     case AML_QWORD_OP:
403 
404         AcpiOsPrintf ("0x%8.8X%8.8X",
405             ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
406         break;
407 
408 
409     case AML_STRING_OP:
410 
411         AcpiUtPrintString (Op->Common.Value.String, ACPI_UINT8_MAX);
412         break;
413 
414 
415     case AML_BUFFER_OP:
416 
417         /*
418          * Determine the type of buffer.  We can have one of the following:
419          *
420          * 1) ResourceTemplate containing Resource Descriptors.
421          * 2) Unicode String buffer
422          * 3) ASCII String buffer
423          * 4) Raw data buffer (if none of the above)
424          *
425          * Since there are no special AML opcodes to differentiate these
426          * types of buffers, we have to closely look at the data in the
427          * buffer to determine the type.
428          */
429         Status = AcpiDmIsResourceTemplate (Op);
430         if (ACPI_SUCCESS (Status))
431         {
432             Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
433             AcpiOsPrintf ("ResourceTemplate");
434             break;
435         }
436         else if (Status == AE_AML_NO_RESOURCE_END_TAG)
437         {
438             AcpiOsPrintf ("/**** Is ResourceTemplate, but EndTag not at buffer end ****/ ");
439         }
440 
441         if (AcpiDmIsUnicodeBuffer (Op))
442         {
443             Op->Common.DisasmOpcode = ACPI_DASM_UNICODE;
444             AcpiOsPrintf ("Unicode (");
445         }
446         else if (AcpiDmIsStringBuffer (Op))
447         {
448             Op->Common.DisasmOpcode = ACPI_DASM_STRING;
449             AcpiOsPrintf ("Buffer");
450         }
451         else
452         {
453             Op->Common.DisasmOpcode = ACPI_DASM_BUFFER;
454             AcpiOsPrintf ("Buffer");
455         }
456         break;
457 
458 
459     case AML_INT_STATICSTRING_OP:
460 
461         if (Op->Common.Value.String)
462         {
463             AcpiOsPrintf ("%s", Op->Common.Value.String);
464         }
465         else
466         {
467             AcpiOsPrintf ("\"<NULL STATIC STRING PTR>\"");
468         }
469         break;
470 
471 
472     case AML_INT_NAMEPATH_OP:
473 
474         AcpiDmNamestring (Op->Common.Value.Name);
475         break;
476 
477 
478     case AML_INT_NAMEDFIELD_OP:
479 
480         Length = AcpiDmDumpName (Op->Named.Name);
481         AcpiOsPrintf (",%*.s  %u", (unsigned) (5 - Length), " ",
482             (UINT32) Op->Common.Value.Integer);
483         AcpiDmCommaIfFieldMember (Op);
484 
485         Info->BitOffset += (UINT32) Op->Common.Value.Integer;
486         break;
487 
488 
489     case AML_INT_RESERVEDFIELD_OP:
490 
491         /* Offset() -- Must account for previous offsets */
492 
493         Offset = (UINT32) Op->Common.Value.Integer;
494         Info->BitOffset += Offset;
495 
496         if (Info->BitOffset % 8 == 0)
497         {
498             AcpiOsPrintf ("        Offset (0x%.2X)", ACPI_DIV_8 (Info->BitOffset));
499         }
500         else
501         {
502             AcpiOsPrintf ("    ,   %u", Offset);
503         }
504 
505         AcpiDmCommaIfFieldMember (Op);
506         break;
507 
508 
509     case AML_INT_ACCESSFIELD_OP:
510 
511         AcpiOsPrintf ("        AccessAs (%s, ",
512             AcpiGbl_AccessTypes [(UINT32) (Op->Common.Value.Integer >> 8) & 0x7]);
513 
514         AcpiDmDecodeAttribute ((UINT8) Op->Common.Value.Integer);
515         AcpiOsPrintf (")");
516         AcpiDmCommaIfFieldMember (Op);
517         break;
518 
519 
520     case AML_INT_BYTELIST_OP:
521 
522         AcpiDmByteList (Info, Op);
523         break;
524 
525 
526     case AML_INT_METHODCALL_OP:
527 
528         Op = AcpiPsGetDepthNext (NULL, Op);
529         Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
530 
531         AcpiDmNamestring (Op->Common.Value.Name);
532         break;
533 
534 
535     default:
536 
537         /* Just get the opcode name and print it */
538 
539         AcpiOsPrintf ("%s", OpInfo->Name);
540 
541 
542 #ifdef ACPI_DEBUGGER
543 
544         if ((Op->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP) &&
545             (WalkState) &&
546             (WalkState->Results) &&
547             (WalkState->ResultCount))
548         {
549             AcpiDmDecodeInternalObject (
550                 WalkState->Results->Results.ObjDesc [
551                     (WalkState->ResultCount - 1) %
552                         ACPI_RESULTS_FRAME_OBJ_NUM]);
553         }
554 #endif
555 
556         break;
557     }
558 }
559 
560 #endif  /* ACPI_DISASSEMBLER */
561