dmopcode.c revision 228110
1238104Sdes/*******************************************************************************
2238104Sdes *
3238104Sdes * Module Name: dmopcode - AML disassembler, specific AML opcodes
4238104Sdes *
5238104Sdes ******************************************************************************/
6238104Sdes
7238104Sdes/*
8238104Sdes * Copyright (C) 2000 - 2011, Intel Corp.
9238104Sdes * All rights reserved.
10238104Sdes *
11238104Sdes * Redistribution and use in source and binary forms, with or without
12238104Sdes * modification, are permitted provided that the following conditions
13238104Sdes * are met:
14238104Sdes * 1. Redistributions of source code must retain the above copyright
15238104Sdes *    notice, this list of conditions, and the following disclaimer,
16238104Sdes *    without modification.
17238104Sdes * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18238104Sdes *    substantially similar to the "NO WARRANTY" disclaimer below
19238104Sdes *    ("Disclaimer") and any redistribution must be conditioned upon
20238104Sdes *    including a substantially similar Disclaimer requirement for further
21238104Sdes *    binary redistribution.
22238104Sdes * 3. Neither the names of the above-listed copyright holders nor the names
23238104Sdes *    of any contributors may be used to endorse or promote products derived
24238104Sdes *    from this software without specific prior written permission.
25238104Sdes *
26238104Sdes * Alternatively, this software may be distributed under the terms of the
27238104Sdes * GNU General Public License ("GPL") version 2 as published by the Free
28238104Sdes * Software Foundation.
29238104Sdes *
30238104Sdes * NO WARRANTY
31238104Sdes * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32238104Sdes * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33238104Sdes * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34238104Sdes * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35238104Sdes * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36238104Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37238104Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38238104Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39238104Sdes * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40238104Sdes * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41238104Sdes * POSSIBILITY OF SUCH DAMAGES.
42238104Sdes */
43238104Sdes
44238104Sdes#include <contrib/dev/acpica/include/acpi.h>
45238104Sdes#include <contrib/dev/acpica/include/accommon.h>
46238104Sdes#include <contrib/dev/acpica/include/acparser.h>
47238104Sdes#include <contrib/dev/acpica/include/amlcode.h>
48238104Sdes#include <contrib/dev/acpica/include/acdisasm.h>
49238104Sdes
50238104Sdes#ifdef ACPI_DISASSEMBLER
51238104Sdes
52238104Sdes#define _COMPONENT          ACPI_CA_DEBUGGER
53238104Sdes        ACPI_MODULE_NAME    ("dmopcode")
54238104Sdes
55238104Sdes/* Local prototypes */
56238104Sdes
57238104Sdesstatic void
58238104SdesAcpiDmMatchKeyword (
59238104Sdes    ACPI_PARSE_OBJECT       *Op);
60238104Sdes
61238104Sdes
62238104Sdes/*******************************************************************************
63238104Sdes *
64238104Sdes * FUNCTION:    AcpiDmMethodFlags
65238104Sdes *
66238104Sdes * PARAMETERS:  Op              - Method Object to be examined
67238104Sdes *
68238104Sdes * RETURN:      None
69238104Sdes *
70238104Sdes * DESCRIPTION: Decode control method flags
71238104Sdes *
72238104Sdes ******************************************************************************/
73238104Sdes
74238104Sdesvoid
75238104SdesAcpiDmMethodFlags (
76238104Sdes    ACPI_PARSE_OBJECT       *Op)
77238104Sdes{
78238104Sdes    UINT32                  Flags;
79238104Sdes    UINT32                  Args;
80238104Sdes
81238104Sdes
82238104Sdes    /* The next Op contains the flags */
83238104Sdes
84238104Sdes    Op = AcpiPsGetDepthNext (NULL, Op);
85238104Sdes    Flags = (UINT8) Op->Common.Value.Integer;
86238104Sdes    Args = Flags & 0x07;
87238104Sdes
88238104Sdes    /* Mark the Op as completed */
89238104Sdes
90238104Sdes    Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
91238104Sdes
92238104Sdes    /* 1) Method argument count */
93238104Sdes
94238104Sdes    AcpiOsPrintf (", %u, ", Args);
95238104Sdes
96238104Sdes    /* 2) Serialize rule */
97238104Sdes
98238104Sdes    if (!(Flags & 0x08))
99238104Sdes    {
100238104Sdes        AcpiOsPrintf ("Not");
101238104Sdes    }
102238104Sdes
103238104Sdes    AcpiOsPrintf ("Serialized");
104238104Sdes
105238104Sdes    /* 3) SyncLevel */
106238104Sdes
107238104Sdes    if (Flags & 0xF0)
108238104Sdes    {
109238104Sdes        AcpiOsPrintf (", %u", Flags >> 4);
110238104Sdes    }
111238104Sdes}
112238104Sdes
113238104Sdes
114238104Sdes/*******************************************************************************
115238104Sdes *
116238104Sdes * FUNCTION:    AcpiDmFieldFlags
117238104Sdes *
118238104Sdes * PARAMETERS:  Op              - Field Object to be examined
119238104Sdes *
120238104Sdes * RETURN:      None
121238104Sdes *
122238104Sdes * DESCRIPTION: Decode Field definition flags
123238104Sdes *
124238104Sdes ******************************************************************************/
125238104Sdes
126238104Sdesvoid
127238104SdesAcpiDmFieldFlags (
128238104Sdes    ACPI_PARSE_OBJECT       *Op)
129238104Sdes{
130238104Sdes    UINT32                  Flags;
131238104Sdes
132238104Sdes
133238104Sdes    Op = Op->Common.Next;
134238104Sdes    Flags = (UINT8) Op->Common.Value.Integer;
135238104Sdes
136238104Sdes    /* Mark the Op as completed */
137238104Sdes
138238104Sdes    Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
139238104Sdes
140238104Sdes    AcpiOsPrintf ("%s, ", AcpiGbl_AccessTypes [Flags & 0x07]);
141238104Sdes    AcpiOsPrintf ("%s, ", AcpiGbl_LockRule [(Flags & 0x10) >> 4]);
142238104Sdes    AcpiOsPrintf ("%s)",  AcpiGbl_UpdateRules [(Flags & 0x60) >> 5]);
143238104Sdes}
144238104Sdes
145238104Sdes
146238104Sdes/*******************************************************************************
147238104Sdes *
148238104Sdes * FUNCTION:    AcpiDmAddressSpace
149238104Sdes *
150238104Sdes * PARAMETERS:  SpaceId         - ID to be translated
151238104Sdes *
152238104Sdes * RETURN:      None
153238104Sdes *
154238104Sdes * DESCRIPTION: Decode a SpaceId to an AddressSpaceKeyword
155238104Sdes *
156238104Sdes ******************************************************************************/
157238104Sdes
158238104Sdesvoid
159238104SdesAcpiDmAddressSpace (
160238104Sdes    UINT8                   SpaceId)
161238104Sdes{
162238104Sdes
163238104Sdes    if (SpaceId >= ACPI_NUM_PREDEFINED_REGIONS)
164238104Sdes    {
165238104Sdes        if (SpaceId == 0x7F)
166238104Sdes        {
167238104Sdes            AcpiOsPrintf ("FFixedHW, ");
168238104Sdes        }
169238104Sdes        else
170238104Sdes        {
171238104Sdes            AcpiOsPrintf ("0x%.2X, ", SpaceId);
172238104Sdes        }
173238104Sdes    }
174238104Sdes    else
175238104Sdes    {
176238104Sdes        AcpiOsPrintf ("%s, ", AcpiGbl_RegionTypes [SpaceId]);
177238104Sdes    }
178238104Sdes}
179238104Sdes
180238104Sdes
181238104Sdes/*******************************************************************************
182238104Sdes *
183238104Sdes * FUNCTION:    AcpiDmRegionFlags
184238104Sdes *
185238104Sdes * PARAMETERS:  Op              - Object to be examined
186238104Sdes *
187238104Sdes * RETURN:      None
188238104Sdes *
189238104Sdes * DESCRIPTION: Decode OperationRegion flags
190238104Sdes *
191238104Sdes ******************************************************************************/
192238104Sdes
193238104Sdesvoid
194238104SdesAcpiDmRegionFlags (
195238104Sdes    ACPI_PARSE_OBJECT       *Op)
196238104Sdes{
197238104Sdes
198238104Sdes
199238104Sdes    /* The next Op contains the SpaceId */
200238104Sdes
201238104Sdes    Op = AcpiPsGetDepthNext (NULL, Op);
202238104Sdes
203238104Sdes    /* Mark the Op as completed */
204238104Sdes
205238104Sdes    Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
206238104Sdes
207238104Sdes    AcpiOsPrintf (", ");
208238104Sdes    AcpiDmAddressSpace ((UINT8) Op->Common.Value.Integer);
209238104Sdes}
210238104Sdes
211238104Sdes
212238104Sdes/*******************************************************************************
213238104Sdes *
214238104Sdes * FUNCTION:    AcpiDmMatchOp
215238104Sdes *
216238104Sdes * PARAMETERS:  Op              - Match Object to be examined
217238104Sdes *
218238104Sdes * RETURN:      None
219238104Sdes *
220238104Sdes * DESCRIPTION: Decode Match opcode operands
221238104Sdes *
222238104Sdes ******************************************************************************/
223238104Sdes
224238104Sdesvoid
225238104SdesAcpiDmMatchOp (
226238104Sdes    ACPI_PARSE_OBJECT       *Op)
227238104Sdes{
228238104Sdes    ACPI_PARSE_OBJECT       *NextOp;
229238104Sdes
230238104Sdes
231238104Sdes    NextOp = AcpiPsGetDepthNext (NULL, Op);
232238104Sdes    NextOp = NextOp->Common.Next;
233238104Sdes
234238104Sdes    if (!NextOp)
235238104Sdes    {
236238104Sdes        /* Handle partial tree during single-step */
237238104Sdes
238238104Sdes        return;
239238104Sdes    }
240238104Sdes
241238104Sdes    /* Mark the two nodes that contain the encoding for the match keywords */
242238104Sdes
243238104Sdes    NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;
244238104Sdes
245238104Sdes    NextOp = NextOp->Common.Next;
246238104Sdes    NextOp = NextOp->Common.Next;
247238104Sdes    NextOp->Common.DisasmOpcode = ACPI_DASM_MATCHOP;
248238104Sdes}
249238104Sdes
250238104Sdes
251238104Sdes/*******************************************************************************
252238104Sdes *
253238104Sdes * FUNCTION:    AcpiDmMatchKeyword
254238104Sdes *
255238104Sdes * PARAMETERS:  Op              - Match Object to be examined
256238104Sdes *
257238104Sdes * RETURN:      None
258238104Sdes *
259238104Sdes * DESCRIPTION: Decode Match opcode operands
260238104Sdes *
261238104Sdes ******************************************************************************/
262238104Sdes
263238104Sdesstatic void
264238104SdesAcpiDmMatchKeyword (
265238104Sdes    ACPI_PARSE_OBJECT       *Op)
266238104Sdes{
267238104Sdes
268238104Sdes
269238104Sdes    if (((UINT32) Op->Common.Value.Integer) > ACPI_MAX_MATCH_OPCODE)
270238104Sdes    {
271238104Sdes        AcpiOsPrintf ("/* Unknown Match Keyword encoding */");
272238104Sdes    }
273238104Sdes    else
274238104Sdes    {
275238104Sdes        AcpiOsPrintf ("%s", ACPI_CAST_PTR (char,
276238104Sdes            AcpiGbl_MatchOps[(ACPI_SIZE) Op->Common.Value.Integer]));
277238104Sdes    }
278238104Sdes}
279238104Sdes
280238104Sdes
281238104Sdes/*******************************************************************************
282238104Sdes *
283238104Sdes * FUNCTION:    AcpiDmDisassembleOneOp
284238104Sdes *
285238104Sdes * PARAMETERS:  WalkState           - Current walk info
286238104Sdes *              Info                - Parse tree walk info
287238104Sdes *              Op                  - Op that is to be printed
288238104Sdes *
289238104Sdes * RETURN:      None
290238104Sdes *
291238104Sdes * DESCRIPTION: Disassemble a single AML opcode
292238104Sdes *
293238104Sdes ******************************************************************************/
294238104Sdes
295238104Sdesvoid
296238104SdesAcpiDmDisassembleOneOp (
297238104Sdes    ACPI_WALK_STATE         *WalkState,
298238104Sdes    ACPI_OP_WALK_INFO       *Info,
299238104Sdes    ACPI_PARSE_OBJECT       *Op)
300238104Sdes{
301238104Sdes    const ACPI_OPCODE_INFO  *OpInfo = NULL;
302238104Sdes    UINT32                  Offset;
303238104Sdes    UINT32                  Length;
304238104Sdes    ACPI_PARSE_OBJECT       *Child;
305238104Sdes    ACPI_STATUS             Status;
306238104Sdes    UINT8                   *Aml;
307238104Sdes
308238104Sdes
309238104Sdes    if (!Op)
310238104Sdes    {
311238104Sdes        AcpiOsPrintf ("<NULL OP PTR>");
312238104Sdes        return;
313238104Sdes    }
314238104Sdes
315238104Sdes    switch (Op->Common.DisasmOpcode)
316238104Sdes    {
317238104Sdes    case ACPI_DASM_MATCHOP:
318238104Sdes
319238104Sdes        AcpiDmMatchKeyword (Op);
320238104Sdes        return;
321238104Sdes
322238104Sdes    case ACPI_DASM_LNOT_SUFFIX:
323238104Sdes        switch (Op->Common.AmlOpcode)
324238104Sdes        {
325238104Sdes        case AML_LEQUAL_OP:
326238104Sdes            AcpiOsPrintf ("LNotEqual");
327238104Sdes            break;
328238104Sdes
329238104Sdes        case AML_LGREATER_OP:
330238104Sdes            AcpiOsPrintf ("LLessEqual");
331238104Sdes            break;
332238104Sdes
333238104Sdes        case AML_LLESS_OP:
334238104Sdes            AcpiOsPrintf ("LGreaterEqual");
335238104Sdes            break;
336238104Sdes
337238104Sdes        default:
338238104Sdes            break;
339238104Sdes        }
340238104Sdes        Op->Common.DisasmOpcode = 0;
341238104Sdes        Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
342238104Sdes        return;
343238104Sdes
344238104Sdes    default:
345238104Sdes        break;
346238104Sdes    }
347238104Sdes
348238104Sdes
349238104Sdes    OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
350238104Sdes
351238104Sdes    /* The op and arguments */
352238104Sdes
353238104Sdes    switch (Op->Common.AmlOpcode)
354238104Sdes    {
355238104Sdes    case AML_LNOT_OP:
356238104Sdes
357238104Sdes        Child = Op->Common.Value.Arg;
358238104Sdes        if ((Child->Common.AmlOpcode == AML_LEQUAL_OP) ||
359238104Sdes            (Child->Common.AmlOpcode == AML_LGREATER_OP) ||
360238104Sdes            (Child->Common.AmlOpcode == AML_LLESS_OP))
361238104Sdes        {
362238104Sdes            Child->Common.DisasmOpcode = ACPI_DASM_LNOT_SUFFIX;
363238104Sdes            Op->Common.DisasmOpcode = ACPI_DASM_LNOT_PREFIX;
364        }
365        else
366        {
367            AcpiOsPrintf ("%s", OpInfo->Name);
368        }
369        break;
370
371    case AML_BYTE_OP:
372
373        AcpiOsPrintf ("0x%2.2X", (UINT32) Op->Common.Value.Integer);
374        break;
375
376
377    case AML_WORD_OP:
378
379        if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
380        {
381            AcpiDmEisaId ((UINT32) Op->Common.Value.Integer);
382        }
383        else
384        {
385            AcpiOsPrintf ("0x%4.4X", (UINT32) Op->Common.Value.Integer);
386        }
387        break;
388
389
390    case AML_DWORD_OP:
391
392        if (Op->Common.DisasmOpcode == ACPI_DASM_EISAID)
393        {
394            AcpiDmEisaId ((UINT32) Op->Common.Value.Integer);
395        }
396        else
397        {
398            AcpiOsPrintf ("0x%8.8X", (UINT32) Op->Common.Value.Integer);
399        }
400        break;
401
402
403    case AML_QWORD_OP:
404
405        AcpiOsPrintf ("0x%8.8X%8.8X",
406            ACPI_FORMAT_UINT64 (Op->Common.Value.Integer));
407        break;
408
409
410    case AML_STRING_OP:
411
412        AcpiUtPrintString (Op->Common.Value.String, ACPI_UINT8_MAX);
413        break;
414
415
416    case AML_BUFFER_OP:
417
418        /*
419         * Determine the type of buffer.  We can have one of the following:
420         *
421         * 1) ResourceTemplate containing Resource Descriptors.
422         * 2) Unicode String buffer
423         * 3) ASCII String buffer
424         * 4) Raw data buffer (if none of the above)
425         *
426         * Since there are no special AML opcodes to differentiate these
427         * types of buffers, we have to closely look at the data in the
428         * buffer to determine the type.
429         */
430        if (!AcpiGbl_NoResourceDisassembly)
431        {
432            Status = AcpiDmIsResourceTemplate (Op);
433            if (ACPI_SUCCESS (Status))
434            {
435                Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
436                AcpiOsPrintf ("ResourceTemplate");
437                break;
438            }
439            else if (Status == AE_AML_NO_RESOURCE_END_TAG)
440            {
441                AcpiOsPrintf ("/**** Is ResourceTemplate, but EndTag not at buffer end ****/ ");
442            }
443        }
444
445        if (AcpiDmIsUnicodeBuffer (Op))
446        {
447            Op->Common.DisasmOpcode = ACPI_DASM_UNICODE;
448            AcpiOsPrintf ("Unicode (");
449        }
450        else if (AcpiDmIsStringBuffer (Op))
451        {
452            Op->Common.DisasmOpcode = ACPI_DASM_STRING;
453            AcpiOsPrintf ("Buffer");
454        }
455        else
456        {
457            Op->Common.DisasmOpcode = ACPI_DASM_BUFFER;
458            AcpiOsPrintf ("Buffer");
459        }
460        break;
461
462
463    case AML_INT_STATICSTRING_OP:
464
465        if (Op->Common.Value.String)
466        {
467            AcpiOsPrintf ("%s", Op->Common.Value.String);
468        }
469        else
470        {
471            AcpiOsPrintf ("\"<NULL STATIC STRING PTR>\"");
472        }
473        break;
474
475
476    case AML_INT_NAMEPATH_OP:
477
478        AcpiDmNamestring (Op->Common.Value.Name);
479        break;
480
481
482    case AML_INT_NAMEDFIELD_OP:
483
484        Length = AcpiDmDumpName (Op->Named.Name);
485        AcpiOsPrintf (",%*.s  %u", (unsigned) (5 - Length), " ",
486            (UINT32) Op->Common.Value.Integer);
487        AcpiDmCommaIfFieldMember (Op);
488
489        Info->BitOffset += (UINT32) Op->Common.Value.Integer;
490        break;
491
492
493    case AML_INT_RESERVEDFIELD_OP:
494
495        /* Offset() -- Must account for previous offsets */
496
497        Offset = (UINT32) Op->Common.Value.Integer;
498        Info->BitOffset += Offset;
499
500        if (Info->BitOffset % 8 == 0)
501        {
502            AcpiOsPrintf ("Offset (0x%.2X)", ACPI_DIV_8 (Info->BitOffset));
503        }
504        else
505        {
506            AcpiOsPrintf ("    ,   %u", Offset);
507        }
508
509        AcpiDmCommaIfFieldMember (Op);
510        break;
511
512
513    case AML_INT_ACCESSFIELD_OP:
514    case AML_INT_EXTACCESSFIELD_OP:
515
516        AcpiOsPrintf ("AccessAs (%s, ",
517            AcpiGbl_AccessTypes [(UINT32) (Op->Common.Value.Integer & 0x7)]);
518
519        AcpiDmDecodeAttribute ((UINT8) (Op->Common.Value.Integer >> 8));
520
521        if (Op->Common.AmlOpcode == AML_INT_EXTACCESSFIELD_OP)
522        {
523            AcpiOsPrintf (" (0x%2.2X)", (unsigned) ((Op->Common.Value.Integer >> 16) & 0xFF));
524        }
525
526        AcpiOsPrintf (")");
527        AcpiDmCommaIfFieldMember (Op);
528        break;
529
530
531    case AML_INT_CONNECTION_OP:
532
533        /*
534         * Two types of Connection() - one with a buffer object, the
535         * other with a namestring that points to a buffer object.
536         */
537        AcpiOsPrintf ("Connection (");
538        Child = Op->Common.Value.Arg;
539
540        if (Child->Common.AmlOpcode == AML_INT_BYTELIST_OP)
541        {
542            AcpiOsPrintf ("\n");
543
544            Aml = Child->Named.Data;
545            Length = (UINT32) Child->Common.Value.Integer;
546
547            Info->Level += 1;
548            Op->Common.DisasmOpcode = ACPI_DASM_RESOURCE;
549            AcpiDmResourceTemplate (Info, Op->Common.Parent, Aml, Length);
550
551            Info->Level -= 1;
552            AcpiDmIndent (Info->Level);
553        }
554        else
555        {
556            AcpiDmNamestring (Child->Common.Value.Name);
557        }
558
559        AcpiOsPrintf (")");
560        AcpiDmCommaIfFieldMember (Op);
561        AcpiOsPrintf ("\n");
562
563        Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE; /* for now, ignore in AcpiDmAscendingOp */
564        Child->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
565        break;
566
567    case AML_INT_BYTELIST_OP:
568
569        AcpiDmByteList (Info, Op);
570        break;
571
572
573    case AML_INT_METHODCALL_OP:
574
575        Op = AcpiPsGetDepthNext (NULL, Op);
576        Op->Common.DisasmFlags |= ACPI_PARSEOP_IGNORE;
577
578        AcpiDmNamestring (Op->Common.Value.Name);
579        break;
580
581
582    default:
583
584        /* Just get the opcode name and print it */
585
586        AcpiOsPrintf ("%s", OpInfo->Name);
587
588
589#ifdef ACPI_DEBUGGER
590
591        if ((Op->Common.AmlOpcode == AML_INT_RETURN_VALUE_OP) &&
592            (WalkState) &&
593            (WalkState->Results) &&
594            (WalkState->ResultCount))
595        {
596            AcpiDmDecodeInternalObject (
597                WalkState->Results->Results.ObjDesc [
598                    (WalkState->ResultCount - 1) %
599                        ACPI_RESULTS_FRAME_OBJ_NUM]);
600        }
601#endif
602
603        break;
604    }
605}
606
607#endif  /* ACPI_DISASSEMBLER */
608