You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1903 lines
54 KiB
1903 lines
54 KiB
/*** parser.c - AML Parser
|
|
*
|
|
* Copyright (c) 1996,1997 Microsoft Corporation
|
|
* Author: Michael Tsang (MikeTs)
|
|
* Created 06/13/97
|
|
*
|
|
* MODIFICATION HISTORY
|
|
*/
|
|
|
|
#include "pch.h"
|
|
|
|
#ifdef LOCKABLE_PRAGMA
|
|
#pragma ACPI_LOCKABLE_DATA
|
|
#pragma ACPI_LOCKABLE_CODE
|
|
#endif
|
|
|
|
/***LP ParseScope - Parse a scope
|
|
*
|
|
* ENTRY
|
|
* pctxt -> CTXT
|
|
* pscope -> SCOPE
|
|
* rc - status code
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
|
|
NTSTATUS LOCAL ParseScope(PCTXT pctxt, PSCOPE pscope, NTSTATUS rc)
|
|
{
|
|
TRACENAME("PARSESCOPE")
|
|
ULONG dwStage = ((rc == STATUS_SUCCESS) || (rc == AMLISTA_BREAK))?
|
|
(pscope->FrameHdr.dwfFrame & FRAMEF_STAGE_MASK): 2;
|
|
|
|
ENTER(2, ("ParseScope(Stage=%d,pctxt=%p,pbOp=%p,pscope=%p,rc=%x)\n",
|
|
dwStage, pctxt, pctxt->pbOp, pscope, rc));
|
|
|
|
ASSERT(pscope->FrameHdr.dwSig == SIG_SCOPE);
|
|
|
|
switch (dwStage)
|
|
{
|
|
case 0:
|
|
//
|
|
// Stage 0: Do debug print if necessary.
|
|
//
|
|
#ifdef DEBUGGER
|
|
if (gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
PrintIndent(pctxt);
|
|
PRINTF("{");
|
|
gDebugger.iPrintLevel++;
|
|
pscope->FrameHdr.dwfFrame |= SCOPEF_FIRST_TERM;
|
|
}
|
|
#endif
|
|
//
|
|
// There is nothing blockable, so continue to next stage.
|
|
//
|
|
pscope->FrameHdr.dwfFrame++;
|
|
|
|
case 1:
|
|
Stage1:
|
|
//
|
|
// Stage 1: Parse next opcode.
|
|
//
|
|
if (rc == AMLISTA_BREAK)
|
|
{
|
|
pctxt->pbOp = pscope->pbOpEnd;
|
|
rc = STATUS_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
while (pctxt->pbOp < pscope->pbOpEnd)
|
|
{
|
|
#ifdef DEBUGGER
|
|
gDebugger.pbUnAsm = pctxt->pbOp;
|
|
if (gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
if (pscope->FrameHdr.dwfFrame & SCOPEF_FIRST_TERM)
|
|
{
|
|
pscope->FrameHdr.dwfFrame &= ~SCOPEF_FIRST_TERM;
|
|
}
|
|
else if (gDebugger.dwfDebugger & DBGF_STEP_OVER)
|
|
{
|
|
gDebugger.dwfDebugger &= ~DBGF_STEP_OVER;
|
|
AMLIDebugger(FALSE);
|
|
}
|
|
}
|
|
|
|
if ((gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) &&
|
|
(*pctxt->pbOp != OP_PACKAGE))
|
|
{
|
|
PrintIndent(pctxt);
|
|
}
|
|
#endif
|
|
//
|
|
// Discard result of previous term if any.
|
|
//
|
|
FreeDataBuffs(pscope->pdataResult, 1);
|
|
if (((rc = ParseOpcode(pctxt, pscope->pbOpEnd,
|
|
pscope->pdataResult)) !=
|
|
STATUS_SUCCESS) ||
|
|
(&pscope->FrameHdr !=
|
|
(PFRAMEHDR)pctxt->LocalHeap.pbHeapEnd))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (rc == AMLISTA_BREAK)
|
|
{
|
|
pctxt->pbOp = pscope->pbOpEnd;
|
|
rc = STATUS_SUCCESS;
|
|
}
|
|
else if ((rc == AMLISTA_PENDING) ||
|
|
(&pscope->FrameHdr !=
|
|
(PFRAMEHDR)pctxt->LocalHeap.pbHeapEnd))
|
|
{
|
|
break;
|
|
}
|
|
else if ((rc == STATUS_SUCCESS) &&
|
|
(pctxt->pbOp < pscope->pbOpEnd))
|
|
{
|
|
goto Stage1;
|
|
}
|
|
}
|
|
//
|
|
// If we come here, there was no more opcode in this scope, so
|
|
// continue to next stage.
|
|
//
|
|
pscope->FrameHdr.dwfFrame++;
|
|
|
|
case 2:
|
|
//
|
|
// Stage 2: clean up.
|
|
//
|
|
#ifdef DEBUGGER
|
|
if (gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
gDebugger.iPrintLevel--;
|
|
PrintIndent(pctxt);
|
|
PRINTF("}");
|
|
}
|
|
#endif
|
|
|
|
pctxt->pnsScope = pscope->pnsPrevScope;
|
|
pctxt->powner = pscope->pownerPrev;
|
|
pctxt->pheapCurrent = pscope->pheapPrev;
|
|
if (pscope->pbOpRet != NULL)
|
|
{
|
|
pctxt->pbOp = pscope->pbOpRet;
|
|
}
|
|
PopFrame(pctxt);
|
|
}
|
|
|
|
EXIT(2, ("ParseScope=%x\n", rc));
|
|
return rc;
|
|
} //ParseScope
|
|
|
|
/***LP ParseNestedContext - Parse and evaluate a nested context
|
|
*
|
|
* ENTRY
|
|
* pctxt -> CTXT
|
|
* pcall -> CALL
|
|
* rc - status code
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
NTSTATUS LOCAL ParseNestedContext(PCTXT pctxt, PNESTEDCTXT pnctxt, NTSTATUS rc)
|
|
{
|
|
TRACENAME("PARSENESTEDCONTEXT")
|
|
|
|
ENTER(2, ("ParseNestedContext(pctxt=%x,pnctxt=%x,rc=%x)\n",
|
|
pctxt, pnctxt, rc));
|
|
|
|
ASSERT(pctxt->dwfCtxt & CTXTF_NEST_EVAL);
|
|
|
|
if ((rc == STATUS_SUCCESS) && (pnctxt->pdataCallBack != NULL))
|
|
{
|
|
rc = DupObjData(gpheapGlobal, pnctxt->pdataCallBack, &pnctxt->Result);
|
|
}
|
|
|
|
AsyncCallBack(pctxt, rc);
|
|
|
|
FreeDataBuffs(&pnctxt->Result, 1);
|
|
pctxt->dwfCtxt &= ~CTXTF_ASYNC_EVAL;
|
|
pctxt->dwfCtxt |= pnctxt->dwfPrevCtxt & CTXTF_ASYNC_EVAL;
|
|
pctxt->pnctxt = pnctxt->pnctxtPrev;
|
|
|
|
PopFrame(pctxt);
|
|
|
|
EXIT(2, ("ParseNestedContext=%x (rcEval=%x)\n", AMLISTA_DONE, rc));
|
|
return AMLISTA_DONE;
|
|
} //ParseNestedContext
|
|
|
|
/***LP ParseCall - Parse and evaluate a method call
|
|
*
|
|
* ENTRY
|
|
* pctxt -> CTXT
|
|
* pcall -> CALL
|
|
* rc - status code
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
|
|
NTSTATUS LOCAL ParseCall(PCTXT pctxt, PCALL pcall, NTSTATUS rc)
|
|
{
|
|
TRACENAME("PARSECALL")
|
|
ULONG dwStage = (rc == STATUS_SUCCESS)?
|
|
(pcall->FrameHdr.dwfFrame & FRAMEF_STAGE_MASK): 4;
|
|
PMETHODOBJ pm;
|
|
POBJOWNER powner;
|
|
|
|
ENTER(2, ("ParseCall(Stage=%d,pctxt=%x,pbOp=%x,pcall=%x,rc=%x)\n",
|
|
dwStage, pctxt, pctxt->pbOp, pcall, rc));
|
|
|
|
ASSERT(pcall->FrameHdr.dwSig == SIG_CALL);
|
|
pm = (pcall->pnsMethod != NULL)?
|
|
(PMETHODOBJ)pcall->pnsMethod->ObjData.pbDataBuff: NULL;
|
|
|
|
switch (dwStage)
|
|
{
|
|
case 0:
|
|
//
|
|
// Stage 0: Print debug stuff if necessary.
|
|
//
|
|
pcall->FrameHdr.dwfFrame++;
|
|
#ifdef DEBUGGER
|
|
if (gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
PRINTF("(");
|
|
}
|
|
#endif
|
|
|
|
case 1:
|
|
Stage1:
|
|
//
|
|
// Stage 1: Parse arguments.
|
|
//
|
|
while (pcall->iArg < pcall->icArgs)
|
|
{
|
|
//
|
|
// There are still arguments, parse it.
|
|
//
|
|
#ifdef DEBUGGER
|
|
if (gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
if (pcall->iArg > 0)
|
|
{
|
|
PRINTF(",");
|
|
}
|
|
}
|
|
#endif
|
|
|
|
rc = ParseArg(pctxt, 'C', &pcall->pdataArgs[pcall->iArg++]);
|
|
|
|
if ((rc != STATUS_SUCCESS) ||
|
|
(&pcall->FrameHdr !=
|
|
(PFRAMEHDR)pctxt->LocalHeap.pbHeapEnd))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((rc != STATUS_SUCCESS) ||
|
|
(&pcall->FrameHdr != (PFRAMEHDR)pctxt->LocalHeap.pbHeapEnd))
|
|
{
|
|
break;
|
|
}
|
|
else if (pcall->iArg < pcall->icArgs)
|
|
{
|
|
goto Stage1;
|
|
}
|
|
//
|
|
// If we come here, there is no more argument, so we can fall
|
|
// through to the next stage.
|
|
//
|
|
#ifdef DEBUGGER
|
|
if (gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
PRINTF(")");
|
|
}
|
|
#endif
|
|
|
|
pcall->FrameHdr.dwfFrame++;
|
|
|
|
case 2:
|
|
//
|
|
// Stage 2: Acquire mutex if necessary
|
|
//
|
|
pcall->FrameHdr.dwfFrame++;
|
|
|
|
if(pm)
|
|
{
|
|
if (pm->bMethodFlags & METHOD_SERIALIZED)
|
|
{
|
|
PACQUIRE pacq;
|
|
|
|
if ((rc = PushFrame(pctxt, SIG_ACQUIRE, sizeof(ACQUIRE),
|
|
ParseAcquire, &pacq)) == STATUS_SUCCESS)
|
|
{
|
|
pacq->pmutex = &pm->Mutex;
|
|
pacq->wTimeout = 0xffff;
|
|
pacq->pdataResult = pcall->pdataResult;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_ASSERT_FAILED, ("ParseCall: pcall->pnsMethod == NULL"));
|
|
break;
|
|
}
|
|
|
|
case 3:
|
|
//
|
|
// Stage 3: Invoke the method.
|
|
//
|
|
pcall->FrameHdr.dwfFrame++;
|
|
//
|
|
// If we come here, we must have acquired the serialization mutex.
|
|
//
|
|
if (pcall->FrameHdr.dwfFrame & CALLF_NEED_MUTEX)
|
|
{
|
|
pcall->FrameHdr.dwfFrame |= CALLF_ACQ_MUTEX;
|
|
}
|
|
|
|
if ((rc = NewObjOwner(pctxt->pheapCurrent, &powner)) ==
|
|
STATUS_SUCCESS)
|
|
{
|
|
pcall->pownerPrev = pctxt->powner;
|
|
pctxt->powner = powner;
|
|
pcall->pcallPrev = pctxt->pcall;
|
|
pctxt->pcall = pcall;
|
|
pcall->FrameHdr.dwfFrame |= CALLF_INVOKE_CALL;
|
|
rc = PushScope(pctxt, pm->abCodeBuff,
|
|
pcall->pnsMethod->ObjData.pbDataBuff +
|
|
pcall->pnsMethod->ObjData.dwDataLen,
|
|
pctxt->pbOp,
|
|
pcall->pnsMethod,
|
|
powner,
|
|
pctxt->pheapCurrent,
|
|
pcall->pdataResult);
|
|
break;
|
|
}
|
|
|
|
case 4:
|
|
//
|
|
// Stage 4: Clean up.
|
|
//
|
|
pcall->FrameHdr.dwfFrame++;
|
|
if (rc == AMLISTA_RETURN)
|
|
{
|
|
rc = STATUS_SUCCESS;
|
|
}
|
|
|
|
if (pcall->pdataResult->dwfData & DATAF_BUFF_ALIAS)
|
|
{
|
|
OBJDATA data;
|
|
//
|
|
// The result object is an alias. It could be an alias of
|
|
// ArgX or LocalX. We better dup it because we are going
|
|
// to blow ArgX and LocalX away.
|
|
//
|
|
DupObjData(pctxt->pheapCurrent, &data, pcall->pdataResult);
|
|
FreeDataBuffs(pcall->pdataResult, 1);
|
|
MoveObjData(pcall->pdataResult, &data);
|
|
}
|
|
|
|
FreeDataBuffs(pcall->Locals, MAX_NUM_LOCALS);
|
|
|
|
if (pcall->FrameHdr.dwfFrame & CALLF_INVOKE_CALL)
|
|
{
|
|
FreeObjOwner(pctxt->powner, FALSE);
|
|
pctxt->powner = pcall->pownerPrev;
|
|
pctxt->pcall = pcall->pcallPrev;
|
|
}
|
|
else if (pcall->pnsMethod == NULL)
|
|
{
|
|
//
|
|
// This is the dummy call frame for LoadDDB. All NameSpace
|
|
// objects created by LoadDDB are persistent (i.e. don't
|
|
// destroy them).
|
|
//
|
|
pctxt->powner = pcall->pownerPrev;
|
|
pctxt->pcall = pcall->pcallPrev;
|
|
}
|
|
|
|
if (pcall->pdataArgs != NULL)
|
|
{
|
|
FreeDataBuffs(pcall->pdataArgs, pcall->icArgs);
|
|
FREEODOBJ(pcall->pdataArgs);
|
|
}
|
|
|
|
if (pcall->FrameHdr.dwfFrame & CALLF_ACQ_MUTEX)
|
|
{
|
|
ReleaseASLMutex(pctxt, &pm->Mutex);
|
|
}
|
|
|
|
case 5:
|
|
//
|
|
// Stage 5: This stage is for the dummy call frame to exit.
|
|
//
|
|
PopFrame(pctxt);
|
|
}
|
|
|
|
EXIT(2, ("ParseCall=%x\n", rc));
|
|
return rc;
|
|
} //ParseCall
|
|
|
|
/***LP ParseTerm - Parse and evaluate an ASL term
|
|
*
|
|
* ENTRY
|
|
* pctxt -> CTXT
|
|
* pterm -> TERM
|
|
* rc - status code
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
|
|
NTSTATUS LOCAL ParseTerm(PCTXT pctxt, PTERM pterm, NTSTATUS rc)
|
|
{
|
|
TRACENAME("PARSETERM")
|
|
ULONG dwStage = (rc == STATUS_SUCCESS)?
|
|
(pterm->FrameHdr.dwfFrame & FRAMEF_STAGE_MASK): 4;
|
|
int i;
|
|
|
|
ENTER(2, ("ParseTerm(Term=%s,Stage=%d,pctxt=%x,pbOp=%x,pterm=%x,rc=%x)\n",
|
|
pterm->pamlterm->pszTermName, dwStage, pctxt, pctxt->pbOp, pterm,
|
|
rc));
|
|
|
|
ASSERT(pterm->FrameHdr.dwSig == SIG_TERM);
|
|
switch (dwStage)
|
|
{
|
|
case 0:
|
|
//
|
|
// Stage 0: Parse package length if any.
|
|
//
|
|
pterm->FrameHdr.dwfFrame++;
|
|
|
|
#ifdef DEBUGGER
|
|
if (gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
if (pterm->pamlterm->dwOpcode == OP_PACKAGE)
|
|
{
|
|
gDebugger.iPrintLevel++;
|
|
PrintIndent(pctxt);
|
|
}
|
|
PRINTF("%s", pterm->pamlterm->pszTermName);
|
|
if (pterm->icArgs > 0)
|
|
{
|
|
PRINTF("(");
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (pterm->pamlterm->dwfOpcode & OF_VARIABLE_LIST)
|
|
{
|
|
ParsePackageLen(&pctxt->pbOp, &pterm->pbOpEnd);
|
|
}
|
|
|
|
case 1:
|
|
Stage1:
|
|
//
|
|
// Stage 1: Parse arguments.
|
|
//
|
|
while (pterm->iArg < pterm->icArgs)
|
|
{
|
|
i = pterm->iArg++;
|
|
#ifdef DEBUGGER
|
|
if (gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
if (i > 0)
|
|
{
|
|
PRINTF(",");
|
|
}
|
|
}
|
|
#endif
|
|
|
|
rc = ParseArg(pctxt, pterm->pamlterm->pszArgTypes[i],
|
|
&pterm->pdataArgs[i]);
|
|
|
|
if ((rc != STATUS_SUCCESS) ||
|
|
(&pterm->FrameHdr != (PFRAMEHDR)pctxt->LocalHeap.pbHeapEnd))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ((rc != STATUS_SUCCESS) ||
|
|
(&pterm->FrameHdr != (PFRAMEHDR)pctxt->LocalHeap.pbHeapEnd))
|
|
{
|
|
break;
|
|
}
|
|
else if (pterm->iArg < pterm->icArgs)
|
|
{
|
|
goto Stage1;
|
|
}
|
|
//
|
|
// If we come here, there is no more argument, so we can fall
|
|
// through to the next stage.
|
|
//
|
|
pterm->FrameHdr.dwfFrame++;
|
|
|
|
case 2:
|
|
//
|
|
// Stage 2: Execute the term and prepare to go to the next stage.
|
|
//
|
|
pterm->FrameHdr.dwfFrame++;
|
|
|
|
#ifdef DEBUGGER
|
|
if (gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
if (pterm->icArgs > 0)
|
|
{
|
|
PRINTF(")");
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if ((pterm->pamlterm->dwfOpcode & OF_CALLBACK_EX) &&
|
|
(pterm->pamlterm->pfnCallBack != NULL))
|
|
{
|
|
((PFNOPEX)pterm->pamlterm->pfnCallBack)(
|
|
EVTYPE_OPCODE_EX,
|
|
OPEXF_NOTIFY_PRE,
|
|
pterm->pamlterm->dwOpcode,
|
|
pterm->pnsObj,
|
|
pterm->pamlterm->dwCBData);
|
|
}
|
|
|
|
if (pterm->pamlterm->pfnOpcode != NULL)
|
|
{
|
|
if (((rc = pterm->pamlterm->pfnOpcode(pctxt, pterm)) !=
|
|
STATUS_SUCCESS) ||
|
|
(&pterm->FrameHdr != (PFRAMEHDR)pctxt->LocalHeap.pbHeapEnd))
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
case 3:
|
|
//
|
|
// Stage 3: Do Opcode Callback if any
|
|
//
|
|
pterm->FrameHdr.dwfFrame++;
|
|
|
|
#ifdef DEBUGGER
|
|
if (gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
if ((pterm->pamlterm->dwOpcode != OP_BUFFER) &&
|
|
(pterm->pamlterm->dwOpcode != OP_PACKAGE))
|
|
{
|
|
if (pterm->pamlterm->dwTermClass == TC_OPCODE_TYPE2)
|
|
{
|
|
PRINTF("=");
|
|
PrintObject(pterm->pdataResult);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (gDebugger.dwfDebugger & DBGF_SINGLE_STEP)
|
|
{
|
|
gDebugger.dwfDebugger &= ~DBGF_SINGLE_STEP;
|
|
AMLIDebugger(FALSE);
|
|
}
|
|
else
|
|
{
|
|
#endif
|
|
|
|
if (pterm->pamlterm->pfnCallBack != NULL)
|
|
{
|
|
if (pterm->pamlterm->dwfOpcode & OF_CALLBACK_EX)
|
|
{
|
|
((PFNOPEX)pterm->pamlterm->pfnCallBack)(
|
|
EVTYPE_OPCODE_EX,
|
|
OPEXF_NOTIFY_POST,
|
|
pterm->pamlterm->dwOpcode,
|
|
pterm->pnsObj,
|
|
pterm->pamlterm->dwCBData);
|
|
}
|
|
else
|
|
{
|
|
pterm->pamlterm->pfnCallBack(
|
|
EVTYPE_OPCODE,
|
|
pterm->pamlterm->dwOpcode,
|
|
pterm->pnsObj,
|
|
pterm->pamlterm->dwCBData
|
|
);
|
|
}
|
|
}
|
|
#ifdef DEBUGGER
|
|
}
|
|
#endif
|
|
|
|
case 4:
|
|
//
|
|
// Stage 4: Clean up.
|
|
//
|
|
#ifdef DEBUGGER
|
|
if (gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
if (pterm->pamlterm->dwOpcode == OP_PACKAGE)
|
|
{
|
|
gDebugger.iPrintLevel--;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (pterm->pdataArgs != NULL)
|
|
{
|
|
FreeDataBuffs(pterm->pdataArgs, pterm->icArgs);
|
|
FREEODOBJ(pterm->pdataArgs);
|
|
}
|
|
PopFrame(pctxt);
|
|
}
|
|
|
|
EXIT(2, ("ParseTerm=%x\n", rc));
|
|
return rc;
|
|
} //ParseTerm
|
|
|
|
/***LP ParseAcquire - Parse and evaluate an Acquire term
|
|
*
|
|
* ENTRY
|
|
* pctxt -> CTXT
|
|
* pacq - ACQUIRE
|
|
* rc - status code
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
|
|
NTSTATUS LOCAL ParseAcquire(PCTXT pctxt, PACQUIRE pacq, NTSTATUS rc)
|
|
{
|
|
TRACENAME("PARSEACQUIRE")
|
|
ULONG dwStage = (rc == STATUS_SUCCESS)?
|
|
(pacq->FrameHdr.dwfFrame & FRAMEF_STAGE_MASK): 2;
|
|
|
|
ENTER(2, ("ParseAcquire(Stage=%d,pctxt=%x,pbOp=%x,pacq=%x,rc=%x)\n",
|
|
dwStage, pctxt, pctxt->pbOp, pacq, rc));
|
|
|
|
ASSERT(pacq->FrameHdr.dwSig == SIG_ACQUIRE);
|
|
|
|
switch (dwStage)
|
|
{
|
|
case 0:
|
|
//
|
|
// Stage 0: Acquire GlobalLock if necessary.
|
|
//
|
|
pacq->FrameHdr.dwfFrame++;
|
|
if (pacq->FrameHdr.dwfFrame & ACQF_NEED_GLOBALLOCK)
|
|
{
|
|
if ((rc = AcquireGL(pctxt)) != STATUS_SUCCESS)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
case 1:
|
|
//
|
|
// Stage 1: Acquire the mutex.
|
|
//
|
|
if (pacq->FrameHdr.dwfFrame & ACQF_NEED_GLOBALLOCK)
|
|
{
|
|
//
|
|
// If we come here, we must have acquired the global lock.
|
|
//
|
|
pacq->FrameHdr.dwfFrame |= ACQF_HAVE_GLOBALLOCK;
|
|
}
|
|
|
|
rc = AcquireASLMutex(pctxt, pacq->pmutex, pacq->wTimeout);
|
|
|
|
if (rc == AMLISTA_PENDING)
|
|
{
|
|
//
|
|
// If it is pending, we must release the global lock and
|
|
// retry the whole operation.
|
|
//
|
|
if (pacq->FrameHdr.dwfFrame & ACQF_HAVE_GLOBALLOCK)
|
|
{
|
|
pacq->FrameHdr.dwfFrame &= ~ACQF_HAVE_GLOBALLOCK;
|
|
if ((rc = ReleaseGL(pctxt)) == STATUS_SUCCESS)
|
|
{
|
|
pacq->FrameHdr.dwfFrame--;
|
|
}
|
|
else
|
|
{
|
|
pacq->FrameHdr.dwfFrame++;
|
|
rc = AMLI_LOGERR(AMLIERR_ASSERT_FAILED,
|
|
("ParseAcquire: failed to release global lock (rc=%x)",
|
|
rc));
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if (pacq->FrameHdr.dwfFrame & ACQF_SET_RESULT)
|
|
{
|
|
pacq->pdataResult->dwDataType = OBJTYPE_INTDATA;
|
|
if (rc == AMLISTA_TIMEOUT)
|
|
{
|
|
pacq->pdataResult->uipDataValue = DATAVALUE_ONES;
|
|
rc = STATUS_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
pacq->pdataResult->uipDataValue = DATAVALUE_ZERO;
|
|
}
|
|
}
|
|
}
|
|
pacq->FrameHdr.dwfFrame++;
|
|
|
|
case 2:
|
|
//
|
|
// Stage 2: Clean up.
|
|
//
|
|
PopFrame(pctxt);
|
|
}
|
|
|
|
EXIT(2, ("ParseAcquire=%x\n", rc));
|
|
return rc;
|
|
} //ParseAcquire
|
|
|
|
/***LP ParseOpcode - Parse AML opcode
|
|
*
|
|
* ENTRY
|
|
* pctxt -> CTXT
|
|
* pbScopeEnd -> end of current scope
|
|
* pdataResult -> result object
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
|
|
NTSTATUS LOCAL ParseOpcode(PCTXT pctxt, PUCHAR pbScopeEnd, POBJDATA pdataResult)
|
|
{
|
|
TRACENAME("PARSEOPCODE")
|
|
NTSTATUS rc = STATUS_SUCCESS;
|
|
PUCHAR pbOpTerm;
|
|
PAMLTERM pamlterm;
|
|
#ifdef DEBUGGER
|
|
int iBrkPt;
|
|
#endif
|
|
|
|
ENTER(2, ("ParseOpcode(pctxt=%x,pbOp=%x,pbScopeEnd=%x,pdataResult=%x)\n",
|
|
pctxt, pctxt->pbOp, pbScopeEnd, pdataResult));
|
|
|
|
ASSERT(pdataResult != NULL);
|
|
#ifdef DEBUGGER
|
|
if ((iBrkPt = CheckBP(pctxt->pbOp)) != -1)
|
|
{
|
|
PRINTF("\nHit Breakpoint %d.\n", iBrkPt);
|
|
AMLIDebugger(FALSE);
|
|
}
|
|
#endif
|
|
pbOpTerm = pctxt->pbOp;
|
|
if (*pctxt->pbOp == OP_EXT_PREFIX)
|
|
{
|
|
pctxt->pbOp++;
|
|
pamlterm = FindOpcodeTerm(*pctxt->pbOp, ExOpcodeTable);
|
|
}
|
|
else
|
|
{
|
|
pamlterm = OpcodeTable[*pctxt->pbOp];
|
|
}
|
|
|
|
if (pamlterm == NULL)
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_INVALID_OPCODE,
|
|
("ParseOpcode: invalid opcode 0x%02x at 0x%08x",
|
|
*pctxt->pbOp, pctxt->pbOp));
|
|
}
|
|
else if (pamlterm->dwfOpcode & OF_DATA_OBJECT)
|
|
{
|
|
rc = ParseIntObj(&pctxt->pbOp, pdataResult, FALSE);
|
|
}
|
|
else if (pamlterm->dwfOpcode & OF_STRING_OBJECT)
|
|
{
|
|
rc = ParseString(&pctxt->pbOp, pdataResult, FALSE);
|
|
}
|
|
else if (pamlterm->dwfOpcode & OF_ARG_OBJECT)
|
|
{
|
|
rc = ParseArgObj(pctxt, pdataResult);
|
|
}
|
|
else if (pamlterm->dwfOpcode & OF_LOCAL_OBJECT)
|
|
{
|
|
rc = ParseLocalObj(pctxt, pdataResult);
|
|
}
|
|
else if (pamlterm->dwfOpcode & OF_NAME_OBJECT)
|
|
{
|
|
rc = ParseNameObj(pctxt, pdataResult);
|
|
}
|
|
else if (pamlterm->dwfOpcode & OF_DEBUG_OBJECT)
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_FATAL,
|
|
("ParseOpcode: debug object cannot be evaluated"));
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Must be an ASL Term.
|
|
//
|
|
pctxt->pbOp++;
|
|
rc = PushTerm(pctxt, pbOpTerm, pbScopeEnd, pamlterm, pdataResult);
|
|
}
|
|
|
|
EXIT(2, ("ParseOpcode=%x (pbOp=%x,pamlterm=%x)\n",
|
|
rc, pctxt->pbOp, pamlterm));
|
|
return rc;
|
|
} //ParseOpcode
|
|
|
|
/***LP ParseArgObj - Parse and execute the ArgX instruction
|
|
*
|
|
* ENTRY
|
|
* pctxt -> CTXT
|
|
* pdataResult -> result object
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
|
|
NTSTATUS LOCAL ParseArgObj(PCTXT pctxt, POBJDATA pdataResult)
|
|
{
|
|
TRACENAME("PARSEARGOBJ")
|
|
NTSTATUS rc = STATUS_SUCCESS;
|
|
int i;
|
|
|
|
ENTER(2, ("ParseArgObj(pctxt=%x,pbOp=%x,pdataResult=%x)\n",
|
|
pctxt, pctxt->pbOp, pdataResult));
|
|
|
|
ASSERT(pdataResult != NULL);
|
|
i = *pctxt->pbOp - OP_ARG0;
|
|
|
|
if (i >= pctxt->pcall->icArgs)
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_ARG_NOT_EXIST,
|
|
("ParseArgObj: Arg%d does not exist", i));
|
|
}
|
|
else
|
|
{
|
|
CopyObjData(pdataResult, &pctxt->pcall->pdataArgs[i]);
|
|
pctxt->pbOp++;
|
|
#ifdef DEBUGGER
|
|
if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
PRINTF("Arg%d=", i);
|
|
PrintObject(pdataResult);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
EXIT(2, ("ParseArgObj=%x (pbOp=%x)\n", rc, pctxt->pbOp));
|
|
return rc;
|
|
} //ParseArgObj
|
|
|
|
/***LP ParseLocalObj - Parse and execute the LocalX instruction
|
|
*
|
|
* ENTRY
|
|
* pctxt -> CTXT
|
|
* pdataResult -> Result object
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
|
|
NTSTATUS LOCAL ParseLocalObj(PCTXT pctxt, POBJDATA pdataResult)
|
|
{
|
|
TRACENAME("PARSELOCALOBJ")
|
|
NTSTATUS rc = STATUS_SUCCESS;
|
|
int i;
|
|
|
|
ENTER(2, ("ParseLocalObj(pctxt=%x,pbOp=%x,pdataResult=%x)\n",
|
|
pctxt, pctxt->pbOp, pdataResult));
|
|
|
|
ASSERT(pdataResult != NULL);
|
|
i = *pctxt->pbOp - OP_LOCAL0;
|
|
CopyObjData(pdataResult, &pctxt->pcall->Locals[i]);
|
|
|
|
#ifdef DEBUGGER
|
|
if (gDebugger.dwfDebugger & (DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
PRINTF("Local%d=", i);
|
|
PrintObject(pdataResult);
|
|
}
|
|
#endif
|
|
|
|
pctxt->pbOp++;
|
|
|
|
EXIT(2, ("ParseLocalObj=%x (pbOp=%x)\n", rc, pctxt->pbOp));
|
|
return rc;
|
|
} //ParseLocalObj
|
|
|
|
/***LP ParseNameObj - Parse and evaluate an AML name object
|
|
*
|
|
* ENTRY
|
|
* pctxt -> CTXT
|
|
* pdataResult -> result object
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
|
|
NTSTATUS LOCAL ParseNameObj(PCTXT pctxt, POBJDATA pdataResult)
|
|
{
|
|
TRACENAME("PARSENAMEOBJ")
|
|
NTSTATUS rc = STATUS_SUCCESS;
|
|
PNSOBJ pns = NULL;
|
|
|
|
ENTER(2, ("ParseNameObj(pctxt=%x,pbOp=%x,pdataResult=%x)\n",
|
|
pctxt, pctxt->pbOp, pdataResult));
|
|
|
|
ASSERT(pdataResult != NULL);
|
|
|
|
rc = ParseAndGetNameSpaceObject(&pctxt->pbOp, pctxt->pnsScope, &pns, FALSE);
|
|
|
|
if (rc == STATUS_SUCCESS)
|
|
{
|
|
pns = GetBaseObject(pns);
|
|
if (pns->ObjData.dwDataType == OBJTYPE_METHOD)
|
|
{
|
|
rc = PushCall(pctxt, pns, pdataResult);
|
|
}
|
|
else
|
|
{
|
|
rc = ReadObject(pctxt, &pns->ObjData, pdataResult);
|
|
}
|
|
}
|
|
|
|
EXIT(2, ("ParseNameObj=%x\n", rc));
|
|
return rc;
|
|
} //ParseNameObj
|
|
|
|
/***LP ParseAndGetNameSpaceObject - Parse NameSpace path and get the object
|
|
*
|
|
* ENTRY
|
|
* ppbOp -> opcode pointer
|
|
* pnsScope - current scope
|
|
* ppns -> to hold the object found
|
|
* fAbsentOK - if TRUE, do not print error message when object is not
|
|
* found
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
|
|
NTSTATUS LOCAL ParseAndGetNameSpaceObject(PUCHAR *ppbOp, PNSOBJ pnsScope,
|
|
PPNSOBJ ppns, BOOLEAN fAbsentOK)
|
|
{
|
|
TRACENAME("PARSEANDGETNAMESPACEOBJECT")
|
|
NTSTATUS rc;
|
|
char szNameBuff[MAX_NAME_LEN + 1];
|
|
|
|
ENTER(2, ("ParseAndGetNameSpaceObject(pbOp=%x,Scope=%s,ppns=%x,fAbsentOK=%x)\n",
|
|
*ppbOp, GetObjectPath(pnsScope), ppns, fAbsentOK));
|
|
|
|
if ((rc = ParseName(ppbOp, szNameBuff, sizeof(szNameBuff))) ==
|
|
STATUS_SUCCESS)
|
|
{
|
|
rc = GetNameSpaceObject(szNameBuff, pnsScope, ppns, 0);
|
|
if (rc == AMLIERR_OBJ_NOT_FOUND)
|
|
{
|
|
if (fAbsentOK)
|
|
{
|
|
rc = STATUS_SUCCESS;
|
|
*ppns = NULL;
|
|
}
|
|
else
|
|
{
|
|
rc = AMLI_LOGERR(rc,
|
|
("ParseAndGetNameSpaceObject: object %s not found",
|
|
szNameBuff));
|
|
}
|
|
}
|
|
}
|
|
|
|
EXIT(2, ("ParseAndGetNameSpaceObject=%x (Name=%s)\n", rc, szNameBuff));
|
|
return rc;
|
|
} //ParseAndGetNameSpaceObject
|
|
|
|
/***LP ParseArg - Parse and evaluate an argument
|
|
*
|
|
* ENTRY
|
|
* pctxt -> CTXT
|
|
* chArgType - expected argument type
|
|
* pdataArg -> argument object
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
|
|
NTSTATUS LOCAL ParseArg(PCTXT pctxt, char chArgType, POBJDATA pdataArg)
|
|
{
|
|
TRACENAME("PARSEARG")
|
|
NTSTATUS rc = STATUS_SUCCESS;
|
|
|
|
ENTER(2, ("ParseArg(pctxt=%x,pbOp=%x,ArgType=%c,pdataArg=%x)\n",
|
|
pctxt, pctxt->pbOp, chArgType, pdataArg));
|
|
|
|
ASSERT(pdataArg != NULL);
|
|
switch (chArgType)
|
|
{
|
|
case ARGTYPE_NAME:
|
|
rc = ParseObjName(&pctxt->pbOp, pdataArg, FALSE);
|
|
break;
|
|
|
|
case ARGTYPE_DATAOBJ:
|
|
if (((rc = ParseIntObj(&pctxt->pbOp, pdataArg, TRUE)) ==
|
|
AMLIERR_INVALID_OPCODE) &&
|
|
((rc = ParseString(&pctxt->pbOp, pdataArg, TRUE)) ==
|
|
AMLIERR_INVALID_OPCODE) &&
|
|
((*pctxt->pbOp == OP_BUFFER) || (*pctxt->pbOp == OP_PACKAGE)))
|
|
{
|
|
rc = PushTerm(pctxt, pctxt->pbOp, NULL,
|
|
OpcodeTable[*pctxt->pbOp], pdataArg);
|
|
pctxt->pbOp++;
|
|
}
|
|
break;
|
|
|
|
case ARGTYPE_BYTE:
|
|
rc = ParseInteger(&pctxt->pbOp, pdataArg, sizeof(UCHAR));
|
|
break;
|
|
|
|
case ARGTYPE_WORD:
|
|
rc = ParseInteger(&pctxt->pbOp, pdataArg, sizeof(USHORT));
|
|
break;
|
|
|
|
case ARGTYPE_DWORD:
|
|
rc = ParseInteger(&pctxt->pbOp, pdataArg, sizeof(ULONG));
|
|
break;
|
|
|
|
case ARGTYPE_SNAME:
|
|
rc = ParseSuperName(pctxt, pdataArg, FALSE);
|
|
break;
|
|
|
|
case ARGTYPE_SNAME2:
|
|
rc = ParseSuperName(pctxt, pdataArg, TRUE);
|
|
break;
|
|
|
|
case ARGTYPE_OPCODE:
|
|
rc = ParseOpcode(pctxt, NULL, pdataArg);
|
|
break;
|
|
|
|
default:
|
|
rc = AMLI_LOGERR(AMLIERR_ASSERT_FAILED,
|
|
("ParseArg: unexpected arguemnt type (%c)",
|
|
chArgType));
|
|
}
|
|
|
|
EXIT(2, ("ParseArg=%x\n", rc));
|
|
return rc;
|
|
} //ParseArg
|
|
|
|
/***LP ParseSuperName - Parse AML SuperName
|
|
*
|
|
* ENTRY
|
|
* pctxt -> CTXT
|
|
* pdata -> object data
|
|
* fAbsentOK - If TRUE, it is not an error for the object to be absent
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
|
|
NTSTATUS LOCAL ParseSuperName(PCTXT pctxt, POBJDATA pdata, BOOLEAN fAbsentOK)
|
|
{
|
|
TRACENAME("PARSESUPERNAME")
|
|
NTSTATUS rc = STATUS_SUCCESS;
|
|
PAMLTERM pamlterm;
|
|
PNSOBJ pns = NULL;
|
|
int i;
|
|
|
|
ENTER(2, ("ParseSuperName(pctxt=%x,pbOp=%x,pdata=%x,fAbsentOK=%x)\n",
|
|
pctxt, pctxt->pbOp, pdata, fAbsentOK));
|
|
|
|
ASSERT(pdata != NULL);
|
|
if (*pctxt->pbOp == 0)
|
|
{
|
|
ASSERT(pdata->dwDataType == OBJTYPE_UNKNOWN);
|
|
pctxt->pbOp++;
|
|
}
|
|
else if ((*pctxt->pbOp == OP_EXT_PREFIX) &&
|
|
(*(pctxt->pbOp + 1) == EXOP_DEBUG))
|
|
{
|
|
pctxt->pbOp += 2;
|
|
pdata->dwDataType = OBJTYPE_DEBUG;
|
|
#ifdef DEBUGGER
|
|
if (gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
PRINTF("Debug");
|
|
}
|
|
#endif
|
|
}
|
|
else if ((pamlterm = OpcodeTable[*pctxt->pbOp]) == NULL)
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_INVALID_SUPERNAME,
|
|
("ParseSuperName: invalid SuperName - 0x%02x at 0x%08x",
|
|
*pctxt->pbOp, pctxt->pbOp));
|
|
}
|
|
else if (pamlterm->dwfOpcode & OF_NAME_OBJECT)
|
|
{
|
|
rc = ParseAndGetNameSpaceObject(&pctxt->pbOp, pctxt->pnsScope, &pns,
|
|
fAbsentOK);
|
|
|
|
if (rc == STATUS_SUCCESS)
|
|
{
|
|
if (pns != NULL)
|
|
{
|
|
pdata->dwDataType = OBJTYPE_OBJALIAS;
|
|
pdata->pnsAlias = GetBaseObject(pns);
|
|
}
|
|
else
|
|
{
|
|
ASSERT(pdata->dwDataType == OBJTYPE_UNKNOWN);
|
|
}
|
|
}
|
|
}
|
|
else if (pamlterm->dwfOpcode & OF_ARG_OBJECT)
|
|
{
|
|
i = *pctxt->pbOp - OP_ARG0;
|
|
pctxt->pbOp++;
|
|
|
|
if (i < pctxt->pcall->icArgs)
|
|
{
|
|
#ifdef DEBUGGER
|
|
if (gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
PRINTF("Arg%d", i);
|
|
}
|
|
#endif
|
|
pdata->dwDataType = OBJTYPE_DATAALIAS;
|
|
pdata->pdataAlias = GetBaseData(&pctxt->pcall->pdataArgs[i]);
|
|
}
|
|
else
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_ARG_NOT_EXIST,
|
|
("ParseSuperName: Arg%d does not exist", i));
|
|
}
|
|
}
|
|
else if (pamlterm->dwfOpcode & OF_LOCAL_OBJECT)
|
|
{
|
|
i = *pctxt->pbOp - OP_LOCAL0;
|
|
pctxt->pbOp++;
|
|
|
|
#ifdef DEBUGGER
|
|
if (gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
PRINTF("Local%d", i);
|
|
}
|
|
#endif
|
|
pdata->dwDataType = OBJTYPE_DATAALIAS;
|
|
pdata->pdataAlias = &pctxt->pcall->Locals[i];
|
|
}
|
|
else if (pamlterm->dwfOpcode & OF_REF_OBJECT)
|
|
{
|
|
rc = PushTerm(pctxt, pctxt->pbOp, NULL, pamlterm, pdata);
|
|
pctxt->pbOp++;
|
|
}
|
|
else
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_INVALID_SUPERNAME,
|
|
("ParseSuperName: invalid SuperName %x at %x",
|
|
*pctxt->pbOp, pctxt->pbOp));
|
|
}
|
|
|
|
EXIT(2, ("ParseSuperName=%x\n", rc));
|
|
return rc;
|
|
} //ParseSuperName
|
|
|
|
/***LP ParseIntObj - Parse AML integer object
|
|
*
|
|
* ENTRY
|
|
* ppbOp -> opcode pointer
|
|
* pdataResult -> result object
|
|
* fErrOK - TRUE if error is OK
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
|
|
NTSTATUS LOCAL ParseIntObj(PUCHAR *ppbOp, POBJDATA pdataResult, BOOLEAN fErrOK)
|
|
{
|
|
TRACENAME("PARSEINTOBJ")
|
|
NTSTATUS rc = STATUS_SUCCESS;
|
|
UCHAR bOp;
|
|
|
|
ENTER(2, ("ParseIntObj(pbOp=%x,pdataResult=%x,fErrOK=%x)\n",
|
|
*ppbOp, pdataResult, fErrOK));
|
|
|
|
ASSERT(pdataResult != NULL);
|
|
bOp = **ppbOp;
|
|
(*ppbOp)++;
|
|
pdataResult->dwDataType = OBJTYPE_INTDATA;
|
|
pdataResult->uipDataValue = 0;
|
|
|
|
switch (bOp)
|
|
{
|
|
case OP_ZERO:
|
|
pdataResult->uipDataValue = DATAVALUE_ZERO;
|
|
#ifdef DEBUGGER
|
|
if (gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
PRINTF("Zero");
|
|
}
|
|
#endif
|
|
break;
|
|
|
|
case OP_ONE:
|
|
pdataResult->uipDataValue = DATAVALUE_ONE;
|
|
#ifdef DEBUGGER
|
|
if (gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
PRINTF("One");
|
|
}
|
|
#endif
|
|
break;
|
|
|
|
case OP_ONES:
|
|
pdataResult->uipDataValue = DATAVALUE_ONES;
|
|
#ifdef DEBUGGER
|
|
if (gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
PRINTF("Ones");
|
|
}
|
|
#endif
|
|
break;
|
|
|
|
case OP_REVISION:
|
|
pdataResult->uipDataValue = AMLI_REVISION;
|
|
#ifdef DEBUGGER
|
|
if (gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
PRINTF("Revision");
|
|
}
|
|
#endif
|
|
break;
|
|
|
|
case OP_BYTE:
|
|
MEMCPY(&pdataResult->uipDataValue, *ppbOp, sizeof(UCHAR));
|
|
(*ppbOp) += sizeof(UCHAR);
|
|
#ifdef DEBUGGER
|
|
if (gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
PRINTF("0x%x", pdataResult->uipDataValue);
|
|
}
|
|
#endif
|
|
break;
|
|
|
|
case OP_WORD:
|
|
MEMCPY(&pdataResult->uipDataValue, *ppbOp, sizeof(USHORT));
|
|
(*ppbOp) += sizeof(USHORT);
|
|
#ifdef DEBUGGER
|
|
if (gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
PRINTF("0x%x", pdataResult->uipDataValue);
|
|
}
|
|
#endif
|
|
break;
|
|
|
|
case OP_DWORD:
|
|
MEMCPY(&pdataResult->uipDataValue, *ppbOp, sizeof(ULONG));
|
|
(*ppbOp) += sizeof(ULONG);
|
|
#ifdef DEBUGGER
|
|
if (gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
PRINTF("0x%x", pdataResult->uipDataValue);
|
|
}
|
|
#endif
|
|
break;
|
|
|
|
default:
|
|
(*ppbOp)--;
|
|
if (fErrOK)
|
|
{
|
|
rc = AMLIERR_INVALID_OPCODE;
|
|
}
|
|
else
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_INVALID_OPCODE,
|
|
("ParseIntObj: invalid opcode 0x%02x at 0x%08x",
|
|
**ppbOp, *ppbOp));
|
|
}
|
|
}
|
|
|
|
EXIT(2, ("ParseIntObj=%x (pbOp=%x,Value=%x)\n",
|
|
rc, *ppbOp, pdataResult->uipDataValue));
|
|
return rc;
|
|
} //ParseIntObj
|
|
|
|
/***LP ParseString - Parse AML string object
|
|
*
|
|
* ENTRY
|
|
* ppbOp -> opcode pointer
|
|
* pdataResult -> result object
|
|
* fErrOK - TRUE if error is OK
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
|
|
NTSTATUS LOCAL ParseString(PUCHAR *ppbOp, POBJDATA pdataResult, BOOLEAN fErrOK)
|
|
{
|
|
TRACENAME("PARSESTRING")
|
|
NTSTATUS rc = STATUS_SUCCESS;
|
|
|
|
ENTER(2, ("ParseString(pbOp=%x,pdataResult=%x,fErrOK=%x)\n",
|
|
*ppbOp, pdataResult, fErrOK));
|
|
|
|
ASSERT(pdataResult != NULL);
|
|
if (**ppbOp == OP_STRING)
|
|
{
|
|
(*ppbOp)++;
|
|
pdataResult->dwDataType = OBJTYPE_STRDATA;
|
|
pdataResult->dwDataLen = STRLEN((PSZ)*ppbOp) + 1;
|
|
|
|
#ifdef DEBUGGER
|
|
if (gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
PRINTF("\"%s\"", *ppbOp);
|
|
}
|
|
#endif
|
|
|
|
if ((pdataResult->pbDataBuff = NEWSDOBJ(gpheapGlobal,
|
|
pdataResult->dwDataLen)) ==
|
|
NULL)
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM,
|
|
("ParseString: failed to allocate string buffer"));
|
|
}
|
|
else
|
|
{
|
|
MEMCPY(pdataResult->pbDataBuff, *ppbOp, pdataResult->dwDataLen);
|
|
}
|
|
|
|
(*ppbOp) += pdataResult->dwDataLen;
|
|
}
|
|
else if (fErrOK)
|
|
{
|
|
rc = AMLIERR_INVALID_OPCODE;
|
|
}
|
|
else
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_INVALID_OPCODE,
|
|
("ParseStrObj: invalid opcode 0x%02x at 0x%08x",
|
|
**ppbOp, *ppbOp));
|
|
}
|
|
|
|
EXIT(2, ("ParseString=%x (Value=%s)\n",
|
|
rc, pdataResult->pbDataBuff? (PSZ)pdataResult->pbDataBuff:
|
|
"<null>"));
|
|
return rc;
|
|
} //ParseString
|
|
|
|
/***LP ParseObjName - Parse AML object name
|
|
*
|
|
* ENTRY
|
|
* ppbOp -> opcode pointer
|
|
* pdata -> to hold name data
|
|
* fErrOK - TRUE if error is OK
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
|
|
NTSTATUS LOCAL ParseObjName(PUCHAR *ppbOp, POBJDATA pdata, BOOLEAN fErrOK)
|
|
{
|
|
TRACENAME("PARSEOBJNAME")
|
|
NTSTATUS rc = STATUS_SUCCESS;
|
|
PAMLTERM pamlterm = OpcodeTable[**ppbOp];
|
|
char szNameBuff[MAX_NAME_LEN+1];
|
|
|
|
ENTER(2, ("ParseObjName(pbOp=%x,pdata=%x,fErrOK=%x)\n",
|
|
*ppbOp, pdata, fErrOK));
|
|
|
|
ASSERT(pdata != NULL);
|
|
|
|
if ((pamlterm == NULL) || !(pamlterm->dwfOpcode & OF_NAME_OBJECT))
|
|
{
|
|
if (fErrOK)
|
|
{
|
|
rc = AMLIERR_INVALID_OPCODE;
|
|
}
|
|
else
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_INVALID_OPCODE,
|
|
("ParseObjName: invalid opcode 0x%02x at 0x%08x",
|
|
**ppbOp, *ppbOp));
|
|
}
|
|
}
|
|
else if ((rc = ParseName(ppbOp, szNameBuff, sizeof(szNameBuff))) ==
|
|
STATUS_SUCCESS)
|
|
{
|
|
pdata->dwDataType = OBJTYPE_STRDATA;
|
|
pdata->dwDataLen = STRLEN(szNameBuff) + 1;
|
|
if ((pdata->pbDataBuff = (PUCHAR)NEWSDOBJ(gpheapGlobal,
|
|
pdata->dwDataLen)) == NULL)
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM,
|
|
("ParseObjName: failed to allocate name buffer - %s",
|
|
szNameBuff));
|
|
}
|
|
else
|
|
{
|
|
MEMCPY(pdata->pbDataBuff, szNameBuff, pdata->dwDataLen);
|
|
}
|
|
}
|
|
|
|
EXIT(2, ("ParseObjName=%x (Name=%s)\n", rc, szNameBuff));
|
|
return rc;
|
|
} //ParseObjName
|
|
|
|
/***LP ParseName - Parse AML name
|
|
*
|
|
* ENTRY
|
|
* ppbOp -> opcode pointer
|
|
* pszBuff -> to hold parsed name
|
|
* dwLen - buffer length
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
|
|
NTSTATUS LOCAL ParseName(PUCHAR *ppbOp, PSZ pszBuff, ULONG dwLen)
|
|
{
|
|
TRACENAME("PARSENAME")
|
|
NTSTATUS rc = STATUS_SUCCESS;
|
|
|
|
ENTER(2, ("ParseName(pbOp=%x,pszBuff=%x,Len=%d)\n",
|
|
*ppbOp, pszBuff, dwLen));
|
|
|
|
if (**ppbOp == OP_ROOT_PREFIX)
|
|
{
|
|
if (dwLen > 1)
|
|
{
|
|
STRCPY(pszBuff, "\\");
|
|
(*ppbOp)++;
|
|
rc = ParseNameTail(ppbOp, pszBuff, dwLen);
|
|
}
|
|
else
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_NAME_TOO_LONG,
|
|
("ParseName: name too long - \"%s\"", pszBuff));
|
|
}
|
|
}
|
|
else if (**ppbOp == OP_PARENT_PREFIX)
|
|
{
|
|
if (dwLen > 1)
|
|
{
|
|
int i;
|
|
|
|
STRCPY(pszBuff, "^");
|
|
for ((*ppbOp)++, i = 1;
|
|
(i < (int)dwLen) && (**ppbOp == OP_PARENT_PREFIX);
|
|
(*ppbOp)++, i++)
|
|
{
|
|
pszBuff[i] = '^';
|
|
}
|
|
pszBuff[i] = '\0';
|
|
|
|
if (**ppbOp == OP_PARENT_PREFIX)
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_NAME_TOO_LONG,
|
|
("ParseName: name too long - \"%s\"",
|
|
pszBuff));
|
|
}
|
|
else
|
|
{
|
|
rc = ParseNameTail(ppbOp, pszBuff, dwLen);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_NAME_TOO_LONG,
|
|
("ParseName: name too long - \"%s\"", pszBuff));
|
|
}
|
|
}
|
|
else if (dwLen > 0)
|
|
{
|
|
pszBuff[0] = '\0';
|
|
rc = ParseNameTail(ppbOp, pszBuff, dwLen);
|
|
}
|
|
else
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_NAME_TOO_LONG,
|
|
("ParseName: name too long - \"%s\"", pszBuff));
|
|
}
|
|
|
|
#ifdef DEBUGGER
|
|
if ((rc == STATUS_SUCCESS) &&
|
|
(gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES)))
|
|
{
|
|
PRINTF("%s", pszBuff);
|
|
}
|
|
#endif
|
|
|
|
EXIT(2, ("ParseName=%x (Name=%s)\n", rc, pszBuff));
|
|
return rc;
|
|
} //ParseName
|
|
|
|
/***LP ParseNameTail - Parse AML name tail
|
|
*
|
|
* ENTRY
|
|
* ppbOp -> opcode pointer
|
|
* pszBuff -> to hold parsed name
|
|
* dwLen - buffer length
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
|
|
NTSTATUS LOCAL ParseNameTail(PUCHAR *ppbOp, PSZ pszBuff, ULONG dwLen)
|
|
{
|
|
TRACENAME("PARSENAMETAIL")
|
|
NTSTATUS rc = STATUS_SUCCESS;
|
|
int iLen;
|
|
int icNameSegs = 0;
|
|
|
|
ENTER(2, ("ParseNameTail(pbOp=%x,Name=%s,Len=%d)\n",
|
|
*ppbOp, pszBuff, dwLen));
|
|
|
|
//
|
|
// We do not check for invalid NameSeg characters here and assume that
|
|
// the compiler does its job not generating it.
|
|
//
|
|
iLen = STRLEN(pszBuff);
|
|
if (**ppbOp == '\0')
|
|
{
|
|
//
|
|
// There is no NameTail (i.e. either NULL name or name with just
|
|
// prefixes.
|
|
//
|
|
(*ppbOp)++;
|
|
}
|
|
else if (**ppbOp == OP_MULTI_NAME_PREFIX)
|
|
{
|
|
(*ppbOp)++;
|
|
icNameSegs = (int)**ppbOp;
|
|
(*ppbOp)++;
|
|
}
|
|
else if (**ppbOp == OP_DUAL_NAME_PREFIX)
|
|
{
|
|
(*ppbOp)++;
|
|
icNameSegs = 2;
|
|
}
|
|
else
|
|
icNameSegs = 1;
|
|
|
|
while ((icNameSegs > 0) && (iLen + sizeof(NAMESEG) < dwLen))
|
|
{
|
|
STRCPYN(&pszBuff[iLen], (PSZ)(*ppbOp), sizeof(NAMESEG));
|
|
iLen += sizeof(NAMESEG);
|
|
(*ppbOp) += sizeof(NAMESEG);
|
|
icNameSegs--;
|
|
if ((icNameSegs > 0) && (iLen + 1 < (int)dwLen))
|
|
{
|
|
STRCPY(&pszBuff[iLen], ".");
|
|
iLen++;
|
|
}
|
|
}
|
|
|
|
if (icNameSegs > 0)
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_NAME_TOO_LONG,
|
|
("ParseNameTail: name too long - %s", pszBuff));
|
|
}
|
|
|
|
EXIT(2, ("ParseNameTail=%x (Name=%s)\n", rc, pszBuff));
|
|
return rc;
|
|
} //ParseNameTail
|
|
|
|
/***LP ParseInteger - Parse AML integer object
|
|
*
|
|
* ENTRY
|
|
* ppbOp -> opcode pointer
|
|
* pdata -> to hold data
|
|
* dwDataLen - data length in bytes
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
|
|
NTSTATUS LOCAL ParseInteger(PUCHAR *ppbOp, POBJDATA pdata, ULONG dwDataLen)
|
|
{
|
|
TRACENAME("PARSEINTEGER")
|
|
NTSTATUS rc = STATUS_SUCCESS;
|
|
|
|
ENTER(2, ("ParseInteger(pbOp=%x,pdata=%x,DataLen=%d)\n",
|
|
*ppbOp, pdata, dwDataLen));
|
|
|
|
ASSERT(pdata != NULL);
|
|
pdata->dwDataType = OBJTYPE_INTDATA;
|
|
pdata->uipDataValue = 0;
|
|
MEMCPY(&pdata->uipDataValue, *ppbOp, dwDataLen);
|
|
(*ppbOp) += dwDataLen;
|
|
|
|
#ifdef DEBUGGER
|
|
if ((rc == STATUS_SUCCESS) &&
|
|
(gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES)))
|
|
|
|
{
|
|
PRINTF("0x%x", pdata->uipDataValue);
|
|
}
|
|
#endif
|
|
|
|
EXIT(2, ("ParseInteger=%x (Value=%x,pbOp=%x)\n",
|
|
rc, pdata->uipDataValue, *ppbOp));
|
|
return rc;
|
|
} //ParseInteger
|
|
|
|
/***LP ParseField - Parse AML field data
|
|
*
|
|
* ENTRY
|
|
* pctxt -> CTXT
|
|
* pnsParent -> parent
|
|
* pdwFieldFlags -> field flags
|
|
* pdwBitPos -> to hold the bit position parsed
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
|
|
NTSTATUS LOCAL ParseField(PCTXT pctxt, PNSOBJ pnsParent, PULONG pdwFieldFlags,
|
|
PULONG pdwBitPos)
|
|
{
|
|
TRACENAME("PARSEFIELD")
|
|
NTSTATUS rc = STATUS_SUCCESS;
|
|
char szName[sizeof(NAMESEG) + 1];
|
|
|
|
ENTER(2, ("ParseField(pctxt=%x,pbOp=%x,pnsParent=%x,FieldFlags=%x,BitPos=%x)\n",
|
|
pctxt, pctxt->pbOp, pnsParent, *pdwFieldFlags, *pdwBitPos));
|
|
|
|
if (*pctxt->pbOp == 0x01)
|
|
{
|
|
pctxt->pbOp++;
|
|
*pdwFieldFlags &= ~ACCTYPE_MASK;
|
|
*pdwFieldFlags |= *pctxt->pbOp & ACCTYPE_MASK;
|
|
pctxt->pbOp++;
|
|
*pdwFieldFlags &= ~ACCATTRIB_MASK;
|
|
*pdwFieldFlags |= (ULONG)*pctxt->pbOp << 8;
|
|
pctxt->pbOp++;
|
|
#ifdef DEBUGGER
|
|
if (gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
PrintIndent(pctxt);
|
|
PRINTF("AccessAs(0x%x,0x%x)",
|
|
*pdwFieldFlags & 0xff, (*pdwFieldFlags >> 8) & 0xff);
|
|
}
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
ULONG dwcbBits, dwAccSize = ACCSIZE(*pdwFieldFlags);
|
|
PNSOBJ pns;
|
|
|
|
if (*pctxt->pbOp == 0)
|
|
{
|
|
szName[0] = '\0';
|
|
pctxt->pbOp++;
|
|
}
|
|
else
|
|
{
|
|
STRCPYN(szName, (PSZ)pctxt->pbOp, sizeof(NAMESEG));
|
|
pctxt->pbOp += sizeof(NAMESEG);
|
|
}
|
|
|
|
dwcbBits = ParsePackageLen(&pctxt->pbOp, NULL);
|
|
#ifdef DEBUGGER
|
|
if (gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
PrintIndent(pctxt);
|
|
if (szName[0] == '\0')
|
|
{
|
|
if ((dwcbBits > 32) && (((*pdwBitPos + dwcbBits) % 8) == 0))
|
|
{
|
|
PRINTF("Offset(0x%x)", (*pdwBitPos + dwcbBits)/8);
|
|
}
|
|
else
|
|
{
|
|
PRINTF(",%d", dwcbBits);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
PRINTF("%s,%d", szName, dwcbBits);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if ((rc = CreateNameSpaceObject(pctxt->pheapCurrent, szName,
|
|
pctxt->pnsScope, pctxt->powner, &pns,
|
|
0)) == STATUS_SUCCESS)
|
|
{
|
|
pns->ObjData.dwDataType = OBJTYPE_FIELDUNIT;
|
|
pns->ObjData.dwDataLen = sizeof(FIELDUNITOBJ);
|
|
|
|
if ((pns->ObjData.pbDataBuff = NEWFUOBJ(pctxt->pheapCurrent,
|
|
pns->ObjData.dwDataLen)) ==
|
|
NULL)
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_OUT_OF_MEM,
|
|
("ParseField: failed to allocate FieldUnit object"));
|
|
}
|
|
else
|
|
{
|
|
PFIELDUNITOBJ pfu;
|
|
|
|
MEMZERO(pns->ObjData.pbDataBuff, pns->ObjData.dwDataLen);
|
|
pfu = (PFIELDUNITOBJ)pns->ObjData.pbDataBuff;
|
|
pfu->pnsFieldParent = pnsParent;
|
|
pfu->FieldDesc.dwFieldFlags = *pdwFieldFlags;
|
|
pfu->FieldDesc.dwByteOffset = (*pdwBitPos / (dwAccSize*8))*
|
|
dwAccSize;
|
|
pfu->FieldDesc.dwStartBitPos = *pdwBitPos -
|
|
pfu->FieldDesc.dwByteOffset*8;
|
|
pfu->FieldDesc.dwNumBits = dwcbBits;
|
|
(*pdwBitPos) += dwcbBits;
|
|
}
|
|
}
|
|
}
|
|
|
|
EXIT(2, ("ParseField=%x (Field=%s,BitPos=%x)\n", rc, szName, *pdwBitPos));
|
|
return rc;
|
|
} //ParseField
|
|
|
|
/***LP ParseFieldList - Parse the FieldUnit list
|
|
*
|
|
* ENTRY
|
|
* pctxt -> CTXT
|
|
* pbOpEnd -> end of field list
|
|
* pnsParent -> parent
|
|
* dwFieldFlags - field flags
|
|
* dwRegionLen - length of operation region (0xffffffff if no length limit)
|
|
*
|
|
* EXIT-SUCCESS
|
|
* returns STATUS_SUCCESS
|
|
* EXIT-FAILURE
|
|
* returns AMLIERR_ code
|
|
*/
|
|
|
|
NTSTATUS LOCAL ParseFieldList(PCTXT pctxt, PUCHAR pbOpEnd, PNSOBJ pnsParent,
|
|
ULONG dwFieldFlags, ULONG dwRegionLen)
|
|
{
|
|
TRACENAME("PARSESFIELDLIST")
|
|
NTSTATUS rc = STATUS_SUCCESS;
|
|
ULONG dwBitPos = 0;
|
|
|
|
ENTER(2, ("ParseFieldList(pctxt=%x,pbOp=%x,pnsParent=%x,FieldFlags=%x,RegionLen=%x)\n",
|
|
pctxt, pctxt->pbOp, pnsParent, dwFieldFlags, dwRegionLen));
|
|
|
|
#ifdef DEBUGGER
|
|
if (gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
PrintIndent(pctxt);
|
|
PRINTF("{");
|
|
gDebugger.iPrintLevel++;
|
|
}
|
|
#endif
|
|
|
|
while ((rc == STATUS_SUCCESS) && (pctxt->pbOp < pbOpEnd))
|
|
{
|
|
if ((rc = ParseField(pctxt, pnsParent, &dwFieldFlags, &dwBitPos)) ==
|
|
STATUS_SUCCESS)
|
|
{
|
|
#ifdef DEBUGGER
|
|
if ((gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES)) &&
|
|
(rc == STATUS_SUCCESS) &&
|
|
(pctxt->pbOp < pbOpEnd))
|
|
{
|
|
PRINTF(",");
|
|
}
|
|
#endif
|
|
|
|
if ((dwRegionLen != 0xffffffff) && ((dwBitPos + 7)/8 > dwRegionLen))
|
|
{
|
|
rc = AMLI_LOGERR(AMLIERR_INDEX_TOO_BIG,
|
|
("ParseFieldList: offset exceeds OpRegion range (Offset=0x%x, RegionLen=0x%x)",
|
|
(dwBitPos + 7)/8, dwRegionLen));
|
|
}
|
|
}
|
|
}
|
|
#ifdef DEBUGGER
|
|
if (gDebugger.dwfDebugger &
|
|
(DBGF_AMLTRACE_ON | DBGF_STEP_MODES))
|
|
{
|
|
gDebugger.iPrintLevel--;
|
|
PrintIndent(pctxt);
|
|
PRINTF("}");
|
|
}
|
|
#endif
|
|
|
|
EXIT(2, ("ParseFieldList=%x\n", rc));
|
|
return rc;
|
|
} //ParseFieldList
|
|
|
|
/***LP ParsePackageLen - parse package length
|
|
*
|
|
* ENTRY
|
|
* ppbOp -> instruction pointer
|
|
* ppbOpNext -> to hold pointer to next instruction (can be NULL)
|
|
*
|
|
* EXIT
|
|
* returns package length
|
|
*/
|
|
|
|
ULONG LOCAL ParsePackageLen(PUCHAR *ppbOp, PUCHAR *ppbOpNext)
|
|
{
|
|
TRACENAME("PARSEPACKAGELEN")
|
|
ULONG dwLen;
|
|
UCHAR bFollowCnt, i;
|
|
|
|
ENTER(2, ("ParsePackageLen(pbOp=%x,ppbOpNext=%x)\n", *ppbOp, ppbOpNext));
|
|
|
|
if (ppbOpNext != NULL)
|
|
*ppbOpNext = *ppbOp;
|
|
|
|
dwLen = (ULONG)(**ppbOp);
|
|
(*ppbOp)++;
|
|
bFollowCnt = (UCHAR)((dwLen & 0xc0) >> 6);
|
|
if (bFollowCnt != 0)
|
|
{
|
|
dwLen &= 0x0000000f;
|
|
for (i = 0; i < bFollowCnt; ++i)
|
|
{
|
|
dwLen |= (ULONG)(**ppbOp) << (i*8 + 4);
|
|
(*ppbOp)++;
|
|
}
|
|
}
|
|
|
|
if (ppbOpNext != NULL)
|
|
*ppbOpNext += dwLen;
|
|
|
|
EXIT(2, ("ParsePackageLen=%x (pbOp=%x,pbOpNext=%x)\n",
|
|
dwLen, *ppbOp, ppbOpNext? *ppbOpNext: 0));
|
|
return dwLen;
|
|
} //ParsePackageLen
|