1 /******************************************************************************
3 * Module Name: exdebug - Support for stores to the AML Debug Object
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2015, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
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.
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.
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.
51 #define _COMPONENT ACPI_EXECUTER
52 ACPI_MODULE_NAME ("exdebug")
55 static ACPI_OPERAND_OBJECT *AcpiGbl_TraceMethodObject = NULL;
57 /* Local prototypes */
59 #ifdef ACPI_DEBUG_OUTPUT
61 AcpiExGetTraceEventName (
62 ACPI_TRACE_EVENT_TYPE Type);
66 #ifndef ACPI_NO_ERROR_MESSAGES
67 /*******************************************************************************
69 * FUNCTION: AcpiExDoDebugObject
71 * PARAMETERS: SourceDesc - Object to be output to "Debug Object"
72 * Level - Indentation level (used for packages)
73 * Index - Current package element, zero if not pkg
77 * DESCRIPTION: Handles stores to the AML Debug Object. For example:
80 * This function is not compiled if ACPI_NO_ERROR_MESSAGES is set.
82 * This function is only enabled if AcpiGbl_EnableAmlDebugObject is set, or
83 * if ACPI_LV_DEBUG_OBJECT is set in the AcpiDbgLevel. Thus, in the normal
84 * operational case, stores to the debug object are ignored but can be easily
85 * enabled if necessary.
87 ******************************************************************************/
91 ACPI_OPERAND_OBJECT *SourceDesc,
97 ACPI_OPERAND_OBJECT *ObjectDesc;
101 ACPI_FUNCTION_TRACE_PTR (ExDoDebugObject, SourceDesc);
104 /* Output must be enabled via the DebugObject global or the DbgLevel */
106 if (!AcpiGbl_EnableAmlDebugObject &&
107 !(AcpiDbgLevel & ACPI_LV_DEBUG_OBJECT))
113 * We will emit the current timer value (in microseconds) with each
114 * debug output. Only need the lower 26 bits. This allows for 67
115 * million microseconds or 67 seconds before rollover.
117 Timer = ((UINT32) AcpiOsGetTimer () / 10); /* (100 nanoseconds to microseconds) */
121 * Print line header as long as we are not in the middle of an
124 if (!((Level > 0) && Index == 0))
126 AcpiOsPrintf ("[ACPI Debug %.8u] %*s", Timer, Level, " ");
129 /* Display the index for package output only */
133 AcpiOsPrintf ("(%.2u) ", Index-1);
138 AcpiOsPrintf ("[Null Object]\n");
142 if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_OPERAND)
144 AcpiOsPrintf ("%s ", AcpiUtGetObjectTypeName (SourceDesc));
146 if (!AcpiUtValidInternalObject (SourceDesc))
148 AcpiOsPrintf ("%p, Invalid Internal Object!\n", SourceDesc);
152 else if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc) == ACPI_DESC_TYPE_NAMED)
154 AcpiOsPrintf ("%s: %p\n",
155 AcpiUtGetTypeName (((ACPI_NAMESPACE_NODE *) SourceDesc)->Type),
164 /* SourceDesc is of type ACPI_DESC_TYPE_OPERAND */
166 switch (SourceDesc->Common.Type)
168 case ACPI_TYPE_INTEGER:
170 /* Output correct integer width */
172 if (AcpiGbl_IntegerByteWidth == 4)
174 AcpiOsPrintf ("0x%8.8X\n",
175 (UINT32) SourceDesc->Integer.Value);
179 AcpiOsPrintf ("0x%8.8X%8.8X\n",
180 ACPI_FORMAT_UINT64 (SourceDesc->Integer.Value));
184 case ACPI_TYPE_BUFFER:
186 AcpiOsPrintf ("[0x%.2X]\n", (UINT32) SourceDesc->Buffer.Length);
187 AcpiUtDumpBuffer (SourceDesc->Buffer.Pointer,
188 (SourceDesc->Buffer.Length < 256) ?
189 SourceDesc->Buffer.Length : 256, DB_BYTE_DISPLAY, 0);
192 case ACPI_TYPE_STRING:
194 AcpiOsPrintf ("[0x%.2X] \"%s\"\n",
195 SourceDesc->String.Length, SourceDesc->String.Pointer);
198 case ACPI_TYPE_PACKAGE:
200 AcpiOsPrintf ("[Contains 0x%.2X Elements]\n",
201 SourceDesc->Package.Count);
203 /* Output the entire contents of the package */
205 for (i = 0; i < SourceDesc->Package.Count; i++)
207 AcpiExDoDebugObject (SourceDesc->Package.Elements[i],
212 case ACPI_TYPE_LOCAL_REFERENCE:
214 AcpiOsPrintf ("[%s] ", AcpiUtGetReferenceName (SourceDesc));
216 /* Decode the reference */
218 switch (SourceDesc->Reference.Class)
220 case ACPI_REFCLASS_INDEX:
222 AcpiOsPrintf ("0x%X\n", SourceDesc->Reference.Value);
225 case ACPI_REFCLASS_TABLE:
227 /* Case for DdbHandle */
229 AcpiOsPrintf ("Table Index 0x%X\n", SourceDesc->Reference.Value);
239 /* Check for valid node first, then valid object */
241 if (SourceDesc->Reference.Node)
243 if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc->Reference.Node) !=
244 ACPI_DESC_TYPE_NAMED)
246 AcpiOsPrintf (" %p - Not a valid namespace node\n",
247 SourceDesc->Reference.Node);
251 AcpiOsPrintf ("Node %p [%4.4s] ", SourceDesc->Reference.Node,
252 (SourceDesc->Reference.Node)->Name.Ascii);
254 switch ((SourceDesc->Reference.Node)->Type)
256 /* These types have no attached object */
258 case ACPI_TYPE_DEVICE:
259 AcpiOsPrintf ("Device\n");
262 case ACPI_TYPE_THERMAL:
263 AcpiOsPrintf ("Thermal Zone\n");
268 AcpiExDoDebugObject ((SourceDesc->Reference.Node)->Object,
274 else if (SourceDesc->Reference.Object)
276 if (ACPI_GET_DESCRIPTOR_TYPE (SourceDesc->Reference.Object) ==
277 ACPI_DESC_TYPE_NAMED)
279 AcpiExDoDebugObject (((ACPI_NAMESPACE_NODE *)
280 SourceDesc->Reference.Object)->Object,
285 ObjectDesc = SourceDesc->Reference.Object;
286 Value = SourceDesc->Reference.Value;
288 switch (ObjectDesc->Common.Type)
290 case ACPI_TYPE_BUFFER:
292 AcpiOsPrintf ("Buffer[%u] = 0x%2.2X\n",
293 Value, *SourceDesc->Reference.IndexPointer);
296 case ACPI_TYPE_STRING:
298 AcpiOsPrintf ("String[%u] = \"%c\" (0x%2.2X)\n",
299 Value, *SourceDesc->Reference.IndexPointer,
300 *SourceDesc->Reference.IndexPointer);
303 case ACPI_TYPE_PACKAGE:
305 AcpiOsPrintf ("Package[%u] = ", Value);
306 AcpiExDoDebugObject (*SourceDesc->Reference.Where,
312 AcpiOsPrintf ("Unknown Reference object type %X\n",
313 ObjectDesc->Common.Type);
322 AcpiOsPrintf ("%p\n", SourceDesc);
326 ACPI_DEBUG_PRINT_RAW ((ACPI_DB_EXEC, "\n"));
332 /*******************************************************************************
334 * FUNCTION: AcpiExInterpreterTraceEnabled
336 * PARAMETERS: Name - Whether method name should be matched,
337 * this should be checked before starting
340 * RETURN: TRUE if interpreter trace is enabled.
342 * DESCRIPTION: Check whether interpreter trace is enabled
344 ******************************************************************************/
347 AcpiExInterpreterTraceEnabled (
351 /* Check if tracing is enabled */
353 if (!(AcpiGbl_TraceFlags & ACPI_TRACE_ENABLED))
359 * Check if tracing is filtered:
361 * 1. If the tracer is started, AcpiGbl_TraceMethodObject should have
362 * been filled by the trace starter
363 * 2. If the tracer is not started, AcpiGbl_TraceMethodName should be
364 * matched if it is specified
365 * 3. If the tracer is oneshot style, AcpiGbl_TraceMethodName should
366 * not be cleared by the trace stopper during the first match
368 if (AcpiGbl_TraceMethodObject)
373 (AcpiGbl_TraceMethodName &&
374 strcmp (AcpiGbl_TraceMethodName, Name)))
378 if ((AcpiGbl_TraceFlags & ACPI_TRACE_ONESHOT) &&
379 !AcpiGbl_TraceMethodName)
388 /*******************************************************************************
390 * FUNCTION: AcpiExGetTraceEventName
392 * PARAMETERS: Type - Trace event type
394 * RETURN: Trace event name.
396 * DESCRIPTION: Used to obtain the full trace event name.
398 ******************************************************************************/
400 #ifdef ACPI_DEBUG_OUTPUT
403 AcpiExGetTraceEventName (
404 ACPI_TRACE_EVENT_TYPE Type)
408 case ACPI_TRACE_AML_METHOD:
412 case ACPI_TRACE_AML_OPCODE:
416 case ACPI_TRACE_AML_REGION:
429 /*******************************************************************************
431 * FUNCTION: AcpiExTracePoint
433 * PARAMETERS: Type - Trace event type
434 * Begin - TRUE if before execution
435 * Aml - Executed AML address
436 * Pathname - Object path
440 * DESCRIPTION: Internal interpreter execution trace.
442 ******************************************************************************/
446 ACPI_TRACE_EVENT_TYPE Type,
452 ACPI_FUNCTION_NAME (ExTracePoint);
457 ACPI_DEBUG_PRINT ((ACPI_DB_TRACE_POINT,
458 "%s %s [0x%p:%s] execution.\n",
459 AcpiExGetTraceEventName (Type), Begin ? "Begin" : "End",
464 ACPI_DEBUG_PRINT ((ACPI_DB_TRACE_POINT,
465 "%s %s [0x%p] execution.\n",
466 AcpiExGetTraceEventName (Type), Begin ? "Begin" : "End",
472 /*******************************************************************************
474 * FUNCTION: AcpiExStartTraceMethod
476 * PARAMETERS: MethodNode - Node of the method
477 * ObjDesc - The method object
478 * WalkState - current state, NULL if not yet executing
483 * DESCRIPTION: Start control method execution trace
485 ******************************************************************************/
488 AcpiExStartTraceMethod (
489 ACPI_NAMESPACE_NODE *MethodNode,
490 ACPI_OPERAND_OBJECT *ObjDesc,
491 ACPI_WALK_STATE *WalkState)
494 char *Pathname = NULL;
495 BOOLEAN Enabled = FALSE;
498 ACPI_FUNCTION_NAME (ExStartTraceMethod);
503 Pathname = AcpiNsGetNormalizedPathname (MethodNode, TRUE);
506 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
507 if (ACPI_FAILURE (Status))
512 Enabled = AcpiExInterpreterTraceEnabled (Pathname);
513 if (Enabled && !AcpiGbl_TraceMethodObject)
515 AcpiGbl_TraceMethodObject = ObjDesc;
516 AcpiGbl_OriginalDbgLevel = AcpiDbgLevel;
517 AcpiGbl_OriginalDbgLayer = AcpiDbgLayer;
518 AcpiDbgLevel = ACPI_TRACE_LEVEL_ALL;
519 AcpiDbgLayer = ACPI_TRACE_LAYER_ALL;
521 if (AcpiGbl_TraceDbgLevel)
523 AcpiDbgLevel = AcpiGbl_TraceDbgLevel;
525 if (AcpiGbl_TraceDbgLayer)
527 AcpiDbgLayer = AcpiGbl_TraceDbgLayer;
530 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
535 ACPI_TRACE_POINT (ACPI_TRACE_AML_METHOD, TRUE,
536 ObjDesc ? ObjDesc->Method.AmlStart : NULL, Pathname);
540 ACPI_FREE (Pathname);
545 /*******************************************************************************
547 * FUNCTION: AcpiExStopTraceMethod
549 * PARAMETERS: MethodNode - Node of the method
550 * ObjDesc - The method object
551 * WalkState - current state, NULL if not yet executing
556 * DESCRIPTION: Stop control method execution trace
558 ******************************************************************************/
561 AcpiExStopTraceMethod (
562 ACPI_NAMESPACE_NODE *MethodNode,
563 ACPI_OPERAND_OBJECT *ObjDesc,
564 ACPI_WALK_STATE *WalkState)
567 char *Pathname = NULL;
571 ACPI_FUNCTION_NAME (ExStopTraceMethod);
576 Pathname = AcpiNsGetNormalizedPathname (MethodNode, TRUE);
579 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
580 if (ACPI_FAILURE (Status))
585 Enabled = AcpiExInterpreterTraceEnabled (NULL);
587 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
591 ACPI_TRACE_POINT (ACPI_TRACE_AML_METHOD, FALSE,
592 ObjDesc ? ObjDesc->Method.AmlStart : NULL, Pathname);
595 Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE);
596 if (ACPI_FAILURE (Status))
601 /* Check whether the tracer should be stopped */
603 if (AcpiGbl_TraceMethodObject == ObjDesc)
605 /* Disable further tracing if type is one-shot */
607 if (AcpiGbl_TraceFlags & ACPI_TRACE_ONESHOT)
609 AcpiGbl_TraceMethodName = NULL;
612 AcpiDbgLevel = AcpiGbl_OriginalDbgLevel;
613 AcpiDbgLayer = AcpiGbl_OriginalDbgLayer;
614 AcpiGbl_TraceMethodObject = NULL;
617 (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE);
622 ACPI_FREE (Pathname);
627 /*******************************************************************************
629 * FUNCTION: AcpiExStartTraceOpcode
631 * PARAMETERS: Op - The parser opcode object
632 * WalkState - current state, NULL if not yet executing
637 * DESCRIPTION: Start opcode execution trace
639 ******************************************************************************/
642 AcpiExStartTraceOpcode (
643 ACPI_PARSE_OBJECT *Op,
644 ACPI_WALK_STATE *WalkState)
647 ACPI_FUNCTION_NAME (ExStartTraceOpcode);
650 if (AcpiExInterpreterTraceEnabled (NULL) &&
651 (AcpiGbl_TraceFlags & ACPI_TRACE_OPCODE))
653 ACPI_TRACE_POINT (ACPI_TRACE_AML_OPCODE, TRUE,
654 Op->Common.Aml, Op->Common.AmlOpName);
659 /*******************************************************************************
661 * FUNCTION: AcpiExStopTraceOpcode
663 * PARAMETERS: Op - The parser opcode object
664 * WalkState - current state, NULL if not yet executing
669 * DESCRIPTION: Stop opcode execution trace
671 ******************************************************************************/
674 AcpiExStopTraceOpcode (
675 ACPI_PARSE_OBJECT *Op,
676 ACPI_WALK_STATE *WalkState)
679 ACPI_FUNCTION_NAME (ExStopTraceOpcode);
682 if (AcpiExInterpreterTraceEnabled (NULL) &&
683 (AcpiGbl_TraceFlags & ACPI_TRACE_OPCODE))
685 ACPI_TRACE_POINT (ACPI_TRACE_AML_OPCODE, FALSE,
686 Op->Common.Aml, Op->Common.AmlOpName);