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