diff options
Diffstat (limited to 'sys/contrib/dev/acpica/psparse.c')
-rw-r--r-- | sys/contrib/dev/acpica/psparse.c | 868 |
1 files changed, 102 insertions, 766 deletions
diff --git a/sys/contrib/dev/acpica/psparse.c b/sys/contrib/dev/acpica/psparse.c index 9a626703636e8..826032915a67a 100644 --- a/sys/contrib/dev/acpica/psparse.c +++ b/sys/contrib/dev/acpica/psparse.c @@ -1,7 +1,7 @@ /****************************************************************************** * * Module Name: psparse - Parser top level AML parse routines - * $Revision: 146 $ + * $Revision: 1.158 $ * *****************************************************************************/ @@ -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 @@ -135,9 +135,6 @@ ACPI_MODULE_NAME ("psparse") -static UINT32 AcpiGbl_Depth = 0; - - /******************************************************************************* * * FUNCTION: AcpiPsGetOpcodeSize @@ -174,7 +171,7 @@ AcpiPsGetOpcodeSize ( * * PARAMETERS: ParserState - A parser state object * - * RETURN: Status + * RETURN: Next AML opcode * * DESCRIPTION: Get next AML opcode (without incrementing AML pointer) * @@ -191,10 +188,9 @@ AcpiPsPeekOpcode ( Aml = ParserState->Aml; Opcode = (UINT16) ACPI_GET8 (Aml); - - if (Opcode == AML_EXTOP) + if (Opcode == AML_EXTENDED_OP_PREFIX) { - /* Extended opcode */ + /* Extended opcode, get the second opcode byte */ Aml++; Opcode = (UINT16) ((Opcode << 8) | ACPI_GET8 (Aml)); @@ -211,13 +207,13 @@ AcpiPsPeekOpcode ( * PARAMETERS: WalkState - Current State * Op - Op to complete * - * RETURN: None. + * RETURN: Status * * DESCRIPTION: Perform any cleanup at the completion of an Op. * ******************************************************************************/ -void +ACPI_STATUS AcpiPsCompleteThisOp ( ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT *Op) @@ -235,7 +231,7 @@ AcpiPsCompleteThisOp ( if (!Op) { - return_VOID; + return_ACPI_STATUS (AE_OK); /* OK for now */ } /* Delete this op and the subtree below it if asked to */ @@ -243,18 +239,26 @@ AcpiPsCompleteThisOp ( if (((WalkState->ParseFlags & ACPI_PARSE_TREE_MASK) != ACPI_PARSE_DELETE_TREE) || (WalkState->OpInfo->Class == AML_CLASS_ARGUMENT)) { - return_VOID; + return_ACPI_STATUS (AE_OK); } /* Make sure that we only delete this subtree */ if (Op->Common.Parent) { + Prev = Op->Common.Parent->Common.Value.Arg; + if (!Prev) + { + /* Nothing more to do */ + + goto Cleanup; + } + /* * Check if we need to replace the operator and its subtree * with a return value op (placeholder op) */ - ParentInfo = AcpiPsGetOpcodeInfo (Op->Common.Parent->Common.AmlOpcode); + ParentInfo = AcpiPsGetOpcodeInfo (Op->Common.Parent->Common.AmlOpcode); switch (ParentInfo->Class) { @@ -270,7 +274,7 @@ AcpiPsCompleteThisOp ( ReplacementOp = AcpiPsAllocOp (AML_INT_RETURN_VALUE_OP); if (!ReplacementOp) { - goto Cleanup; + goto AllocateError; } break; @@ -289,13 +293,11 @@ AcpiPsCompleteThisOp ( ReplacementOp = AcpiPsAllocOp (AML_INT_RETURN_VALUE_OP); if (!ReplacementOp) { - goto Cleanup; + goto AllocateError; } } - - if ((Op->Common.Parent->Common.AmlOpcode == AML_NAME_OP) && - (WalkState->DescendingCallback != AcpiDsExecBeginOp)) - + else if ((Op->Common.Parent->Common.AmlOpcode == AML_NAME_OP) && + (WalkState->PassNumber <= ACPI_IMODE_LOAD_PASS2)) { if ((Op->Common.AmlOpcode == AML_BUFFER_OP) || (Op->Common.AmlOpcode == AML_PACKAGE_OP) || @@ -304,7 +306,7 @@ AcpiPsCompleteThisOp ( ReplacementOp = AcpiPsAllocOp (Op->Common.AmlOpcode); if (!ReplacementOp) { - goto Cleanup; + goto AllocateError; } ReplacementOp->Named.Data = Op->Named.Data; @@ -314,16 +316,16 @@ AcpiPsCompleteThisOp ( break; default: + ReplacementOp = AcpiPsAllocOp (AML_INT_RETURN_VALUE_OP); if (!ReplacementOp) { - goto Cleanup; + goto AllocateError; } } /* We must unlink this op from the parent tree */ - Prev = Op->Common.Parent->Common.Value.Arg; if (Prev == Op) { /* This op is the first in the list */ @@ -366,7 +368,6 @@ AcpiPsCompleteThisOp ( Next = NULL; } } - Prev = Next; } } @@ -374,10 +375,18 @@ AcpiPsCompleteThisOp ( Cleanup: - /* Now we can actually delete the subtree rooted at op */ + /* Now we can actually delete the subtree rooted at Op */ + + AcpiPsDeleteParseTree (Op); + return_ACPI_STATUS (AE_OK); + + +AllocateError: + + /* Always delete the subtree, even on error */ AcpiPsDeleteParseTree (Op); - return_VOID; + return_ACPI_STATUS (AE_NO_MEMORY); } @@ -385,7 +394,9 @@ Cleanup: * * FUNCTION: AcpiPsNextParseState * - * PARAMETERS: ParserState - Current parser state object + * PARAMETERS: WalkState - Current state + * Op - Current parse op + * CallbackStatus - Status from previous operation * * RETURN: Status * @@ -477,9 +488,8 @@ AcpiPsNextParseState ( case AE_CTRL_TRANSFER: - /* - * A method call (invocation) -- transfer control - */ + /* A method call (invocation) -- transfer control */ + Status = AE_CTRL_TRANSFER; WalkState->PrevOp = Op; WalkState->MethodCallOp = Op; @@ -492,6 +502,7 @@ AcpiPsNextParseState ( default: + Status = CallbackStatus; if ((CallbackStatus & AE_CODE_MASK) == AE_CODE_CONTROL) { @@ -506,715 +517,9 @@ AcpiPsNextParseState ( /******************************************************************************* * - * FUNCTION: AcpiPsParseLoop - * - * PARAMETERS: ParserState - Current parser state object - * - * RETURN: Status - * - * DESCRIPTION: Parse AML (pointed to by the current parser state) and return - * a tree of ops. - * - ******************************************************************************/ - -ACPI_STATUS -AcpiPsParseLoop ( - ACPI_WALK_STATE *WalkState) -{ - ACPI_STATUS Status = AE_OK; - ACPI_PARSE_OBJECT *Op = NULL; /* current op */ - ACPI_PARSE_OBJECT *Arg = NULL; - ACPI_PARSE_OBJECT *PreOp = NULL; - ACPI_PARSE_STATE *ParserState; - UINT8 *AmlOpStart = NULL; - - - ACPI_FUNCTION_TRACE_PTR ("PsParseLoop", WalkState); - - if (WalkState->DescendingCallback == NULL) - { - return_ACPI_STATUS (AE_BAD_PARAMETER); - } - - ParserState = &WalkState->ParserState; - WalkState->ArgTypes = 0; - -#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY)) - if (WalkState->WalkType & ACPI_WALK_METHOD_RESTART) - { - /* We are restarting a preempted control method */ - - if (AcpiPsHasCompletedScope (ParserState)) - { - /* - * We must check if a predicate to an IF or WHILE statement - * was just completed - */ - if ((ParserState->Scope->ParseScope.Op) && - ((ParserState->Scope->ParseScope.Op->Common.AmlOpcode == AML_IF_OP) || - (ParserState->Scope->ParseScope.Op->Common.AmlOpcode == AML_WHILE_OP)) && - (WalkState->ControlState) && - (WalkState->ControlState->Common.State == - ACPI_CONTROL_PREDICATE_EXECUTING)) - { - /* - * A predicate was just completed, get the value of the - * predicate and branch based on that value - */ - WalkState->Op = NULL; - Status = AcpiDsGetPredicateValue (WalkState, ACPI_TO_POINTER (TRUE)); - if (ACPI_FAILURE (Status) && - ((Status & AE_CODE_MASK) != AE_CODE_CONTROL)) - { - if (Status == AE_AML_NO_RETURN_VALUE) - { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Invoked method did not return a value, %s\n", - AcpiFormatException (Status))); - - } - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "GetPredicate Failed, %s\n", - AcpiFormatException (Status))); - return_ACPI_STATUS (Status); - } - - Status = AcpiPsNextParseState (WalkState, Op, Status); - } - - AcpiPsPopScope (ParserState, &Op, - &WalkState->ArgTypes, &WalkState->ArgCount); - ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", Op)); - } - else if (WalkState->PrevOp) - { - /* We were in the middle of an op */ - - Op = WalkState->PrevOp; - WalkState->ArgTypes = WalkState->PrevArgTypes; - } - } -#endif - - /* - * Iterative parsing loop, while there is more aml to process: - */ - while ((ParserState->Aml < ParserState->AmlEnd) || (Op)) - { - AmlOpStart = ParserState->Aml; - if (!Op) - { - /* Get the next opcode from the AML stream */ - - WalkState->AmlOffset = (UINT32) ACPI_PTR_DIFF (ParserState->Aml, - ParserState->AmlStart); - WalkState->Opcode = AcpiPsPeekOpcode (ParserState); - - /* - * First cut to determine what we have found: - * 1) A valid AML opcode - * 2) A name string - * 3) An unknown/invalid opcode - */ - WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode); - switch (WalkState->OpInfo->Class) - { - case AML_CLASS_ASCII: - case AML_CLASS_PREFIX: - /* - * Starts with a valid prefix or ASCII char, this is a name - * string. Convert the bare name string to a namepath. - */ - WalkState->Opcode = AML_INT_NAMEPATH_OP; - WalkState->ArgTypes = ARGP_NAMESTRING; - break; - - case AML_CLASS_UNKNOWN: - - /* The opcode is unrecognized. Just skip unknown opcodes */ - - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, - "Found unknown opcode %X at AML address %p offset %X, ignoring\n", - WalkState->Opcode, ParserState->Aml, WalkState->AmlOffset)); - - ACPI_DUMP_BUFFER (ParserState->Aml, 128); - - /* Assume one-byte bad opcode */ - - ParserState->Aml++; - continue; - - default: - - /* Found opcode info, this is a normal opcode */ - - ParserState->Aml += AcpiPsGetOpcodeSize (WalkState->Opcode); - WalkState->ArgTypes = WalkState->OpInfo->ParseArgs; - break; - } - - /* Create Op structure and append to parent's argument list */ - - if (WalkState->OpInfo->Flags & AML_NAMED) - { - /* Allocate a new PreOp if necessary */ - - if (!PreOp) - { - PreOp = AcpiPsAllocOp (WalkState->Opcode); - if (!PreOp) - { - Status = AE_NO_MEMORY; - goto CloseThisOp; - } - } - - PreOp->Common.Value.Arg = NULL; - PreOp->Common.AmlOpcode = WalkState->Opcode; - - /* - * Get and append arguments until we find the node that contains - * the name (the type ARGP_NAME). - */ - while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) && - (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) != ARGP_NAME)) - { - Status = AcpiPsGetNextArg (WalkState, ParserState, - GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg); - if (ACPI_FAILURE (Status)) - { - goto CloseThisOp; - } - - AcpiPsAppendArg (PreOp, Arg); - INCREMENT_ARG_LIST (WalkState->ArgTypes); - } - - /* Make sure that we found a NAME and didn't run out of arguments */ - - if (!GET_CURRENT_ARG_TYPE (WalkState->ArgTypes)) - { - Status = AE_AML_NO_OPERAND; - goto CloseThisOp; - } - - /* We know that this arg is a name, move to next arg */ - - INCREMENT_ARG_LIST (WalkState->ArgTypes); - - /* - * Find the object. This will either insert the object into - * the namespace or simply look it up - */ - WalkState->Op = NULL; - - Status = WalkState->DescendingCallback (WalkState, &Op); - if (ACPI_FAILURE (Status)) - { - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "During name lookup/catalog, %s\n", - AcpiFormatException (Status))); - goto CloseThisOp; - } - - if (Op == NULL) - { - continue; - } - - Status = AcpiPsNextParseState (WalkState, Op, Status); - if (Status == AE_CTRL_PENDING) - { - Status = AE_OK; - goto CloseThisOp; - } - - if (ACPI_FAILURE (Status)) - { - goto CloseThisOp; - } - - AcpiPsAppendArg (Op, PreOp->Common.Value.Arg); - AcpiGbl_Depth++; - - if (Op->Common.AmlOpcode == AML_REGION_OP) - { - /* - * Defer final parsing of an OperationRegion body, - * because we don't have enough info in the first pass - * to parse it correctly (i.e., there may be method - * calls within the TermArg elements of the body.) - * - * However, we must continue parsing because - * the opregion is not a standalone package -- - * we don't know where the end is at this point. - * - * (Length is unknown until parse of the body complete) - */ - Op->Named.Data = AmlOpStart; - Op->Named.Length = 0; - } - } - else - { - /* Not a named opcode, just allocate Op and append to parent */ - - WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode); - Op = AcpiPsAllocOp (WalkState->Opcode); - if (!Op) - { - Status = AE_NO_MEMORY; - goto CloseThisOp; - } - - if (WalkState->OpInfo->Flags & AML_CREATE) - { - /* - * Backup to beginning of CreateXXXfield declaration - * BodyLength is unknown until we parse the body - */ - Op->Named.Data = AmlOpStart; - Op->Named.Length = 0; - } - - AcpiPsAppendArg (AcpiPsGetParentScope (ParserState), Op); - - if ((WalkState->DescendingCallback != NULL)) - { - /* - * Find the object. This will either insert the object into - * the namespace or simply look it up - */ - WalkState->Op = Op; - - Status = WalkState->DescendingCallback (WalkState, &Op); - Status = AcpiPsNextParseState (WalkState, Op, Status); - if (Status == AE_CTRL_PENDING) - { - Status = AE_OK; - goto CloseThisOp; - } - - if (ACPI_FAILURE (Status)) - { - goto CloseThisOp; - } - } - } - - Op->Common.AmlOffset = WalkState->AmlOffset; - - if (WalkState->OpInfo) - { - ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, - "Opcode %4.4X [%s] Op %p Aml %p AmlOffset %5.5X\n", - (UINT32) Op->Common.AmlOpcode, WalkState->OpInfo->Name, - Op, ParserState->Aml, Op->Common.AmlOffset)); - } - } - - - /* Start ArgCount at zero because we don't know if there are any args yet */ - - WalkState->ArgCount = 0; - - if (WalkState->ArgTypes) /* Are there any arguments that must be processed? */ - { - /* Get arguments */ - - switch (Op->Common.AmlOpcode) - { - case AML_BYTE_OP: /* AML_BYTEDATA_ARG */ - case AML_WORD_OP: /* AML_WORDDATA_ARG */ - case AML_DWORD_OP: /* AML_DWORDATA_ARG */ - case AML_QWORD_OP: /* AML_QWORDATA_ARG */ - case AML_STRING_OP: /* AML_ASCIICHARLIST_ARG */ - - /* Fill in constant or string argument directly */ - - AcpiPsGetNextSimpleArg (ParserState, - GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), Op); - break; - - case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */ - - Status = AcpiPsGetNextNamepath (WalkState, ParserState, Op, 1); - if (ACPI_FAILURE (Status)) - { - goto CloseThisOp; - } - - WalkState->ArgTypes = 0; - break; - - default: - - /* Op is not a constant or string, append each argument to the Op */ - - while (GET_CURRENT_ARG_TYPE (WalkState->ArgTypes) && - !WalkState->ArgCount) - { - WalkState->AmlOffset = (UINT32) ACPI_PTR_DIFF (ParserState->Aml, - ParserState->AmlStart); - Status = AcpiPsGetNextArg (WalkState, ParserState, - GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg); - if (ACPI_FAILURE (Status)) - { - goto CloseThisOp; - } - - if (Arg) - { - Arg->Common.AmlOffset = WalkState->AmlOffset; - AcpiPsAppendArg (Op, Arg); - } - INCREMENT_ARG_LIST (WalkState->ArgTypes); - } - - /* Special processing for certain opcodes */ - - switch (Op->Common.AmlOpcode) - { - case AML_METHOD_OP: - - /* - * Skip parsing of control method - * because we don't have enough info in the first pass - * to parse it correctly. - * - * Save the length and address of the body - */ - Op->Named.Data = ParserState->Aml; - Op->Named.Length = (UINT32) (ParserState->PkgEnd - ParserState->Aml); - - /* Skip body of method */ - - ParserState->Aml = ParserState->PkgEnd; - WalkState->ArgCount = 0; - break; - - case AML_BUFFER_OP: - case AML_PACKAGE_OP: - case AML_VAR_PACKAGE_OP: - - if ((Op->Common.Parent) && - (Op->Common.Parent->Common.AmlOpcode == AML_NAME_OP) && - (WalkState->DescendingCallback != AcpiDsExecBeginOp)) - { - /* - * Skip parsing of Buffers and Packages - * because we don't have enough info in the first pass - * to parse them correctly. - */ - Op->Named.Data = AmlOpStart; - Op->Named.Length = (UINT32) (ParserState->PkgEnd - AmlOpStart); - - /* Skip body */ - - ParserState->Aml = ParserState->PkgEnd; - WalkState->ArgCount = 0; - } - break; - - case AML_WHILE_OP: - - if (WalkState->ControlState) - { - WalkState->ControlState->Control.PackageEnd = ParserState->PkgEnd; - } - break; - - default: - - /* No action for all other opcodes */ - break; - } - break; - } - } - - /* Check for arguments that need to be processed */ - - if (WalkState->ArgCount) - { - /* There are arguments (complex ones), push Op and prepare for argument */ - - Status = AcpiPsPushScope (ParserState, Op, - WalkState->ArgTypes, WalkState->ArgCount); - if (ACPI_FAILURE (Status)) - { - goto CloseThisOp; - } - Op = NULL; - continue; - } - - /* All arguments have been processed -- Op is complete, prepare for next */ - - WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); - if (WalkState->OpInfo->Flags & AML_NAMED) - { - if (AcpiGbl_Depth) - { - AcpiGbl_Depth--; - } - - if (Op->Common.AmlOpcode == AML_REGION_OP) - { - /* - * Skip parsing of control method or opregion body, - * because we don't have enough info in the first pass - * to parse them correctly. - * - * Completed parsing an OpRegion declaration, we now - * know the length. - */ - Op->Named.Length = (UINT32) (ParserState->Aml - Op->Named.Data); - } - } - - if (WalkState->OpInfo->Flags & AML_CREATE) - { - /* - * Backup to beginning of CreateXXXfield declaration (1 for - * Opcode) - * - * BodyLength is unknown until we parse the body - */ - Op->Named.Length = (UINT32) (ParserState->Aml - Op->Named.Data); - } - - /* This op complete, notify the dispatcher */ - - if (WalkState->AscendingCallback != NULL) - { - WalkState->Op = Op; - WalkState->Opcode = Op->Common.AmlOpcode; - - Status = WalkState->AscendingCallback (WalkState); - Status = AcpiPsNextParseState (WalkState, Op, Status); - if (Status == AE_CTRL_PENDING) - { - Status = AE_OK; - goto CloseThisOp; - } - } - - -CloseThisOp: - /* - * Finished one argument of the containing scope - */ - ParserState->Scope->ParseScope.ArgCount--; - - /* Close this Op (will result in parse subtree deletion) */ - - AcpiPsCompleteThisOp (WalkState, Op); - Op = NULL; - if (PreOp) - { - AcpiPsFreeOp (PreOp); - PreOp = NULL; - } - - switch (Status) - { - case AE_OK: - break; - - - case AE_CTRL_TRANSFER: - - /* - * We are about to transfer to a called method. - */ - WalkState->PrevOp = Op; - WalkState->PrevArgTypes = WalkState->ArgTypes; - return_ACPI_STATUS (Status); - - - case AE_CTRL_END: - - AcpiPsPopScope (ParserState, &Op, - &WalkState->ArgTypes, &WalkState->ArgCount); - - if (Op) - { - WalkState->Op = Op; - WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); - WalkState->Opcode = Op->Common.AmlOpcode; - - Status = WalkState->AscendingCallback (WalkState); - Status = AcpiPsNextParseState (WalkState, Op, Status); - - AcpiPsCompleteThisOp (WalkState, Op); - Op = NULL; - } - Status = AE_OK; - break; - - - case AE_CTRL_BREAK: - case AE_CTRL_CONTINUE: - - /* Pop off scopes until we find the While */ - - while (!Op || (Op->Common.AmlOpcode != AML_WHILE_OP)) - { - AcpiPsPopScope (ParserState, &Op, - &WalkState->ArgTypes, &WalkState->ArgCount); - } - - /* Close this iteration of the While loop */ - - WalkState->Op = Op; - WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); - WalkState->Opcode = Op->Common.AmlOpcode; - - Status = WalkState->AscendingCallback (WalkState); - Status = AcpiPsNextParseState (WalkState, Op, Status); - - AcpiPsCompleteThisOp (WalkState, Op); - Op = NULL; - - Status = AE_OK; - break; - - - case AE_CTRL_TERMINATE: - - Status = AE_OK; - - /* Clean up */ - do - { - if (Op) - { - AcpiPsCompleteThisOp (WalkState, Op); - } - AcpiPsPopScope (ParserState, &Op, - &WalkState->ArgTypes, &WalkState->ArgCount); - - } while (Op); - - return_ACPI_STATUS (Status); - - - default: /* All other non-AE_OK status */ - - do - { - if (Op) - { - AcpiPsCompleteThisOp (WalkState, Op); - } - AcpiPsPopScope (ParserState, &Op, - &WalkState->ArgTypes, &WalkState->ArgCount); - - } while (Op); - - - /* - * TBD: Cleanup parse ops on error - */ -#if 0 - if (Op == NULL) - { - AcpiPsPopScope (ParserState, &Op, - &WalkState->ArgTypes, &WalkState->ArgCount); - } -#endif - WalkState->PrevOp = Op; - WalkState->PrevArgTypes = WalkState->ArgTypes; - return_ACPI_STATUS (Status); - } - - /* This scope complete? */ - - if (AcpiPsHasCompletedScope (ParserState)) - { - AcpiPsPopScope (ParserState, &Op, - &WalkState->ArgTypes, &WalkState->ArgCount); - ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", Op)); - } - else - { - Op = NULL; - } - - } /* while ParserState->Aml */ - - - /* - * Complete the last Op (if not completed), and clear the scope stack. - * It is easily possible to end an AML "package" with an unbounded number - * of open scopes (such as when several ASL blocks are closed with - * sequential closing braces). We want to terminate each one cleanly. - */ - ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "AML package complete at Op %p\n", Op)); - do - { - if (Op) - { - if (WalkState->AscendingCallback != NULL) - { - WalkState->Op = Op; - WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode); - WalkState->Opcode = Op->Common.AmlOpcode; - - Status = WalkState->AscendingCallback (WalkState); - Status = AcpiPsNextParseState (WalkState, Op, Status); - if (Status == AE_CTRL_PENDING) - { - Status = AE_OK; - goto CloseThisOp; - } - - if (Status == AE_CTRL_TERMINATE) - { - Status = AE_OK; - - /* Clean up */ - do - { - if (Op) - { - AcpiPsCompleteThisOp (WalkState, Op); - } - - AcpiPsPopScope (ParserState, &Op, - &WalkState->ArgTypes, &WalkState->ArgCount); - - } while (Op); - - return_ACPI_STATUS (Status); - } - - else if (ACPI_FAILURE (Status)) - { - AcpiPsCompleteThisOp (WalkState, Op); - return_ACPI_STATUS (Status); - } - } - - AcpiPsCompleteThisOp (WalkState, Op); - } - - AcpiPsPopScope (ParserState, &Op, &WalkState->ArgTypes, - &WalkState->ArgCount); - - } while (Op); - - return_ACPI_STATUS (Status); -} - - -/******************************************************************************* - * * FUNCTION: AcpiPsParseAml * - * PARAMETERS: StartScope - The starting point of the parse. Becomes the - * root of the parsed op tree. - * Aml - Pointer to the raw AML code to parse - * AmlSize - Length of the AML to parse + * PARAMETERS: WalkState - Current state * * * RETURN: Status @@ -1228,7 +533,6 @@ AcpiPsParseAml ( ACPI_WALK_STATE *WalkState) { ACPI_STATUS Status; - ACPI_STATUS TerminateStatus; ACPI_THREAD_STATE *Thread; ACPI_THREAD_STATE *PrevWalkList = AcpiGbl_CurrentWalkList; ACPI_WALK_STATE *PreviousWalkState; @@ -1236,8 +540,10 @@ AcpiPsParseAml ( ACPI_FUNCTION_TRACE ("PsParseAml"); - ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Entered with WalkState=%p Aml=%p size=%X\n", - WalkState, WalkState->ParserState.Aml, WalkState->ParserState.AmlSize)); + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, + "Entered with WalkState=%p Aml=%p size=%X\n", + WalkState, WalkState->ParserState.Aml, + WalkState->ParserState.AmlSize)); /* Create and initialize a new thread state */ @@ -1303,31 +609,26 @@ AcpiPsParseAml ( ACPI_REPORT_METHOD_ERROR ("Method execution failed", WalkState->MethodNode, NULL, Status); + /* Ensure proper cleanup */ + + WalkState->ParseFlags |= ACPI_PARSE_EXECUTE; + /* Check for possible multi-thread reentrancy problem */ if ((Status == AE_ALREADY_EXISTS) && (!WalkState->MethodDesc->Method.Semaphore)) { /* - * This method is marked NotSerialized, but it tried to create a named - * object, causing the second thread entrance to fail. We will workaround - * this by marking the method permanently as Serialized. + * This method is marked NotSerialized, but it tried to create + * a named object, causing the second thread entrance to fail. + * We will workaround this by marking the method permanently + * as Serialized. */ WalkState->MethodDesc->Method.MethodFlags |= AML_METHOD_SERIALIZED; WalkState->MethodDesc->Method.Concurrency = 1; } } - if (WalkState->MethodDesc) - { - /* Decrement the thread count on the method parse tree */ - - if (WalkState->MethodDesc->Method.ThreadCount) - { - WalkState->MethodDesc->Method.ThreadCount--; - } - } - /* We are done with this walk, move on to the parent if any */ WalkState = AcpiDsPopWalkState (Thread); @@ -1342,14 +643,14 @@ AcpiPsParseAml ( */ if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) { - TerminateStatus = AcpiDsTerminateControlMethod (WalkState); - if (ACPI_FAILURE (TerminateStatus)) + if (WalkState->MethodDesc) { - ACPI_REPORT_ERROR (( - "Could not terminate control method properly\n")); + /* Decrement the thread count on the method parse tree */ - /* Ignore error and continue */ + WalkState->MethodDesc->Method.ThreadCount--; } + + AcpiDsTerminateControlMethod (WalkState); } /* Delete this walk state and all linked control states */ @@ -1358,8 +659,9 @@ AcpiPsParseAml ( PreviousWalkState = WalkState; - ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "ReturnValue=%p, State=%p\n", - WalkState->ReturnDesc, WalkState)); + ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, + "ReturnValue=%p, ImplicitValue=%p State=%p\n", + WalkState->ReturnDesc, WalkState->ImplicitReturnObj, WalkState)); /* Check if we have restarted a preempted walk */ @@ -1373,8 +675,22 @@ AcpiPsParseAml ( * If the method return value is not used by the parent, * The object is deleted */ - Status = AcpiDsRestartControlMethod (WalkState, - PreviousWalkState->ReturnDesc); + if (!PreviousWalkState->ReturnDesc) + { + Status = AcpiDsRestartControlMethod (WalkState, + PreviousWalkState->ImplicitReturnObj); + } + else + { + /* + * We have a valid return value, delete any implicit + * return value. + */ + AcpiDsClearImplicitReturn (PreviousWalkState); + + Status = AcpiDsRestartControlMethod (WalkState, + PreviousWalkState->ReturnDesc); + } if (ACPI_SUCCESS (Status)) { WalkState->WalkType |= ACPI_WALK_METHOD_RESTART; @@ -1394,13 +710,33 @@ AcpiPsParseAml ( */ else if (PreviousWalkState->CallerReturnDesc) { - *(PreviousWalkState->CallerReturnDesc) = PreviousWalkState->ReturnDesc; /* NULL if no return value */ + if (PreviousWalkState->ImplicitReturnObj) + { + *(PreviousWalkState->CallerReturnDesc) = + PreviousWalkState->ImplicitReturnObj; + } + else + { + /* NULL if no return value */ + + *(PreviousWalkState->CallerReturnDesc) = + PreviousWalkState->ReturnDesc; + } } - else if (PreviousWalkState->ReturnDesc) + else { - /* Caller doesn't want it, must delete it */ + if (PreviousWalkState->ReturnDesc) + { + /* Caller doesn't want it, must delete it */ - AcpiUtRemoveReference (PreviousWalkState->ReturnDesc); + AcpiUtRemoveReference (PreviousWalkState->ReturnDesc); + } + if (PreviousWalkState->ImplicitReturnObj) + { + /* Caller doesn't want it, must delete it */ + + AcpiUtRemoveReference (PreviousWalkState->ImplicitReturnObj); + } } AcpiDsDeleteWalkState (PreviousWalkState); |