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