exdebug.c revision 306536
1178525Sjb/******************************************************************************
2178525Sjb *
3178525Sjb * Module Name: exdebug - Support for stores to the AML Debug Object
4178525Sjb *
5178525Sjb *****************************************************************************/
6178525Sjb
7178525Sjb/*
8178525Sjb * Copyright (C) 2000 - 2016, Intel Corp.
9178525Sjb * All rights reserved.
10178525Sjb *
11178525Sjb * Redistribution and use in source and binary forms, with or without
12178525Sjb * modification, are permitted provided that the following conditions
13178525Sjb * are met:
14178525Sjb * 1. Redistributions of source code must retain the above copyright
15178525Sjb *    notice, this list of conditions, and the following disclaimer,
16178525Sjb *    without modification.
17178525Sjb * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18178525Sjb *    substantially similar to the "NO WARRANTY" disclaimer below
19178525Sjb *    ("Disclaimer") and any redistribution must be conditioned upon
20178525Sjb *    including a substantially similar Disclaimer requirement for further
21178525Sjb *    binary redistribution.
22178525Sjb * 3. Neither the names of the above-listed copyright holders nor the names
23178525Sjb *    of any contributors may be used to endorse or promote products derived
24178525Sjb *    from this software without specific prior written permission.
25178525Sjb *
26178525Sjb * Alternatively, this software may be distributed under the terms of the
27178525Sjb * GNU General Public License ("GPL") version 2 as published by the Free
28178525Sjb * Software Foundation.
29178525Sjb *
30178525Sjb * NO WARRANTY
31178525Sjb * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32178525Sjb * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33178525Sjb * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34178525Sjb * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35178525Sjb * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36178525Sjb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37178525Sjb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38178525Sjb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39178525Sjb * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40178525Sjb * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41178525Sjb * POSSIBILITY OF SUCH DAMAGES.
42178525Sjb */
43178525Sjb
44178525Sjb#include <contrib/dev/acpica/include/acpi.h>
45178525Sjb#include <contrib/dev/acpica/include/accommon.h>
46178525Sjb#include <contrib/dev/acpica/include/acinterp.h>
47178525Sjb
48178525Sjb
49178525Sjb#define _COMPONENT          ACPI_EXECUTER
50178525Sjb        ACPI_MODULE_NAME    ("exdebug")
51178525Sjb
52178525Sjb
53178525Sjb#ifndef ACPI_NO_ERROR_MESSAGES
54178525Sjb/*******************************************************************************
55178525Sjb *
56178525Sjb * FUNCTION:    AcpiExDoDebugObject
57178525Sjb *
58178525Sjb * PARAMETERS:  SourceDesc          - Object to be output to "Debug Object"
59178525Sjb *              Level               - Indentation level (used for packages)
60178525Sjb *              Index               - Current package element, zero if not pkg
61178525Sjb *
62178525Sjb * RETURN:      None
63178525Sjb *
64178525Sjb * DESCRIPTION: Handles stores to the AML Debug Object. For example:
65178525Sjb *              Store(INT1, Debug)
66178525Sjb *
67178525Sjb * This function is not compiled if ACPI_NO_ERROR_MESSAGES is set.
68178525Sjb *
69178525Sjb * This function is only enabled if AcpiGbl_EnableAmlDebugObject is set, or
70178525Sjb * if ACPI_LV_DEBUG_OBJECT is set in the AcpiDbgLevel. Thus, in the normal
71178525Sjb * operational case, stores to the debug object are ignored but can be easily
72178525Sjb * enabled if necessary.
73178525Sjb *
74178525Sjb ******************************************************************************/
75178525Sjb
76178525Sjbvoid
77178525SjbAcpiExDoDebugObject (
78178525Sjb    ACPI_OPERAND_OBJECT     *SourceDesc,
79178525Sjb    UINT32                  Level,
80178525Sjb    UINT32                  Index)
81178525Sjb{
82178525Sjb    UINT32                  i;
83178525Sjb    UINT32                  Timer;
84178525Sjb    ACPI_OPERAND_OBJECT     *ObjectDesc;
85178525Sjb    UINT32                  Value;
86178525Sjb
87178525Sjb
88178525Sjb    ACPI_FUNCTION_TRACE_PTR (ExDoDebugObject, SourceDesc);
89178525Sjb
90178525Sjb
91178525Sjb    /* Output must be enabled via the DebugObject global or the DbgLevel */
92178525Sjb
93178525Sjb    if (!AcpiGbl_EnableAmlDebugObject &&
94178525Sjb        !(AcpiDbgLevel & ACPI_LV_DEBUG_OBJECT))
95178525Sjb    {
96178525Sjb        return_VOID;
97178525Sjb    }
98178525Sjb
99178525Sjb    /* Null string or newline -- don't emit the line header */
100178525Sjb
101178525Sjb    if (SourceDesc &&
102178525Sjb        (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_OPERAND) &&
103178525Sjb        (SourceDesc->Common.Type == ACPI_TYPE_STRING))
104178525Sjb    {
105178525Sjb        if ((SourceDesc->String.Length == 0) ||
106178525Sjb                ((SourceDesc->String.Length == 1) &&
107178525Sjb                (*SourceDesc->String.Pointer == '\n')))
108178525Sjb        {
109178525Sjb            AcpiOsPrintf ("\n");
110178525Sjb            return_VOID;
111178525Sjb        }
112178525Sjb    }
113178525Sjb
114178525Sjb    /*
115178525Sjb     * Print line header as long as we are not in the middle of an
116178525Sjb     * object display
117178525Sjb     */
118178525Sjb    if (!((Level > 0) && Index == 0))
119178525Sjb    {
120178525Sjb        if (AcpiGbl_DisplayDebugTimer)
121178525Sjb        {
122178525Sjb            /*
123178525Sjb             * We will emit the current timer value (in microseconds) with each
124178525Sjb             * debug output. Only need the lower 26 bits. This allows for 67
125178525Sjb             * million microseconds or 67 seconds before rollover.
126178525Sjb             *
127178525Sjb             * Convert 100 nanosecond units to microseconds
128178525Sjb             */
129178525Sjb            Timer = ((UINT32) AcpiOsGetTimer () / 10);
130178525Sjb            Timer &= 0x03FFFFFF;
131178525Sjb
132178525Sjb            AcpiOsPrintf ("[ACPI Debug T=0x%8.8X] %*s", Timer, Level, " ");
133178525Sjb        }
134178525Sjb        else
135178525Sjb        {
136178525Sjb            AcpiOsPrintf ("[ACPI Debug] %*s", Level, " ");
137178525Sjb        }
138178525Sjb    }
139178525Sjb
140178525Sjb    /* Display the index for package output only */
141178525Sjb
142178525Sjb    if (Index > 0)
143178525Sjb    {
144178525Sjb       AcpiOsPrintf ("(%.2u) ", Index - 1);
145178525Sjb    }
146178525Sjb
147178525Sjb    if (!SourceDesc)
148178525Sjb    {
149178525Sjb        AcpiOsPrintf ("[Null Object]\n");
150178525Sjb        return_VOID;
151178525Sjb    }
152178525Sjb
153178525Sjb    if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_OPERAND)
154178525Sjb    {
155178525Sjb        /* No object type prefix needed for integers and strings */
156178525Sjb
157178525Sjb        if ((SourceDesc->Common.Type != ACPI_TYPE_INTEGER) &&
158178525Sjb            (SourceDesc->Common.Type != ACPI_TYPE_STRING))
159178525Sjb        {
160178525Sjb            AcpiOsPrintf ("%s  ", AcpiUtGetObjectTypeName (SourceDesc));
161178525Sjb        }
162178525Sjb
163178525Sjb        if (!AcpiUtValidInternalObject (SourceDesc))
164178525Sjb        {
165178525Sjb           AcpiOsPrintf ("%p, Invalid Internal Object!\n", SourceDesc);
166178525Sjb           return_VOID;
167178525Sjb        }
168178525Sjb    }
169178525Sjb    else if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_NAMED)
170178525Sjb    {
171178525Sjb        AcpiOsPrintf ("%s  (Node %p)\n",
172178525Sjb            AcpiUtGetTypeName (((ACPI_NAMESPACE_NODE *) SourceDesc)->Type),
173178525Sjb                SourceDesc);
174178525Sjb        return_VOID;
175178525Sjb    }
176178525Sjb    else
177178525Sjb    {
178178525Sjb        return_VOID;
179178525Sjb    }
180178525Sjb
181178525Sjb    /* SourceDesc is of type ACPI_DESC_TYPE_OPERAND */
182178525Sjb
183178525Sjb    switch (SourceDesc->Common.Type)
184178525Sjb    {
185178525Sjb    case ACPI_TYPE_INTEGER:
186178525Sjb
187178525Sjb        /* Output correct integer width */
188178525Sjb
189178525Sjb        if (AcpiGbl_IntegerByteWidth == 4)
190178525Sjb        {
191178525Sjb            AcpiOsPrintf ("0x%8.8X\n",
192178525Sjb                (UINT32) SourceDesc->Integer.Value);
193178525Sjb        }
194178525Sjb        else
195178525Sjb        {
196178525Sjb            AcpiOsPrintf ("0x%8.8X%8.8X\n",
197178525Sjb                ACPI_FORMAT_UINT64 (SourceDesc->Integer.Value));
198178525Sjb        }
199178525Sjb        break;
200178525Sjb
201178525Sjb    case ACPI_TYPE_BUFFER:
202178525Sjb
203178525Sjb        AcpiOsPrintf ("[0x%.2X]\n", (UINT32) SourceDesc->Buffer.Length);
204178525Sjb        AcpiUtDumpBuffer (SourceDesc->Buffer.Pointer,
205178525Sjb            (SourceDesc->Buffer.Length < 256) ?
206178525Sjb                SourceDesc->Buffer.Length : 256, DB_BYTE_DISPLAY, 0);
207178525Sjb        break;
208178525Sjb
209178525Sjb    case ACPI_TYPE_STRING:
210178525Sjb
211178525Sjb        AcpiOsPrintf ("\"%s\"\n", SourceDesc->String.Pointer);
212178525Sjb        break;
213178525Sjb
214178525Sjb    case ACPI_TYPE_PACKAGE:
215178525Sjb
216178525Sjb        AcpiOsPrintf ("(Contains 0x%.2X Elements):\n",
217178525Sjb            SourceDesc->Package.Count);
218178525Sjb
219178525Sjb        /* Output the entire contents of the package */
220178525Sjb
221178525Sjb        for (i = 0; i < SourceDesc->Package.Count; i++)
222178525Sjb        {
223178525Sjb            AcpiExDoDebugObject (SourceDesc->Package.Elements[i],
224178525Sjb                Level + 4, i + 1);
225178525Sjb        }
226178525Sjb        break;
227178525Sjb
228178525Sjb    case ACPI_TYPE_LOCAL_REFERENCE:
229178525Sjb
230178525Sjb        AcpiOsPrintf ("[%s] ", AcpiUtGetReferenceName (SourceDesc));
231
232        /* Decode the reference */
233
234        switch (SourceDesc->Reference.Class)
235        {
236        case ACPI_REFCLASS_INDEX:
237
238            AcpiOsPrintf ("0x%X\n", SourceDesc->Reference.Value);
239            break;
240
241        case ACPI_REFCLASS_TABLE:
242
243            /* Case for DdbHandle */
244
245            AcpiOsPrintf ("Table Index 0x%X\n", SourceDesc->Reference.Value);
246            return_VOID;
247
248        default:
249
250            break;
251        }
252
253        AcpiOsPrintf ("  ");
254
255        /* Check for valid node first, then valid object */
256
257        if (SourceDesc->Reference.Node)
258        {
259            if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc->Reference.Node) !=
260                ACPI_DESC_TYPE_NAMED)
261            {
262                AcpiOsPrintf (" %p - Not a valid namespace node\n",
263                    SourceDesc->Reference.Node);
264            }
265            else
266            {
267                AcpiOsPrintf ("Node %p [%4.4s] ", SourceDesc->Reference.Node,
268                    (SourceDesc->Reference.Node)->Name.Ascii);
269
270                switch ((SourceDesc->Reference.Node)->Type)
271                {
272                /* These types have no attached object */
273
274                case ACPI_TYPE_DEVICE:
275                    AcpiOsPrintf ("Device\n");
276                    break;
277
278                case ACPI_TYPE_THERMAL:
279                    AcpiOsPrintf ("Thermal Zone\n");
280                    break;
281
282                default:
283
284                    AcpiExDoDebugObject ((SourceDesc->Reference.Node)->Object,
285                        Level + 4, 0);
286                    break;
287                }
288            }
289        }
290        else if (SourceDesc->Reference.Object)
291        {
292            if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc->Reference.Object) ==
293                ACPI_DESC_TYPE_NAMED)
294            {
295                /* Reference object is a namespace node */
296
297                AcpiExDoDebugObject (ACPI_CAST_PTR (ACPI_OPERAND_OBJECT,
298                    SourceDesc->Reference.Object),
299                    Level + 4, 0);
300            }
301            else
302            {
303                ObjectDesc = SourceDesc->Reference.Object;
304                Value = SourceDesc->Reference.Value;
305
306                switch (ObjectDesc->Common.Type)
307                {
308                case ACPI_TYPE_BUFFER:
309
310                    AcpiOsPrintf ("Buffer[%u] = 0x%2.2X\n",
311                        Value, *SourceDesc->Reference.IndexPointer);
312                    break;
313
314                case ACPI_TYPE_STRING:
315
316                    AcpiOsPrintf ("String[%u] = \"%c\" (0x%2.2X)\n",
317                        Value, *SourceDesc->Reference.IndexPointer,
318                        *SourceDesc->Reference.IndexPointer);
319                    break;
320
321                case ACPI_TYPE_PACKAGE:
322
323                    AcpiOsPrintf ("Package[%u] = ", Value);
324                    if (!(*SourceDesc->Reference.Where))
325                    {
326                        AcpiOsPrintf ("[Uninitialized Package Element]\n");
327                    }
328                    else
329                    {
330                        AcpiExDoDebugObject (*SourceDesc->Reference.Where,
331                            Level+4, 0);
332                    }
333                    break;
334
335                default:
336
337                    AcpiOsPrintf ("Unknown Reference object type %X\n",
338                        ObjectDesc->Common.Type);
339                    break;
340                }
341            }
342        }
343        break;
344
345    default:
346
347        AcpiOsPrintf ("(Descriptor %p)\n", SourceDesc);
348        break;
349    }
350
351    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "\n"));
352    return_VOID;
353}
354#endif
355