diff options
Diffstat (limited to 'sys/contrib/dev/acpica/pswalk.c')
-rw-r--r-- | sys/contrib/dev/acpica/pswalk.c | 474 |
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; } |