1291333Sjkim/****************************************************************************** 2291333Sjkim * 3291333Sjkim * Module Name: extrace - Support for interpreter execution tracing 4291333Sjkim * 5291333Sjkim *****************************************************************************/ 6291333Sjkim 7291333Sjkim/* 8298714Sjkim * Copyright (C) 2000 - 2016, Intel Corp. 9291333Sjkim * All rights reserved. 10291333Sjkim * 11291333Sjkim * Redistribution and use in source and binary forms, with or without 12291333Sjkim * modification, are permitted provided that the following conditions 13291333Sjkim * are met: 14291333Sjkim * 1. Redistributions of source code must retain the above copyright 15291333Sjkim * notice, this list of conditions, and the following disclaimer, 16291333Sjkim * without modification. 17291333Sjkim * 2. Redistributions in binary form must reproduce at minimum a disclaimer 18291333Sjkim * substantially similar to the "NO WARRANTY" disclaimer below 19291333Sjkim * ("Disclaimer") and any redistribution must be conditioned upon 20291333Sjkim * including a substantially similar Disclaimer requirement for further 21291333Sjkim * binary redistribution. 22291333Sjkim * 3. Neither the names of the above-listed copyright holders nor the names 23291333Sjkim * of any contributors may be used to endorse or promote products derived 24291333Sjkim * from this software without specific prior written permission. 25291333Sjkim * 26291333Sjkim * Alternatively, this software may be distributed under the terms of the 27291333Sjkim * GNU General Public License ("GPL") version 2 as published by the Free 28291333Sjkim * Software Foundation. 29291333Sjkim * 30291333Sjkim * NO WARRANTY 31291333Sjkim * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 32291333Sjkim * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 33291333Sjkim * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 34291333Sjkim * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 35291333Sjkim * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36291333Sjkim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37291333Sjkim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38291333Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39291333Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 40291333Sjkim * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41291333Sjkim * POSSIBILITY OF SUCH DAMAGES. 42291333Sjkim */ 43291333Sjkim 44298714Sjkim#include <contrib/dev/acpica/include/acpi.h> 45298714Sjkim#include <contrib/dev/acpica/include/accommon.h> 46298714Sjkim#include <contrib/dev/acpica/include/acnamesp.h> 47298714Sjkim#include <contrib/dev/acpica/include/acinterp.h> 48291333Sjkim 49291333Sjkim 50291333Sjkim#define _COMPONENT ACPI_EXECUTER 51291333Sjkim ACPI_MODULE_NAME ("extrace") 52291333Sjkim 53291333Sjkim 54291333Sjkimstatic ACPI_OPERAND_OBJECT *AcpiGbl_TraceMethodObject = NULL; 55291333Sjkim 56291333Sjkim/* Local prototypes */ 57291333Sjkim 58291333Sjkim#ifdef ACPI_DEBUG_OUTPUT 59291333Sjkimstatic const char * 60291333SjkimAcpiExGetTraceEventName ( 61291333Sjkim ACPI_TRACE_EVENT_TYPE Type); 62291333Sjkim#endif 63291333Sjkim 64291333Sjkim 65291333Sjkim/******************************************************************************* 66291333Sjkim * 67291333Sjkim * FUNCTION: AcpiExInterpreterTraceEnabled 68291333Sjkim * 69291333Sjkim * PARAMETERS: Name - Whether method name should be matched, 70291333Sjkim * this should be checked before starting 71291333Sjkim * the tracer 72291333Sjkim * 73291333Sjkim * RETURN: TRUE if interpreter trace is enabled. 74291333Sjkim * 75291333Sjkim * DESCRIPTION: Check whether interpreter trace is enabled 76291333Sjkim * 77291333Sjkim ******************************************************************************/ 78291333Sjkim 79291333Sjkimstatic BOOLEAN 80291333SjkimAcpiExInterpreterTraceEnabled ( 81291333Sjkim char *Name) 82291333Sjkim{ 83291333Sjkim 84291333Sjkim /* Check if tracing is enabled */ 85291333Sjkim 86291333Sjkim if (!(AcpiGbl_TraceFlags & ACPI_TRACE_ENABLED)) 87291333Sjkim { 88291333Sjkim return (FALSE); 89291333Sjkim } 90291333Sjkim 91291333Sjkim /* 92291333Sjkim * Check if tracing is filtered: 93291333Sjkim * 94291333Sjkim * 1. If the tracer is started, AcpiGbl_TraceMethodObject should have 95291333Sjkim * been filled by the trace starter 96291333Sjkim * 2. If the tracer is not started, AcpiGbl_TraceMethodName should be 97291333Sjkim * matched if it is specified 98291333Sjkim * 3. If the tracer is oneshot style, AcpiGbl_TraceMethodName should 99291333Sjkim * not be cleared by the trace stopper during the first match 100291333Sjkim */ 101291333Sjkim if (AcpiGbl_TraceMethodObject) 102291333Sjkim { 103291333Sjkim return (TRUE); 104291333Sjkim } 105291333Sjkim 106291333Sjkim if (Name && 107291333Sjkim (AcpiGbl_TraceMethodName && 108291333Sjkim strcmp (AcpiGbl_TraceMethodName, Name))) 109291333Sjkim { 110291333Sjkim return (FALSE); 111291333Sjkim } 112291333Sjkim 113291333Sjkim if ((AcpiGbl_TraceFlags & ACPI_TRACE_ONESHOT) && 114291333Sjkim !AcpiGbl_TraceMethodName) 115291333Sjkim { 116291333Sjkim return (FALSE); 117291333Sjkim } 118291333Sjkim 119291333Sjkim return (TRUE); 120291333Sjkim} 121291333Sjkim 122291333Sjkim 123291333Sjkim/******************************************************************************* 124291333Sjkim * 125291333Sjkim * FUNCTION: AcpiExGetTraceEventName 126291333Sjkim * 127291333Sjkim * PARAMETERS: Type - Trace event type 128291333Sjkim * 129291333Sjkim * RETURN: Trace event name. 130291333Sjkim * 131291333Sjkim * DESCRIPTION: Used to obtain the full trace event name. 132291333Sjkim * 133291333Sjkim ******************************************************************************/ 134291333Sjkim 135291333Sjkim#ifdef ACPI_DEBUG_OUTPUT 136291333Sjkim 137291333Sjkimstatic const char * 138291333SjkimAcpiExGetTraceEventName ( 139291333Sjkim ACPI_TRACE_EVENT_TYPE Type) 140291333Sjkim{ 141291333Sjkim 142291333Sjkim switch (Type) 143291333Sjkim { 144291333Sjkim case ACPI_TRACE_AML_METHOD: 145291333Sjkim 146291333Sjkim return "Method"; 147291333Sjkim 148291333Sjkim case ACPI_TRACE_AML_OPCODE: 149291333Sjkim 150291333Sjkim return "Opcode"; 151291333Sjkim 152291333Sjkim case ACPI_TRACE_AML_REGION: 153291333Sjkim 154291333Sjkim return "Region"; 155291333Sjkim 156291333Sjkim default: 157291333Sjkim 158291333Sjkim return ""; 159291333Sjkim } 160291333Sjkim} 161291333Sjkim 162291333Sjkim#endif 163291333Sjkim 164291333Sjkim 165291333Sjkim/******************************************************************************* 166291333Sjkim * 167291333Sjkim * FUNCTION: AcpiExTracePoint 168291333Sjkim * 169291333Sjkim * PARAMETERS: Type - Trace event type 170291333Sjkim * Begin - TRUE if before execution 171291333Sjkim * Aml - Executed AML address 172291333Sjkim * Pathname - Object path 173291333Sjkim * 174291333Sjkim * RETURN: None 175291333Sjkim * 176291333Sjkim * DESCRIPTION: Internal interpreter execution trace. 177291333Sjkim * 178291333Sjkim ******************************************************************************/ 179291333Sjkim 180291333Sjkimvoid 181291333SjkimAcpiExTracePoint ( 182291333Sjkim ACPI_TRACE_EVENT_TYPE Type, 183291333Sjkim BOOLEAN Begin, 184291333Sjkim UINT8 *Aml, 185291333Sjkim char *Pathname) 186291333Sjkim{ 187291333Sjkim 188291333Sjkim ACPI_FUNCTION_NAME (ExTracePoint); 189291333Sjkim 190291333Sjkim 191291333Sjkim if (Pathname) 192291333Sjkim { 193291333Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_TRACE_POINT, 194291333Sjkim "%s %s [0x%p:%s] execution.\n", 195291333Sjkim AcpiExGetTraceEventName (Type), Begin ? "Begin" : "End", 196291333Sjkim Aml, Pathname)); 197291333Sjkim } 198291333Sjkim else 199291333Sjkim { 200291333Sjkim ACPI_DEBUG_PRINT ((ACPI_DB_TRACE_POINT, 201291333Sjkim "%s %s [0x%p] execution.\n", 202291333Sjkim AcpiExGetTraceEventName (Type), Begin ? "Begin" : "End", 203291333Sjkim Aml)); 204291333Sjkim } 205291333Sjkim} 206291333Sjkim 207291333Sjkim 208291333Sjkim/******************************************************************************* 209291333Sjkim * 210291333Sjkim * FUNCTION: AcpiExStartTraceMethod 211291333Sjkim * 212291333Sjkim * PARAMETERS: MethodNode - Node of the method 213291333Sjkim * ObjDesc - The method object 214291333Sjkim * WalkState - current state, NULL if not yet executing 215291333Sjkim * a method. 216291333Sjkim * 217291333Sjkim * RETURN: None 218291333Sjkim * 219291333Sjkim * DESCRIPTION: Start control method execution trace 220291333Sjkim * 221291333Sjkim ******************************************************************************/ 222291333Sjkim 223291333Sjkimvoid 224291333SjkimAcpiExStartTraceMethod ( 225291333Sjkim ACPI_NAMESPACE_NODE *MethodNode, 226291333Sjkim ACPI_OPERAND_OBJECT *ObjDesc, 227291333Sjkim ACPI_WALK_STATE *WalkState) 228291333Sjkim{ 229291333Sjkim ACPI_STATUS Status; 230291333Sjkim char *Pathname = NULL; 231291333Sjkim BOOLEAN Enabled = FALSE; 232291333Sjkim 233291333Sjkim 234291333Sjkim ACPI_FUNCTION_NAME (ExStartTraceMethod); 235291333Sjkim 236291333Sjkim 237291333Sjkim if (MethodNode) 238291333Sjkim { 239291333Sjkim Pathname = AcpiNsGetNormalizedPathname (MethodNode, TRUE); 240291333Sjkim } 241291333Sjkim 242291333Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 243291333Sjkim if (ACPI_FAILURE (Status)) 244291333Sjkim { 245291333Sjkim goto Exit; 246291333Sjkim } 247291333Sjkim 248291333Sjkim Enabled = AcpiExInterpreterTraceEnabled (Pathname); 249291333Sjkim if (Enabled && !AcpiGbl_TraceMethodObject) 250291333Sjkim { 251291333Sjkim AcpiGbl_TraceMethodObject = ObjDesc; 252291333Sjkim AcpiGbl_OriginalDbgLevel = AcpiDbgLevel; 253291333Sjkim AcpiGbl_OriginalDbgLayer = AcpiDbgLayer; 254291333Sjkim AcpiDbgLevel = ACPI_TRACE_LEVEL_ALL; 255291333Sjkim AcpiDbgLayer = ACPI_TRACE_LAYER_ALL; 256291333Sjkim 257291333Sjkim if (AcpiGbl_TraceDbgLevel) 258291333Sjkim { 259291333Sjkim AcpiDbgLevel = AcpiGbl_TraceDbgLevel; 260291333Sjkim } 261291333Sjkim 262291333Sjkim if (AcpiGbl_TraceDbgLayer) 263291333Sjkim { 264291333Sjkim AcpiDbgLayer = AcpiGbl_TraceDbgLayer; 265291333Sjkim } 266291333Sjkim } 267291333Sjkim 268291333Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 269291333Sjkim 270291333SjkimExit: 271291333Sjkim if (Enabled) 272291333Sjkim { 273291333Sjkim ACPI_TRACE_POINT (ACPI_TRACE_AML_METHOD, TRUE, 274291333Sjkim ObjDesc ? ObjDesc->Method.AmlStart : NULL, Pathname); 275291333Sjkim } 276291333Sjkim 277291333Sjkim if (Pathname) 278291333Sjkim { 279291333Sjkim ACPI_FREE (Pathname); 280291333Sjkim } 281291333Sjkim} 282291333Sjkim 283291333Sjkim 284291333Sjkim/******************************************************************************* 285291333Sjkim * 286291333Sjkim * FUNCTION: AcpiExStopTraceMethod 287291333Sjkim * 288291333Sjkim * PARAMETERS: MethodNode - Node of the method 289291333Sjkim * ObjDesc - The method object 290291333Sjkim * WalkState - current state, NULL if not yet executing 291291333Sjkim * a method. 292291333Sjkim * 293291333Sjkim * RETURN: None 294291333Sjkim * 295291333Sjkim * DESCRIPTION: Stop control method execution trace 296291333Sjkim * 297291333Sjkim ******************************************************************************/ 298291333Sjkim 299291333Sjkimvoid 300291333SjkimAcpiExStopTraceMethod ( 301291333Sjkim ACPI_NAMESPACE_NODE *MethodNode, 302291333Sjkim ACPI_OPERAND_OBJECT *ObjDesc, 303291333Sjkim ACPI_WALK_STATE *WalkState) 304291333Sjkim{ 305291333Sjkim ACPI_STATUS Status; 306291333Sjkim char *Pathname = NULL; 307291333Sjkim BOOLEAN Enabled; 308291333Sjkim 309291333Sjkim 310291333Sjkim ACPI_FUNCTION_NAME (ExStopTraceMethod); 311291333Sjkim 312291333Sjkim 313291333Sjkim if (MethodNode) 314291333Sjkim { 315291333Sjkim Pathname = AcpiNsGetNormalizedPathname (MethodNode, TRUE); 316291333Sjkim } 317291333Sjkim 318291333Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 319291333Sjkim if (ACPI_FAILURE (Status)) 320291333Sjkim { 321291333Sjkim goto ExitPath; 322291333Sjkim } 323291333Sjkim 324291333Sjkim Enabled = AcpiExInterpreterTraceEnabled (NULL); 325291333Sjkim 326291333Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 327291333Sjkim 328291333Sjkim if (Enabled) 329291333Sjkim { 330291333Sjkim ACPI_TRACE_POINT (ACPI_TRACE_AML_METHOD, FALSE, 331291333Sjkim ObjDesc ? ObjDesc->Method.AmlStart : NULL, Pathname); 332291333Sjkim } 333291333Sjkim 334291333Sjkim Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); 335291333Sjkim if (ACPI_FAILURE (Status)) 336291333Sjkim { 337291333Sjkim goto ExitPath; 338291333Sjkim } 339291333Sjkim 340291333Sjkim /* Check whether the tracer should be stopped */ 341291333Sjkim 342291333Sjkim if (AcpiGbl_TraceMethodObject == ObjDesc) 343291333Sjkim { 344291333Sjkim /* Disable further tracing if type is one-shot */ 345291333Sjkim 346291333Sjkim if (AcpiGbl_TraceFlags & ACPI_TRACE_ONESHOT) 347291333Sjkim { 348291333Sjkim AcpiGbl_TraceMethodName = NULL; 349291333Sjkim } 350291333Sjkim 351291333Sjkim AcpiDbgLevel = AcpiGbl_OriginalDbgLevel; 352291333Sjkim AcpiDbgLayer = AcpiGbl_OriginalDbgLayer; 353291333Sjkim AcpiGbl_TraceMethodObject = NULL; 354291333Sjkim } 355291333Sjkim 356291333Sjkim (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); 357291333Sjkim 358291333SjkimExitPath: 359291333Sjkim if (Pathname) 360291333Sjkim { 361291333Sjkim ACPI_FREE (Pathname); 362291333Sjkim } 363291333Sjkim} 364291333Sjkim 365291333Sjkim 366291333Sjkim/******************************************************************************* 367291333Sjkim * 368291333Sjkim * FUNCTION: AcpiExStartTraceOpcode 369291333Sjkim * 370291333Sjkim * PARAMETERS: Op - The parser opcode object 371291333Sjkim * WalkState - current state, NULL if not yet executing 372291333Sjkim * a method. 373291333Sjkim * 374291333Sjkim * RETURN: None 375291333Sjkim * 376291333Sjkim * DESCRIPTION: Start opcode execution trace 377291333Sjkim * 378291333Sjkim ******************************************************************************/ 379291333Sjkim 380291333Sjkimvoid 381291333SjkimAcpiExStartTraceOpcode ( 382291333Sjkim ACPI_PARSE_OBJECT *Op, 383291333Sjkim ACPI_WALK_STATE *WalkState) 384291333Sjkim{ 385291333Sjkim 386291333Sjkim ACPI_FUNCTION_NAME (ExStartTraceOpcode); 387291333Sjkim 388291333Sjkim 389291333Sjkim if (AcpiExInterpreterTraceEnabled (NULL) && 390291333Sjkim (AcpiGbl_TraceFlags & ACPI_TRACE_OPCODE)) 391291333Sjkim { 392291333Sjkim ACPI_TRACE_POINT (ACPI_TRACE_AML_OPCODE, TRUE, 393291333Sjkim Op->Common.Aml, Op->Common.AmlOpName); 394291333Sjkim } 395291333Sjkim} 396291333Sjkim 397291333Sjkim 398291333Sjkim/******************************************************************************* 399291333Sjkim * 400291333Sjkim * FUNCTION: AcpiExStopTraceOpcode 401291333Sjkim * 402291333Sjkim * PARAMETERS: Op - The parser opcode object 403291333Sjkim * WalkState - current state, NULL if not yet executing 404291333Sjkim * a method. 405291333Sjkim * 406291333Sjkim * RETURN: None 407291333Sjkim * 408291333Sjkim * DESCRIPTION: Stop opcode execution trace 409291333Sjkim * 410291333Sjkim ******************************************************************************/ 411291333Sjkim 412291333Sjkimvoid 413291333SjkimAcpiExStopTraceOpcode ( 414291333Sjkim ACPI_PARSE_OBJECT *Op, 415291333Sjkim ACPI_WALK_STATE *WalkState) 416291333Sjkim{ 417291333Sjkim 418291333Sjkim ACPI_FUNCTION_NAME (ExStopTraceOpcode); 419291333Sjkim 420291333Sjkim 421291333Sjkim if (AcpiExInterpreterTraceEnabled (NULL) && 422291333Sjkim (AcpiGbl_TraceFlags & ACPI_TRACE_OPCODE)) 423291333Sjkim { 424291333Sjkim ACPI_TRACE_POINT (ACPI_TRACE_AML_OPCODE, FALSE, 425291333Sjkim Op->Common.Aml, Op->Common.AmlOpName); 426291333Sjkim } 427291333Sjkim} 428