summaryrefslogtreecommitdiffstats
path: root/sys/contrib/dev/acpica/psloop.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/contrib/dev/acpica/psloop.c')
-rw-r--r--sys/contrib/dev/acpica/psloop.c1389
1 files changed, 824 insertions, 565 deletions
diff --git a/sys/contrib/dev/acpica/psloop.c b/sys/contrib/dev/acpica/psloop.c
index 91933c7..6c6ce47 100644
--- a/sys/contrib/dev/acpica/psloop.c
+++ b/sys/contrib/dev/acpica/psloop.c
@@ -1,7 +1,7 @@
/******************************************************************************
*
* Module Name: psloop - Main AML parse loop
- * $Revision: 1.5 $
+ * $Revision: 1.16 $
*
*****************************************************************************/
@@ -9,7 +9,7 @@
*
* 1. Copyright Notice
*
- * Some or all of this work - Copyright (c) 1999 - 2005, Intel Corp.
+ * Some or all of this work - Copyright (c) 1999 - 2007, Intel Corp.
* All rights reserved.
*
* 2. License
@@ -116,12 +116,11 @@
/*
- * Parse the AML and build an operation tree as most interpreters,
- * like Perl, do. Parsing is done by hand rather than with a YACC
- * generated parser to tightly constrain stack and dynamic memory
- * usage. At the same time, parsing is kept flexible and the code
- * fairly compact by parsing based on a list of AML opcode
- * templates in AmlOpInfo[]
+ * Parse the AML and build an operation tree as most interpreters, (such as
+ * Perl) do. Parsing is done by hand rather than with a YACC generated parser
+ * to tightly constrain stack and dynamic memory usage. Parsing is kept
+ * flexible and the code fairly compact by parsing based on a list of AML
+ * opcode templates in AmlOpInfo[].
*/
#include <contrib/dev/acpica/acpi.h>
@@ -135,727 +134,739 @@
static UINT32 AcpiGbl_Depth = 0;
+/* Local prototypes */
+
+static ACPI_STATUS
+AcpiPsGetAmlOpcode (
+ ACPI_WALK_STATE *WalkState);
+
+static ACPI_STATUS
+AcpiPsBuildNamedOp (
+ ACPI_WALK_STATE *WalkState,
+ UINT8 *AmlOpStart,
+ ACPI_PARSE_OBJECT *UnnamedOp,
+ ACPI_PARSE_OBJECT **Op);
+
+static ACPI_STATUS
+AcpiPsCreateOp (
+ ACPI_WALK_STATE *WalkState,
+ UINT8 *AmlOpStart,
+ ACPI_PARSE_OBJECT **NewOp);
+
+static ACPI_STATUS
+AcpiPsGetArguments (
+ ACPI_WALK_STATE *WalkState,
+ UINT8 *AmlOpStart,
+ ACPI_PARSE_OBJECT *Op);
+
+static ACPI_STATUS
+AcpiPsCompleteOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT **Op,
+ ACPI_STATUS Status);
+
+static ACPI_STATUS
+AcpiPsCompleteFinalOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_STATUS Status);
+
+
/*******************************************************************************
*
- * FUNCTION: AcpiPsParseLoop
+ * FUNCTION: AcpiPsGetAmlOpcode
*
* PARAMETERS: WalkState - Current state
*
* RETURN: Status
*
- * DESCRIPTION: Parse AML (pointed to by the current parser state) and return
- * a tree of ops.
+ * DESCRIPTION: Extract the next AML opcode from the input stream.
*
******************************************************************************/
-ACPI_STATUS
-AcpiPsParseLoop (
+static ACPI_STATUS
+AcpiPsGetAmlOpcode (
ACPI_WALK_STATE *WalkState)
{
- ACPI_STATUS Status = AE_OK;
- ACPI_STATUS Status2;
- 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 (PsGetAmlOpcode, WalkState);
- ACPI_FUNCTION_TRACE_PTR ("PsParseLoop", WalkState);
- if (WalkState->DescendingCallback == NULL)
+ WalkState->AmlOffset = (UINT32) ACPI_PTR_DIFF (WalkState->ParserState.Aml,
+ WalkState->ParserState.AmlStart);
+ WalkState->Opcode = AcpiPsPeekOpcode (&(WalkState->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)
{
- return_ACPI_STATUS (AE_BAD_PARAMETER);
- }
+ 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;
- ParserState = &WalkState->ParserState;
- WalkState->ArgTypes = 0;
+ case AML_CLASS_UNKNOWN:
-#if (!defined (ACPI_NO_METHOD_EXECUTION) && !defined (ACPI_CONSTANT_EVAL_ONLY))
+ /* The opcode is unrecognized. Just skip unknown opcodes */
- if (WalkState->WalkType & ACPI_WALK_METHOD_RESTART)
- {
- /* We are restarting a preempted control method */
+ ACPI_ERROR ((AE_INFO,
+ "Found unknown opcode %X at AML address %p offset %X, ignoring",
+ WalkState->Opcode, WalkState->ParserState.Aml, WalkState->AmlOffset));
- 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_DUMP_BUFFER (WalkState->ParserState.Aml, 128);
- }
- ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
- "GetPredicate Failed, %s\n",
- AcpiFormatException (Status)));
- return_ACPI_STATUS (Status);
- }
+ /* Assume one-byte bad opcode */
- Status = AcpiPsNextParseState (WalkState, Op, Status);
- }
+ WalkState->ParserState.Aml++;
+ return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
- 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 */
+ default:
- Op = WalkState->PrevOp;
- WalkState->ArgTypes = WalkState->PrevArgTypes;
- }
+ /* Found opcode info, this is a normal opcode */
+
+ WalkState->ParserState.Aml += AcpiPsGetOpcodeSize (WalkState->Opcode);
+ WalkState->ArgTypes = WalkState->OpInfo->ParseArgs;
+ break;
}
-#endif
- /* Iterative parsing loop, while there is more AML to process: */
+ return_ACPI_STATUS (AE_OK);
+}
- 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);
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsBuildNamedOp
+ *
+ * PARAMETERS: WalkState - Current state
+ * AmlOpStart - Begin of named Op in AML
+ * UnnamedOp - Early Op (not a named Op)
+ * Op - Returned Op
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Parse a named Op
+ *
+ ******************************************************************************/
- /*
- * 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;
+static ACPI_STATUS
+AcpiPsBuildNamedOp (
+ ACPI_WALK_STATE *WalkState,
+ UINT8 *AmlOpStart,
+ ACPI_PARSE_OBJECT *UnnamedOp,
+ ACPI_PARSE_OBJECT **Op)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_PARSE_OBJECT *Arg = NULL;
- case AML_CLASS_UNKNOWN:
- /* The opcode is unrecognized. Just skip unknown opcodes */
+ ACPI_FUNCTION_TRACE_PTR (PsBuildNamedOp, WalkState);
- 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);
+ UnnamedOp->Common.Value.Arg = NULL;
+ UnnamedOp->Common.ArgListLength = 0;
+ UnnamedOp->Common.AmlOpcode = WalkState->Opcode;
- /* Assume one-byte bad 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, &(WalkState->ParserState),
+ GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
- ParserState->Aml++;
- continue;
+ AcpiPsAppendArg (UnnamedOp, Arg);
+ INCREMENT_ARG_LIST (WalkState->ArgTypes);
+ }
- default:
+ /*
+ * Make sure that we found a NAME and didn't run out of arguments
+ */
+ if (!GET_CURRENT_ARG_TYPE (WalkState->ArgTypes))
+ {
+ return_ACPI_STATUS (AE_AML_NO_OPERAND);
+ }
- /* Found opcode info, this is a normal opcode */
+ /* We know that this arg is a name, move to next arg */
- ParserState->Aml += AcpiPsGetOpcodeSize (WalkState->Opcode);
- WalkState->ArgTypes = WalkState->OpInfo->ParseArgs;
- break;
- }
+ INCREMENT_ARG_LIST (WalkState->ArgTypes);
- /* Create Op structure and append to parent's argument list */
+ /*
+ * Find the object. This will either insert the object into
+ * the namespace or simply look it up
+ */
+ WalkState->Op = NULL;
- if (WalkState->OpInfo->Flags & AML_NAMED)
- {
- /* Allocate a new PreOp if necessary */
+ Status = WalkState->DescendingCallback (WalkState, Op);
+ if (ACPI_FAILURE (Status))
+ {
+ ACPI_EXCEPTION ((AE_INFO, Status, "During name lookup/catalog"));
+ return_ACPI_STATUS (Status);
+ }
- if (!PreOp)
- {
- PreOp = AcpiPsAllocOp (WalkState->Opcode);
- if (!PreOp)
- {
- Status = AE_NO_MEMORY;
- goto CloseThisOp;
- }
- }
+ if (!*Op)
+ {
+ return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
+ }
- PreOp->Common.Value.Arg = NULL;
- PreOp->Common.AmlOpcode = WalkState->Opcode;
+ Status = AcpiPsNextParseState (WalkState, *Op, Status);
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status == AE_CTRL_PENDING)
+ {
+ return_ACPI_STATUS (AE_CTRL_PARSE_PENDING);
+ }
+ return_ACPI_STATUS (Status);
+ }
- /*
- * 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 (*Op, UnnamedOp->Common.Value.Arg);
+ AcpiGbl_Depth++;
- AcpiPsAppendArg (PreOp, Arg);
- INCREMENT_ARG_LIST (WalkState->ArgTypes);
- }
+ 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;
+ }
- /*
- * 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;
- }
+ return_ACPI_STATUS (AE_OK);
+}
- /* We know that this arg is a name, move to next arg */
- INCREMENT_ARG_LIST (WalkState->ArgTypes);
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsCreateOp
+ *
+ * PARAMETERS: WalkState - Current state
+ * AmlOpStart - Op start in AML
+ * NewOp - Returned Op
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get Op from AML
+ *
+ ******************************************************************************/
- /*
- * Find the object. This will either insert the object into
- * the namespace or simply look it up
- */
- WalkState->Op = NULL;
+static ACPI_STATUS
+AcpiPsCreateOp (
+ ACPI_WALK_STATE *WalkState,
+ UINT8 *AmlOpStart,
+ ACPI_PARSE_OBJECT **NewOp)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_PARSE_OBJECT *Op;
+ ACPI_PARSE_OBJECT *NamedOp = NULL;
+ ACPI_PARSE_OBJECT *ParentScope;
+ UINT8 ArgumentCount;
+ const ACPI_OPCODE_INFO *OpInfo;
- 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)
- {
- continue;
- }
+ ACPI_FUNCTION_TRACE_PTR (PsCreateOp, WalkState);
- Status = AcpiPsNextParseState (WalkState, Op, Status);
- if (Status == AE_CTRL_PENDING)
- {
- Status = AE_OK;
- goto CloseThisOp;
- }
- if (ACPI_FAILURE (Status))
- {
- goto CloseThisOp;
- }
+ Status = AcpiPsGetAmlOpcode (WalkState);
+ if (Status == AE_CTRL_PARSE_CONTINUE)
+ {
+ return_ACPI_STATUS (AE_CTRL_PARSE_CONTINUE);
+ }
- AcpiPsAppendArg (Op, PreOp->Common.Value.Arg);
- AcpiGbl_Depth++;
+ /* Create Op structure and append to parent's argument list */
- 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)
+ {
+ return_ACPI_STATUS (AE_NO_MEMORY);
+ }
- WalkState->OpInfo = AcpiPsGetOpcodeInfo (WalkState->Opcode);
- Op = AcpiPsAllocOp (WalkState->Opcode);
- if (!Op)
- {
- Status = AE_NO_MEMORY;
- goto CloseThisOp;
- }
+ if (WalkState->OpInfo->Flags & AML_NAMED)
+ {
+ Status = AcpiPsBuildNamedOp (WalkState, AmlOpStart, Op, &NamedOp);
+ AcpiPsFreeOp (Op);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
- 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;
- }
+ *NewOp = NamedOp;
+ return_ACPI_STATUS (AE_OK);
+ }
- AcpiPsAppendArg (AcpiPsGetParentScope (ParserState), Op);
+ /* Not a named opcode, just allocate Op and append to parent */
- 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;
- }
- }
- }
+ 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;
+ }
- Op->Common.AmlOffset = WalkState->AmlOffset;
+ ParentScope = AcpiPsGetParentScope (&(WalkState->ParserState));
+ AcpiPsAppendArg (ParentScope, Op);
- if (WalkState->OpInfo)
+ if (ParentScope)
+ {
+ OpInfo = AcpiPsGetOpcodeInfo (ParentScope->Common.AmlOpcode);
+ if (OpInfo->Flags & AML_HAS_TARGET)
+ {
+ ArgumentCount = AcpiPsGetArgumentCount (OpInfo->Type);
+ if (ParentScope->Common.ArgListLength > ArgumentCount)
{
- 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));
+ Op->Common.Flags |= ACPI_PARSEOP_TARGET;
}
}
+ else if (ParentScope->Common.AmlOpcode == AML_INCREMENT_OP)
+ {
+ Op->Common.Flags |= ACPI_PARSEOP_TARGET;
+ }
+ }
-
+ if (WalkState->DescendingCallback != NULL)
+ {
/*
- * Start ArgCount at zero because we don't know if there are
- * any args yet
+ * Find the object. This will either insert the object into
+ * the namespace or simply look it up
*/
- WalkState->ArgCount = 0;
+ WalkState->Op = *NewOp = Op;
- /* Are there any arguments that must be processed? */
-
- if (WalkState->ArgTypes)
+ Status = WalkState->DescendingCallback (WalkState, &Op);
+ Status = AcpiPsNextParseState (WalkState, Op, Status);
+ if (Status == AE_CTRL_PENDING)
{
- /* 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 */
+ Status = AE_CTRL_PARSE_PENDING;
+ }
+ }
- AcpiPsGetNextSimpleArg (ParserState,
- GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), Op);
- break;
+ return_ACPI_STATUS (Status);
+}
- case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */
- Status = AcpiPsGetNextNamepath (WalkState, ParserState, Op, 1);
- if (ACPI_FAILURE (Status))
- {
- goto CloseThisOp;
- }
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsGetArguments
+ *
+ * PARAMETERS: WalkState - Current state
+ * AmlOpStart - Op start in AML
+ * Op - Current Op
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Get arguments for passed Op.
+ *
+ ******************************************************************************/
- WalkState->ArgTypes = 0;
- break;
+static ACPI_STATUS
+AcpiPsGetArguments (
+ ACPI_WALK_STATE *WalkState,
+ UINT8 *AmlOpStart,
+ ACPI_PARSE_OBJECT *Op)
+{
+ ACPI_STATUS Status = AE_OK;
+ ACPI_PARSE_OBJECT *Arg = NULL;
- 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;
- }
+ ACPI_FUNCTION_TRACE_PTR (PsGetArguments, WalkState);
- if (Arg)
- {
- Arg->Common.AmlOffset = WalkState->AmlOffset;
- AcpiPsAppendArg (Op, Arg);
- }
- INCREMENT_ARG_LIST (WalkState->ArgTypes);
- }
+ 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 */
- /* Special processing for certain opcodes */
+ /* Fill in constant or string argument directly */
- /* TBD (remove): Temporary mechanism to disable this code if needed */
+ AcpiPsGetNextSimpleArg (&(WalkState->ParserState),
+ GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), Op);
+ break;
-#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE
+ case AML_INT_NAMEPATH_OP: /* AML_NAMESTRING_ARG */
- if ((WalkState->PassNumber <= ACPI_IMODE_LOAD_PASS1) &&
- ((WalkState->ParseFlags & ACPI_PARSE_DISASSEMBLE) == 0))
- {
- /*
- * We want to skip If/Else/While constructs during Pass1
- * because we want to actually conditionally execute the
- * code during Pass2.
- *
- * Except for disassembly, where we always want to
- * walk the If/Else/While packages
- */
- switch (Op->Common.AmlOpcode)
- {
- case AML_IF_OP:
- case AML_ELSE_OP:
- case AML_WHILE_OP:
+ Status = AcpiPsGetNextNamepath (WalkState, &(WalkState->ParserState), Op, 1);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
- ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
- "Pass1: Skipping an If/Else/While body\n"));
+ WalkState->ArgTypes = 0;
+ break;
- /* Skip body of if/else/while in pass 1 */
+ 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 (WalkState->ParserState.Aml,
+ WalkState->ParserState.AmlStart);
- ParserState->Aml = ParserState->PkgEnd;
- WalkState->ArgCount = 0;
- break;
+ Status = AcpiPsGetNextArg (WalkState, &(WalkState->ParserState),
+ GET_CURRENT_ARG_TYPE (WalkState->ArgTypes), &Arg);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
- default:
- break;
- }
- }
-#endif
- 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->PassNumber <= ACPI_IMODE_LOAD_PASS2))
- {
- /*
- * 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;
+ if (Arg)
+ {
+ Arg->Common.AmlOffset = WalkState->AmlOffset;
+ AcpiPsAppendArg (Op, Arg);
+ }
- case AML_WHILE_OP:
+ INCREMENT_ARG_LIST (WalkState->ArgTypes);
+ }
- if (WalkState->ControlState)
- {
- WalkState->ControlState->Control.PackageEnd =
- ParserState->PkgEnd;
- }
- break;
- default:
+ /* Special processing for certain opcodes */
- /* No action for all other opcodes */
- break;
- }
- break;
- }
- }
+ /* TBD (remove): Temporary mechanism to disable this code if needed */
- /* Check for arguments that need to be processed */
+#ifdef ACPI_ENABLE_MODULE_LEVEL_CODE
- if (WalkState->ArgCount)
+ if ((WalkState->PassNumber <= ACPI_IMODE_LOAD_PASS1) &&
+ ((WalkState->ParseFlags & ACPI_PARSE_DISASSEMBLE) == 0))
{
/*
- * There are arguments (complex ones), push Op and
- * prepare for argument
+ * We want to skip If/Else/While constructs during Pass1 because we
+ * want to actually conditionally execute the code during Pass2.
+ *
+ * Except for disassembly, where we always want to walk the
+ * If/Else/While packages
*/
- Status = AcpiPsPushScope (ParserState, Op,
- WalkState->ArgTypes, WalkState->ArgCount);
- if (ACPI_FAILURE (Status))
+ switch (Op->Common.AmlOpcode)
{
- goto CloseThisOp;
- }
- Op = NULL;
- continue;
- }
+ case AML_IF_OP:
+ case AML_ELSE_OP:
+ case AML_WHILE_OP:
- /*
- * 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--;
- }
+ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
+ "Pass1: Skipping an If/Else/While body\n"));
- 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);
+ /* Skip body of if/else/while in pass 1 */
+
+ WalkState->ParserState.Aml = WalkState->ParserState.PkgEnd;
+ WalkState->ArgCount = 0;
+ break;
+
+ default:
+ break;
}
}
+#endif
- if (WalkState->OpInfo->Flags & AML_CREATE)
+ switch (Op->Common.AmlOpcode)
{
+ case AML_METHOD_OP:
/*
- * Backup to beginning of CreateXXXfield declaration (1 for
- * Opcode)
+ * Skip parsing of control method because we don't have enough
+ * info in the first pass to parse it correctly.
*
- * BodyLength is unknown until we parse the body
+ * Save the length and address of the body
*/
- Op->Named.Length = (UINT32) (ParserState->Aml - Op->Named.Data);
- }
+ Op->Named.Data = WalkState->ParserState.Aml;
+ Op->Named.Length = (UINT32)
+ (WalkState->ParserState.PkgEnd - WalkState->ParserState.Aml);
- /* This op complete, notify the dispatcher */
+ /* Skip body of method */
- if (WalkState->AscendingCallback != NULL)
- {
- WalkState->Op = Op;
- WalkState->Opcode = Op->Common.AmlOpcode;
+ WalkState->ParserState.Aml = WalkState->ParserState.PkgEnd;
+ WalkState->ArgCount = 0;
+ break;
- Status = WalkState->AscendingCallback (WalkState);
- Status = AcpiPsNextParseState (WalkState, Op, Status);
- if (Status == AE_CTRL_PENDING)
+ 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->PassNumber <= ACPI_IMODE_LOAD_PASS2))
{
- Status = AE_OK;
- goto CloseThisOp;
+ /*
+ * 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)
+ (WalkState->ParserState.PkgEnd - AmlOpStart);
+
+ /* Skip body */
+
+ WalkState->ParserState.Aml = WalkState->ParserState.PkgEnd;
+ WalkState->ArgCount = 0;
}
- }
+ break;
+ case AML_WHILE_OP:
-CloseThisOp:
- /*
- * Finished one argument of the containing scope
- */
- ParserState->Scope->ParseScope.ArgCount--;
+ if (WalkState->ControlState)
+ {
+ WalkState->ControlState->Control.PackageEnd =
+ WalkState->ParserState.PkgEnd;
+ }
+ break;
- /* Finished with PreOp */
+ default:
- if (PreOp)
- {
- AcpiPsFreeOp (PreOp);
- PreOp = NULL;
+ /* No action for all other opcodes */
+ break;
}
- /* Close this Op (will result in parse subtree deletion) */
+ break;
+ }
- Status2 = AcpiPsCompleteThisOp (WalkState, Op);
- if (ACPI_FAILURE (Status2))
- {
- return_ACPI_STATUS (Status2);
- }
- Op = NULL;
+ return_ACPI_STATUS (AE_OK);
+}
- switch (Status)
- {
- case AE_OK:
- break;
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsCompleteOp
+ *
+ * PARAMETERS: WalkState - Current state
+ * Op - Returned Op
+ * Status - Parse status before complete Op
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Complete Op
+ *
+ ******************************************************************************/
- case AE_CTRL_TRANSFER:
+static ACPI_STATUS
+AcpiPsCompleteOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT **Op,
+ ACPI_STATUS Status)
+{
+ ACPI_STATUS Status2;
- /* We are about to transfer to a called method. */
- WalkState->PrevOp = Op;
- WalkState->PrevArgTypes = WalkState->ArgTypes;
- return_ACPI_STATUS (Status);
+ ACPI_FUNCTION_TRACE_PTR (PsCompleteOp, WalkState);
- case AE_CTRL_END:
+ /*
+ * Finished one argument of the containing scope
+ */
+ WalkState->ParserState.Scope->ParseScope.ArgCount--;
- AcpiPsPopScope (ParserState, &Op,
- &WalkState->ArgTypes, &WalkState->ArgCount);
+ /* Close this Op (will result in parse subtree deletion) */
- if (Op)
- {
- WalkState->Op = Op;
- WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
- WalkState->Opcode = Op->Common.AmlOpcode;
+ Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
+ if (ACPI_FAILURE (Status2))
+ {
+ return_ACPI_STATUS (Status2);
+ }
- Status = WalkState->AscendingCallback (WalkState);
- Status = AcpiPsNextParseState (WalkState, Op, Status);
+ *Op = NULL;
- Status2 = AcpiPsCompleteThisOp (WalkState, Op);
- if (ACPI_FAILURE (Status2))
- {
- return_ACPI_STATUS (Status2);
- }
- Op = NULL;
- }
- Status = AE_OK;
- break;
+ switch (Status)
+ {
+ case AE_OK:
+ break;
- case AE_CTRL_BREAK:
- case AE_CTRL_CONTINUE:
+ case AE_CTRL_TRANSFER:
- /* Pop off scopes until we find the While */
+ /* We are about to transfer to a called method */
- while (!Op || (Op->Common.AmlOpcode != AML_WHILE_OP))
- {
- AcpiPsPopScope (ParserState, &Op,
- &WalkState->ArgTypes, &WalkState->ArgCount);
- }
+ WalkState->PrevOp = NULL;
+ WalkState->PrevArgTypes = WalkState->ArgTypes;
+ return_ACPI_STATUS (Status);
- /* Close this iteration of the While loop */
- WalkState->Op = Op;
- WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
- WalkState->Opcode = Op->Common.AmlOpcode;
+ case AE_CTRL_END:
+
+ AcpiPsPopScope (&(WalkState->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);
+ Status = AcpiPsNextParseState (WalkState, *Op, Status);
- Status2 = AcpiPsCompleteThisOp (WalkState, Op);
+ Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
if (ACPI_FAILURE (Status2))
{
return_ACPI_STATUS (Status2);
}
- Op = NULL;
+ }
- Status = AE_OK;
- break;
+ Status = AE_OK;
+ break;
- case AE_CTRL_TERMINATE:
+ case AE_CTRL_BREAK:
+ case AE_CTRL_CONTINUE:
- Status = AE_OK;
+ /* Pop off scopes until we find the While */
- /* Clean up */
- do
- {
- if (Op)
- {
- Status2 = AcpiPsCompleteThisOp (WalkState, Op);
- if (ACPI_FAILURE (Status2))
- {
- return_ACPI_STATUS (Status2);
- }
- }
- AcpiPsPopScope (ParserState, &Op,
- &WalkState->ArgTypes, &WalkState->ArgCount);
+ while (!(*Op) || ((*Op)->Common.AmlOpcode != AML_WHILE_OP))
+ {
+ AcpiPsPopScope (&(WalkState->ParserState), Op,
+ &WalkState->ArgTypes, &WalkState->ArgCount);
+ }
- } while (Op);
+ /* Close this iteration of the While loop */
- return_ACPI_STATUS (Status);
+ WalkState->Op = *Op;
+ WalkState->OpInfo = AcpiPsGetOpcodeInfo ((*Op)->Common.AmlOpcode);
+ WalkState->Opcode = (*Op)->Common.AmlOpcode;
+
+ Status = WalkState->AscendingCallback (WalkState);
+ Status = AcpiPsNextParseState (WalkState, *Op, Status);
+ Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
+ if (ACPI_FAILURE (Status2))
+ {
+ return_ACPI_STATUS (Status2);
+ }
- default: /* All other non-AE_OK status */
+ Status = AE_OK;
+ break;
- do
+
+ case AE_CTRL_TERMINATE:
+
+ /* Clean up */
+ do
+ {
+ if (*Op)
{
- if (Op)
+ Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
+ if (ACPI_FAILURE (Status2))
{
- Status2 = AcpiPsCompleteThisOp (WalkState, Op);
- if (ACPI_FAILURE (Status2))
- {
- return_ACPI_STATUS (Status2);
- }
+ return_ACPI_STATUS (Status2);
}
- AcpiPsPopScope (ParserState, &Op,
- &WalkState->ArgTypes, &WalkState->ArgCount);
- } while (Op);
+ AcpiUtDeleteGenericState (
+ AcpiUtPopGenericState (&WalkState->ControlState));
+ }
+ AcpiPsPopScope (&(WalkState->ParserState), Op,
+ &WalkState->ArgTypes, &WalkState->ArgCount);
- /*
- * TBD: Cleanup parse ops on error
- */
-#if 0
- if (Op == NULL)
+ } while (*Op);
+
+ return_ACPI_STATUS (AE_OK);
+
+
+ default: /* All other non-AE_OK status */
+
+ do
+ {
+ if (*Op)
{
- AcpiPsPopScope (ParserState, &Op,
- &WalkState->ArgTypes, &WalkState->ArgCount);
+ Status2 = AcpiPsCompleteThisOp (WalkState, *Op);
+ if (ACPI_FAILURE (Status2))
+ {
+ return_ACPI_STATUS (Status2);
+ }
}
-#endif
- WalkState->PrevOp = Op;
- WalkState->PrevArgTypes = WalkState->ArgTypes;
- return_ACPI_STATUS (Status);
- }
- /* This scope complete? */
+ AcpiPsPopScope (&(WalkState->ParserState), Op,
+ &WalkState->ArgTypes, &WalkState->ArgCount);
- if (AcpiPsHasCompletedScope (ParserState))
+ } while (*Op);
+
+
+#if 0
+ /*
+ * TBD: Cleanup parse ops on error
+ */
+ if (*Op == NULL)
{
- AcpiPsPopScope (ParserState, &Op,
+ AcpiPsPopScope (ParserState, Op,
&WalkState->ArgTypes, &WalkState->ArgCount);
- ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", Op));
- }
- else
- {
- Op = NULL;
}
+#endif
+ WalkState->PrevOp = NULL;
+ WalkState->PrevArgTypes = WalkState->ArgTypes;
+ return_ACPI_STATUS (Status);
+ }
- } /* while ParserState->Aml */
+ /* This scope complete? */
+
+ if (AcpiPsHasCompletedScope (&(WalkState->ParserState)))
+ {
+ AcpiPsPopScope (&(WalkState->ParserState), Op,
+ &WalkState->ArgTypes, &WalkState->ArgCount);
+ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", *Op));
+ }
+ else
+ {
+ *Op = NULL;
+ }
+
+ return_ACPI_STATUS (AE_OK);
+}
+
+
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsCompleteFinalOp
+ *
+ * PARAMETERS: WalkState - Current state
+ * Op - Current Op
+ * Status - Current parse status before complete last
+ * Op
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Complete last Op.
+ *
+ ******************************************************************************/
+
+static ACPI_STATUS
+AcpiPsCompleteFinalOp (
+ ACPI_WALK_STATE *WalkState,
+ ACPI_PARSE_OBJECT *Op,
+ ACPI_STATUS Status)
+{
+ ACPI_STATUS Status2;
+
+
+ ACPI_FUNCTION_TRACE_PTR (PsCompleteFinalOp, WalkState);
/*
* 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.
+ * 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
@@ -864,7 +875,7 @@ CloseThisOp:
{
if (WalkState->AscendingCallback != NULL)
{
- WalkState->Op = Op;
+ WalkState->Op = Op;
WalkState->OpInfo = AcpiPsGetOpcodeInfo (Op->Common.AmlOpcode);
WalkState->Opcode = Op->Common.AmlOpcode;
@@ -872,8 +883,11 @@ CloseThisOp:
Status = AcpiPsNextParseState (WalkState, Op, Status);
if (Status == AE_CTRL_PENDING)
{
- Status = AE_OK;
- goto CloseThisOp;
+ Status = AcpiPsCompleteOp (WalkState, &Op, AE_OK);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
}
if (Status == AE_CTRL_TERMINATE)
@@ -892,7 +906,7 @@ CloseThisOp:
}
}
- AcpiPsPopScope (ParserState, &Op,
+ AcpiPsPopScope (&(WalkState->ParserState), &Op,
&WalkState->ArgTypes, &WalkState->ArgCount);
} while (Op);
@@ -916,7 +930,7 @@ CloseThisOp:
}
}
- AcpiPsPopScope (ParserState, &Op, &WalkState->ArgTypes,
+ AcpiPsPopScope (&(WalkState->ParserState), &Op, &WalkState->ArgTypes,
&WalkState->ArgCount);
} while (Op);
@@ -925,3 +939,248 @@ CloseThisOp:
}
+/*******************************************************************************
+ *
+ * FUNCTION: AcpiPsParseLoop
+ *
+ * PARAMETERS: WalkState - Current state
+ *
+ * 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_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_EXCEPTION ((AE_INFO, Status,
+ "Invoked method did not return a value"));
+
+ }
+
+ ACPI_EXCEPTION ((AE_INFO, Status, "GetPredicate Failed"));
+ 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)
+ {
+ Status = AcpiPsCreateOp (WalkState, AmlOpStart, &Op);
+ if (ACPI_FAILURE (Status))
+ {
+ if (Status == AE_CTRL_PARSE_CONTINUE)
+ {
+ continue;
+ }
+
+ if (Status == AE_CTRL_PARSE_PENDING)
+ {
+ Status = AE_OK;
+ }
+
+ Status = AcpiPsCompleteOp (WalkState, &Op, Status);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ continue;
+ }
+
+ 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;
+
+ /* Are there any arguments that must be processed? */
+
+ if (WalkState->ArgTypes)
+ {
+ /* Get arguments */
+
+ Status = AcpiPsGetArguments (WalkState, AmlOpStart, Op);
+ if (ACPI_FAILURE (Status))
+ {
+ Status = AcpiPsCompleteOp (WalkState, &Op, Status);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ continue;
+ }
+ }
+
+ /* 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))
+ {
+ Status = AcpiPsCompleteOp (WalkState, &Op, Status);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ continue;
+ }
+
+ 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;
+ }
+ }
+
+ Status = AcpiPsCompleteOp (WalkState, &Op, Status);
+ if (ACPI_FAILURE (Status))
+ {
+ return_ACPI_STATUS (Status);
+ }
+
+ } /* while ParserState->Aml */
+
+ Status = AcpiPsCompleteFinalOp (WalkState, Op, Status);
+ return_ACPI_STATUS (Status);
+}
+
OpenPOWER on IntegriCloud