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