dbobject.c revision 306536
1/*******************************************************************************
2 *
3 * Module Name: dbobject - ACPI object decode and display
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/acnamesp.h>
47#include <contrib/dev/acpica/include/acdebug.h>
48
49
50#define _COMPONENT          ACPI_CA_DEBUGGER
51        ACPI_MODULE_NAME    ("dbobject")
52
53
54/* Local prototypes */
55
56static void
57AcpiDbDecodeNode (
58    ACPI_NAMESPACE_NODE     *Node);
59
60
61/*******************************************************************************
62 *
63 * FUNCTION:    AcpiDbDumpMethodInfo
64 *
65 * PARAMETERS:  Status          - Method execution status
66 *              WalkState       - Current state of the parse tree walk
67 *
68 * RETURN:      None
69 *
70 * DESCRIPTION: Called when a method has been aborted because of an error.
71 *              Dumps the method execution stack, and the method locals/args,
72 *              and disassembles the AML opcode that failed.
73 *
74 ******************************************************************************/
75
76void
77AcpiDbDumpMethodInfo (
78    ACPI_STATUS             Status,
79    ACPI_WALK_STATE         *WalkState)
80{
81    ACPI_THREAD_STATE       *Thread;
82
83
84    /* Ignore control codes, they are not errors */
85
86    if ((Status & AE_CODE_MASK) == AE_CODE_CONTROL)
87    {
88        return;
89    }
90
91    /* We may be executing a deferred opcode */
92
93    if (WalkState->DeferredNode)
94    {
95        AcpiOsPrintf ("Executing subtree for Buffer/Package/Region\n");
96        return;
97    }
98
99    /*
100     * If there is no Thread, we are not actually executing a method.
101     * This can happen when the iASL compiler calls the interpreter
102     * to perform constant folding.
103     */
104    Thread = WalkState->Thread;
105    if (!Thread)
106    {
107        return;
108    }
109
110    /* Display the method locals and arguments */
111
112    AcpiOsPrintf ("\n");
113    AcpiDbDecodeLocals (WalkState);
114    AcpiOsPrintf ("\n");
115    AcpiDbDecodeArguments (WalkState);
116    AcpiOsPrintf ("\n");
117}
118
119
120/*******************************************************************************
121 *
122 * FUNCTION:    AcpiDbDecodeInternalObject
123 *
124 * PARAMETERS:  ObjDesc         - Object to be displayed
125 *
126 * RETURN:      None
127 *
128 * DESCRIPTION: Short display of an internal object. Numbers/Strings/Buffers.
129 *
130 ******************************************************************************/
131
132void
133AcpiDbDecodeInternalObject (
134    ACPI_OPERAND_OBJECT     *ObjDesc)
135{
136    UINT32                  i;
137
138
139    if (!ObjDesc)
140    {
141        AcpiOsPrintf (" Uninitialized");
142        return;
143    }
144
145    if (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc) != ACPI_DESC_TYPE_OPERAND)
146    {
147        AcpiOsPrintf (" %p [%s]", ObjDesc,
148            AcpiUtGetDescriptorName (ObjDesc));
149        return;
150    }
151
152    AcpiOsPrintf (" %s", AcpiUtGetObjectTypeName (ObjDesc));
153
154    switch (ObjDesc->Common.Type)
155    {
156    case ACPI_TYPE_INTEGER:
157
158        AcpiOsPrintf (" %8.8X%8.8X",
159            ACPI_FORMAT_UINT64 (ObjDesc->Integer.Value));
160        break;
161
162    case ACPI_TYPE_STRING:
163
164        AcpiOsPrintf ("(%u) \"%.60s",
165            ObjDesc->String.Length, ObjDesc->String.Pointer);
166
167        if (ObjDesc->String.Length > 60)
168        {
169            AcpiOsPrintf ("...");
170        }
171        else
172        {
173            AcpiOsPrintf ("\"");
174        }
175        break;
176
177    case ACPI_TYPE_BUFFER:
178
179        AcpiOsPrintf ("(%u)", ObjDesc->Buffer.Length);
180        for (i = 0; (i < 8) && (i < ObjDesc->Buffer.Length); i++)
181        {
182            AcpiOsPrintf (" %2.2X", ObjDesc->Buffer.Pointer[i]);
183        }
184        break;
185
186    default:
187
188        AcpiOsPrintf (" %p", ObjDesc);
189        break;
190    }
191}
192
193
194/*******************************************************************************
195 *
196 * FUNCTION:    AcpiDbDecodeNode
197 *
198 * PARAMETERS:  Node        - Object to be displayed
199 *
200 * RETURN:      None
201 *
202 * DESCRIPTION: Short display of a namespace node
203 *
204 ******************************************************************************/
205
206static void
207AcpiDbDecodeNode (
208    ACPI_NAMESPACE_NODE     *Node)
209{
210
211    AcpiOsPrintf ("<Node>            Name %4.4s",
212        AcpiUtGetNodeName (Node));
213
214    if (Node->Flags & ANOBJ_METHOD_ARG)
215    {
216        AcpiOsPrintf (" [Method Arg]");
217    }
218    if (Node->Flags & ANOBJ_METHOD_LOCAL)
219    {
220        AcpiOsPrintf (" [Method Local]");
221    }
222
223    switch (Node->Type)
224    {
225    /* These types have no attached object */
226
227    case ACPI_TYPE_DEVICE:
228
229        AcpiOsPrintf (" Device");
230        break;
231
232    case ACPI_TYPE_THERMAL:
233
234        AcpiOsPrintf (" Thermal Zone");
235        break;
236
237    default:
238
239        AcpiDbDecodeInternalObject (AcpiNsGetAttachedObject (Node));
240        break;
241    }
242}
243
244
245/*******************************************************************************
246 *
247 * FUNCTION:    AcpiDbDisplayInternalObject
248 *
249 * PARAMETERS:  ObjDesc         - Object to be displayed
250 *              WalkState       - Current walk state
251 *
252 * RETURN:      None
253 *
254 * DESCRIPTION: Short display of an internal object
255 *
256 ******************************************************************************/
257
258void
259AcpiDbDisplayInternalObject (
260    ACPI_OPERAND_OBJECT     *ObjDesc,
261    ACPI_WALK_STATE         *WalkState)
262{
263    UINT8                   Type;
264
265
266    AcpiOsPrintf ("%p ", ObjDesc);
267
268    if (!ObjDesc)
269    {
270        AcpiOsPrintf ("<Null Object>\n");
271        return;
272    }
273
274    /* Decode the object type */
275
276    switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc))
277    {
278    case ACPI_DESC_TYPE_PARSER:
279
280        AcpiOsPrintf ("<Parser>  ");
281        break;
282
283    case ACPI_DESC_TYPE_NAMED:
284
285        AcpiDbDecodeNode ((ACPI_NAMESPACE_NODE *) ObjDesc);
286        break;
287
288    case ACPI_DESC_TYPE_OPERAND:
289
290        Type = ObjDesc->Common.Type;
291        if (Type > ACPI_TYPE_LOCAL_MAX)
292        {
293            AcpiOsPrintf (" Type %X [Invalid Type]", (UINT32) Type);
294            return;
295        }
296
297        /* Decode the ACPI object type */
298
299        switch (ObjDesc->Common.Type)
300        {
301        case ACPI_TYPE_LOCAL_REFERENCE:
302
303            AcpiOsPrintf ("[%s] ", AcpiUtGetReferenceName (ObjDesc));
304
305            /* Decode the refererence */
306
307            switch (ObjDesc->Reference.Class)
308            {
309            case ACPI_REFCLASS_LOCAL:
310
311                AcpiOsPrintf ("%X ", ObjDesc->Reference.Value);
312                if (WalkState)
313                {
314                    ObjDesc = WalkState->LocalVariables
315                        [ObjDesc->Reference.Value].Object;
316                    AcpiOsPrintf ("%p", ObjDesc);
317                    AcpiDbDecodeInternalObject (ObjDesc);
318                }
319                break;
320
321            case ACPI_REFCLASS_ARG:
322
323                AcpiOsPrintf ("%X ", ObjDesc->Reference.Value);
324                if (WalkState)
325                {
326                    ObjDesc = WalkState->Arguments
327                        [ObjDesc->Reference.Value].Object;
328                    AcpiOsPrintf ("%p", ObjDesc);
329                    AcpiDbDecodeInternalObject (ObjDesc);
330                }
331                break;
332
333            case ACPI_REFCLASS_INDEX:
334
335                switch (ObjDesc->Reference.TargetType)
336                {
337                case ACPI_TYPE_BUFFER_FIELD:
338
339                    AcpiOsPrintf ("%p", ObjDesc->Reference.Object);
340                    AcpiDbDecodeInternalObject (ObjDesc->Reference.Object);
341                    break;
342
343                case ACPI_TYPE_PACKAGE:
344
345                    AcpiOsPrintf ("%p", ObjDesc->Reference.Where);
346                    if (!ObjDesc->Reference.Where)
347                    {
348                        AcpiOsPrintf (" Uninitialized WHERE pointer");
349                    }
350                    else
351                    {
352                        AcpiDbDecodeInternalObject (
353                            *(ObjDesc->Reference.Where));
354                    }
355                    break;
356
357                default:
358
359                    AcpiOsPrintf ("Unknown index target type");
360                    break;
361                }
362                break;
363
364            case ACPI_REFCLASS_REFOF:
365
366                if (!ObjDesc->Reference.Object)
367                {
368                    AcpiOsPrintf (
369                        "Uninitialized reference subobject pointer");
370                    break;
371                }
372
373                /* Reference can be to a Node or an Operand object */
374
375                switch (ACPI_GET_DESCRIPTOR_TYPE (ObjDesc->Reference.Object))
376                {
377                case ACPI_DESC_TYPE_NAMED:
378
379                    AcpiDbDecodeNode (ObjDesc->Reference.Object);
380                    break;
381
382                case ACPI_DESC_TYPE_OPERAND:
383
384                    AcpiDbDecodeInternalObject (ObjDesc->Reference.Object);
385                    break;
386
387                default:
388                    break;
389                }
390                break;
391
392            case ACPI_REFCLASS_NAME:
393
394                AcpiDbDecodeNode (ObjDesc->Reference.Node);
395                break;
396
397            case ACPI_REFCLASS_DEBUG:
398            case ACPI_REFCLASS_TABLE:
399
400                AcpiOsPrintf ("\n");
401                break;
402
403            default:    /* Unknown reference class */
404
405                AcpiOsPrintf ("%2.2X\n", ObjDesc->Reference.Class);
406                break;
407            }
408            break;
409
410        default:
411
412            AcpiOsPrintf ("<Obj>            ");
413            AcpiDbDecodeInternalObject (ObjDesc);
414            break;
415        }
416        break;
417
418    default:
419
420        AcpiOsPrintf ("<Not a valid ACPI Object Descriptor> [%s]",
421            AcpiUtGetDescriptorName (ObjDesc));
422        break;
423    }
424
425    AcpiOsPrintf ("\n");
426}
427
428
429/*******************************************************************************
430 *
431 * FUNCTION:    AcpiDbDecodeLocals
432 *
433 * PARAMETERS:  WalkState       - State for current method
434 *
435 * RETURN:      None
436 *
437 * DESCRIPTION: Display all locals for the currently running control method
438 *
439 ******************************************************************************/
440
441void
442AcpiDbDecodeLocals (
443    ACPI_WALK_STATE         *WalkState)
444{
445    UINT32                  i;
446    ACPI_OPERAND_OBJECT     *ObjDesc;
447    ACPI_NAMESPACE_NODE     *Node;
448    BOOLEAN                 DisplayLocals = FALSE;
449
450
451    ObjDesc = WalkState->MethodDesc;
452    Node    = WalkState->MethodNode;
453
454    if (!Node)
455    {
456        AcpiOsPrintf (
457            "No method node (Executing subtree for buffer or opregion)\n");
458        return;
459    }
460
461    if (Node->Type != ACPI_TYPE_METHOD)
462    {
463        AcpiOsPrintf ("Executing subtree for Buffer/Package/Region\n");
464        return;
465    }
466
467    /* Are any locals actually set? */
468
469    for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++)
470    {
471        ObjDesc = WalkState->LocalVariables[i].Object;
472        if (ObjDesc)
473        {
474            DisplayLocals = TRUE;
475            break;
476        }
477    }
478
479    /* If any are set, only display the ones that are set */
480
481    if (DisplayLocals)
482    {
483        AcpiOsPrintf ("\nInitialized Local Variables for method [%4.4s]:\n",
484            AcpiUtGetNodeName (Node));
485
486        for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++)
487        {
488            ObjDesc = WalkState->LocalVariables[i].Object;
489            if (ObjDesc)
490            {
491                AcpiOsPrintf ("    Local%X: ", i);
492                AcpiDbDisplayInternalObject (ObjDesc, WalkState);
493            }
494        }
495    }
496    else
497    {
498        AcpiOsPrintf (
499            "No Local Variables are initialized for method [%4.4s]\n",
500            AcpiUtGetNodeName (Node));
501    }
502}
503
504
505/*******************************************************************************
506 *
507 * FUNCTION:    AcpiDbDecodeArguments
508 *
509 * PARAMETERS:  WalkState       - State for current method
510 *
511 * RETURN:      None
512 *
513 * DESCRIPTION: Display all arguments for the currently running control method
514 *
515 ******************************************************************************/
516
517void
518AcpiDbDecodeArguments (
519    ACPI_WALK_STATE         *WalkState)
520{
521    UINT32                  i;
522    ACPI_OPERAND_OBJECT     *ObjDesc;
523    ACPI_NAMESPACE_NODE     *Node;
524    BOOLEAN                 DisplayArgs = FALSE;
525
526
527    Node = WalkState->MethodNode;
528    ObjDesc = WalkState->MethodDesc;
529
530    if (!Node)
531    {
532        AcpiOsPrintf (
533            "No method node (Executing subtree for buffer or opregion)\n");
534        return;
535    }
536
537    if (Node->Type != ACPI_TYPE_METHOD)
538    {
539        AcpiOsPrintf ("Executing subtree for Buffer/Package/Region\n");
540        return;
541    }
542
543    /* Are any arguments actually set? */
544
545    for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
546    {
547        ObjDesc = WalkState->Arguments[i].Object;
548        if (ObjDesc)
549        {
550            DisplayArgs = TRUE;
551            break;
552        }
553    }
554
555    /* If any are set, only display the ones that are set */
556
557    if (DisplayArgs)
558    {
559        AcpiOsPrintf (
560            "Initialized Arguments for Method [%4.4s]:  "
561            "(%X arguments defined for method invocation)\n",
562            AcpiUtGetNodeName (Node), ObjDesc->Method.ParamCount);
563
564        for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
565        {
566            ObjDesc = WalkState->Arguments[i].Object;
567            if (ObjDesc)
568            {
569                AcpiOsPrintf ("    Arg%u:   ", i);
570                AcpiDbDisplayInternalObject (ObjDesc, WalkState);
571            }
572        }
573    }
574    else
575    {
576        AcpiOsPrintf (
577            "No Arguments are initialized for method [%4.4s]\n",
578            AcpiUtGetNodeName (Node));
579    }
580}
581