1 /****************************************************************************** 2 * 3 * Module Name: extrace - Support for interpreter execution tracing 4 * 5 *****************************************************************************/ 6 7 /* 8 * Copyright (C) 2000 - 2020, 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 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 } 400