exdebug.c revision 1.11 1 /******************************************************************************
2 *
3 * Module Name: exdebug - Support for stores to the AML Debug Object
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2018, 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 "acinterp.h"
47
48
49 #define _COMPONENT ACPI_EXECUTER
50 ACPI_MODULE_NAME ("exdebug")
51
52
53 #ifndef ACPI_NO_ERROR_MESSAGES
54 /*******************************************************************************
55 *
56 * FUNCTION: AcpiExDoDebugObject
57 *
58 * PARAMETERS: SourceDesc - Object to be output to "Debug Object"
59 * Level - Indentation level (used for packages)
60 * Index - Current package element, zero if not pkg
61 *
62 * RETURN: None
63 *
64 * DESCRIPTION: Handles stores to the AML Debug Object. For example:
65 * Store(INT1, Debug)
66 *
67 * This function is not compiled if ACPI_NO_ERROR_MESSAGES is set.
68 *
69 * This function is only enabled if AcpiGbl_EnableAmlDebugObject is set.
70 * Thus, in the normal operational case, stores to the debug object are
71 * ignored but can be easily enabled if necessary.
72 *
73 ******************************************************************************/
74
75 void
76 AcpiExDoDebugObject (
77 ACPI_OPERAND_OBJECT *SourceDesc,
78 UINT32 Level,
79 UINT32 Index)
80 {
81 UINT32 i;
82 UINT32 Timer;
83 ACPI_OPERAND_OBJECT *ObjectDesc;
84 UINT32 Value;
85
86
87 ACPI_FUNCTION_TRACE_PTR (ExDoDebugObject, SourceDesc);
88
89
90 /* Output must be enabled via the DebugObject global */
91
92 if (!AcpiGbl_EnableAmlDebugObject)
93 {
94 return_VOID;
95 }
96
97 /* Newline -- don't emit the line header */
98
99 if (SourceDesc &&
100 (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_OPERAND) &&
101 (SourceDesc->Common.Type == ACPI_TYPE_STRING))
102 {
103 if ((SourceDesc->String.Length == 1) &&
104 (*SourceDesc->String.Pointer == '\n'))
105 {
106 AcpiOsPrintf ("\n");
107 return_VOID;
108 }
109 }
110
111 /*
112 * Print line header as long as we are not in the middle of an
113 * object display
114 */
115 if (!((Level > 0) && Index == 0))
116 {
117 if (AcpiGbl_DisplayDebugTimer)
118 {
119 /*
120 * We will emit the current timer value (in microseconds) with each
121 * debug output. Only need the lower 26 bits. This allows for 67
122 * million microseconds or 67 seconds before rollover.
123 *
124 * Convert 100 nanosecond units to microseconds
125 */
126 Timer = ((UINT32) AcpiOsGetTimer () / 10);
127 Timer &= 0x03FFFFFF;
128
129 AcpiOsPrintf ("ACPI Debug: T=0x%8.8X %*s", Timer, Level, " ");
130 }
131 else
132 {
133 AcpiOsPrintf ("ACPI Debug: %*s", Level, " ");
134 }
135 }
136
137 /* Display the index for package output only */
138
139 if (Index > 0)
140 {
141 AcpiOsPrintf ("(%.2u) ", Index - 1);
142 }
143
144 if (!SourceDesc)
145 {
146 AcpiOsPrintf ("[Null Object]\n");
147 return_VOID;
148 }
149
150 if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_OPERAND)
151 {
152 /* No object type prefix needed for integers and strings */
153
154 if ((SourceDesc->Common.Type != ACPI_TYPE_INTEGER) &&
155 (SourceDesc->Common.Type != ACPI_TYPE_STRING))
156 {
157 AcpiOsPrintf ("%s ", AcpiUtGetObjectTypeName (SourceDesc));
158 }
159
160 if (!AcpiUtValidInternalObject (SourceDesc))
161 {
162 AcpiOsPrintf ("%p, Invalid Internal Object!\n", SourceDesc);
163 return_VOID;
164 }
165 }
166 else if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_NAMED)
167 {
168 AcpiOsPrintf ("%s (Node %p)\n",
169 AcpiUtGetTypeName (((ACPI_NAMESPACE_NODE *) SourceDesc)->Type),
170 SourceDesc);
171 return_VOID;
172 }
173 else
174 {
175 return_VOID;
176 }
177
178 /* SourceDesc is of type ACPI_DESC_TYPE_OPERAND */
179
180 switch (SourceDesc->Common.Type)
181 {
182 case ACPI_TYPE_INTEGER:
183
184 /* Output correct integer width */
185
186 if (AcpiGbl_IntegerByteWidth == 4)
187 {
188 AcpiOsPrintf ("0x%8.8X\n",
189 (UINT32) SourceDesc->Integer.Value);
190 }
191 else
192 {
193 AcpiOsPrintf ("0x%8.8X%8.8X\n",
194 ACPI_FORMAT_UINT64 (SourceDesc->Integer.Value));
195 }
196 break;
197
198 case ACPI_TYPE_BUFFER:
199
200 AcpiOsPrintf ("[0x%.2X]\n", (UINT32) SourceDesc->Buffer.Length);
201 AcpiUtDumpBuffer (SourceDesc->Buffer.Pointer,
202 (SourceDesc->Buffer.Length < 256) ?
203 SourceDesc->Buffer.Length : 256, DB_BYTE_DISPLAY, 0);
204 break;
205
206 case ACPI_TYPE_STRING:
207
208 AcpiOsPrintf ("\"%s\"\n", SourceDesc->String.Pointer);
209 break;
210
211 case ACPI_TYPE_PACKAGE:
212
213 AcpiOsPrintf ("(Contains 0x%.2X Elements):\n",
214 SourceDesc->Package.Count);
215
216 /* Output the entire contents of the package */
217
218 for (i = 0; i < SourceDesc->Package.Count; i++)
219 {
220 AcpiExDoDebugObject (SourceDesc->Package.Elements[i],
221 Level + 4, i + 1);
222 }
223 break;
224
225 case ACPI_TYPE_LOCAL_REFERENCE:
226
227 AcpiOsPrintf ("[%s] ", AcpiUtGetReferenceName (SourceDesc));
228
229 /* Decode the reference */
230
231 switch (SourceDesc->Reference.Class)
232 {
233 case ACPI_REFCLASS_INDEX:
234
235 AcpiOsPrintf ("0x%X\n", SourceDesc->Reference.Value);
236 break;
237
238 case ACPI_REFCLASS_TABLE:
239
240 /* Case for DdbHandle */
241
242 AcpiOsPrintf ("Table Index 0x%X\n", SourceDesc->Reference.Value);
243 return_VOID;
244
245 default:
246
247 break;
248 }
249
250 AcpiOsPrintf (" ");
251
252 /* Check for valid node first, then valid object */
253
254 if (SourceDesc->Reference.Node)
255 {
256 if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc->Reference.Node) !=
257 ACPI_DESC_TYPE_NAMED)
258 {
259 AcpiOsPrintf (" %p - Not a valid namespace node\n",
260 SourceDesc->Reference.Node);
261 }
262 else
263 {
264 AcpiOsPrintf ("Node %p [%4.4s] ", SourceDesc->Reference.Node,
265 (SourceDesc->Reference.Node)->Name.Ascii);
266
267 switch ((SourceDesc->Reference.Node)->Type)
268 {
269 /* These types have no attached object */
270
271 case ACPI_TYPE_DEVICE:
272 AcpiOsPrintf ("Device\n");
273 break;
274
275 case ACPI_TYPE_THERMAL:
276 AcpiOsPrintf ("Thermal Zone\n");
277 break;
278
279 default:
280
281 AcpiExDoDebugObject ((SourceDesc->Reference.Node)->Object,
282 Level + 4, 0);
283 break;
284 }
285 }
286 }
287 else if (SourceDesc->Reference.Object)
288 {
289 if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc->Reference.Object) ==
290 ACPI_DESC_TYPE_NAMED)
291 {
292 /* Reference object is a namespace node */
293
294 AcpiExDoDebugObject (ACPI_CAST_PTR (ACPI_OPERAND_OBJECT,
295 SourceDesc->Reference.Object),
296 Level + 4, 0);
297 }
298 else
299 {
300 ObjectDesc = SourceDesc->Reference.Object;
301 Value = SourceDesc->Reference.Value;
302
303 switch (ObjectDesc->Common.Type)
304 {
305 case ACPI_TYPE_BUFFER:
306
307 AcpiOsPrintf ("Buffer[%u] = 0x%2.2X\n",
308 Value, *SourceDesc->Reference.IndexPointer);
309 break;
310
311 case ACPI_TYPE_STRING:
312
313 AcpiOsPrintf ("String[%u] = \"%c\" (0x%2.2X)\n",
314 Value, *SourceDesc->Reference.IndexPointer,
315 *SourceDesc->Reference.IndexPointer);
316 break;
317
318 case ACPI_TYPE_PACKAGE:
319
320 AcpiOsPrintf ("Package[%u] = ", Value);
321 if (!(*SourceDesc->Reference.Where))
322 {
323 AcpiOsPrintf ("[Uninitialized Package Element]\n");
324 }
325 else
326 {
327 AcpiExDoDebugObject (*SourceDesc->Reference.Where,
328 Level+4, 0);
329 }
330 break;
331
332 default:
333
334 AcpiOsPrintf ("Unknown Reference object type %X\n",
335 ObjectDesc->Common.Type);
336 break;
337 }
338 }
339 }
340 break;
341
342 default:
343
344 AcpiOsPrintf ("(Descriptor %p)\n", SourceDesc);
345 break;
346 }
347
348 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "\n"));
349 return_VOID;
350 }
351 #endif
352