mirror of
https://github.com/acpica/acpica/
synced 2025-01-18 15:39:18 +03:00
Added parser op cache, NsLookup during method parse
date 2000.05.04.20.52.00; author rmoore1; state Exp;
This commit is contained in:
parent
1e2a2c0dea
commit
8dd72f7325
@ -160,7 +160,7 @@ PsDeleteCompletedOp (
|
||||
ACPI_GENERIC_OP *Op)
|
||||
{
|
||||
|
||||
CmFree (Op);
|
||||
PsFreeOp (Op);
|
||||
return AE_OK;
|
||||
}
|
||||
|
||||
@ -438,8 +438,65 @@ PsParseLoop (
|
||||
/* TBD: what if a control method references outside its scope? */
|
||||
/* ie - should we be using nslookup here? */
|
||||
|
||||
Op = PsFind (PsGetParentScope (ParserState),
|
||||
PsGetNextNamestring (ParserState), Opcode, 1);
|
||||
if (Gbl_ParsedNamespaceRoot)
|
||||
{
|
||||
Op = PsFind (PsGetParentScope (ParserState),
|
||||
PsGetNextNamestring (ParserState), Opcode, 1);
|
||||
}
|
||||
|
||||
#ifndef PARSER_ONLY
|
||||
else
|
||||
{
|
||||
/*
|
||||
* The full parse tree has already been deleted -- therefore, we are parsing
|
||||
* a control method. We can lookup the name in the namespace instead of
|
||||
* the parse tree!
|
||||
*/
|
||||
|
||||
NAME_TABLE_ENTRY *Nte = NULL;
|
||||
ACPI_GENERIC_STATE ScopeInfo;
|
||||
char *Path;
|
||||
|
||||
Path = PsGetNextNamestring (ParserState);
|
||||
/*
|
||||
* Lookup the name in the internal namespace
|
||||
*/
|
||||
|
||||
ScopeInfo.Scope.Entry = NULL;
|
||||
Nte = ParserState->StartOp->NameTableEntry;
|
||||
if (Nte)
|
||||
{
|
||||
ScopeInfo.Scope.Entry = Nte->Scope;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enter the object into the namespace
|
||||
*/
|
||||
|
||||
Status = NsLookup (&ScopeInfo, Path, ACPI_TYPE_Any, IMODE_LoadPass2, /* Create if not found */
|
||||
NS_NO_UPSEARCH | NS_DONT_OPEN_SCOPE, NULL, &Nte);
|
||||
if (ACPI_FAILURE (Status))
|
||||
{
|
||||
return_ACPI_STATUS (Status);
|
||||
}
|
||||
|
||||
/* Create a new op */
|
||||
|
||||
Op = PsAllocOp (Opcode);
|
||||
if (!Op)
|
||||
{
|
||||
return_ACPI_STATUS (AE_NO_MEMORY);
|
||||
}
|
||||
|
||||
/* Initialize */
|
||||
|
||||
((ACPI_NAMED_OP *)Op)->Name = Nte->Name;
|
||||
Op->NameTableEntry = Nte;
|
||||
|
||||
|
||||
PsAppendArg (PsGetParentScope (ParserState), Op);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!Op)
|
||||
{
|
||||
|
@ -122,6 +122,11 @@
|
||||
MODULE_NAME ("psutils");
|
||||
|
||||
|
||||
#define PARSEOP_GENERIC 1
|
||||
#define PARSEOP_NAMED 2
|
||||
#define PARSEOP_DEFERRED 3
|
||||
#define PARSEOP_BYTELIST 4
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
@ -144,6 +149,7 @@ PsInitOp (
|
||||
ACPI_OP_INFO *AmlOp;
|
||||
|
||||
|
||||
Op->DataType = DESC_TYPE_PARSER;
|
||||
Op->Opcode = Opcode;
|
||||
|
||||
|
||||
@ -166,6 +172,8 @@ PsInitOp (
|
||||
* RETURN: Pointer to the new Op.
|
||||
*
|
||||
* DESCRIPTION: Allocate an acpi_op, choose op type (and thus size) based on opcode
|
||||
* A cache of opcodes is available for the pure GENERIC_OP, since this
|
||||
* is by far the most commonly used.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
@ -175,6 +183,7 @@ PsAllocOp (
|
||||
{
|
||||
ACPI_GENERIC_OP *Op = NULL;
|
||||
UINT32 Size;
|
||||
UINT8 Flags;
|
||||
|
||||
|
||||
/* Allocate the minimum required size object */
|
||||
@ -182,29 +191,63 @@ PsAllocOp (
|
||||
if (PsIsDeferredOp (Opcode))
|
||||
{
|
||||
Size = sizeof (ACPI_DEFERRED_OP);
|
||||
Flags = PARSEOP_DEFERRED;
|
||||
}
|
||||
|
||||
else if (PsIsNamedOp (Opcode))
|
||||
{
|
||||
Size = sizeof (ACPI_NAMED_OP);
|
||||
Flags = PARSEOP_NAMED;
|
||||
}
|
||||
|
||||
else if (PsIsBytelistOp (Opcode))
|
||||
{
|
||||
Size = sizeof (ACPI_BYTELIST_OP);
|
||||
Flags = PARSEOP_BYTELIST;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
Size = sizeof (ACPI_GENERIC_OP);
|
||||
Flags = PARSEOP_GENERIC;
|
||||
|
||||
/*
|
||||
* The generic op is by far the most common (16 to 1), and therefore the op cache is
|
||||
* implemented with this type.
|
||||
*
|
||||
* Check if there is an Op already available in the cache
|
||||
*/
|
||||
|
||||
CmAcquireMutex (MTX_MEMORY);
|
||||
if (Gbl_ParseCache)
|
||||
{
|
||||
/* Extract an op from the front of the cache list */
|
||||
|
||||
Gbl_ParseCacheRequests++;
|
||||
Gbl_ParseCacheDepth--;
|
||||
|
||||
Op = Gbl_ParseCache;
|
||||
Gbl_ParseCache = Op->Next;
|
||||
|
||||
/* Clear the previously used Op */
|
||||
|
||||
MEMSET (Op, 0, sizeof (ACPI_GENERIC_OP));
|
||||
}
|
||||
CmReleaseMutex (MTX_MEMORY);
|
||||
}
|
||||
|
||||
/* Allocate and init the object */
|
||||
/* Allocate a new Op if necessary */
|
||||
|
||||
Op = CmCallocate (Size);
|
||||
if (!Op)
|
||||
{
|
||||
Op = CmCallocate (Size);
|
||||
}
|
||||
|
||||
/* Initialize the Op */
|
||||
if (Op)
|
||||
{
|
||||
PsInitOp (Op, Opcode);
|
||||
Op->Flags = Flags;
|
||||
}
|
||||
|
||||
return Op;
|
||||
@ -212,16 +255,105 @@ PsAllocOp (
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: PsFreeOp
|
||||
*
|
||||
* PARAMETERS: Op - Op to be freed
|
||||
*
|
||||
* RETURN: None.
|
||||
*
|
||||
* DESCRIPTION: Free an Op object. Either put it on the GENERIC_OP cache list
|
||||
* or actually free it.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void
|
||||
PsFreeOp (
|
||||
ACPI_GENERIC_OP *Op)
|
||||
{
|
||||
|
||||
|
||||
if (Op->Flags == PARSEOP_GENERIC)
|
||||
{
|
||||
/* Is the cache full? */
|
||||
|
||||
if (Gbl_ParseCacheDepth < MAX_PARSE_CACHE_DEPTH)
|
||||
{
|
||||
/* Put a GENERIC_OP back into the cache */
|
||||
|
||||
CmAcquireMutex (MTX_MEMORY);
|
||||
Gbl_ParseCacheDepth++;
|
||||
|
||||
Op->Next = Gbl_ParseCache;
|
||||
Gbl_ParseCache = Op;
|
||||
|
||||
CmReleaseMutex (MTX_MEMORY);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Not a GENERIC OP, or the cache is full, just free the Op
|
||||
*/
|
||||
|
||||
CmFree (Op);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: PsDeleteParseCache
|
||||
*
|
||||
* PARAMETERS: None
|
||||
*
|
||||
* RETURN: None
|
||||
*
|
||||
* DESCRIPTION: Free all objects that are on the parse cache list.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
void
|
||||
PsDeleteParseCache (
|
||||
void)
|
||||
{
|
||||
ACPI_GENERIC_OP *Next;
|
||||
|
||||
|
||||
FUNCTION_TRACE ("PsDeleteParseCache");
|
||||
|
||||
|
||||
/* Traverse the global cache list */
|
||||
|
||||
while (Gbl_ParseCache)
|
||||
{
|
||||
/* Delete one cached state object */
|
||||
|
||||
Next = Gbl_ParseCache->Next;
|
||||
CmFree (Gbl_ParseCache);
|
||||
Gbl_ParseCache = Next;
|
||||
}
|
||||
|
||||
return_VOID;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FUNCTION: Utility functions
|
||||
*
|
||||
* DESCRIPTION: Low level functions
|
||||
*
|
||||
* TBD:
|
||||
* 1) Some of these functions should be macros
|
||||
* 2) Some can be simplified
|
||||
*/
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
|
||||
/*
|
||||
@ -248,6 +380,59 @@ PsIsPrefixChar (
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN
|
||||
PsIsNamespaceObjectOp (
|
||||
UINT16 Opcode)
|
||||
{
|
||||
return ((BOOLEAN)
|
||||
(Opcode == AML_ScopeOp ||
|
||||
Opcode == AML_DeviceOp ||
|
||||
Opcode == AML_ThermalZoneOp ||
|
||||
Opcode == AML_MethodOp ||
|
||||
Opcode == AML_PowerResOp ||
|
||||
Opcode == AML_ProcessorOp ||
|
||||
Opcode == AML_DefFieldOp ||
|
||||
Opcode == AML_IndexFieldOp ||
|
||||
Opcode == AML_BankFieldOp ||
|
||||
Opcode == AML_NAMEDFIELD_OP ||
|
||||
Opcode == AML_NameOp ||
|
||||
Opcode == AML_AliasOp ||
|
||||
Opcode == AML_MutexOp ||
|
||||
Opcode == AML_EventOp ||
|
||||
Opcode == AML_RegionOp ||
|
||||
Opcode == AML_CreateFieldOp ||
|
||||
Opcode == AML_BitFieldOp ||
|
||||
Opcode == AML_ByteFieldOp ||
|
||||
Opcode == AML_WordFieldOp ||
|
||||
Opcode == AML_DWordFieldOp ||
|
||||
Opcode == AML_METHODCALL_OP ||
|
||||
Opcode == AML_NAMEPATH_OP));
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
PsIsNamespaceOp (
|
||||
UINT16 Opcode)
|
||||
{
|
||||
return ((BOOLEAN)
|
||||
(Opcode == AML_ScopeOp ||
|
||||
Opcode == AML_DeviceOp ||
|
||||
Opcode == AML_ThermalZoneOp ||
|
||||
Opcode == AML_MethodOp ||
|
||||
Opcode == AML_PowerResOp ||
|
||||
Opcode == AML_ProcessorOp ||
|
||||
Opcode == AML_DefFieldOp ||
|
||||
Opcode == AML_IndexFieldOp ||
|
||||
Opcode == AML_BankFieldOp ||
|
||||
Opcode == AML_NameOp ||
|
||||
Opcode == AML_AliasOp ||
|
||||
Opcode == AML_MutexOp ||
|
||||
Opcode == AML_EventOp ||
|
||||
Opcode == AML_RegionOp ||
|
||||
Opcode == AML_NAMEDFIELD_OP));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Is opcode for a named object Op?
|
||||
@ -266,10 +451,7 @@ PsIsNamedObjectOp (
|
||||
Opcode == AML_MethodOp ||
|
||||
Opcode == AML_PowerResOp ||
|
||||
Opcode == AML_ProcessorOp ||
|
||||
Opcode == AML_DefFieldOp ||
|
||||
Opcode == AML_IndexFieldOp ||
|
||||
Opcode == AML_BankFieldOp ||
|
||||
Opcode == AML_NAMEDFIELD ||
|
||||
Opcode == AML_NAMEDFIELD_OP ||
|
||||
Opcode == AML_NameOp ||
|
||||
Opcode == AML_AliasOp ||
|
||||
Opcode == AML_MutexOp ||
|
||||
@ -282,8 +464,8 @@ PsIsNamedObjectOp (
|
||||
Opcode == AML_ByteFieldOp ||
|
||||
Opcode == AML_WordFieldOp ||
|
||||
Opcode == AML_DWordFieldOp ||
|
||||
Opcode == AML_METHODCALL ||
|
||||
Opcode == AML_NAMEPATH));
|
||||
Opcode == AML_METHODCALL_OP ||
|
||||
Opcode == AML_NAMEPATH_OP));
|
||||
}
|
||||
|
||||
|
||||
@ -301,15 +483,12 @@ PsIsNamedOp (
|
||||
Opcode == AML_MethodOp ||
|
||||
Opcode == AML_PowerResOp ||
|
||||
Opcode == AML_ProcessorOp ||
|
||||
Opcode == AML_DefFieldOp ||
|
||||
Opcode == AML_IndexFieldOp ||
|
||||
Opcode == AML_BankFieldOp ||
|
||||
Opcode == AML_NameOp ||
|
||||
Opcode == AML_AliasOp ||
|
||||
Opcode == AML_MutexOp ||
|
||||
Opcode == AML_EventOp ||
|
||||
Opcode == AML_RegionOp ||
|
||||
Opcode == AML_NAMEDFIELD));
|
||||
Opcode == AML_NAMEDFIELD_OP));
|
||||
}
|
||||
|
||||
|
||||
@ -330,7 +509,7 @@ BOOLEAN
|
||||
PsIsBytelistOp (
|
||||
UINT16 Opcode)
|
||||
{
|
||||
return ((BOOLEAN) (Opcode == AML_BYTELIST));
|
||||
return ((BOOLEAN) (Opcode == AML_BYTELIST_OP));
|
||||
}
|
||||
|
||||
|
||||
|
@ -118,6 +118,7 @@
|
||||
#include <acpi.h>
|
||||
#include <amlcode.h>
|
||||
#include <parser.h>
|
||||
#include <dispatch.h>
|
||||
#include <namesp.h>
|
||||
#include <interp.h>
|
||||
|
||||
@ -181,13 +182,15 @@ PsGetNextWalkOp (
|
||||
* in case the Op object gets deleted by the callback routine
|
||||
*/
|
||||
|
||||
Next = Op->Next;
|
||||
Parent = Op->Parent;
|
||||
Next = Op->Next;
|
||||
Parent = Op->Parent;
|
||||
|
||||
Status = AscendingCallback (WalkState, Op);
|
||||
|
||||
if (Status == AE_TERMINATE)
|
||||
switch (Status)
|
||||
{
|
||||
case AE_CTRL_TERMINATE:
|
||||
|
||||
/*
|
||||
* A control method was terminated via a RETURN statement.
|
||||
* The walk of this method is complete.
|
||||
@ -196,50 +199,83 @@ PsGetNextWalkOp (
|
||||
WalkState->NextOp = NULL;
|
||||
|
||||
return_ACPI_STATUS (AE_OK);
|
||||
}
|
||||
|
||||
if (Status == AE_FALSE)
|
||||
{
|
||||
break;
|
||||
|
||||
|
||||
case AE_CTRL_FALSE:
|
||||
|
||||
/*
|
||||
* Predicate was false, so instead of moving on to the
|
||||
* body (TermList), we close out the IF/WHILE
|
||||
* 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;
|
||||
|
||||
Status = AscendingCallback (WalkState, Parent);
|
||||
/*
|
||||
* 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);
|
||||
|
||||
/* Now continue to the next node in the tree */
|
||||
}
|
||||
/* The parent sibling will be next */
|
||||
|
||||
/* Look for a sibling to the current op */
|
||||
WalkState->PrevOp = Op;
|
||||
WalkState->NextOp = Next;
|
||||
WalkState->NextOpInfo = NEXT_OP_DOWNWARD;
|
||||
|
||||
if (Next)
|
||||
{
|
||||
/* There is a sibling, it will be next */
|
||||
/* Continue downward */
|
||||
|
||||
WalkState->PrevOp = Op;
|
||||
WalkState->NextOp = Next;
|
||||
WalkState->NextOpInfo = NEXT_OP_DOWNWARD;
|
||||
return_ACPI_STATUS (AE_OK);
|
||||
}
|
||||
|
||||
return_ACPI_STATUS (Status);
|
||||
}
|
||||
/* Drop into the loop below because we are moving upwards in the tree */
|
||||
|
||||
break;
|
||||
|
||||
|
||||
/*
|
||||
* No sibling, but check status.
|
||||
* Abort on error from callback routine
|
||||
*/
|
||||
default:
|
||||
/*
|
||||
* Check for a sibling to the current op. A sibling means
|
||||
* we are still going "downward" in the tree.
|
||||
*/
|
||||
|
||||
if (Status != AE_OK)
|
||||
{
|
||||
/* Next op will be the parent */
|
||||
if (Next)
|
||||
{
|
||||
/* There is a sibling, it will be next */
|
||||
|
||||
WalkState->PrevOp = Op;
|
||||
WalkState->NextOp = Parent;
|
||||
WalkState->NextOpInfo = NEXT_OP_UPWARD;
|
||||
WalkState->PrevOp = Op;
|
||||
WalkState->NextOp = Next;
|
||||
WalkState->NextOpInfo = NEXT_OP_DOWNWARD;
|
||||
|
||||
return_ACPI_STATUS (Status);
|
||||
/* Continue downward */
|
||||
|
||||
return_ACPI_STATUS (Status);
|
||||
}
|
||||
|
||||
/*
|
||||
* No sibling, but check status.
|
||||
* Abort on error from callback routine
|
||||
*/
|
||||
if (Status != AE_OK)
|
||||
{
|
||||
/* Next op will be the parent */
|
||||
|
||||
WalkState->PrevOp = Op;
|
||||
WalkState->NextOp = Parent;
|
||||
WalkState->NextOpInfo = NEXT_OP_UPWARD;
|
||||
|
||||
return_ACPI_STATUS (Status);
|
||||
}
|
||||
|
||||
/* Drop into the loop below because we are moving upwards in the tree */
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -268,13 +304,16 @@ PsGetNextWalkOp (
|
||||
|
||||
Status = AscendingCallback (WalkState, Parent);
|
||||
|
||||
/* All evaluated predicates come through here */
|
||||
|
||||
if (Status == AE_FALSE)
|
||||
switch (Status)
|
||||
{
|
||||
case AE_CTRL_FALSE:
|
||||
|
||||
/*
|
||||
* Predicate was false, so instead of moving on to the
|
||||
* body (TermList), we close out the IF/WHILE
|
||||
* 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;
|
||||
@ -284,27 +323,31 @@ PsGetNextWalkOp (
|
||||
Status = AscendingCallback (WalkState, Parent);
|
||||
|
||||
/* Now continue to the next node in the tree */
|
||||
}
|
||||
|
||||
else if (Status == AE_TRUE)
|
||||
{
|
||||
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->PredicateOp; /* Points to the predicate */
|
||||
Op = WalkState->ControlState->Control.PredicateOp; /* Points to the predicate */
|
||||
|
||||
WalkState->ControlState->Common.State = CONTROL_PREDICATE_EXECUTING;
|
||||
|
||||
WalkState->ControlState->Exec = CONTROL_PREDICATE_EXECUTING;
|
||||
WalkState->PrevOp = Op->Parent;
|
||||
WalkState->NextOp = Op; /* Evaluate the predicate again (next) */
|
||||
WalkState->NextOpInfo = NEXT_OP_DOWNWARD; /* Because we will traverse WHILE tree again */
|
||||
|
||||
return_ACPI_STATUS (AE_OK);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case AE_CTRL_TERMINATE:
|
||||
|
||||
else if (Status == AE_TERMINATE)
|
||||
{
|
||||
/*
|
||||
* A control method was terminated via a RETURN statement.
|
||||
* The walk of this method is complete.
|
||||
@ -313,8 +356,10 @@ PsGetNextWalkOp (
|
||||
WalkState->NextOp = NULL;
|
||||
|
||||
return_ACPI_STATUS (AE_OK);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* If we are back to the starting point, the walk is complete.
|
||||
*/
|
||||
@ -405,7 +450,7 @@ PsWalkLoop (
|
||||
FUNCTION_TRACE_PTR ("PsWalkLoop", StartOp);
|
||||
|
||||
|
||||
WalkState = PsGetCurrentWalkState (WalkList);
|
||||
WalkState = DsGetCurrentWalkState (WalkList);
|
||||
|
||||
|
||||
/* Walk entire subtree, visiting all nodes depth-first */
|
||||
@ -420,7 +465,7 @@ PsWalkLoop (
|
||||
/*
|
||||
* A TRUE exception means that an ELSE was detected, but the IF predicate evaluated TRUE.
|
||||
*/
|
||||
if (Status == AE_TRUE)
|
||||
if (Status == AE_CTRL_TRUE)
|
||||
{
|
||||
/*
|
||||
* Ignore the entire ELSE block by moving on to the the next opcode.
|
||||
@ -437,15 +482,15 @@ PsWalkLoop (
|
||||
|
||||
/* A PENDING exception means that a control method invocation has been detected */
|
||||
|
||||
if (Status == AE_PENDING)
|
||||
if (Status == AE_CTRL_PENDING)
|
||||
{
|
||||
/* Transfer control to the called control method */
|
||||
|
||||
Status = PsxCallControlMethod (WalkList, WalkState, Op);
|
||||
Status = DsCallControlMethod (WalkList, WalkState, Op);
|
||||
|
||||
/* If the method call worked, a new walk state was created -- get it */
|
||||
|
||||
WalkState = PsGetCurrentWalkState (WalkList);
|
||||
WalkState = DsGetCurrentWalkState (WalkList);
|
||||
}
|
||||
|
||||
/* Abort the walk on any exception */
|
||||
@ -486,9 +531,10 @@ PsWalkParsedAml (
|
||||
ACPI_GENERIC_OP *StartOp,
|
||||
ACPI_GENERIC_OP *EndOp,
|
||||
ACPI_OBJECT_INTERNAL *MthDesc,
|
||||
NAME_TABLE_ENTRY *StartScope,
|
||||
NAME_TABLE_ENTRY *StartScope,
|
||||
ACPI_OBJECT_INTERNAL **Params,
|
||||
ACPI_OBJECT_INTERNAL **CallerReturnDesc,
|
||||
ACPI_OWNER_ID OwnerId,
|
||||
INTERPRETER_CALLBACK DescendingCallback,
|
||||
INTERPRETER_CALLBACK AscendingCallback)
|
||||
{
|
||||
@ -514,33 +560,41 @@ PsWalkParsedAml (
|
||||
|
||||
WalkList.WalkState = NULL;
|
||||
|
||||
WalkState = PsCreateWalkState (EndOp, MthDesc, &WalkList);
|
||||
WalkState = DsCreateWalkState (EndOp, MthDesc, &WalkList);
|
||||
if (!WalkState)
|
||||
{
|
||||
return_ACPI_STATUS (AE_NO_MEMORY);
|
||||
}
|
||||
|
||||
/* TBD: move to createWalkSTate */
|
||||
|
||||
WalkState->OwnerId = OwnerId;
|
||||
|
||||
/* TBD:
|
||||
* TEMP until we pass WalkState to the interpreter
|
||||
*/
|
||||
PrevWalkList = Gbl_CurrentWalkList;
|
||||
Gbl_CurrentWalkList = &WalkList;
|
||||
|
||||
if (MthDesc)
|
||||
{
|
||||
/* Push start scope on scope stack and make it current */
|
||||
if (StartScope)
|
||||
{
|
||||
/* Push start scope on scope stack and make it current */
|
||||
|
||||
Status = NsScopeStackPush (StartScope, ACPI_TYPE_Method, WalkState);
|
||||
if (ACPI_FAILURE (Status))
|
||||
{
|
||||
return_ACPI_STATUS (Status);
|
||||
}
|
||||
Status = DsScopeStackPush (StartScope, ACPI_TYPE_Method, WalkState);
|
||||
if (ACPI_FAILURE (Status))
|
||||
{
|
||||
return_ACPI_STATUS (Status);
|
||||
}
|
||||
|
||||
/* Init arguments if this is a control method */
|
||||
/* TBD: add walkstate as a param */
|
||||
}
|
||||
|
||||
PsxMthStackInitArgs (Params, MTH_NUM_ARGS);
|
||||
}
|
||||
if (MthDesc)
|
||||
{
|
||||
/* Init arguments if this is a control method */
|
||||
/* TBD: add walkstate as a param */
|
||||
|
||||
DsMethodDataInitArgs (Params, MTH_NUM_ARGS);
|
||||
}
|
||||
|
||||
Op = StartOp;
|
||||
Status = AE_OK;
|
||||
@ -566,11 +620,15 @@ PsWalkParsedAml (
|
||||
|
||||
BREAKPOINT3;
|
||||
|
||||
WalkState = PsPopWalkState (&WalkList);
|
||||
WalkState = DsPopWalkState (&WalkList);
|
||||
ReturnDesc = WalkState->ReturnDesc; /* Extract return value before we delete WalkState */
|
||||
|
||||
DEBUG_PRINT (TRACE_PARSE, ("PsWalkParsedAml: ReturnValue=%p, State=%p\n", WalkState->ReturnDesc, WalkState));
|
||||
|
||||
/* Reset the current scope to the beginning of scope stack */
|
||||
|
||||
DsScopeStackClear (WalkState);
|
||||
|
||||
/* If we just returned from the execution of a control method, there's lots of cleanup to do */
|
||||
|
||||
if (WalkState->MethodDesc)
|
||||
@ -582,30 +640,18 @@ PsWalkParsedAml (
|
||||
Status = OsdSignalSemaphore (WalkState->MethodDesc->Method.Semaphore, 1);
|
||||
}
|
||||
|
||||
/* Reset the current scope to the beginning of scope stack */
|
||||
|
||||
NsScopeStackClear (WalkState);
|
||||
|
||||
/* Delete all arguments and locals */
|
||||
|
||||
PsxMthStackDeleteArgs (WalkState);
|
||||
|
||||
/* Delete the parse tree if asked to */
|
||||
|
||||
if (Gbl_WhenToParseMethods & METHOD_DELETE_AT_COMPLETION)
|
||||
{
|
||||
PsDeleteParseTree (WalkState->MethodDesc->Method.ParserOp);
|
||||
WalkState->MethodDesc->Method.ParserOp = NULL;
|
||||
}
|
||||
DsMethodDataDeleteAll (WalkState);
|
||||
}
|
||||
|
||||
/* Delete this walk state and all linked control states */
|
||||
|
||||
PsDeleteWalkState (WalkState);
|
||||
DsDeleteWalkState (WalkState);
|
||||
|
||||
/* Check if we have restarted a preempted walk */
|
||||
|
||||
WalkState = PsGetCurrentWalkState (&WalkList);
|
||||
WalkState = DsGetCurrentWalkState (&WalkList);
|
||||
if (WalkState &&
|
||||
Status == AE_OK)
|
||||
{
|
||||
@ -616,7 +662,7 @@ PsWalkParsedAml (
|
||||
* The object is deleted
|
||||
*/
|
||||
|
||||
PsxRestartControlMethod (WalkState, ReturnDesc);
|
||||
DsRestartControlMethod (WalkState, ReturnDesc);
|
||||
|
||||
/* Get the next Op to process */
|
||||
|
||||
@ -632,7 +678,7 @@ PsWalkParsedAml (
|
||||
|
||||
else if (ReturnDesc)
|
||||
{
|
||||
CmDeleteInternalObject (ReturnDesc); /* Caller doesn't want it, must delete it */
|
||||
CmRemoveReference (ReturnDesc); /* Caller doesn't want it, must delete it */
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user