Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /******************************************************************************
0003  *
0004  * Module Name: extrace - Support for interpreter execution tracing
0005  *
0006  * Copyright (C) 2000 - 2022, Intel Corp.
0007  *
0008  *****************************************************************************/
0009 
0010 #include <acpi/acpi.h>
0011 #include "accommon.h"
0012 #include "acnamesp.h"
0013 #include "acinterp.h"
0014 
0015 #define _COMPONENT          ACPI_EXECUTER
0016 ACPI_MODULE_NAME("extrace")
0017 
0018 static union acpi_operand_object *acpi_gbl_trace_method_object = NULL;
0019 
0020 /* Local prototypes */
0021 
0022 #ifdef ACPI_DEBUG_OUTPUT
0023 static const char *acpi_ex_get_trace_event_name(acpi_trace_event_type type);
0024 #endif
0025 
0026 /*******************************************************************************
0027  *
0028  * FUNCTION:    acpi_ex_interpreter_trace_enabled
0029  *
0030  * PARAMETERS:  name                - Whether method name should be matched,
0031  *                                    this should be checked before starting
0032  *                                    the tracer
0033  *
0034  * RETURN:      TRUE if interpreter trace is enabled.
0035  *
0036  * DESCRIPTION: Check whether interpreter trace is enabled
0037  *
0038  ******************************************************************************/
0039 
0040 static u8 acpi_ex_interpreter_trace_enabled(char *name)
0041 {
0042 
0043     /* Check if tracing is enabled */
0044 
0045     if (!(acpi_gbl_trace_flags & ACPI_TRACE_ENABLED)) {
0046         return (FALSE);
0047     }
0048 
0049     /*
0050      * Check if tracing is filtered:
0051      *
0052      * 1. If the tracer is started, acpi_gbl_trace_method_object should have
0053      *    been filled by the trace starter
0054      * 2. If the tracer is not started, acpi_gbl_trace_method_name should be
0055      *    matched if it is specified
0056      * 3. If the tracer is oneshot style, acpi_gbl_trace_method_name should
0057      *    not be cleared by the trace stopper during the first match
0058      */
0059     if (acpi_gbl_trace_method_object) {
0060         return (TRUE);
0061     }
0062 
0063     if (name &&
0064         (acpi_gbl_trace_method_name &&
0065          strcmp(acpi_gbl_trace_method_name, name))) {
0066         return (FALSE);
0067     }
0068 
0069     if ((acpi_gbl_trace_flags & ACPI_TRACE_ONESHOT) &&
0070         !acpi_gbl_trace_method_name) {
0071         return (FALSE);
0072     }
0073 
0074     return (TRUE);
0075 }
0076 
0077 /*******************************************************************************
0078  *
0079  * FUNCTION:    acpi_ex_get_trace_event_name
0080  *
0081  * PARAMETERS:  type            - Trace event type
0082  *
0083  * RETURN:      Trace event name.
0084  *
0085  * DESCRIPTION: Used to obtain the full trace event name.
0086  *
0087  ******************************************************************************/
0088 
0089 #ifdef ACPI_DEBUG_OUTPUT
0090 
0091 static const char *acpi_ex_get_trace_event_name(acpi_trace_event_type type)
0092 {
0093 
0094     switch (type) {
0095     case ACPI_TRACE_AML_METHOD:
0096 
0097         return "Method";
0098 
0099     case ACPI_TRACE_AML_OPCODE:
0100 
0101         return "Opcode";
0102 
0103     case ACPI_TRACE_AML_REGION:
0104 
0105         return "Region";
0106 
0107     default:
0108 
0109         return "";
0110     }
0111 }
0112 
0113 #endif
0114 
0115 /*******************************************************************************
0116  *
0117  * FUNCTION:    acpi_ex_trace_point
0118  *
0119  * PARAMETERS:  type                - Trace event type
0120  *              begin               - TRUE if before execution
0121  *              aml                 - Executed AML address
0122  *              pathname            - Object path
0123  *
0124  * RETURN:      None
0125  *
0126  * DESCRIPTION: Internal interpreter execution trace.
0127  *
0128  ******************************************************************************/
0129 
0130 void
0131 acpi_ex_trace_point(acpi_trace_event_type type,
0132             u8 begin, u8 *aml, char *pathname)
0133 {
0134 
0135     ACPI_FUNCTION_NAME(ex_trace_point);
0136 
0137     if (pathname) {
0138         ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT,
0139                   "%s %s [0x%p:%s] execution.\n",
0140                   acpi_ex_get_trace_event_name(type),
0141                   begin ? "Begin" : "End", aml, pathname));
0142     } else {
0143         ACPI_DEBUG_PRINT((ACPI_DB_TRACE_POINT,
0144                   "%s %s [0x%p] execution.\n",
0145                   acpi_ex_get_trace_event_name(type),
0146                   begin ? "Begin" : "End", aml));
0147     }
0148 }
0149 
0150 /*******************************************************************************
0151  *
0152  * FUNCTION:    acpi_ex_start_trace_method
0153  *
0154  * PARAMETERS:  method_node         - Node of the method
0155  *              obj_desc            - The method object
0156  *              walk_state          - current state, NULL if not yet executing
0157  *                                    a method.
0158  *
0159  * RETURN:      None
0160  *
0161  * DESCRIPTION: Start control method execution trace
0162  *
0163  ******************************************************************************/
0164 
0165 void
0166 acpi_ex_start_trace_method(struct acpi_namespace_node *method_node,
0167                union acpi_operand_object *obj_desc,
0168                struct acpi_walk_state *walk_state)
0169 {
0170     char *pathname = NULL;
0171     u8 enabled = FALSE;
0172 
0173     ACPI_FUNCTION_NAME(ex_start_trace_method);
0174 
0175     if (method_node) {
0176         pathname = acpi_ns_get_normalized_pathname(method_node, TRUE);
0177     }
0178 
0179     enabled = acpi_ex_interpreter_trace_enabled(pathname);
0180     if (enabled && !acpi_gbl_trace_method_object) {
0181         acpi_gbl_trace_method_object = obj_desc;
0182         acpi_gbl_original_dbg_level = acpi_dbg_level;
0183         acpi_gbl_original_dbg_layer = acpi_dbg_layer;
0184         acpi_dbg_level = ACPI_TRACE_LEVEL_ALL;
0185         acpi_dbg_layer = ACPI_TRACE_LAYER_ALL;
0186 
0187         if (acpi_gbl_trace_dbg_level) {
0188             acpi_dbg_level = acpi_gbl_trace_dbg_level;
0189         }
0190 
0191         if (acpi_gbl_trace_dbg_layer) {
0192             acpi_dbg_layer = acpi_gbl_trace_dbg_layer;
0193         }
0194     }
0195 
0196     if (enabled) {
0197         ACPI_TRACE_POINT(ACPI_TRACE_AML_METHOD, TRUE,
0198                  obj_desc ? obj_desc->method.aml_start : NULL,
0199                  pathname);
0200     }
0201 
0202     if (pathname) {
0203         ACPI_FREE(pathname);
0204     }
0205 }
0206 
0207 /*******************************************************************************
0208  *
0209  * FUNCTION:    acpi_ex_stop_trace_method
0210  *
0211  * PARAMETERS:  method_node         - Node of the method
0212  *              obj_desc            - The method object
0213  *              walk_state          - current state, NULL if not yet executing
0214  *                                    a method.
0215  *
0216  * RETURN:      None
0217  *
0218  * DESCRIPTION: Stop control method execution trace
0219  *
0220  ******************************************************************************/
0221 
0222 void
0223 acpi_ex_stop_trace_method(struct acpi_namespace_node *method_node,
0224               union acpi_operand_object *obj_desc,
0225               struct acpi_walk_state *walk_state)
0226 {
0227     char *pathname = NULL;
0228     u8 enabled;
0229 
0230     ACPI_FUNCTION_NAME(ex_stop_trace_method);
0231 
0232     if (method_node) {
0233         pathname = acpi_ns_get_normalized_pathname(method_node, TRUE);
0234     }
0235 
0236     enabled = acpi_ex_interpreter_trace_enabled(NULL);
0237 
0238     if (enabled) {
0239         ACPI_TRACE_POINT(ACPI_TRACE_AML_METHOD, FALSE,
0240                  obj_desc ? obj_desc->method.aml_start : NULL,
0241                  pathname);
0242     }
0243 
0244     /* Check whether the tracer should be stopped */
0245 
0246     if (acpi_gbl_trace_method_object == obj_desc) {
0247 
0248         /* Disable further tracing if type is one-shot */
0249 
0250         if (acpi_gbl_trace_flags & ACPI_TRACE_ONESHOT) {
0251             acpi_gbl_trace_method_name = NULL;
0252         }
0253 
0254         acpi_dbg_level = acpi_gbl_original_dbg_level;
0255         acpi_dbg_layer = acpi_gbl_original_dbg_layer;
0256         acpi_gbl_trace_method_object = NULL;
0257     }
0258 
0259     if (pathname) {
0260         ACPI_FREE(pathname);
0261     }
0262 }
0263 
0264 /*******************************************************************************
0265  *
0266  * FUNCTION:    acpi_ex_start_trace_opcode
0267  *
0268  * PARAMETERS:  op                  - The parser opcode object
0269  *              walk_state          - current state, NULL if not yet executing
0270  *                                    a method.
0271  *
0272  * RETURN:      None
0273  *
0274  * DESCRIPTION: Start opcode execution trace
0275  *
0276  ******************************************************************************/
0277 
0278 void
0279 acpi_ex_start_trace_opcode(union acpi_parse_object *op,
0280                struct acpi_walk_state *walk_state)
0281 {
0282 
0283     ACPI_FUNCTION_NAME(ex_start_trace_opcode);
0284 
0285     if (acpi_ex_interpreter_trace_enabled(NULL) &&
0286         (acpi_gbl_trace_flags & ACPI_TRACE_OPCODE)) {
0287         ACPI_TRACE_POINT(ACPI_TRACE_AML_OPCODE, TRUE,
0288                  op->common.aml, op->common.aml_op_name);
0289     }
0290 }
0291 
0292 /*******************************************************************************
0293  *
0294  * FUNCTION:    acpi_ex_stop_trace_opcode
0295  *
0296  * PARAMETERS:  op                  - The parser opcode object
0297  *              walk_state          - current state, NULL if not yet executing
0298  *                                    a method.
0299  *
0300  * RETURN:      None
0301  *
0302  * DESCRIPTION: Stop opcode execution trace
0303  *
0304  ******************************************************************************/
0305 
0306 void
0307 acpi_ex_stop_trace_opcode(union acpi_parse_object *op,
0308               struct acpi_walk_state *walk_state)
0309 {
0310 
0311     ACPI_FUNCTION_NAME(ex_stop_trace_opcode);
0312 
0313     if (acpi_ex_interpreter_trace_enabled(NULL) &&
0314         (acpi_gbl_trace_flags & ACPI_TRACE_OPCODE)) {
0315         ACPI_TRACE_POINT(ACPI_TRACE_AML_OPCODE, FALSE,
0316                  op->common.aml, op->common.aml_op_name);
0317     }
0318 }