xref: /openbmc/linux/drivers/acpi/acpica/extrace.c (revision 612c2932)
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