]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/contrib/dev/acpica/disassembler/dmopcode.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / contrib / dev / acpica / disassembler / dmopcode.c
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 <contrib/dev/acpica/include/acpi.h>
45 #include <contrib/dev/acpica/include/accommon.h>
46 #include <contrib/dev/acpica/include/acparser.h>
47 #include <contrib/dev/acpica/include/amlcode.h>
48 #include <contrib/dev/acpica/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 */