]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/contrib/dev/acpica/components/executer/extrace.c
Merge in changes from ^/vendor/NetBSD/tests/dist@r313245
[FreeBSD/FreeBSD.git] / sys / contrib / dev / acpica / components / executer / extrace.c
1 /******************************************************************************
2  *
3  * Module Name: extrace - Support for interpreter execution tracing
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2017, 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/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     char                    *Pathname = NULL;
230     BOOLEAN                 Enabled = FALSE;
231
232
233     ACPI_FUNCTION_NAME (ExStartTraceMethod);
234
235
236     if (MethodNode)
237     {
238         Pathname = AcpiNsGetNormalizedPathname (MethodNode, TRUE);
239     }
240
241     Enabled = AcpiExInterpreterTraceEnabled (Pathname);
242     if (Enabled && !AcpiGbl_TraceMethodObject)
243     {
244         AcpiGbl_TraceMethodObject = ObjDesc;
245         AcpiGbl_OriginalDbgLevel = AcpiDbgLevel;
246         AcpiGbl_OriginalDbgLayer = AcpiDbgLayer;
247         AcpiDbgLevel = ACPI_TRACE_LEVEL_ALL;
248         AcpiDbgLayer = ACPI_TRACE_LAYER_ALL;
249
250         if (AcpiGbl_TraceDbgLevel)
251         {
252             AcpiDbgLevel = AcpiGbl_TraceDbgLevel;
253         }
254
255         if (AcpiGbl_TraceDbgLayer)
256         {
257             AcpiDbgLayer = AcpiGbl_TraceDbgLayer;
258         }
259     }
260
261     if (Enabled)
262     {
263         ACPI_TRACE_POINT (ACPI_TRACE_AML_METHOD, TRUE,
264             ObjDesc ? ObjDesc->Method.AmlStart : NULL, Pathname);
265     }
266
267     if (Pathname)
268     {
269         ACPI_FREE (Pathname);
270     }
271 }
272
273
274 /*******************************************************************************
275  *
276  * FUNCTION:    AcpiExStopTraceMethod
277  *
278  * PARAMETERS:  MethodNode          - Node of the method
279  *              ObjDesc             - The method object
280  *              WalkState           - current state, NULL if not yet executing
281  *                                    a method.
282  *
283  * RETURN:      None
284  *
285  * DESCRIPTION: Stop control method execution trace
286  *
287  ******************************************************************************/
288
289 void
290 AcpiExStopTraceMethod (
291     ACPI_NAMESPACE_NODE     *MethodNode,
292     ACPI_OPERAND_OBJECT     *ObjDesc,
293     ACPI_WALK_STATE         *WalkState)
294 {
295     char                    *Pathname = NULL;
296     BOOLEAN                 Enabled;
297
298
299     ACPI_FUNCTION_NAME (ExStopTraceMethod);
300
301
302     if (MethodNode)
303     {
304         Pathname = AcpiNsGetNormalizedPathname (MethodNode, TRUE);
305     }
306
307     Enabled = AcpiExInterpreterTraceEnabled (NULL);
308
309     if (Enabled)
310     {
311         ACPI_TRACE_POINT (ACPI_TRACE_AML_METHOD, FALSE,
312             ObjDesc ? ObjDesc->Method.AmlStart : NULL, Pathname);
313     }
314
315     /* Check whether the tracer should be stopped */
316
317     if (AcpiGbl_TraceMethodObject == ObjDesc)
318     {
319         /* Disable further tracing if type is one-shot */
320
321         if (AcpiGbl_TraceFlags & ACPI_TRACE_ONESHOT)
322         {
323             AcpiGbl_TraceMethodName = NULL;
324         }
325
326         AcpiDbgLevel = AcpiGbl_OriginalDbgLevel;
327         AcpiDbgLayer = AcpiGbl_OriginalDbgLayer;
328         AcpiGbl_TraceMethodObject = NULL;
329     }
330
331     if (Pathname)
332     {
333         ACPI_FREE (Pathname);
334     }
335 }
336
337
338 /*******************************************************************************
339  *
340  * FUNCTION:    AcpiExStartTraceOpcode
341  *
342  * PARAMETERS:  Op                  - The parser opcode object
343  *              WalkState           - current state, NULL if not yet executing
344  *                                    a method.
345  *
346  * RETURN:      None
347  *
348  * DESCRIPTION: Start opcode execution trace
349  *
350  ******************************************************************************/
351
352 void
353 AcpiExStartTraceOpcode (
354     ACPI_PARSE_OBJECT       *Op,
355     ACPI_WALK_STATE         *WalkState)
356 {
357
358     ACPI_FUNCTION_NAME (ExStartTraceOpcode);
359
360
361     if (AcpiExInterpreterTraceEnabled (NULL) &&
362         (AcpiGbl_TraceFlags & ACPI_TRACE_OPCODE))
363     {
364         ACPI_TRACE_POINT (ACPI_TRACE_AML_OPCODE, TRUE,
365             Op->Common.Aml, Op->Common.AmlOpName);
366     }
367 }
368
369
370 /*******************************************************************************
371  *
372  * FUNCTION:    AcpiExStopTraceOpcode
373  *
374  * PARAMETERS:  Op                  - The parser opcode object
375  *              WalkState           - current state, NULL if not yet executing
376  *                                    a method.
377  *
378  * RETURN:      None
379  *
380  * DESCRIPTION: Stop opcode execution trace
381  *
382  ******************************************************************************/
383
384 void
385 AcpiExStopTraceOpcode (
386     ACPI_PARSE_OBJECT       *Op,
387     ACPI_WALK_STATE         *WalkState)
388 {
389
390     ACPI_FUNCTION_NAME (ExStopTraceOpcode);
391
392
393     if (AcpiExInterpreterTraceEnabled (NULL) &&
394         (AcpiGbl_TraceFlags & ACPI_TRACE_OPCODE))
395     {
396         ACPI_TRACE_POINT (ACPI_TRACE_AML_OPCODE, FALSE,
397             Op->Common.Aml, Op->Common.AmlOpName);
398     }
399 }