summaryrefslogtreecommitdiff
path: root/source/components/dispatcher
diff options
context:
space:
mode:
authorJung-uk Kim <jkim@FreeBSD.org>2015-07-20 22:31:50 +0000
committerJung-uk Kim <jkim@FreeBSD.org>2015-07-20 22:31:50 +0000
commit136eac2a0638d3c751b1987603f71a9ae26879fd (patch)
tree1e61df024e8a47b6bc4e25d07f455c9dcd7e2dc8 /source/components/dispatcher
parentf3bbb1ca6c1b2b877d015a8f5f0c67e48a7a57ae (diff)
downloadsrc-test2-136eac2a0638d3c751b1987603f71a9ae26879fd.tar.gz
src-test2-136eac2a0638d3c751b1987603f71a9ae26879fd.zip
Notes
Diffstat (limited to 'source/components/dispatcher')
-rw-r--r--source/components/dispatcher/dsargs.c4
-rw-r--r--source/components/dispatcher/dsdebug.c249
-rw-r--r--source/components/dispatcher/dsmethod.c34
-rw-r--r--source/components/dispatcher/dswload.c2
-rw-r--r--source/components/dispatcher/dswload2.c2
5 files changed, 275 insertions, 16 deletions
diff --git a/source/components/dispatcher/dsargs.c b/source/components/dispatcher/dsargs.c
index c9a1709a64aa..5d2d5f5684ad 100644
--- a/source/components/dispatcher/dsargs.c
+++ b/source/components/dispatcher/dsargs.c
@@ -94,7 +94,7 @@ AcpiDsExecuteArguments (
/* Allocate a new parser op to be the root of the parsed tree */
- Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP);
+ Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP, AmlStart);
if (!Op)
{
return_ACPI_STATUS (AE_NO_MEMORY);
@@ -141,7 +141,7 @@ AcpiDsExecuteArguments (
/* Evaluate the deferred arguments */
- Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP);
+ Op = AcpiPsAllocOp (AML_INT_EVAL_SUBTREE_OP, AmlStart);
if (!Op)
{
return_ACPI_STATUS (AE_NO_MEMORY);
diff --git a/source/components/dispatcher/dsdebug.c b/source/components/dispatcher/dsdebug.c
new file mode 100644
index 000000000000..527bbf7461d2
--- /dev/null
+++ b/source/components/dispatcher/dsdebug.c
@@ -0,0 +1,249 @@
+/******************************************************************************
+ *
+ * Module Name: dsdebug - Parser/Interpreter interface - debugging
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2015, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include "acpi.h"
+#include "accommon.h"
+#include "acdispat.h"
+#include "acnamesp.h"
+#include "acdisasm.h"
+#include "acinterp.h"
+
+
+#define _COMPONENT ACPI_DISPATCHER
+ ACPI_MODULE_NAME ("dsdebug")
+
+
+#if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER)
+
+/* Local prototypes */
+
+static void
+AcpiDsPrintNodePathname (
+ ACPI_NAMESPACE_NODE *Node,
+ const char *Message);
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsPrintNodePathname
+ *
+ * PARAMETERS: Node - Object
+ * Message - Prefix message
+ *
+ * DESCRIPTION: Print an object's full namespace pathname
+ * Manages allocation/freeing of a pathname buffer
+ *
+ ******************************************************************************/
+
+static void
+AcpiDsPrintNodePathname (
+ ACPI_NAMESPACE_NODE *Node,
+ const char *Message)
+{
+ ACPI_BUFFER Buffer;
+ ACPI_STATUS Status;
+
+
+ ACPI_FUNCTION_TRACE (DsPrintNodePathname);
+
+ if (!Node)
+ {
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "[NULL NAME]"));
+ return_VOID;
+ }
+
+ /* Convert handle to full pathname and print it (with supplied message) */
+
+ Buffer.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
+
+ Status = AcpiNsHandleToPathname (Node, &Buffer, FALSE);
+ if (ACPI_SUCCESS (Status))
+ {
+ if (Message)
+ {
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "%s ", Message));
+ }
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "[%s] (Node %p)",
+ (char *) Buffer.Pointer, Node));
+ ACPI_FREE (Buffer.Pointer);
+ }
+
+ return_VOID;
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsDumpMethodStack
+ *
+ * PARAMETERS: Status - Method execution status
+ * WalkState - Current state of the parse tree walk
+ * Op - Executing parse op
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Called when a method has been aborted because of an error.
+ * Dumps the method execution stack.
+ *
+ ******************************************************************************/
+
+void
+AcpiDsDumpMethodStack (
+ ACPI_STATUS Status,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_PARSE_OBJECT *Next;
+ ACPI_THREAD_STATE *Thread;
+ ACPI_WALK_STATE *NextWalkState;
+ ACPI_NAMESPACE_NODE *PreviousMethod = NULL;
+ ACPI_OPERAND_OBJECT *MethodDesc;
+
+
+ ACPI_FUNCTION_TRACE (DsDumpMethodStack);
+
+ /* Ignore control codes, they are not errors */
+
+ if ((Status & AE_CODE_MASK) == AE_CODE_CONTROL)
+ {
+ return_VOID;
+ }
+
+ /* We may be executing a deferred opcode */
+
+ if (WalkState->DeferredNode)
+ {
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Executing subtree for Buffer/Package/Region\n"));
+ return_VOID;
+ }
+
+ /*
+ * If there is no Thread, we are not actually executing a method.
+ * This can happen when the iASL compiler calls the interpreter
+ * to perform constant folding.
+ */
+ Thread = WalkState->Thread;
+ if (!Thread)
+ {
+ return_VOID;
+ }
+
+ /* Display exception and method name */
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "\n**** Exception %s during execution of method ",
+ AcpiFormatException (Status)));
+ AcpiDsPrintNodePathname (WalkState->MethodNode, NULL);
+
+ /* Display stack of executing methods */
+
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH,
+ "\n\nMethod Execution Stack:\n"));
+ NextWalkState = Thread->WalkStateList;
+
+ /* Walk list of linked walk states */
+
+ while (NextWalkState)
+ {
+ MethodDesc = NextWalkState->MethodDesc;
+ if (MethodDesc)
+ {
+ AcpiExStopTraceMethod (
+ (ACPI_NAMESPACE_NODE *) MethodDesc->Method.Node,
+ MethodDesc, WalkState);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ " Method [%4.4s] executing: ",
+ AcpiUtGetNodeName (NextWalkState->MethodNode)));
+
+ /* First method is the currently executing method */
+
+ if (NextWalkState == WalkState)
+ {
+ if (Op)
+ {
+ /* Display currently executing ASL statement */
+
+ Next = Op->Common.Next;
+ Op->Common.Next = NULL;
+
+#ifdef ACPI_DISASSEMBLER
+ AcpiDmDisassemble (NextWalkState, Op, ACPI_UINT32_MAX);
+#endif
+ Op->Common.Next = Next;
+ }
+ }
+ else
+ {
+ /*
+ * This method has called another method
+ * NOTE: the method call parse subtree is already deleted at this
+ * point, so we cannot disassemble the method invocation.
+ */
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "Call to method "));
+ AcpiDsPrintNodePathname (PreviousMethod, NULL);
+ }
+
+ PreviousMethod = NextWalkState->MethodNode;
+ NextWalkState = NextWalkState->Next;
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_DISPATCH, "\n"));
+ }
+
+ return_VOID;
+}
+
+#else
+
+void
+AcpiDsDumpMethodStack (
+ ACPI_STATUS Status,
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op)
+{
+ return;
+}
+
+#endif
diff --git a/source/components/dispatcher/dsmethod.c b/source/components/dispatcher/dsmethod.c
index f1c3be8b1953..95e0cb3f2a00 100644
--- a/source/components/dispatcher/dsmethod.c
+++ b/source/components/dispatcher/dsmethod.c
@@ -46,9 +46,9 @@
#include "acdispat.h"
#include "acinterp.h"
#include "acnamesp.h"
-#include "acdisasm.h"
#include "acparser.h"
#include "amlcode.h"
+#include "acdebug.h"
#define _COMPONENT ACPI_DISPATCHER
@@ -109,7 +109,7 @@ AcpiDsAutoSerializeMethod (
/* Create/Init a root op for the method parse tree */
- Op = AcpiPsAllocOp (AML_METHOD_OP);
+ Op = AcpiPsAllocOp (AML_METHOD_OP, ObjDesc->Method.AmlStart);
if (!Op)
{
return_ACPI_STATUS (AE_NO_MEMORY);
@@ -213,7 +213,7 @@ AcpiDsDetectNamedOpcodes (
* RETURN: Status
*
* DESCRIPTION: Called on method error. Invoke the global exception handler if
- * present, dump the method data if the disassembler is configured
+ * present, dump the method data if the debugger is configured
*
* Note: Allows the exception handler to change the status code
*
@@ -224,6 +224,9 @@ AcpiDsMethodError (
ACPI_STATUS Status,
ACPI_WALK_STATE *WalkState)
{
+ UINT32 AmlOffset;
+
+
ACPI_FUNCTION_ENTRY ();
@@ -247,23 +250,28 @@ AcpiDsMethodError (
* Handler can map the exception code to anything it wants, including
* AE_OK, in which case the executing method will not be aborted.
*/
+ AmlOffset = (UINT32) ACPI_PTR_DIFF (WalkState->Aml,
+ WalkState->ParserState.AmlStart);
+
Status = AcpiGbl_ExceptionHandler (Status,
WalkState->MethodNode ?
WalkState->MethodNode->Name.Integer : 0,
- WalkState->Opcode, WalkState->AmlOffset, NULL);
+ WalkState->Opcode, AmlOffset, NULL);
AcpiExEnterInterpreter ();
}
AcpiDsClearImplicitReturn (WalkState);
-#ifdef ACPI_DISASSEMBLER
if (ACPI_FAILURE (Status))
{
- /* Display method locals/args if disassembler is present */
+ AcpiDsDumpMethodStack (Status, WalkState, WalkState->Op);
- AcpiDmDumpMethodInfo (Status, WalkState, WalkState->Op);
- }
+ /* Display method locals/args if debugger is present */
+
+#ifdef ACPI_DEBUGGER
+ AcpiDbDumpMethodInfo (Status, WalkState);
#endif
+ }
return (Status);
}
@@ -349,6 +357,8 @@ AcpiDsBeginMethodExecution (
return_ACPI_STATUS (AE_NULL_ENTRY);
}
+ AcpiExStartTraceMethod (MethodNode, ObjDesc, WalkState);
+
/* Prevent wraparound of thread count */
if (ObjDesc->Method.ThreadCount == ACPI_UINT8_MAX)
@@ -610,10 +620,7 @@ Cleanup:
/* On error, we must terminate the method properly */
AcpiDsTerminateControlMethod (ObjDesc, NextWalkState);
- if (NextWalkState)
- {
- AcpiDsDeleteWalkState (NextWalkState);
- }
+ AcpiDsDeleteWalkState (NextWalkState);
return_ACPI_STATUS (Status);
}
@@ -870,5 +877,8 @@ AcpiDsTerminateControlMethod (
}
}
+ AcpiExStopTraceMethod ((ACPI_NAMESPACE_NODE *) MethodDesc->Method.Node,
+ MethodDesc, WalkState);
+
return_VOID;
}
diff --git a/source/components/dispatcher/dswload.c b/source/components/dispatcher/dswload.c
index 37b7b39cbccc..bcc786801154 100644
--- a/source/components/dispatcher/dswload.c
+++ b/source/components/dispatcher/dswload.c
@@ -398,7 +398,7 @@ AcpiDsLoad1BeginOp (
{
/* Create a new op */
- Op = AcpiPsAllocOp (WalkState->Opcode);
+ Op = AcpiPsAllocOp (WalkState->Opcode, WalkState->Aml);
if (!Op)
{
return_ACPI_STATUS (AE_NO_MEMORY);
diff --git a/source/components/dispatcher/dswload2.c b/source/components/dispatcher/dswload2.c
index f7d43fe19e8a..f6095d971900 100644
--- a/source/components/dispatcher/dswload2.c
+++ b/source/components/dispatcher/dswload2.c
@@ -344,7 +344,7 @@ AcpiDsLoad2BeginOp (
{
/* Create a new op */
- Op = AcpiPsAllocOp (WalkState->Opcode);
+ Op = AcpiPsAllocOp (WalkState->Opcode, WalkState->Aml);
if (!Op)
{
return_ACPI_STATUS (AE_NO_MEMORY);