summaryrefslogtreecommitdiff
path: root/sys/contrib/dev/acpica/pswalk.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/dev/acpica/pswalk.c')
-rw-r--r--sys/contrib/dev/acpica/pswalk.c474
1 files changed, 67 insertions, 407 deletions
diff --git a/sys/contrib/dev/acpica/pswalk.c b/sys/contrib/dev/acpica/pswalk.c
index 176a54d6cd88e..2709f00c87eb5 100644
--- a/sys/contrib/dev/acpica/pswalk.c
+++ b/sys/contrib/dev/acpica/pswalk.c
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Module Name: pswalk - Parser routines to walk parsed op tree(s)
- * $Revision: 47 $
+ * $Revision: 50 $
*
*****************************************************************************/
@@ -184,116 +184,42 @@ AcpiPsGetNextWalkOp (
Status = AscendingCallback (WalkState, Op);
- switch (Status)
+ /*
+ * If we are back to the starting point, the walk is complete.
+ */
+ if (Op == WalkState->Origin)
{
- case AE_CTRL_TERMINATE:
+ /* Reached the point of origin, the walk is complete */
- /*
- * A control method was terminated via a RETURN statement.
- * The walk of this method is complete.
- */
- WalkState->PrevOp = WalkState->Origin;
+ WalkState->PrevOp = Op;
WalkState->NextOp = NULL;
- return_ACPI_STATUS (AE_OK);
- break;
-
-
- case AE_CTRL_FALSE:
-
- /*
- * Either an IF/WHILE Predicate was false or we encountered a BREAK
- * opcode. In both cases, we do not execute the rest of the
- * package; We simply close out the parent (finishing the walk of
- * this branch of the tree) and continue execution at the parent
- * level.
- */
-
- Next = Parent->Next;
- Status = AE_OK;
-
- /*
- * If there is a sibling to the parent, we must close out the
- * parent now, because we are going to continue to go downward (to
- * the sibling) in the parse tree.
- */
- if (Next)
- {
- Status = AscendingCallback (WalkState, Parent);
-
- /* The parent sibling will be next */
-
- WalkState->PrevOp = Op;
- WalkState->NextOp = Next;
- WalkState->NextOpInfo = NEXT_OP_DOWNWARD;
-
- /* Continue downward */
-
- return_ACPI_STATUS (AE_OK);
- }
-
- /*
- * Drop into the loop below because we are moving upwards in
- * the tree
- */
-
- break;
-
-
- default:
- /*
- * If we are back to the starting point, the walk is complete.
- */
- if (Op == WalkState->Origin)
- {
- /* Reached the point of origin, the walk is complete */
-
- WalkState->PrevOp = Op;
- WalkState->NextOp = NULL;
-
- return_ACPI_STATUS (Status);
- }
-
- /*
- * Check for a sibling to the current op. A sibling means
- * we are still going "downward" in the tree.
- */
-
- if (Next)
- {
- /* There is a sibling, it will be next */
-
- WalkState->PrevOp = Op;
- WalkState->NextOp = Next;
- WalkState->NextOpInfo = NEXT_OP_DOWNWARD;
+ return_ACPI_STATUS (Status);
+ }
- /* Continue downward */
+ /*
+ * Check for a sibling to the current op. A sibling means
+ * we are still going "downward" in the tree.
+ */
- return_ACPI_STATUS (Status);
- }
+ if (Next)
+ {
+ /* There is a sibling, it will be next */
- /*
- * No sibling, but check status.
- * Abort on error from callback routine
- */
- if (ACPI_FAILURE (Status))
- {
- /* Next op will be the parent */
+ WalkState->PrevOp = Op;
+ WalkState->NextOp = Next;
+ WalkState->NextOpInfo = NEXT_OP_DOWNWARD;
- WalkState->PrevOp = Op;
- WalkState->NextOp = Parent;
- WalkState->NextOpInfo = NEXT_OP_UPWARD;
+ /* Continue downward */
- return_ACPI_STATUS (Status);
- }
+ return_ACPI_STATUS (Status);
+ }
- /*
- * Drop into the loop below because we are moving upwards in
- * the tree
- */
- break;
- }
+ /*
+ * Drop into the loop below because we are moving upwards in
+ * the tree
+ */
}
else
@@ -321,69 +247,6 @@ AcpiPsGetNextWalkOp (
Status = AscendingCallback (WalkState, Parent);
-
- switch (Status)
- {
- case AE_CTRL_FALSE:
-
- /*
- * Either an IF/WHILE Predicate was false or we encountered a
- * BREAK opcode. In both cases, we do not execute the rest of the
- * package; We simply close out the parent (finishing the walk of
- * this branch of the tree) and continue execution at the parent
- * level.
- */
-
- Parent = GrandParent;
- Next = GrandParent->Next;
- GrandParent = GrandParent->Parent;
-
- Status = AscendingCallback (WalkState, Parent);
-
- /* Now continue to the next node in the tree */
-
- break;
-
-
- case AE_CTRL_TRUE:
-
- /*
- * Predicate of a WHILE was true and the loop just completed an
- * execution. Go back to the start of the loop and reevaluate the
- * predicate.
- */
-
- Op = WalkState->ControlState->Control.PredicateOp;
-
- WalkState->ControlState->Common.State = CONTROL_PREDICATE_EXECUTING;
-
- /*
- * AcpiEvaluate the predicate again (next)
- * Because we will traverse WHILE tree again
- */
-
- WalkState->PrevOp = Op->Parent;
- WalkState->NextOp = Op;
- WalkState->NextOpInfo = NEXT_OP_DOWNWARD;
-
- return_ACPI_STATUS (AE_OK);
- break;
-
-
- case AE_CTRL_TERMINATE:
-
- /*
- * A control method was terminated via a RETURN statement.
- * The walk of this method is complete.
- */
- WalkState->PrevOp = WalkState->Origin;
- WalkState->NextOp = NULL;
-
- return_ACPI_STATUS (AE_OK);
- break;
- }
-
-
/*
* If we are back to the starting point, the walk is complete.
*/
@@ -397,7 +260,6 @@ AcpiPsGetNextWalkOp (
return_ACPI_STATUS (Status);
}
-
/*
* If there is a sibling to this parent (it is not the starting point
* Op), then we will visit it.
@@ -413,19 +275,6 @@ AcpiPsGetNextWalkOp (
return_ACPI_STATUS (Status);
}
- /*
- * No sibling, check for an error from closing the parent
- * (Also, AE_PENDING if a method call was encountered)
- */
- if (ACPI_FAILURE (Status))
- {
- WalkState->PrevOp = Parent;
- WalkState->NextOp = GrandParent;
- WalkState->NextOpInfo = NEXT_OP_UPWARD;
-
- return_ACPI_STATUS (Status);
- }
-
/* No siblings, no errors, just move up one more level in the tree */
Op = Parent;
@@ -445,283 +294,94 @@ AcpiPsGetNextWalkOp (
/*******************************************************************************
*
- * FUNCTION: AcpiPsWalkLoop
+ * FUNCTION: AcpiPsDeleteCompletedOp
*
- * PARAMETERS: WalkList - State of the walk
- * StartOp - Starting Op of the subtree to be walked
- * DescendingCallback - Procedure called when a new Op is
- * encountered
- * AscendingCallback - Procedure called when Op is complete
+ * PARAMETERS: State - Walk state
+ * Op - Completed op
*
- * RETURN: Status
+ * RETURN: AE_OK
*
- * DESCRIPTION: Perform a walk of the parsed AML tree. Begins and terminates at
- * the StartOp.
+ * DESCRIPTION: Callback function for AcpiPsGetNextWalkOp(). Used during
+ * AcpiPsDeleteParse tree to delete Op objects when all sub-objects
+ * have been visited (and deleted.)
*
******************************************************************************/
-ACPI_STATUS
-AcpiPsWalkLoop (
- ACPI_WALK_LIST *WalkList,
- ACPI_PARSE_OBJECT *StartOp,
- ACPI_PARSE_DOWNWARDS DescendingCallback,
- ACPI_PARSE_UPWARDS AscendingCallback)
+static ACPI_STATUS
+AcpiPsDeleteCompletedOp (
+ ACPI_WALK_STATE *State,
+ ACPI_PARSE_OBJECT *Op)
{
- ACPI_STATUS Status = AE_OK;
- ACPI_WALK_STATE *WalkState;
- ACPI_PARSE_OBJECT *Op = StartOp;
-
-
- FUNCTION_TRACE_PTR ("PsWalkLoop", StartOp);
-
- WalkState = AcpiDsGetCurrentWalkState (WalkList);
-
-
- /* Walk entire subtree, visiting all nodes depth-first */
-
- while (Op)
- {
- if (WalkState->NextOpInfo != NEXT_OP_UPWARD)
- {
- Status = DescendingCallback (Op->Opcode, Op, WalkState, NULL);
- }
-
- /*
- * A TRUE exception means that an ELSE was detected, but the IF
- * predicate evaluated TRUE.
- */
- if (Status == AE_CTRL_TRUE)
- {
- /*
- * Ignore the entire ELSE block by moving on to the the next opcode.
- * And we do that by simply going up in the tree (either to the next
- * sibling or to the parent) from here.
- */
-
- WalkState->NextOpInfo = NEXT_OP_UPWARD;
- }
-
- /* Get the next node (op) in the depth-first walk */
-
- Status = AcpiPsGetNextWalkOp (WalkState, Op, AscendingCallback);
-
- /*
- * A PENDING exception means that a control method invocation has been
- * detected
- */
-
- if (Status == AE_CTRL_PENDING)
- {
- /* Transfer control to the called control method */
-
- Status = AcpiDsCallControlMethod (WalkList, WalkState, Op);
-
- /*
- * If the transfer to the new method method call worked, a new walk
- * state was created -- get it
- */
-
- WalkState = AcpiDsGetCurrentWalkState (WalkList);
- }
-
- /* Abort the walk on any exception */
-
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
-
- Op = WalkState->NextOp;
- }
-
- return_ACPI_STATUS (AE_OK);
+ AcpiPsFreeOp (Op);
+ return (AE_OK);
}
/*******************************************************************************
*
- * FUNCTION: AcpiPsWalkParsedAml
+ * FUNCTION: AcpiPsDeleteParseTree
*
- * PARAMETERS: StartOp - Starting Op of the subtree to be walked
- * EndOp - Where to terminate the walk
- * DescendingCallback - Procedure called when a new Op is
- * encountered
- * AscendingCallback - Procedure called when Op is complete
+ * PARAMETERS: SubtreeRoot - Root of tree (or subtree) to delete
*
- * RETURN: Status
- *
- * DESCRIPTION: Top level interface to walk the parsed AML tree. Handles
- * preemption of executing control methods.
+ * RETURN: None
*
- * NOTE: The EndOp is usually only different from the StartOp if
- * we don't want to visit the StartOp during the tree descent.
+ * DESCRIPTION: Delete a portion of or an entire parse tree.
*
******************************************************************************/
-ACPI_STATUS
-mmmmAcpiPsWalkParsedAml (
- ACPI_PARSE_OBJECT *StartOp,
- ACPI_PARSE_OBJECT *EndOp,
- ACPI_OPERAND_OBJECT *MthDesc,
- ACPI_NAMESPACE_NODE *StartNode,
- ACPI_OPERAND_OBJECT **Params,
- ACPI_OPERAND_OBJECT **CallerReturnDesc,
- ACPI_OWNER_ID OwnerId,
- ACPI_PARSE_DOWNWARDS DescendingCallback,
- ACPI_PARSE_UPWARDS AscendingCallback)
+void
+AcpiPsDeleteParseTree (
+ ACPI_PARSE_OBJECT *SubtreeRoot)
{
- ACPI_PARSE_OBJECT *Op;
ACPI_WALK_STATE *WalkState;
- ACPI_OPERAND_OBJECT *ReturnDesc;
- ACPI_STATUS Status;
ACPI_WALK_LIST WalkList;
- ACPI_WALK_LIST *PrevWalkList;
- FUNCTION_TRACE_PTR ("PsWalkParsedAml", StartOp);
+ FUNCTION_TRACE_PTR ("PsDeleteParseTree", SubtreeRoot);
- /* Parameter Validation */
-
- if (!StartOp || !EndOp)
+ if (!SubtreeRoot)
{
- return (AE_BAD_PARAMETER);
+ return_VOID;
}
- /* Initialize a new walk list */
+ /* Create and initialize a new walk list */
WalkList.WalkState = NULL;
-
- WalkState = AcpiDsCreateWalkState (OwnerId, EndOp, MthDesc, &WalkList);
+ WalkState = AcpiDsCreateWalkState (TABLE_ID_DSDT, NULL, NULL, &WalkList);
if (!WalkState)
{
- return_ACPI_STATUS (AE_NO_MEMORY);
+ return_VOID;
}
- /* TBD: [Restructure] TEMP until we pass WalkState to the interpreter
- */
- PrevWalkList = AcpiGbl_CurrentWalkList;
- AcpiGbl_CurrentWalkList = &WalkList;
+ WalkState->ParserState = NULL;
+ WalkState->ParseFlags = 0;
+ WalkState->DescendingCallback = NULL;
+ WalkState->AscendingCallback = NULL;
- if (StartNode)
- {
- /* Push start scope on scope stack and make it current */
- Status = AcpiDsScopeStackPush (StartNode, ACPI_TYPE_METHOD, WalkState);
- if (ACPI_FAILURE (Status))
- {
- return_ACPI_STATUS (Status);
- }
+ WalkState->Origin = SubtreeRoot;
+ WalkState->NextOp = SubtreeRoot;
- }
- if (MthDesc)
- {
- /* Init arguments if this is a control method */
- /* TBD: [Restructure] add walkstate as a param */
+ /* Head downward in the tree */
- AcpiDsMethodDataInitArgs (Params, MTH_NUM_ARGS, WalkState);
- }
+ WalkState->NextOpInfo = NEXT_OP_DOWNWARD;
- Op = StartOp;
- Status = AE_OK;
+ /* Visit all nodes in the subtree */
-
- /*
- * Execute the walk loop as long as there is a valid Walk State. This
- * handles nested control method invocations without recursion.
- */
-
- DEBUG_PRINT (TRACE_PARSE, ("PsWalkParsedAml: Op=%p EndOp=%p State=%p\n",
- Op, EndOp, WalkState));
-
- while (WalkState)
+ while (WalkState->NextOp)
{
- if (ACPI_SUCCESS (Status))
- {
- Status = AcpiPsWalkLoop (&WalkList, Op, DescendingCallback,
- AscendingCallback);
- }
-
- DEBUG_PRINT (TRACE_PARSE,
- ("PsWalkParsedAml: Completed one call to walk loop, State=%p\n",
- WalkState));
-
- /* We are done with this walk, move on to the parent if any */
-
- BREAKPOINT3;
-
- WalkState = AcpiDsPopWalkState (&WalkList);
-
- /* Extract return value before we delete WalkState */
-
- ReturnDesc = WalkState->ReturnDesc;
-
- DEBUG_PRINT (TRACE_PARSE,
- ("PsWalkParsedAml: ReturnValue=%p, State=%p\n",
- WalkState->ReturnDesc, WalkState));
-
- /* Reset the current scope to the beginning of scope stack */
-
- AcpiDsScopeStackClear (WalkState);
-
- /*
- * If we just returned from the execution of a control method,
- * there's lots of cleanup to do
- */
-
- if (WalkState->MethodDesc)
- {
- AcpiDsTerminateControlMethod (WalkState);
- }
-
- /* Delete this walk state and all linked control states */
-
- AcpiDsDeleteWalkState (WalkState);
-
- /* Check if we have restarted a preempted walk */
-
- WalkState = AcpiDsGetCurrentWalkState (&WalkList);
- if (WalkState &&
- ACPI_SUCCESS (Status))
- {
- /* There is another walk state, restart it */
-
- /*
- * If the method returned value is not used by the parent,
- * The object is deleted
- */
-
- AcpiDsRestartControlMethod (WalkState, ReturnDesc);
-
- /* Get the next Op to process */
-
- Op = WalkState->NextOp;
- }
-
- /*
- * Just completed a 1st-level method, save the final internal return
- * value (if any)
- */
-
- else if (CallerReturnDesc)
- {
- *CallerReturnDesc = ReturnDesc; /* NULL if no return value */
- }
-
- else if (ReturnDesc)
- {
- /* Caller doesn't want it, must delete it */
-
- AcpiCmRemoveReference (ReturnDesc);
- }
+ AcpiPsGetNextWalkOp (WalkState, WalkState->NextOp,
+ AcpiPsDeleteCompletedOp);
}
+ /* We are done with this walk */
- AcpiGbl_CurrentWalkList = PrevWalkList;
+ AcpiDsDeleteWalkState (WalkState);
- return_ACPI_STATUS (Status);
+ return_VOID;
}