195857638SErik Schmauss // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
25df2e3edSBob Moore /******************************************************************************
35df2e3edSBob Moore *
45df2e3edSBob Moore * Module Name: extrace - Support for interpreter execution tracing
55df2e3edSBob Moore *
6*612c2932SBob Moore * Copyright (C) 2000 - 2023, Intel Corp.
75df2e3edSBob Moore *
895857638SErik Schmauss *****************************************************************************/
95df2e3edSBob Moore
105df2e3edSBob Moore #include <acpi/acpi.h>
115df2e3edSBob Moore #include "accommon.h"
125df2e3edSBob Moore #include "acnamesp.h"
135df2e3edSBob Moore #include "acinterp.h"
145df2e3edSBob Moore
155df2e3edSBob Moore #define _COMPONENT ACPI_EXECUTER
165df2e3edSBob Moore ACPI_MODULE_NAME("extrace")
175df2e3edSBob Moore
185df2e3edSBob Moore static union acpi_operand_object *acpi_gbl_trace_method_object = NULL;
195df2e3edSBob Moore
205df2e3edSBob Moore /* Local prototypes */
215df2e3edSBob Moore
225df2e3edSBob Moore #ifdef ACPI_DEBUG_OUTPUT
235df2e3edSBob Moore static const char *acpi_ex_get_trace_event_name(acpi_trace_event_type type);
245df2e3edSBob Moore #endif
255df2e3edSBob Moore
265df2e3edSBob Moore /*******************************************************************************
275df2e3edSBob Moore *
285df2e3edSBob Moore * FUNCTION: acpi_ex_interpreter_trace_enabled
295df2e3edSBob Moore *
305df2e3edSBob Moore * PARAMETERS: name - Whether method name should be matched,
315df2e3edSBob Moore * this should be checked before starting
325df2e3edSBob Moore * the tracer
335df2e3edSBob Moore *
345df2e3edSBob Moore * RETURN: TRUE if interpreter trace is enabled.
355df2e3edSBob Moore *
365df2e3edSBob Moore * DESCRIPTION: Check whether interpreter trace is enabled
375df2e3edSBob Moore *
385df2e3edSBob Moore ******************************************************************************/
395df2e3edSBob Moore
acpi_ex_interpreter_trace_enabled(char * name)405df2e3edSBob Moore static u8 acpi_ex_interpreter_trace_enabled(char *name)
415df2e3edSBob Moore {
425df2e3edSBob Moore
435df2e3edSBob Moore /* Check if tracing is enabled */
445df2e3edSBob Moore
455df2e3edSBob Moore if (!(acpi_gbl_trace_flags & ACPI_TRACE_ENABLED)) {
465df2e3edSBob Moore return (FALSE);
475df2e3edSBob Moore }
485df2e3edSBob Moore
495df2e3edSBob Moore /*
505df2e3edSBob Moore * Check if tracing is filtered:
515df2e3edSBob Moore *
525df2e3edSBob Moore * 1. If the tracer is started, acpi_gbl_trace_method_object should have
535df2e3edSBob Moore * been filled by the trace starter
545df2e3edSBob Moore * 2. If the tracer is not started, acpi_gbl_trace_method_name should be
555df2e3edSBob Moore * matched if it is specified
565df2e3edSBob Moore * 3. If the tracer is oneshot style, acpi_gbl_trace_method_name should
575df2e3edSBob Moore * not be cleared by the trace stopper during the first match
585df2e3edSBob Moore */
595df2e3edSBob Moore if (acpi_gbl_trace_method_object) {
605df2e3edSBob Moore return (TRUE);
615df2e3edSBob Moore }
625df2e3edSBob Moore
635df2e3edSBob Moore if (name &&
645df2e3edSBob Moore (acpi_gbl_trace_method_name &&
655df2e3edSBob Moore strcmp(acpi_gbl_trace_method_name, name))) {
665df2e3edSBob Moore return (FALSE);
675df2e3edSBob Moore }
685df2e3edSBob Moore
695df2e3edSBob Moore if ((acpi_gbl_trace_flags & ACPI_TRACE_ONESHOT) &&
705df2e3edSBob Moore !acpi_gbl_trace_method_name) {
715df2e3edSBob Moore return (FALSE);
725df2e3edSBob Moore }
735df2e3edSBob Moore
745df2e3edSBob Moore return (TRUE);
755df2e3edSBob Moore }
765df2e3edSBob Moore
775df2e3edSBob Moore /*******************************************************************************
785df2e3edSBob Moore *
795df2e3edSBob Moore * FUNCTION: acpi_ex_get_trace_event_name
805df2e3edSBob Moore *
815df2e3edSBob Moore * PARAMETERS: type - Trace event type
825df2e3edSBob Moore *
835df2e3edSBob Moore * RETURN: Trace event name.
845df2e3edSBob Moore *
855df2e3edSBob Moore * DESCRIPTION: Used to obtain the full trace event name.
865df2e3edSBob Moore *
875df2e3edSBob Moore ******************************************************************************/
885df2e3edSBob Moore
895df2e3edSBob Moore #ifdef ACPI_DEBUG_OUTPUT
905df2e3edSBob Moore
acpi_ex_get_trace_event_name(acpi_trace_event_type type)915df2e3edSBob Moore static const char *acpi_ex_get_trace_event_name(acpi_trace_event_type type)
925df2e3edSBob Moore {
935df2e3edSBob Moore
945df2e3edSBob Moore switch (type) {
955df2e3edSBob Moore case ACPI_TRACE_AML_METHOD:
965df2e3edSBob Moore
975df2e3edSBob Moore return "Method";
985df2e3edSBob Moore
995df2e3edSBob Moore case ACPI_TRACE_AML_OPCODE:
1005df2e3edSBob Moore
1015df2e3edSBob Moore return "Opcode";
1025df2e3edSBob Moore
1035df2e3edSBob Moore case ACPI_TRACE_AML_REGION:
1045df2e3edSBob Moore
1055df2e3edSBob Moore return "Region";
1065df2e3edSBob Moore
1075df2e3edSBob Moore default:
1085df2e3edSBob Moore
1095df2e3edSBob Moore return "";
1105df2e3edSBob Moore }
1115df2e3edSBob Moore }
1125df2e3edSBob Moore
1135df2e3edSBob Moore #endif
1145df2e3edSBob Moore
1155df2e3edSBob Moore /*******************************************************************************
1165df2e3edSBob Moore *
1175df2e3edSBob Moore * FUNCTION: acpi_ex_trace_point
1185df2e3edSBob Moore *
1195df2e3edSBob Moore * PARAMETERS: type - Trace event type
1205df2e3edSBob Moore * begin - TRUE if before execution
1215df2e3edSBob Moore * aml - Executed AML address
1225df2e3edSBob Moore * pathname - Object path
1235df2e3edSBob Moore *
1245df2e3edSBob Moore * RETURN: None
1255df2e3edSBob Moore *
1265df2e3edSBob Moore * DESCRIPTION: Internal interpreter execution trace.
1275df2e3edSBob Moore *
1285df2e3edSBob Moore ******************************************************************************/
1295df2e3edSBob Moore
1305df2e3edSBob Moore void
acpi_ex_trace_point(acpi_trace_event_type type,u8 begin,u8 * aml,char * pathname)1315df2e3edSBob Moore acpi_ex_trace_point(acpi_trace_event_type type,
1325df2e3edSBob Moore u8 begin, u8 *aml, char *pathname)
1335df2e3edSBob Moore {
1345df2e3edSBob Moore
1355df2e3edSBob Moore ACPI_FUNCTION_NAME(ex_trace_point);
1365df2e3edSBob Moore
1375df2e3edSBob Moore if (pathname) {
1385df2e3edSBob Moore ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT,
1395df2e3edSBob Moore "%s %s [0x%p:%s] execution.\n",
1405df2e3edSBob Moore acpi_ex_get_trace_event_name(type),
1415df2e3edSBob Moore begin ? "Begin" : "End", aml, pathname));
1425df2e3edSBob Moore } else {
1435df2e3edSBob Moore ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT,
1445df2e3edSBob Moore "%s %s [0x%p] execution.\n",
1455df2e3edSBob Moore acpi_ex_get_trace_event_name(type),
1465df2e3edSBob Moore begin ? "Begin" : "End", aml));
1475df2e3edSBob Moore }
1485df2e3edSBob Moore }
1495df2e3edSBob Moore
1505df2e3edSBob Moore /*******************************************************************************
1515df2e3edSBob Moore *
1525df2e3edSBob Moore * FUNCTION: acpi_ex_start_trace_method
1535df2e3edSBob Moore *
1545df2e3edSBob Moore * PARAMETERS: method_node - Node of the method
1555df2e3edSBob Moore * obj_desc - The method object
1565df2e3edSBob Moore * walk_state - current state, NULL if not yet executing
1575df2e3edSBob Moore * a method.
1585df2e3edSBob Moore *
1595df2e3edSBob Moore * RETURN: None
1605df2e3edSBob Moore *
1615df2e3edSBob Moore * DESCRIPTION: Start control method execution trace
1625df2e3edSBob Moore *
1635df2e3edSBob Moore ******************************************************************************/
1645df2e3edSBob Moore
1655df2e3edSBob Moore void
acpi_ex_start_trace_method(struct acpi_namespace_node * method_node,union acpi_operand_object * obj_desc,struct acpi_walk_state * walk_state)1665df2e3edSBob Moore acpi_ex_start_trace_method(struct acpi_namespace_node *method_node,
1675df2e3edSBob Moore union acpi_operand_object *obj_desc,
1685df2e3edSBob Moore struct acpi_walk_state *walk_state)
1695df2e3edSBob Moore {
1705df2e3edSBob Moore char *pathname = NULL;
1715df2e3edSBob Moore u8 enabled = FALSE;
1725df2e3edSBob Moore
1735df2e3edSBob Moore ACPI_FUNCTION_NAME(ex_start_trace_method);
1745df2e3edSBob Moore
1755df2e3edSBob Moore if (method_node) {
1765df2e3edSBob Moore pathname = acpi_ns_get_normalized_pathname(method_node, TRUE);
1775df2e3edSBob Moore }
1785df2e3edSBob Moore
1795df2e3edSBob Moore enabled = acpi_ex_interpreter_trace_enabled(pathname);
1805df2e3edSBob Moore if (enabled && !acpi_gbl_trace_method_object) {
1815df2e3edSBob Moore acpi_gbl_trace_method_object = obj_desc;
1825df2e3edSBob Moore acpi_gbl_original_dbg_level = acpi_dbg_level;
1835df2e3edSBob Moore acpi_gbl_original_dbg_layer = acpi_dbg_layer;
1845df2e3edSBob Moore acpi_dbg_level = ACPI_TRACE_LEVEL_ALL;
1855df2e3edSBob Moore acpi_dbg_layer = ACPI_TRACE_LAYER_ALL;
1865df2e3edSBob Moore
1875df2e3edSBob Moore if (acpi_gbl_trace_dbg_level) {
1885df2e3edSBob Moore acpi_dbg_level = acpi_gbl_trace_dbg_level;
1895df2e3edSBob Moore }
1905df2e3edSBob Moore
1915df2e3edSBob Moore if (acpi_gbl_trace_dbg_layer) {
1925df2e3edSBob Moore acpi_dbg_layer = acpi_gbl_trace_dbg_layer;
1935df2e3edSBob Moore }
1945df2e3edSBob Moore }
1955df2e3edSBob Moore
1965df2e3edSBob Moore if (enabled) {
1975df2e3edSBob Moore ACPI_TRACE_POINT(ACPI_TRACE_AML_METHOD, TRUE,
1985df2e3edSBob Moore obj_desc ? obj_desc->method.aml_start : NULL,
1995df2e3edSBob Moore pathname);
2005df2e3edSBob Moore }
2015df2e3edSBob Moore
2025df2e3edSBob Moore if (pathname) {
2035df2e3edSBob Moore ACPI_FREE(pathname);
2045df2e3edSBob Moore }
2055df2e3edSBob Moore }
2065df2e3edSBob Moore
2075df2e3edSBob Moore /*******************************************************************************
2085df2e3edSBob Moore *
2095df2e3edSBob Moore * FUNCTION: acpi_ex_stop_trace_method
2105df2e3edSBob Moore *
2115df2e3edSBob Moore * PARAMETERS: method_node - Node of the method
2125df2e3edSBob Moore * obj_desc - The method object
2135df2e3edSBob Moore * walk_state - current state, NULL if not yet executing
2145df2e3edSBob Moore * a method.
2155df2e3edSBob Moore *
2165df2e3edSBob Moore * RETURN: None
2175df2e3edSBob Moore *
2185df2e3edSBob Moore * DESCRIPTION: Stop control method execution trace
2195df2e3edSBob Moore *
2205df2e3edSBob Moore ******************************************************************************/
2215df2e3edSBob Moore
2225df2e3edSBob Moore void
acpi_ex_stop_trace_method(struct acpi_namespace_node * method_node,union acpi_operand_object * obj_desc,struct acpi_walk_state * walk_state)2235df2e3edSBob Moore acpi_ex_stop_trace_method(struct acpi_namespace_node *method_node,
2245df2e3edSBob Moore union acpi_operand_object *obj_desc,
2255df2e3edSBob Moore struct acpi_walk_state *walk_state)
2265df2e3edSBob Moore {
2275df2e3edSBob Moore char *pathname = NULL;
2285df2e3edSBob Moore u8 enabled;
2295df2e3edSBob Moore
2305df2e3edSBob Moore ACPI_FUNCTION_NAME(ex_stop_trace_method);
2315df2e3edSBob Moore
2325df2e3edSBob Moore if (method_node) {
2335df2e3edSBob Moore pathname = acpi_ns_get_normalized_pathname(method_node, TRUE);
2345df2e3edSBob Moore }
2355df2e3edSBob Moore
2365df2e3edSBob Moore enabled = acpi_ex_interpreter_trace_enabled(NULL);
2375df2e3edSBob Moore
2385df2e3edSBob Moore if (enabled) {
2395df2e3edSBob Moore ACPI_TRACE_POINT(ACPI_TRACE_AML_METHOD, FALSE,
2405df2e3edSBob Moore obj_desc ? obj_desc->method.aml_start : NULL,
2415df2e3edSBob Moore pathname);
2425df2e3edSBob Moore }
2435df2e3edSBob Moore
2445df2e3edSBob Moore /* Check whether the tracer should be stopped */
2455df2e3edSBob Moore
2465df2e3edSBob Moore if (acpi_gbl_trace_method_object == obj_desc) {
2475df2e3edSBob Moore
2485df2e3edSBob Moore /* Disable further tracing if type is one-shot */
2495df2e3edSBob Moore
2505df2e3edSBob Moore if (acpi_gbl_trace_flags & ACPI_TRACE_ONESHOT) {
2515df2e3edSBob Moore acpi_gbl_trace_method_name = NULL;
2525df2e3edSBob Moore }
2535df2e3edSBob Moore
2545df2e3edSBob Moore acpi_dbg_level = acpi_gbl_original_dbg_level;
2555df2e3edSBob Moore acpi_dbg_layer = acpi_gbl_original_dbg_layer;
2565df2e3edSBob Moore acpi_gbl_trace_method_object = NULL;
2575df2e3edSBob Moore }
2585df2e3edSBob Moore
2595df2e3edSBob Moore if (pathname) {
2605df2e3edSBob Moore ACPI_FREE(pathname);
2615df2e3edSBob Moore }
2625df2e3edSBob Moore }
2635df2e3edSBob Moore
2645df2e3edSBob Moore /*******************************************************************************
2655df2e3edSBob Moore *
2665df2e3edSBob Moore * FUNCTION: acpi_ex_start_trace_opcode
2675df2e3edSBob Moore *
2685df2e3edSBob Moore * PARAMETERS: op - The parser opcode object
2695df2e3edSBob Moore * walk_state - current state, NULL if not yet executing
2705df2e3edSBob Moore * a method.
2715df2e3edSBob Moore *
2725df2e3edSBob Moore * RETURN: None
2735df2e3edSBob Moore *
2745df2e3edSBob Moore * DESCRIPTION: Start opcode execution trace
2755df2e3edSBob Moore *
2765df2e3edSBob Moore ******************************************************************************/
2775df2e3edSBob Moore
2785df2e3edSBob Moore void
acpi_ex_start_trace_opcode(union acpi_parse_object * op,struct acpi_walk_state * walk_state)2795df2e3edSBob Moore acpi_ex_start_trace_opcode(union acpi_parse_object *op,
2805df2e3edSBob Moore struct acpi_walk_state *walk_state)
2815df2e3edSBob Moore {
2825df2e3edSBob Moore
2835df2e3edSBob Moore ACPI_FUNCTION_NAME(ex_start_trace_opcode);
2845df2e3edSBob Moore
2855df2e3edSBob Moore if (acpi_ex_interpreter_trace_enabled(NULL) &&
2865df2e3edSBob Moore (acpi_gbl_trace_flags & ACPI_TRACE_OPCODE)) {
2875df2e3edSBob Moore ACPI_TRACE_POINT(ACPI_TRACE_AML_OPCODE, TRUE,
2885df2e3edSBob Moore op->common.aml, op->common.aml_op_name);
2895df2e3edSBob Moore }
2905df2e3edSBob Moore }
2915df2e3edSBob Moore
2925df2e3edSBob Moore /*******************************************************************************
2935df2e3edSBob Moore *
2945df2e3edSBob Moore * FUNCTION: acpi_ex_stop_trace_opcode
2955df2e3edSBob Moore *
2965df2e3edSBob Moore * PARAMETERS: op - The parser opcode object
2975df2e3edSBob Moore * walk_state - current state, NULL if not yet executing
2985df2e3edSBob Moore * a method.
2995df2e3edSBob Moore *
3005df2e3edSBob Moore * RETURN: None
3015df2e3edSBob Moore *
3025df2e3edSBob Moore * DESCRIPTION: Stop opcode execution trace
3035df2e3edSBob Moore *
3045df2e3edSBob Moore ******************************************************************************/
3055df2e3edSBob Moore
3065df2e3edSBob Moore void
acpi_ex_stop_trace_opcode(union acpi_parse_object * op,struct acpi_walk_state * walk_state)3075df2e3edSBob Moore acpi_ex_stop_trace_opcode(union acpi_parse_object *op,
3085df2e3edSBob Moore struct acpi_walk_state *walk_state)
3095df2e3edSBob Moore {
3105df2e3edSBob Moore
3115df2e3edSBob Moore ACPI_FUNCTION_NAME(ex_stop_trace_opcode);
3125df2e3edSBob Moore
3135df2e3edSBob Moore if (acpi_ex_interpreter_trace_enabled(NULL) &&
3145df2e3edSBob Moore (acpi_gbl_trace_flags & ACPI_TRACE_OPCODE)) {
3155df2e3edSBob Moore ACPI_TRACE_POINT(ACPI_TRACE_AML_OPCODE, FALSE,
3165df2e3edSBob Moore op->common.aml, op->common.aml_op_name);
3175df2e3edSBob Moore }
3185df2e3edSBob Moore }
319