Sync ACPICA with Intel's version 20160108.
[dragonfly.git] / sys / contrib / dev / acpica / source / components / executer / extrace.c
1 /******************************************************************************
2  *
3  * Module Name: extrace - Support for interpreter execution tracing
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 "acnamesp.h"
47 #include "acinterp.h"
48
49
50 #define _COMPONENT          ACPI_EXECUTER
51         ACPI_MODULE_NAME    ("extrace")
52
53
54 static ACPI_OPERAND_OBJECT  *AcpiGbl_TraceMethodObject = NULL;
55
56 /* Local prototypes */
57
58 #ifdef ACPI_DEBUG_OUTPUT
59 static const char *
60 AcpiExGetTraceEventName (
61     ACPI_TRACE_EVENT_TYPE   Type);
62 #endif
63
64
65 /*******************************************************************************
66  *
67  * FUNCTION:    AcpiExInterpreterTraceEnabled
68  *
69  * PARAMETERS:  Name                - Whether method name should be matched,
70  *                                    this should be checked before starting
71  *                                    the tracer
72  *
73  * RETURN:      TRUE if interpreter trace is enabled.
74  *
75  * DESCRIPTION: Check whether interpreter trace is enabled
76  *
77  ******************************************************************************/
78
79 static BOOLEAN
80 AcpiExInterpreterTraceEnabled (
81     char                    *Name)
82 {
83
84     /* Check if tracing is enabled */
85
86     if (!(AcpiGbl_TraceFlags & ACPI_TRACE_ENABLED))
87     {
88         return (FALSE);
89     }
90
91     /*
92      * Check if tracing is filtered:
93      *
94      * 1. If the tracer is started, AcpiGbl_TraceMethodObject should have
95      *    been filled by the trace starter
96      * 2. If the tracer is not started, AcpiGbl_TraceMethodName should be
97      *    matched if it is specified
98      * 3. If the tracer is oneshot style, AcpiGbl_TraceMethodName should
99      *    not be cleared by the trace stopper during the first match
100      */
101     if (AcpiGbl_TraceMethodObject)
102     {
103         return (TRUE);
104     }
105
106     if (Name &&
107         (AcpiGbl_TraceMethodName &&
108          strcmp (AcpiGbl_TraceMethodName, Name)))
109     {
110         return (FALSE);
111     }
112
113     if ((AcpiGbl_TraceFlags & ACPI_TRACE_ONESHOT) &&
114         !AcpiGbl_TraceMethodName)
115     {
116         return (FALSE);
117     }
118
119     return (TRUE);
120 }
121
122
123 /*******************************************************************************
124  *
125  * FUNCTION:    AcpiExGetTraceEventName
126  *
127  * PARAMETERS:  Type            - Trace event type
128  *
129  * RETURN:      Trace event name.
130  *
131  * DESCRIPTION: Used to obtain the full trace event name.
132  *
133  ******************************************************************************/
134
135 #ifdef ACPI_DEBUG_OUTPUT
136
137 static const char *
138 AcpiExGetTraceEventName (
139     ACPI_TRACE_EVENT_TYPE   Type)
140 {
141
142     switch (Type)
143     {
144     case ACPI_TRACE_AML_METHOD:
145
146         return "Method";
147
148     case ACPI_TRACE_AML_OPCODE:
149
150         return "Opcode";
151
152     case ACPI_TRACE_AML_REGION:
153
154         return "Region";
155
156     default:
157
158         return "";
159     }
160 }
161
162 #endif
163
164
165 /*******************************************************************************
166  *
167  * FUNCTION:    AcpiExTracePoint
168  *
169  * PARAMETERS:  Type                - Trace event type
170  *              Begin               - TRUE if before execution
171  *              Aml                 - Executed AML address
172  *              Pathname            - Object path
173  *
174  * RETURN:      None
175  *
176  * DESCRIPTION: Internal interpreter execution trace.
177  *
178  ******************************************************************************/
179
180 void
181 AcpiExTracePoint (
182     ACPI_TRACE_EVENT_TYPE   Type,
183     BOOLEAN                 Begin,
184     UINT8                   *Aml,
185     char                    *Pathname)
186 {
187
188     ACPI_FUNCTION_NAME (ExTracePoint);
189
190
191     if (Pathname)
192     {
193         ACPI_DEBUG_PRINT ((ACPI_DB_TRACE_POINT,
194             "%s %s [0x%p:%s] execution.\n",
195             AcpiExGetTraceEventName (Type), Begin ? "Begin" : "End",
196             Aml, Pathname));
197     }
198     else
199     {
200         ACPI_DEBUG_PRINT ((ACPI_DB_TRACE_POINT,
201             "%s %s [0x%p] execution.\n",
202             AcpiExGetTraceEventName (Type), Begin ? "Begin" : "End",
203             Aml));
204     }
205 }
206
207
208 /*******************************************************************************
209  *
210  * FUNCTION:    AcpiExStartTraceMethod
211  *
212  * PARAMETERS:  MethodNode          - Node of the method
213  *              ObjDesc             - The method object
214  *              WalkState           - current state, NULL if not yet executing
215  *                                    a method.
216  *
217  * RETURN:      None
218  *
219  * DESCRIPTION: Start control method execution trace
220  *
221  ******************************************************************************/
222
223 void
224 AcpiExStartTraceMethod (
225     ACPI_NAMESPACE_NODE     *MethodNode,
226     ACPI_OPERAND_OBJECT     *ObjDesc,
227     ACPI_WALK_STATE         *WalkState)
228 {
229     ACPI_STATUS             Status;
230     char                    *Pathname = NULL;
231     BOOLEAN                 Enabled = FALSE;
232
233
234     ACPI_FUNCTION_NAME (ExStartTraceMethod);
235
236
237     if (MethodNode)
238     {
239         Pathname = AcpiNsGetNormalizedPathname (MethodNode, TRUE);
240     }
241
242     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
243     if (ACPI_FAILURE (Status))
244     {
245         goto Exit;
246     }
247
248     Enabled = AcpiExInterpreterTraceEnabled (Pathname);
249     if (Enabled && !AcpiGbl_TraceMethodObject)
250     {
251         AcpiGbl_TraceMethodObject = ObjDesc;
252         AcpiGbl_OriginalDbgLevel = AcpiDbgLevel;
253         AcpiGbl_OriginalDbgLayer = AcpiDbgLayer;
254         AcpiDbgLevel = ACPI_TRACE_LEVEL_ALL;
255         AcpiDbgLayer = ACPI_TRACE_LAYER_ALL;
256
257         if (AcpiGbl_TraceDbgLevel)
258         {
259             AcpiDbgLevel = AcpiGbl_TraceDbgLevel;
260         }
261
262         if (AcpiGbl_TraceDbgLayer)
263         {
264             AcpiDbgLayer = AcpiGbl_TraceDbgLayer;
265         }
266     }
267
268     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
269
270 Exit:
271     if (Enabled)
272     {
273         ACPI_TRACE_POINT (ACPI_TRACE_AML_METHOD, TRUE,
274             ObjDesc ? ObjDesc->Method.AmlStart : NULL, Pathname);
275     }
276
277     if (Pathname)
278     {
279         ACPI_FREE (Pathname);
280     }
281 }
282
283
284 /*******************************************************************************
285  *
286  * FUNCTION:    AcpiExStopTraceMethod
287  *
288  * PARAMETERS:  MethodNode          - Node of the method
289  *              ObjDesc             - The method object
290  *              WalkState           - current state, NULL if not yet executing
291  *                                    a method.
292  *
293  * RETURN:      None
294  *
295  * DESCRIPTION: Stop control method execution trace
296  *
297  ******************************************************************************/
298
299 void
300 AcpiExStopTraceMethod (
301     ACPI_NAMESPACE_NODE     *MethodNode,
302     ACPI_OPERAND_OBJECT     *ObjDesc,
303     ACPI_WALK_STATE         *WalkState)
304 {
305     ACPI_STATUS             Status;
306     char                    *Pathname = NULL;
307     BOOLEAN                 Enabled;
308
309
310     ACPI_FUNCTION_NAME (ExStopTraceMethod);
311
312
313     if (MethodNode)
314     {
315         Pathname = AcpiNsGetNormalizedPathname (MethodNode, TRUE);
316     }
317
318     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
319     if (ACPI_FAILURE (Status))
320     {
321         goto ExitPath;
322     }
323
324     Enabled = AcpiExInterpreterTraceEnabled (NULL);
325
326     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
327
328     if (Enabled)
329     {
330         ACPI_TRACE_POINT (ACPI_TRACE_AML_METHOD, FALSE,
331             ObjDesc ? ObjDesc->Method.AmlStart : NULL, Pathname);
332     }
333
334     Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
335     if (ACPI_FAILURE (Status))
336     {
337         goto ExitPath;
338     }
339
340     /* Check whether the tracer should be stopped */
341
342     if (AcpiGbl_TraceMethodObject == ObjDesc)
343     {
344         /* Disable further tracing if type is one-shot */
345
346         if (AcpiGbl_TraceFlags & ACPI_TRACE_ONESHOT)
347         {
348             AcpiGbl_TraceMethodName = NULL;
349         }
350
351         AcpiDbgLevel = AcpiGbl_OriginalDbgLevel;
352         AcpiDbgLayer = AcpiGbl_OriginalDbgLayer;
353         AcpiGbl_TraceMethodObject = NULL;
354     }
355
356     (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
357
358 ExitPath:
359     if (Pathname)
360     {
361         ACPI_FREE (Pathname);
362     }
363 }
364
365
366 /*******************************************************************************
367  *
368  * FUNCTION:    AcpiExStartTraceOpcode
369  *
370  * PARAMETERS:  Op                  - The parser opcode object
371  *              WalkState           - current state, NULL if not yet executing
372  *                                    a method.
373  *
374  * RETURN:      None
375  *
376  * DESCRIPTION: Start opcode execution trace
377  *
378  ******************************************************************************/
379
380 void
381 AcpiExStartTraceOpcode (
382     ACPI_PARSE_OBJECT       *Op,
383     ACPI_WALK_STATE         *WalkState)
384 {
385
386     ACPI_FUNCTION_NAME (ExStartTraceOpcode);
387
388
389     if (AcpiExInterpreterTraceEnabled (NULL) &&
390         (AcpiGbl_TraceFlags & ACPI_TRACE_OPCODE))
391     {
392         ACPI_TRACE_POINT (ACPI_TRACE_AML_OPCODE, TRUE,
393             Op->Common.Aml, Op->Common.AmlOpName);
394     }
395 }
396
397
398 /*******************************************************************************
399  *
400  * FUNCTION:    AcpiExStopTraceOpcode
401  *
402  * PARAMETERS:  Op                  - The parser opcode object
403  *              WalkState           - current state, NULL if not yet executing
404  *                                    a method.
405  *
406  * RETURN:      None
407  *
408  * DESCRIPTION: Stop opcode execution trace
409  *
410  ******************************************************************************/
411
412 void
413 AcpiExStopTraceOpcode (
414     ACPI_PARSE_OBJECT       *Op,
415     ACPI_WALK_STATE         *WalkState)
416 {
417
418     ACPI_FUNCTION_NAME (ExStopTraceOpcode);
419
420
421     if (AcpiExInterpreterTraceEnabled (NULL) &&
422         (AcpiGbl_TraceFlags & ACPI_TRACE_OPCODE))
423     {
424         ACPI_TRACE_POINT (ACPI_TRACE_AML_OPCODE, FALSE,
425             Op->Common.Aml, Op->Common.AmlOpName);
426     }
427 }