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