dbobject.c revision 1.1.1.2 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 "acpi.h"
45 #include "accommon.h"
46 #include "acnamesp.h"
47 #include "acdebug.h"
48
49
50 #define _COMPONENT ACPI_CA_DEBUGGER
51 ACPI_MODULE_NAME ("dbobject")
52
53
54 /* Local prototypes */
55
56 static void
57 AcpiDbDecodeNode (
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
76 void
77 AcpiDbDumpMethodInfo (
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
132 void
133 AcpiDbDecodeInternalObject (
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) \"%.24s",
165 ObjDesc->String.Length, ObjDesc->String.Pointer);
166
167 if (ObjDesc->String.Length > 24)
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
206 static void
207 AcpiDbDecodeNode (
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
258 void
259 AcpiDbDisplayInternalObject (
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
441 void
442 AcpiDbDecodeLocals (
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
517 void
518 AcpiDbDecodeArguments (
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