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 <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
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
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
AcpiDbDecodeInternalObject(ACPI_OPERAND_OBJECT * ObjDesc)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
AcpiDbDecodeNode(ACPI_NAMESPACE_NODE * Node)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
AcpiDbDisplayInternalObject(ACPI_OPERAND_OBJECT * ObjDesc,ACPI_WALK_STATE * WalkState)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
AcpiDbDecodeLocals(ACPI_WALK_STATE * WalkState)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
453 if (!Node)
454 {
455 AcpiOsPrintf (
456 "No method node (Executing subtree for buffer or opregion)\n");
457 return;
458 }
459
460 if (Node->Type != ACPI_TYPE_METHOD)
461 {
462 AcpiOsPrintf ("Executing subtree for Buffer/Package/Region\n");
463 return;
464 }
465
466 AcpiOsPrintf ("Local Variables for method [%4.4s]:\n",
467 AcpiUtGetNodeName (Node));
468
469 for (i = 0; i < ACPI_METHOD_NUM_LOCALS; i++)
470 {
471 ObjDesc = WalkState->LocalVariables[i].Object;
472 AcpiOsPrintf (" Local%X: ", i);
473 AcpiDbDisplayInternalObject (ObjDesc, WalkState);
474 }
475 }
476
477
478 /*******************************************************************************
479 *
480 * FUNCTION: AcpiDbDecodeArguments
481 *
482 * PARAMETERS: WalkState - State for current method
483 *
484 * RETURN: None
485 *
486 * DESCRIPTION: Display all arguments for the currently running control method
487 *
488 ******************************************************************************/
489
490 void
AcpiDbDecodeArguments(ACPI_WALK_STATE * WalkState)491 AcpiDbDecodeArguments (
492 ACPI_WALK_STATE *WalkState)
493 {
494 UINT32 i;
495 ACPI_OPERAND_OBJECT *ObjDesc;
496 ACPI_NAMESPACE_NODE *Node;
497
498
499 ObjDesc = WalkState->MethodDesc;
500 Node = WalkState->MethodNode;
501
502 if (!Node)
503 {
504 AcpiOsPrintf (
505 "No method node (Executing subtree for buffer or opregion)\n");
506 return;
507 }
508
509 if (Node->Type != ACPI_TYPE_METHOD)
510 {
511 AcpiOsPrintf ("Executing subtree for Buffer/Package/Region\n");
512 return;
513 }
514
515 AcpiOsPrintf (
516 "Arguments for Method [%4.4s]: "
517 "(%X arguments defined, max concurrency = %X)\n",
518 AcpiUtGetNodeName (Node), ObjDesc->Method.ParamCount,
519 ObjDesc->Method.SyncLevel);
520
521 for (i = 0; i < ACPI_METHOD_NUM_ARGS; i++)
522 {
523 ObjDesc = WalkState->Arguments[i].Object;
524 AcpiOsPrintf (" Arg%u: ", i);
525 AcpiDbDisplayInternalObject (ObjDesc, WalkState);
526 }
527 }
528