summaryrefslogtreecommitdiffstats
path: root/sys/contrib/dev/acpica/dsutils.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/dev/acpica/dsutils.c')
-rw-r--r--sys/contrib/dev/acpica/dsutils.c241
1 files changed, 176 insertions, 65 deletions
diff --git a/sys/contrib/dev/acpica/dsutils.c b/sys/contrib/dev/acpica/dsutils.c
index 757f1f2..eb7149a 100644
--- a/sys/contrib/dev/acpica/dsutils.c
+++ b/sys/contrib/dev/acpica/dsutils.c
@@ -1,7 +1,7 @@
/*******************************************************************************
*
* Module Name: dsutils - Dispatcher utilities
- * $Revision: 107 $
+ * $Revision: 1.115 $
*
******************************************************************************/
@@ -9,7 +9,7 @@
*
* 1. Copyright Notice
*
- * Some or all of this work - Copyright (c) 1999 - 2004, Intel Corp.
+ * Some or all of this work - Copyright (c) 1999 - 2005, Intel Corp.
* All rights reserved.
*
* 2. License
@@ -128,7 +128,122 @@
ACPI_MODULE_NAME ("dsutils")
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsClearImplicitReturn
+ *
+ * PARAMETERS: WalkState - Current State
+ *
+ * RETURN: None.
+ *
+ * DESCRIPTION: Clear and remove a reference on an implicit return value. Used
+ * to delete "stale" return values (if enabled, the return value
+ * from every operator is saved at least momentarily, in case the
+ * parent method exits.)
+ *
+ ******************************************************************************/
+
+void
+AcpiDsClearImplicitReturn (
+ ACPI_WALK_STATE *WalkState)
+{
+ ACPI_FUNCTION_NAME ("DsClearImplicitReturn");
+
+
+ /*
+ * Slack must be enabled for this feature
+ */
+ if (!AcpiGbl_EnableInterpreterSlack)
+ {
+ return;
+ }
+
+ if (WalkState->ImplicitReturnObj)
+ {
+ /*
+ * Delete any "stale" implicit return. However, in
+ * complex statements, the implicit return value can be
+ * bubbled up several levels.
+ */
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Removing reference on stale implicit return obj %p\n",
+ WalkState->ImplicitReturnObj));
+
+ AcpiUtRemoveReference (WalkState->ImplicitReturnObj);
+ WalkState->ImplicitReturnObj = NULL;
+ }
+}
+
+
#ifndef ACPI_NO_METHOD_EXECUTION
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiDsDoImplicitReturn
+ *
+ * PARAMETERS: ReturnDesc - The return value
+ * WalkState - Current State
+ * AddReference - True if a reference should be added to the
+ * return object
+ *
+ * RETURN: TRUE if implicit return enabled, FALSE otherwise
+ *
+ * DESCRIPTION: Implements the optional "implicit return". We save the result
+ * of every ASL operator and control method invocation in case the
+ * parent method exit. Before storing a new return value, we
+ * delete the previous return value.
+ *
+ ******************************************************************************/
+
+BOOLEAN
+AcpiDsDoImplicitReturn (
+ ACPI_OPERAND_OBJECT *ReturnDesc,
+ ACPI_WALK_STATE *WalkState,
+ BOOLEAN AddReference)
+{
+ ACPI_FUNCTION_NAME ("DsDoImplicitReturn");
+
+
+ /*
+ * Slack must be enabled for this feature, and we must
+ * have a valid return object
+ */
+ if ((!AcpiGbl_EnableInterpreterSlack) ||
+ (!ReturnDesc))
+ {
+ return (FALSE);
+ }
+
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Result %p will be implicitly returned; Prev=%p\n",
+ ReturnDesc,
+ WalkState->ImplicitReturnObj));
+
+ /*
+ * Delete any "stale" implicit return value first. However, in
+ * complex statements, the implicit return value can be
+ * bubbled up several levels, so we don't clear the value if it
+ * is the same as the ReturnDesc.
+ */
+ if (WalkState->ImplicitReturnObj)
+ {
+ if (WalkState->ImplicitReturnObj == ReturnDesc)
+ {
+ return (TRUE);
+ }
+ AcpiDsClearImplicitReturn (WalkState);
+ }
+
+ /* Save the implicit return value, add a reference if requested */
+
+ WalkState->ImplicitReturnObj = ReturnDesc;
+ if (AddReference)
+ {
+ AcpiUtAddReference (ReturnDesc);
+ }
+
+ return (TRUE);
+}
+
/*******************************************************************************
*
@@ -150,7 +265,6 @@ AcpiDsIsResultUsed (
{
const ACPI_OPCODE_INFO *ParentInfo;
-
ACPI_FUNCTION_TRACE_PTR ("DsIsResultUsed", Op);
@@ -159,42 +273,37 @@ AcpiDsIsResultUsed (
if (!Op)
{
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Null Op\n"));
- return_VALUE (TRUE);
+ return_UINT8 (TRUE);
}
/*
- * If there is no parent, we are executing at the method level.
- * An executing method typically has no parent, since each method
- * is parsed separately.
+ * We know that this operator is not a
+ * Return() operator (would not come here.) The following code is the
+ * optional support for a so-called "implicit return". Some AML code
+ * assumes that the last value of the method is "implicitly" returned
+ * to the caller. Just save the last result as the return value.
+ * NOTE: this is optional because the ASL language does not actually
+ * support this behavior.
*/
- if (!Op->Common.Parent ||
- Op->Common.Parent->Common.AmlOpcode == AML_SCOPE_OP)
- {
- /*
- * If this is the last statement in the method, we know it is not a
- * Return() operator (would not come here.) The following code is the
- * optional support for a so-called "implicit return". Some AML code
- * assumes that the last value of the method is "implicitly" returned
- * to the caller. Just save the last result as the return value.
- * NOTE: this is optional because the ASL language does not actually
- * support this behavior.
- */
- if ((AcpiGbl_EnableInterpreterSlack) &&
- (WalkState->ParserState.Aml >= WalkState->ParserState.AmlEnd))
- {
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "Result of [%s] will be implicitly returned\n",
- AcpiPsGetOpcodeName (Op->Common.AmlOpcode)));
-
- /* Use the top of the result stack as the implicit return value */
-
- WalkState->ReturnDesc = WalkState->Results->Results.ObjDesc[0];
- return_VALUE (TRUE);
- }
+ (void) AcpiDsDoImplicitReturn (WalkState->ResultObj, WalkState, TRUE);
+ /*
+ * Now determine if the parent will use the result
+ *
+ * If there is no parent, or the parent is a ScopeOp, we are executing
+ * at the method level. An executing method typically has no parent,
+ * since each method is parsed separately. A method invoked externally
+ * via ExecuteControlMethod has a ScopeOp as the parent.
+ */
+ if ((!Op->Common.Parent) ||
+ (Op->Common.Parent->Common.AmlOpcode == AML_SCOPE_OP))
+ {
/* No parent, the return value cannot possibly be used */
- return_VALUE (FALSE);
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "At Method level, result of [%s] not used\n",
+ AcpiPsGetOpcodeName (Op->Common.AmlOpcode)));
+ return_UINT8 (FALSE);
}
/* Get info on the parent. The RootOp is AML_SCOPE */
@@ -202,8 +311,9 @@ AcpiDsIsResultUsed (
ParentInfo = AcpiPsGetOpcodeInfo (Op->Common.Parent->Common.AmlOpcode);
if (ParentInfo->Class == AML_CLASS_UNKNOWN)
{
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown parent opcode. Op=%p\n", Op));
- return_VALUE (FALSE);
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Unknown parent opcode. Op=%p\n", Op));
+ return_UINT8 (FALSE);
}
/*
@@ -287,19 +397,21 @@ AcpiDsIsResultUsed (
ResultUsed:
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Result of [%s] used by Parent [%s] Op=%p\n",
- AcpiPsGetOpcodeName (Op->Common.AmlOpcode),
- AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode), Op));
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Result of [%s] used by Parent [%s] Op=%p\n",
+ AcpiPsGetOpcodeName (Op->Common.AmlOpcode),
+ AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode), Op));
- return_VALUE (TRUE);
+ return_UINT8 (TRUE);
ResultNotUsed:
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Result of [%s] not used by Parent [%s] Op=%p\n",
- AcpiPsGetOpcodeName (Op->Common.AmlOpcode),
- AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode), Op));
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Result of [%s] not used by Parent [%s] Op=%p\n",
+ AcpiPsGetOpcodeName (Op->Common.AmlOpcode),
+ AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode), Op));
- return_VALUE (FALSE);
+ return_UINT8 (FALSE);
}
@@ -346,9 +458,8 @@ AcpiDsDeleteResultIfNotUsed (
if (!AcpiDsIsResultUsed (Op, WalkState))
{
- /*
- * Must pop the result stack (ObjDesc should be equal to ResultObj)
- */
+ /* Must pop the result stack (ObjDesc should be equal to ResultObj) */
+
Status = AcpiDsResultPop (&ObjDesc, WalkState);
if (ACPI_SUCCESS (Status))
{
@@ -425,9 +536,8 @@ AcpiDsClearOperands (
ACPI_FUNCTION_TRACE_PTR ("DsClearOperands", WalkState);
- /*
- * Remove a reference on each operand on the stack
- */
+ /* Remove a reference on each operand on the stack */
+
for (i = 0; i < WalkState->NumOperands; i++)
{
/*
@@ -497,11 +607,7 @@ AcpiDsCreateOperand (
return_ACPI_STATUS (Status);
}
- /*
- * All prefixes have been handled, and the name is
- * in NameString
- */
-
+ /* All prefixes have been handled, and the name is in NameString */
/*
* Special handling for BufferField declarations. This is a deferred
@@ -516,7 +622,8 @@ AcpiDsCreateOperand (
(WalkState->DeferredNode->Type == ACPI_TYPE_BUFFER_FIELD) &&
(ArgIndex != 0))
{
- ObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, WalkState->DeferredNode);
+ ObjDesc = ACPI_CAST_PTR (
+ ACPI_OPERAND_OBJECT, WalkState->DeferredNode);
Status = AE_OK;
}
else /* All other opcodes */
@@ -546,10 +653,10 @@ AcpiDsCreateOperand (
}
Status = AcpiNsLookup (WalkState->ScopeInfo, NameString,
- ACPI_TYPE_ANY, InterpreterMode,
- ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
- WalkState,
- ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ObjDesc));
+ ACPI_TYPE_ANY, InterpreterMode,
+ ACPI_NS_SEARCH_PARENT | ACPI_NS_DONT_OPEN_SCOPE,
+ WalkState,
+ ACPI_CAST_INDIRECT_PTR (ACPI_NAMESPACE_NODE, &ObjDesc));
/*
* The only case where we pass through (ignore) a NOT_FOUND
* error is for the CondRefOf opcode.
@@ -564,7 +671,8 @@ AcpiDsCreateOperand (
* indicate this to the interpreter, set the
* object to the root
*/
- ObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, AcpiGbl_RootNode);
+ ObjDesc = ACPI_CAST_PTR (
+ ACPI_OPERAND_OBJECT, AcpiGbl_RootNode);
Status = AE_OK;
}
else
@@ -617,7 +725,8 @@ AcpiDsCreateOperand (
*/
Opcode = AML_ZERO_OP; /* Has no arguments! */
- ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Null namepath: Arg=%p\n", Arg));
+ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
+ "Null namepath: Arg=%p\n", Arg));
}
else
{
@@ -635,7 +744,7 @@ AcpiDsCreateOperand (
if (OpInfo->Flags & AML_HAS_RETVAL)
{
ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
- "Argument previously created, already stacked \n"));
+ "Argument previously created, already stacked\n"));
ACPI_DEBUGGER_EXEC (AcpiDbDisplayArgumentObject (
WalkState->Operands [WalkState->NumOperands - 1], WalkState));
@@ -651,7 +760,8 @@ AcpiDsCreateOperand (
* Only error is underflow, and this indicates
* a missing or null operand!
*/
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Missing or null operand, %s\n",
+ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
+ "Missing or null operand, %s\n",
AcpiFormatException (Status)));
return_ACPI_STATUS (Status);
}
@@ -668,8 +778,8 @@ AcpiDsCreateOperand (
/* Initialize the new object */
- Status = AcpiDsInitObjectFromOp (WalkState, Arg,
- Opcode, &ObjDesc);
+ Status = AcpiDsInitObjectFromOp (
+ WalkState, Arg, Opcode, &ObjDesc);
if (ACPI_FAILURE (Status))
{
AcpiUtDeleteObjectDesc (ObjDesc);
@@ -696,7 +806,8 @@ AcpiDsCreateOperand (
*
* FUNCTION: AcpiDsCreateOperands
*
- * PARAMETERS: FirstArg - First argument of a parser argument tree
+ * PARAMETERS: WalkState - Current state
+ * FirstArg - First argument of a parser argument tree
*
* RETURN: Status
*
OpenPOWER on IntegriCloud