singrdk/base/boot/Singldr/acpi/parser.cpp

2964 lines
81 KiB
C++

///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
namespace ACPI
{
#if 0
class Parser
{
enum Prefix {
NullName = 0x00,
};
enum Op {
ZeroOp = 0x00,
OneOp = 0x01,
AliasOp = 0x06,
NameOp = 0x08,
BytePrefix = 0x0a,
WordPrefix = 0x0b,
DWordPrefix = 0x0c,
QWordPrefix = 0x0e,
StringPrefix = 0x0d,
ScopeOp = 0x10,
BufferOp = 0x11,
PackageOp = 0x12,
VarPackageOp = 0x13,
MethodOp = 0x14,
DualNamePrefix = 0x2e,
MultiNamePrefix = 0x2f,
// 0x30-0x39 ('0'-'9') : DigitChar
// 0x41-0x5a ('A'-'Z') : LeadNameChars
ExtOpPrefix = 0x5b,
RootChar = '\\', // 0x5c
ParentPrefixChar = '^', // 0x5e
// 0x5f ('_') : LeadNameChars
Local0Op = 0x60,
Local1Op = 0x61,
Local2Op = 0x62,
Local3Op = 0x63,
Local4Op = 0x64,
Local5Op = 0x65,
Local6Op = 0x66,
Local7Op = 0x67,
Arg0Op = 0x68,
Arg1Op = 0x69,
Arg2Op = 0x6a,
Arg3Op = 0x6b,
Arg4Op = 0x6c,
Arg5Op = 0x6d,
Arg6Op = 0x6e,
StoreOp = 0x70,
RefOfOp = 0x71,
AddOp = 0x72,
ConcatOp = 0x73,
SubtractOp = 0x74,
IncrementOp = 0x75,
DecrementOp = 0x76,
MultiplyOp = 0x77,
DivideOp = 0x78,
ShiftLeftOp = 0x79,
ShiftRightOp = 0x7a,
AndOp = 0x7b,
NandOp = 0x7c,
OrOp = 0x7d,
NorOp = 0x7e,
XorOp = 0x7f,
NotOp = 0x80,
FindSetLeftBitOp = 0x81,
FindSetRightBitOp = 0x82,
DerefOfOp = 0x83,
ConcatResOp = 0x84,
ModOp = 0x85,
NotifyOp = 0x86,
SizeOfOp = 0x87,
IndexOp = 0x88,
MatchOp = 0x89,
CreateDWordFieldOp = 0x8a,
CreateWordFieldOp = 0x8b,
CreateByteFieldOp = 0x8c,
CreateBitFieldOp = 0x8d,
ObjectTypeOp = 0x8e,
CreateQWordFieldOp = 0x8f,
LandOp = 0x90,
LorOp = 0x91,
LnotOp = 0x92,
LequalOp = 0x93,
LgreaterOp = 0x94,
LlessOp = 0x95,
ToBufferOp = 0x96,
ToDecimalStringOp = 0x97,
ToHexStringOp = 0x98,
ToIntegerOp = 0x99,
ToStringOp = 0x9c,
CopyObjectOp = 0x9d,
MidOp = 0x9E,
ContinueOp = 0x9f,
IfOp = 0xa0,
ElseOp = 0xa1,
WhileOp = 0xa2,
NoopOp = 0xa3,
ReturnOp = 0xa4,
BreakOp = 0xa5,
BreakPointOp = 0xcc,
OnesOp = 0xff,
};
enum ExtOp { // NB: little-endian (thus 0x305b is 0x5b,0x30)
MutexOp = 0x015b, /* ExtOpPrefix 0x01 */
EventOp = 0x025b, /* ExtOpPrefix 0x02 */
CondRefOfOp = 0x125b, /* ExtOpPrefix 0x12 */
CreateFieldOp = 0x135b, /* ExtOpPrefix 0x13 */
LoadTableOp = 0x1F5b, /* ExtOpPrefix 0x1F */
LoadOp = 0x205b, /* ExtOpPrefix 0x20 */
StallOp = 0x215b, /* ExtOpPrefix 0x21 */
SleepOp = 0x225b, /* ExtOpPrefix 0x22 */
AcquireOp = 0x235b, /* ExtOpPrefix 0x23 */
SignalOp = 0x245b, /* ExtOpPrefix 0x24 */
WaitOp = 0x255b, /* ExtOpPrefix 0x25 */
ResetOp = 0x265b, /* ExtOpPrefix 0x26 */
ReleaseOp = 0x275b, /* ExtOpPrefix 0x27 */
FromBCDOp = 0x285b, /* ExtOpPrefix 0x28 */
ToBCDOp = 0x295b, /* ExtOpPrefix 0x29 */
UnloadOp = 0x2a5b, /* ExtOpPrefix 0x2a */
RevisionOp = 0x305b, /* ExtOpPrefix 0x30 */
DebugOp = 0x315b, /* ExtOpPrefix 0x31 */
FatalOp = 0x325b, /* ExtOpPrefix 0x32 */
OpRegionOp = 0x805b, /* ExtOpPrefix 0x80 */
FieldOp = 0x815b, /* ExtOpPrefix 0x81 */
DeviceOp = 0x825b, /* ExtOpPrefix 0x82 */
ProcessorOp = 0x835b, /* ExtOpPrefix 0x83 */
PowerResOp = 0x845b, /* ExtOpPrefix 0x84 */
ThermalZoneOp = 0x855b, /* ExtOpPrefix 0x85 */
IndexFieldOp = 0x865b, /* ExtOpPrefix 0x86 */
BankFieldOp = 0x875b, /* ExtOpPrefix 0x87 */
DataRegionOp = 0x885b, /* ExtOpPrefix 0x88 */
};
static Parser *s_pCurrent;
class ParseOp
{
struct ParseOpValues
{
const char * func;
int line;
int depth;
int offset;
int retval;
ParseOpValues()
{
}
ParseOpValues(const char * _func, int _line, int _depth, int _offset)
{
for (const char *psz = _func; *psz; psz++) {
if (*psz == ':') {
_func = psz + 1;
}
}
if (_func[0] == 'P' &&
_func[1] == 'a' &&
_func[2] == 'r' &&
_func[3] == 's' &&
_func[4] == 'e' &&
_func[5] != '\0') {
_func += 5;
}
func = _func;
line = _line;
depth = _depth;
offset = _offset;
retval = -1;
}
void Indent(int n)
{
if (n > 60) {
n = 60;
}
if (n > 0) {
printf("%.*s", n, " . . . . . . . . . . . . . . . . . . . . . . .");
}
}
void PrintDeep(const char *msg = "")
{
Indent(depth);
printf(" %s %d %s\n", func, offset, msg);
}
void Print()
{
printf(" > %s %d\n", func, offset);
}
void PrintValue(const char *label, char *value)
{
Indent(depth);
printf(" > %s=[%s]\n", label, value);
}
void PrintValue(const char *label, UINT32 value)
{
Indent(depth);
printf(" > %s=0x%x\n", label, value);
}
void PrintValue(const char *label, UINT64 value)
{
Indent(depth);
printf(" > %s=0x%lx\n", label, value);
}
void Return(int value)
{
retval = value;
}
};
static ParseOpValues s_rStack[128];
static int s_nStack;
static ParseOpValues s_rTrace[512];
static int s_nTrace;
public:
ParseOp(int offset, const char *func, int line)
{
if (s_nStack >= arrayof(s_rStack) - 1) {
printf("Stack Overflow (%d of %d):\n",
s_nStack, arrayof(s_rStack));
Parser::s_pCurrent->Error();
Halt();
}
s_rStack[s_nStack] = ParseOpValues(func, line, s_nStack, offset);
s_rStack[s_nStack].PrintDeep();
s_rTrace[s_nTrace] = s_rStack[s_nStack];
s_nStack++;
s_nTrace = (s_nTrace + 1) % arrayof(s_rTrace);
}
~ParseOp()
{
s_nStack--;
if (s_rStack[s_nStack].retval != 0) {
s_rStack[s_nStack].PrintDeep(" <<GOOD>>");
}
//s_rStack[s_nStack].PrintDeep(" <Return>");
}
static bool Good(int offset)
{
s_rStack[s_nStack-1].offset = offset;
s_rStack[s_nStack-1].retval = 1;
// s_rStack[s_nStack-1].PrintDeep(" <Good>");
return true;
}
static bool Fail(int offset)
{
s_rStack[s_nStack-1].offset = offset;
s_rStack[s_nStack-1].retval = 0;
// s_rStack[s_nStack-1].PrintDeep(" <Fail>");
return false;
}
static bool Pass(int offset, bool value)
{
s_rStack[s_nStack-1].offset = offset;
s_rStack[s_nStack-1].retval = value;
// s_rStack[s_nStack-1].PrintDeep(" <Fail>");
return value;
}
static void Error(int offset)
{
s_rStack[s_nStack-1].offset = offset;
s_rStack[s_nStack-1].retval = -2;
// s_rStack[s_nStack-1].PrintDeep(" <Error>");
if (s_rStack[s_nStack-1].retval != 0) {
s_rStack[s_nStack-1].PrintDeep(" <<Error>>");
}
}
static void PrintValue(const char *label, char * value)
{
s_rStack[s_nStack-1].PrintValue(label, value);
}
static void PrintValue(const char *label, int value)
{
s_rStack[s_nStack-1].PrintValue(label, (UINT32)value);
}
static void PrintValue(const char *label, UINT value)
{
s_rStack[s_nStack-1].PrintValue(label, (UINT32)value);
}
static void PrintValue(const char *label, UINT32 value)
{
s_rStack[s_nStack-1].PrintValue(label, value);
}
static void PrintValue(const char *label, UINT64 value)
{
s_rStack[s_nStack-1].PrintValue(label, value);
}
static void Dump()
{
#if 0
printf("Trace:\n");
for (int n = 0; n < arrayof(s_rTrace); n++) {
int t = (s_nTrace + n) % arrayof(s_rTrace);
if (s_rTrace[t].func != NULL) {
s_rTrace[t].PrintDeep();
}
}
#endif
printf("Stack:\n");
for (int n = 0; n < s_nStack; n++) {
s_rStack[n].Print();
}
}
};
#define PARSEOP() ParseOp _self(m_pbStream - m_pbBegin, __FUNCTION__, __LINE__)
#define PARSEVAL(label,value) _self.PrintValue(label,value)
#define PARSEVALX(label) _self.PrintValue(#label,label)
#define PARSEGOOD() _self.Good(m_pbStream - m_pbBegin)
#define PARSEFAIL() _self.Fail(m_pbStream - m_pbBegin)
#define PARSEPASS(x) _self.Pass(m_pbStream - m_pbBegin,x)
public:
Parser(UINT8 *_pbStream, UINT32 _cbStream)
{
m_pbBegin = _pbStream;
m_pbLimit = _pbStream + _cbStream;
m_pbStream = _pbStream;
s_pCurrent = this;
}
private:
UINT8 Peek() const
{
return Peek8();
}
UINT8 Peek8() const
{
return (m_pbStream < m_pbLimit) ? *m_pbStream : 0;
}
UINT16 Peek16() const
{
return (m_pbStream + 1 <= m_pbLimit) ? *((UINT16*&)m_pbStream) : 0;
}
UINT8 Pop()
{
return Pop8();
}
UINT8 Pop8()
{
return (m_pbStream + sizeof(UINT8) <= m_pbLimit) ? *((UINT8*&)m_pbStream)++ : 0;
}
UINT16 Pop16()
{
return (m_pbStream + sizeof(UINT16) <= m_pbLimit) ? *((UINT16*&)m_pbStream)++ : 0;
}
UINT32 Pop32()
{
return (m_pbStream + sizeof(UINT32) <= m_pbLimit) ? *((UINT32*&)m_pbStream)++ : 0;
}
UINT64 Pop64()
{
return (m_pbStream + sizeof(UINT64) <= m_pbLimit) ? *((UINT64*&)m_pbStream)++ : 0;
}
bool Error()
{
printf("Parsing Error.\n");
Dump(m_pbStream, m_pbLimit - m_pbStream < 16 ? m_pbLimit - m_pbStream : 16);
ParseOp::Dump();
ParseOp::Error(m_pbStream - m_pbBegin);
Halt();
return false;
}
private:
UINT8 * m_pbBegin;
UINT8 * m_pbLimit;
UINT8 * m_pbStream;
CHAR m_szName[256];
CHAR * m_pszName;
UINT32 m_cbLength;
UINT8 * m_pbPkgLimit;
//////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////
//
bool ParseNameSeg()
{
PARSEOP();
//NameSeg := <LeadNameChar NameChar NameChar NameChar>
// // Notice that NameSegs shorter than 4 characters are
// // filled with trailing '_'s.
UINT8 c = Peek();
if (!(c >= 'A' && c <= 'Z') && !(c == '_')) {
return PARSEFAIL();
}
m_pszName[0] = Pop();
for (int i = 1; i <= 3; i++) {
c = Peek();
if (!(c >= 'A' && c <= 'Z') &&
!(c >= '0' && c <= '9') &&
!(c == '_')) {
return PARSEFAIL();
}
m_pszName[i] = Pop();
}
m_pszName[4] = '\0';
// Remove trailing underscores.
for (int i = 3; i > 1 && m_pszName[i] == '_'; i--) {
m_pszName[i] = '\0';
}
while (*m_pszName != '\0') {
m_pszName++;
}
return PARSEGOOD();
}
bool CanBeNameString(UINT8 c)
{
return ((c == RootChar) ||
(c == ParentPrefixChar) ||
(c >= 'A' && c <= 'Z') ||
(c == '_') ||
(c == DualNamePrefix) ||
(c == MultiNamePrefix) ||
(c == '\0'));
}
bool ParseNameString()
{
PARSEOP();
//NameString := <RootChar NamePath> | <PrefixPath NamePath>
//PrefixPath := Nothing | <'^' PrefixPath>
//NamePath := NameSeg | DualNamePath | MultiNamePath | NullName
//DualNamePath := DualNamePrefix NameSeg NameSeg
//DualNamePrefix := 0x2e
//MultiNamePath := MultiNamePrefix SegCount NameSeg(SegCount)
//MultiNamePrefix := 0x2f
//SegCount := ByteData
m_pszName = m_szName;
m_szName[0] = '0';
UINT8 c = Peek();
if (c == RootChar || c == ParentPrefixChar) {
*m_pszName++ = Pop();
}
if ((c >= 'A' && c <= 'Z') || (c == '_')) {
if (!ParseNameSeg()) {
return Error();
}
PARSEVAL("name", m_szName);
return PARSEGOOD();
}
else if (c == DualNamePrefix) {
Pop();
if (!ParseNameSeg()) {
return Error();
}
*m_pszName++ = '.';
if (!ParseNameSeg()) {
return Error();
}
PARSEVAL("name", m_szName);
return PARSEGOOD();
}
else if (c == MultiNamePrefix) {
Pop();
for (c = Pop(); c > 0; c--) {
if (!ParseNameSeg()) {
return Error();
}
if (c > 0) {
*m_pszName++ = '.';
}
}
PARSEVAL("name", m_szName);
return PARSEGOOD();
}
else if (c == '\0') {
Pop();
*m_pszName = '\0';
PARSEVAL("name", m_szName);
return PARSEGOOD();
}
return PARSEFAIL();
}
bool ParsePkgLength()
{
PARSEOP();
//PkgLength := PkgLeadByte | <PkgLeadByte ByteData> | <PkgLeadByte ByteData ByteData> | <PkgLeadByte ByteData ByteData ByteData>
//PkgLeadByte := <bit 7-6: follow ByteData count> <bit 5-4: reserved> <bit 3-0: least significant package length byte>
// Note: The high 2 bits of the first byte reveal how
// many follow bytes are in the PkgLength. If the
// PkgLength has only one byte, bit 0 through 5 are
// used to encode the package length (in other words,
// values 0-63).
// If the package length value is more than
// 63, more than one byte must be used for the
// encoding in which case bit 5 and 4 of the
// PkgLeadByte are reserved and must be zero. If
// multiple bytes encoding is used, bits 3-0 of the
// PkgLeadByte become the least significant 4 bits
// of the resulting package length value. The next
// ByteData will become the next least significant
// 8 bits of the resulting value and so on.
m_pbPkgLimit = m_pbStream;
UINT8 c = Pop();
m_cbLength = 0;
if (c >= 0x00 && c <= 0x3f) {
m_cbLength = c;
m_pbPkgLimit += m_cbLength;
PARSEVAL("PkgLength",m_cbLength);
::Dump(m_pbStream, m_pbPkgLimit, 128);
return PARSEGOOD();
}
else if (c >= 0x40 && c <= 0x4f) {
m_cbLength = (c & 0xf);
m_cbLength |= (Pop() << 4);
m_pbPkgLimit += m_cbLength;
PARSEVAL("PkgLength",m_cbLength);
::Dump(m_pbStream, m_pbPkgLimit, 128);
return PARSEGOOD();
}
else if (c >= 0x80 && c <= 0x8f) {
m_cbLength = (c & 0xf);
m_cbLength |= (Pop() << 4);
m_cbLength |= (Pop() << 12);
m_pbPkgLimit += m_cbLength;
PARSEVAL("PkgLength",m_cbLength);
::Dump(m_pbStream, m_pbPkgLimit, 128);
return PARSEGOOD();
}
else if (c >= 0xc0 && c <= 0xcf) {
m_cbLength = (c & 0xf);
m_cbLength |= (Pop() << 4);
m_cbLength |= (Pop() << 12);
m_cbLength |= (Pop() << 20);
m_pbPkgLimit += m_cbLength;
PARSEVAL("PkgLength",m_cbLength);
::Dump(m_pbStream, m_pbPkgLimit, 128);
return PARSEGOOD();
}
return Error();
}
bool ParseSimpleName()
{
PARSEOP();
UINT8 c = Peek();
if (CanBeNameString(c)) {
return PARSEPASS(ParseNameString());
}
switch (c) {
case Arg0Op:
case Arg1Op:
case Arg2Op:
case Arg3Op:
case Arg4Op:
case Arg5Op:
case Arg6Op:
return PARSEPASS(ParseArgObj());
case Local0Op:
case Local1Op:
case Local2Op:
case Local3Op:
case Local4Op:
case Local5Op:
case Local6Op:
case Local7Op:
return PARSEPASS(ParseLocalObj());
}
return PARSEGOOD();
}
bool ParseSuperName()
{
PARSEOP();
// SimpleName
if (CanBeNameString(Peek())) { // Ambiguous
return PARSEPASS(ParseNameString());
}
switch (Peek()) {
case Arg0Op:
case Arg1Op:
case Arg2Op:
case Arg3Op:
case Arg4Op:
case Arg5Op:
case Arg6Op:
return PARSEPASS(ParseArgObj());
case Local0Op:
case Local1Op:
case Local2Op:
case Local3Op:
case Local4Op:
case Local5Op:
case Local6Op:
case Local7Op:
return PARSEPASS(ParseLocalObj());
// Type6Opcode
case RefOfOp: return PARSEPASS(ParseDefRefOf());
case DerefOfOp: return PARSEPASS(ParseDefDerefOf());
case IndexOp: return PARSEPASS(ParseDefIndex());
// DebugObj
case ExtOpPrefix:
switch (Peek16()) {
case DebugOp: Pop16(); return PARSEGOOD();
}
break;
}
// Last option of Type6Opcode
if (CanBeNameString(Peek())) { // Ambiguous
if (!ParseUserTermObj()) {
return Error();
}
return PARSEGOOD();
}
return PARSEFAIL();
}
bool ParseArgObj()
{
PARSEOP();
switch (Peek()) {
case Arg0Op:
case Arg1Op:
case Arg2Op:
case Arg3Op:
case Arg4Op:
case Arg5Op:
case Arg6Op:
Pop();
return PARSEGOOD();
}
return PARSEFAIL();
}
bool ParseLocalObj()
{
PARSEOP();
switch (Peek()) {
case Local0Op:
case Local1Op:
case Local2Op:
case Local3Op:
case Local4Op:
case Local5Op:
case Local6Op:
case Local7Op:
Pop();
return PARSEGOOD();
}
return PARSEFAIL();
}
bool ParseDDBHandleObject()
{
PARSEOP();
return ParseSuperName();
}
//////////////////////////////////////////////////////////////// Ugly!
//
bool ParseDataRefObject() //
{
PARSEOP();
if (!ParseDataObject() &&
!ParseTermArg() /*ObjectReference*/ &&
!ParseDDBHandleObject()) {
return PARSEFAIL();
}
return PARSEGOOD();
}
bool ParseDataObject() //
{
PARSEOP();
if (ParseComputationalData() ||
ParseDefPackage() ||
ParseDefVarPackage()) {
return PARSEGOOD();
}
return PARSEFAIL();
}
bool ParseTermArg() //
{
PARSEOP();
if (!ParseType2Opcode() &&
!ParseDataObject() &&
!ParseArgObj() &&
!ParseLocalObj()) {
return PARSEFAIL();
}
return PARSEGOOD();
}
bool ParseUserTermObj() //
{
PARSEOP();
// UserTermObj := NameString TermArgList
if (ParseNameString()) {
while (ParseTermArg()) {
}
return PARSEGOOD();
}
return PARSEFAIL();
}
bool ParsePackageElementList(UINT8 *pbLimit) //
{
PARSEOP();
while (m_pbStream < pbLimit) {
if (!ParseDataRefObject() &&
!ParseNameString()) {
return Error();
}
}
if (m_pbStream != pbLimit) {
return Error();
}
return PARSEGOOD();
}
bool ParseTermList(UINT8 *pbLimit) //
{
PARSEOP();
while (m_pbStream < pbLimit) {
if (!ParseNameSpaceModifierObj() &&
!ParseNamedObj() &&
!ParseType1Opcode() &&
!ParseType2Opcode()) {
return Error();
}
}
if (m_pbStream != pbLimit) {
return Error();
}
return PARSEGOOD();
}
bool ParseObjectList(UINT8 *pbLimit) //
{
PARSEOP();
while (m_pbStream < pbLimit) {
if (!ParseNameSpaceModifierObj() &&
!ParseNamedObj()) {
return Error();
}
}
if (m_pbStream != pbLimit) {
return Error();
}
return PARSEGOOD();
}
//
//////////////////////////////////////////////////////////////////////
bool ParseNameSpaceModifierObj()
{
PARSEOP();
switch (Peek()) {
case AliasOp: return ParseDefAlias();
case NameOp: return ParseDefName();
case ScopeOp: return ParseDefScope();
}
return PARSEFAIL();
}
bool ParseNamedObj()
{
PARSEOP();
switch (Peek()) {
case CreateBitFieldOp: return ParseDefCreateBitField();
case CreateByteFieldOp: return ParseDefCreateByteField();
case CreateDWordFieldOp: return ParseDefCreateDWordField();
case CreateQWordFieldOp: return ParseDefCreateQWordField();
case CreateWordFieldOp: return ParseDefCreateWordField();
case MethodOp: return ParseDefMethod();
case ExtOpPrefix:
switch (Peek16()) {
case BankFieldOp: return ParseDefBankField();
case MutexOp: return ParseDefMutex();
case CreateFieldOp: return ParseDefCreateField();
case EventOp: return ParseDefEvent();
case FieldOp: return ParseDefField();
case OpRegionOp: return ParseDefOpRegion();
case DeviceOp: return ParseDefDevice();
case ProcessorOp: return ParseDefProcessor();
case PowerResOp: return ParseDefPowerRes();
case ThermalZoneOp: return ParseDefThermalZone();
case IndexFieldOp: return ParseDefIndexField();
case DataRegionOp: return ParseDefDataRegion();
}
break;
}
return PARSEFAIL();
}
bool ParseType1Opcode()
{
PARSEOP();
switch (Peek()) {
case BreakOp: return ParseDefBreak();
case BreakPointOp: return ParseDefBreakPoint();
case ContinueOp: return ParseDefContinue();
case IfOp: return ParseDefIfElse();
case NoopOp: return ParseDefNoop();
case NotifyOp: return ParseDefNotify();
case ReturnOp: return ParseDefReturn();
case WhileOp: return ParseDefWhile();
case ExtOpPrefix:
switch (Peek16()) {
case LoadOp: return ParseDefLoad();
case StallOp: return ParseDefStall();
case SleepOp: return ParseDefSleep();
case SignalOp: return ParseDefSignal();
case ResetOp: return ParseDefReset();
case ReleaseOp: return ParseDefRelease();
case UnloadOp: return ParseDefUnload();
case FatalOp: return ParseDefFatal();
}
break;
}
return PARSEFAIL();
}
bool ParseString()
{
PARSEOP();
if (Peek() != StringPrefix) {
return PARSEFAIL();
}
Pop();
m_pszName = m_szName;
m_szName[0] = '\0';
while (Peek() != 0) {
if (Peek() >= 0x7f) {
return Error();
}
*m_pszName = Pop();
}
if (Peek() != 0) {
return Error();
}
Pop();
*m_pszName = '\0';
PARSEVAL("string", m_szName);
return PARSEGOOD();
}
bool ParseComputationalData()
{
PARSEOP();
//ComputationalData := ByteConst | WordConst | DwordConst | QwordConst | String | ConstObj | RevisionOp | DefBuffer
switch (Peek()) {
case BytePrefix: Pop(); PARSEVAL("byte", Pop8()); return PARSEGOOD();
case WordPrefix: Pop(); PARSEVAL("word", Pop16()); return PARSEGOOD();
case DWordPrefix: Pop(); PARSEVAL("dword", Pop32()); return PARSEGOOD();
case QWordPrefix: Pop(); PARSEVAL("qword", Pop64()); return PARSEGOOD();
case StringPrefix: return ParseString();
// ConstObj
case ZeroOp: Pop(); PARSEVAL("zero", 0); return PARSEGOOD();
case OneOp: Pop(); PARSEVAL("one", 1); return PARSEGOOD();
case OnesOp: Pop(); PARSEVAL("ones", 0xff); return PARSEGOOD();
case ExtOpPrefix:
switch (Peek16()) {
case RevisionOp: Pop16(); return PARSEGOOD();
}
break;
case BufferOp: return ParseDefBuffer();
}
return PARSEFAIL();
}
bool ParseTermArgInteger()
{
PARSEOP();
if (!ParseTermArg()) {
return PARSEFAIL();
}
// TermArg=>Integer
return PARSEGOOD();
}
bool ParseTermArgBuffer()
{
PARSEOP();
if (!ParseTermArg()) {
return PARSEFAIL();
}
// TermArg=>Buffer
return PARSEGOOD();
}
bool ParseTermArgDataRefObject()
{
PARSEOP();
if (!ParseTermArg()) {
return PARSEFAIL();
}
// TermArg=>DataRefObject
return PARSEGOOD();
}
bool ParseTermArgByteData()
{
PARSEOP();
if (!ParseTermArg()) {
return PARSEFAIL();
}
// TermArg=>ByteData
return PARSEGOOD();
}
bool ParseTermArgComputationalData()
{
PARSEOP();
if (!ParseTermArg()) {
return PARSEFAIL();
}
// TermArg=>ComputationalData
return PARSEGOOD();
}
bool ParseType2Opcode()
{
PARSEOP();
UINT8 c = Peek();
switch (c) {
case AddOp: return ParseDefAdd();
case AndOp: return ParseDefAnd();
case BufferOp: return ParseDefBuffer();
case ConcatOp: return ParseDefConcat();
case ConcatResOp: return ParseDefConcatRes();
case CopyObjectOp: return ParseDefCopyObject();
case DecrementOp: return ParseDefDecrement();
case DerefOfOp: return ParseDefDerefOf();
case DivideOp: return ParseDefDivide();
case FindSetLeftBitOp: return ParseDefFindSetLeftBit();
case FindSetRightBitOp: return ParseDefFindSetRightBit();
case IncrementOp: return ParseDefIncrement();
case IndexOp: return ParseDefIndex();
case LandOp: return ParseDefLAnd();
case LequalOp: return ParseDefLEqual();
case LgreaterOp: return ParseDefLGreater();
case LlessOp: return ParseDefLLess();
case MidOp: return ParseDefMid();
case LnotOp: return ParseDefLNot();
case LorOp: return ParseDefLOr();
case MatchOp: return ParseDefMatch();
case ModOp: return ParseDefMod();
case MultiplyOp: return ParseDefMultiply();
case NandOp: return ParseDefNAnd();
case NorOp: return ParseDefNOr();
case NotOp: return ParseDefNot();
case ObjectTypeOp: return ParseDefObjectType();
case OrOp: return ParseDefOr();
case PackageOp: return ParseDefPackage();
case VarPackageOp: return ParseDefVarPackage();
case RefOfOp: return ParseDefRefOf();
case ShiftLeftOp: return ParseDefShiftLeft();
case ShiftRightOp: return ParseDefShiftRight();
case SizeOfOp: return ParseDefSizeOf();
case StoreOp: return ParseDefStore();
case SubtractOp: return ParseDefSubtract();
case ToBufferOp: return ParseDefToBuffer();
case ToDecimalStringOp: return ParseDefToDecimalString();
case ToHexStringOp: return ParseDefToHexString();
case ToIntegerOp: return ParseDefToInteger();
case ToStringOp: return ParseDefToString();
case XorOp: return ParseDefXOr();
case ExtOpPrefix:
switch (Peek16()) {
case AcquireOp: return ParseDefAcquire();
case CondRefOfOp: return ParseDefCondRefOf();
case LoadTableOp: return ParseDefLoadTable();
case WaitOp: return ParseDefWait();
case FromBCDOp: return ParseDefFromBCD();
case ToBCDOp: return ParseDefToBCD();
}
break;
}
if (CanBeNameString(c)) {
if (!ParseUserTermObj()) {
return Error();
}
return PARSEGOOD();
}
return PARSEFAIL();
}
bool ParseFieldList(UINT8 *pbLimit)
{
PARSEOP();
while (m_pbStream < pbLimit) {
UINT8 c = Peek();
switch (c) {
case 0x00:
if (ParseReservedField()) {
continue;
}
break;
case 0x01:
if (ParseAccessField()) {
continue;
}
break;
}
if ((c >= 'A' && c <= 'Z') || (c == '_')) {
if (ParseNamedField()) {
continue;
}
}
break;
}
if (m_pbStream != pbLimit) {
return Error();
}
return PARSEGOOD();
}
//////////////////////////////////////////////////////////////////////////////
//
bool ParseNamedField()
{
PARSEOP();
m_pszName = m_szName;
m_szName[0] = '0';
if (!ParseNameSeg()) {
return PARSEFAIL();
}
PARSEVAL("field", m_szName);
if (!ParsePkgLength()) {
return PARSEFAIL();
}
// Skip over Pkg.
m_pbStream = m_pbPkgLimit;
return PARSEGOOD();
}
bool ParseReservedField()
{
PARSEOP();
if (Peek() != 0x00) {
return PARSEFAIL();
}
Pop();
if (!ParsePkgLength()) {
return PARSEFAIL();
}
// Skip over Pkg.
m_pbStream = m_pbPkgLimit;
return PARSEGOOD();
}
bool ParseAccessField()
{
PARSEOP();
if (Peek() != 0x01) {
return PARSEFAIL();
}
Pop();
UINT8 AccessType = Pop();
PARSEVALX(AccessType);
UINT8 AccessAttrib = Pop();
PARSEVALX(AccessAttrib);
return PARSEGOOD();
}
////////////////////////////////////////////////// Guarded and Simple.
//
// These functions are only called from functions that begin with
// a specific Opcode (i.e. by a ParseDef* function. They are also
// deterministic and don't call conditionally any subfunctions.
//
bool ParsePredicate()
{
PARSEOP();
if (!ParseTermArgInteger()) {
return PARSEFAIL();
}
// Predicate := TermArg=>Integer
return PARSEGOOD();
}
bool ParseTarget()
{
PARSEOP();
if (Peek() == NullName) {
Pop();
return PARSEGOOD();
}
if (!ParseSuperName()) {
return PARSEFAIL();
}
return PARSEGOOD();
}
bool ParseOperand()
{
PARSEOP();
if (!ParseTermArgInteger()) {
return PARSEFAIL();
}
// TermArg=>Integer
return PARSEGOOD();
}
bool ParseMutexObject() //
{
PARSEOP();
return ParseSuperName();
}
bool ParseEventObject() //
{
PARSEOP();
return ParseSuperName();
}
///////////////////////////////////////////////////// bool ParseDef*()
//
// These function all begin with a specific OpCode. They are also
// deterministic and don't call conditionally any subfunctions.
//
bool ParseDefAlias()
{
PARSEOP();
if (Peek() != AliasOp) {
return PARSEFAIL();
}
Pop();
if (!ParseNameString()) {
return Error();
}
if (!ParseNameString()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefName()
{
PARSEOP();
if (Peek() != NameOp) {
return PARSEFAIL();
}
Pop();
if (!ParseNameString()) {
return Error();
}
if (!ParseDataRefObject()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefCreateDWordField()
{
PARSEOP();
if (Peek() != CreateDWordFieldOp) {
return PARSEFAIL();
}
Pop();
if (!ParseTermArgBuffer()) {
return Error();
}
if (!ParseTermArgInteger()) {
return PARSEFAIL();
}
// ByteIndex := TermArg=>Integer
if (!ParseNameString()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefCreateQWordField()
{
PARSEOP();
if (Peek() != CreateQWordFieldOp) {
return PARSEFAIL();
}
Pop();
if (!ParseTermArgBuffer()) {
return Error();
}
if (!ParseTermArgInteger()) {
return PARSEFAIL();
}
// ByteIndex := TermArg=>Integer
if (!ParseNameString()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefCreateWordField()
{
PARSEOP();
if (Peek() != CreateWordFieldOp) {
return PARSEFAIL();
}
Pop();
if (!ParseTermArgBuffer()) {
return Error();
}
if (!ParseTermArgInteger()) {
return PARSEFAIL();
}
// ByteIndex := TermArg=>Integer
if (!ParseNameString()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefBreak()
{
PARSEOP();
if (Peek() != BreakOp) {
return PARSEFAIL();
}
Pop();
return PARSEGOOD();
}
bool ParseDefBreakPoint()
{
PARSEOP();
if (Peek() != BreakPointOp) {
return PARSEFAIL();
}
Pop();
return PARSEGOOD();
}
bool ParseDefContinue()
{
PARSEOP();
if (Peek() != ContinueOp) {
return PARSEFAIL();
}
Pop();
return PARSEGOOD();
}
bool ParseDefNoop()
{
PARSEOP();
if (Peek() != NoopOp) {
return PARSEFAIL();
}
Pop();
return PARSEGOOD();
}
bool ParseDefWhile()
{
PARSEOP();
if (Peek() != WhileOp) {
return PARSEFAIL();
}
Pop();
if (!ParsePkgLength()) {
return Error();
}
UINT8 *pbLimit = m_pbPkgLimit;
if (!ParsePredicate()) {
return Error();
}
if (!ParseTermList(pbLimit)) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefAnd()
{
PARSEOP();
if (Peek() != AndOp) {
return PARSEFAIL();
}
Pop();
if (!ParseOperand()) {
return Error();
}
if (!ParseOperand()) {
return Error();
}
if (!ParseTarget()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefCopyObject()
{
PARSEOP();
if (Peek() != CopyObjectOp) {
return PARSEFAIL();
}
Pop();
if (!ParseTermArg()) {
return Error();
}
if (!ParseSimpleName()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefDecrement()
{
PARSEOP();
if (Peek() != DecrementOp) {
return PARSEFAIL();
}
Pop();
if (!ParseSuperName()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefFindSetLeftBit()
{
PARSEOP();
if (Peek() != FindSetLeftBitOp) {
return PARSEFAIL();
}
Pop();
if (!ParseOperand()) {
return Error();
}
if (!ParseTarget()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefFindSetRightBit()
{
PARSEOP();
if (Peek() != FindSetRightBitOp) {
return PARSEFAIL();
}
Pop();
if (!ParseOperand()) {
return Error();
}
if (!ParseTarget()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefIncrement()
{
PARSEOP();
if (Peek() != IncrementOp) {
return PARSEFAIL();
}
Pop();
if (!ParseSuperName()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefLAnd()
{
PARSEOP();
if (Peek() != LandOp) {
return PARSEFAIL();
}
Pop();
if (!ParseOperand()) {
return Error();
}
if (!ParseOperand()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefLEqual()
{
PARSEOP();
if (Peek() != LequalOp) {
return PARSEFAIL();
}
Pop();
if (!ParseOperand()) {
return Error();
}
if (!ParseOperand()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefLGreater()
{
PARSEOP();
if (Peek() != LgreaterOp) {
return PARSEFAIL();
}
Pop();
if (!ParseOperand()) {
return Error();
}
if (!ParseOperand()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefLLess()
{
PARSEOP();
if (Peek() != LlessOp) {
return PARSEFAIL();
}
Pop();
if (!ParseOperand()) {
return Error();
}
if (!ParseOperand()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefLOr()
{
PARSEOP();
if (Peek() != LorOp) {
return PARSEFAIL();
}
Pop();
if (!ParseOperand()) {
return Error();
}
if (!ParseOperand()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefMod()
{
PARSEOP();
if (Peek() != ModOp) {
return PARSEFAIL();
}
Pop();
if (!ParseTermArgInteger()) {
return Error();
}
//Dividend := TermArg=>Integer
if (!ParseTermArgInteger()) {
return Error();
}
//Dividend := TermArg=>Integer
if (!ParseTarget()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefMultiply()
{
PARSEOP();
if (Peek() != MultiplyOp) {
return PARSEFAIL();
}
Pop();
if (!ParseOperand()) {
return Error();
}
if (!ParseOperand()) {
return Error();
}
if (!ParseTarget()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefNAnd()
{
PARSEOP();
if (Peek() != NandOp) {
return PARSEFAIL();
}
Pop();
if (!ParseOperand()) {
return Error();
}
if (!ParseOperand()) {
return Error();
}
if (!ParseTarget()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefNOr()
{
PARSEOP();
if (Peek() != NorOp) {
return PARSEFAIL();
}
Pop();
if (!ParseOperand()) {
return Error();
}
if (!ParseOperand()) {
return Error();
}
if (!ParseTarget()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefNot()
{
PARSEOP();
if (Peek() != NotOp) {
return PARSEFAIL();
}
Pop();
if (!ParseOperand()) {
return Error();
}
if (!ParseTarget()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefObjectType()
{
PARSEOP();
if (Peek() != ObjectTypeOp) {
return PARSEFAIL();
}
Pop();
if (!ParseSuperName()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefOr()
{
PARSEOP();
if (Peek() != OrOp) {
return PARSEFAIL();
}
Pop();
if (!ParseOperand()) {
return Error();
}
if (!ParseOperand()) {
return Error();
}
if (!ParseTarget()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefRefOf()
{
PARSEOP();
if (Peek() != RefOfOp) {
return PARSEFAIL();
}
Pop();
if (!ParseSuperName()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefShiftRight()
{
PARSEOP();
if (Peek() != ShiftRightOp) {
return PARSEFAIL();
}
Pop();
if (!ParseOperand()) {
return Error();
}
if (!ParseTermArgInteger()) {
return Error();
}
//ShiftCount := TermArg=>Integer
if (!ParseTarget()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefSizeOf()
{
PARSEOP();
if (Peek() != SizeOfOp) {
return PARSEFAIL();
}
Pop();
if (!ParseSuperName()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefStore()
{
PARSEOP();
if (Peek() != StoreOp) {
return PARSEFAIL();
}
Pop();
if (!ParseTermArg()) {
return Error();
}
if (!ParseSuperName()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefSubtract()
{
PARSEOP();
if (Peek() != SubtractOp) {
return PARSEFAIL();
}
Pop();
if (!ParseOperand()) {
return Error();
}
if (!ParseOperand()) {
return Error();
}
if (!ParseTarget()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefToBuffer()
{
PARSEOP();
if (Peek() != ToBufferOp) {
return PARSEFAIL();
}
Pop();
if (!ParseOperand()) {
return Error();
}
if (!ParseTarget()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefToDecimalString()
{
PARSEOP();
if (Peek() != ToDecimalStringOp) {
return PARSEFAIL();
}
Pop();
if (!ParseOperand()) {
return Error();
}
if (!ParseTarget()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefToHexString()
{
PARSEOP();
if (Peek() != ToHexStringOp) {
return PARSEFAIL();
}
Pop();
if (!ParseOperand()) {
return Error();
}
if (!ParseTarget()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefToInteger()
{
PARSEOP();
if (Peek() != ToIntegerOp) {
return PARSEFAIL();
}
Pop();
if (!ParseOperand()) {
return Error();
}
if (!ParseTarget()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefXOr()
{
PARSEOP();
if (Peek() != XorOp) {
return PARSEFAIL();
}
Pop();
if (!ParseOperand()) {
return Error();
}
if (!ParseOperand()) {
return Error();
}
if (!ParseTarget()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefDataRegion()
{
PARSEOP();
if (Peek16() != DataRegionOp) {
return PARSEFAIL();
}
Pop16();
if (!ParseNameString()) {
return Error();
}
if (!ParseTermArg()) {
return Error();
}
if (!ParseTermArg()) {
return Error();
}
if (!ParseTermArg()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefDevice()
{
PARSEOP();
if (Peek16() != DeviceOp) {
return PARSEFAIL();
}
Pop16();
if (!ParsePkgLength()) {
return Error();
}
UINT8 *pbLimit = m_pbPkgLimit;
if (!ParseNameString()) {
return Error();
}
if (!ParseObjectList(pbLimit)) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefEvent()
{
PARSEOP();
if (Peek16() != EventOp) {
return PARSEFAIL();
}
Pop16();
if (!ParseNameString()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefField()
{
PARSEOP();
if (Peek16() != FieldOp) {
return PARSEFAIL();
}
Pop16();
if (!ParsePkgLength()) {
return Error();
}
UINT8 *pbLimit = m_pbPkgLimit;
if (!ParseNameString()) {
return Error();
}
UINT8 FieldFlags = Pop();
PARSEVALX(FieldFlags);
if (!ParseFieldList(pbLimit)) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefIndexField()
{
PARSEOP();
if (Peek16() != IndexFieldOp) {
return PARSEFAIL();
}
Pop16();
if (!ParsePkgLength()) {
return Error();
}
UINT8 *pbLimit = m_pbPkgLimit;
if (!ParseNameString()) {
return Error();
}
if (!ParseNameString()) {
return Error();
}
UINT8 FieldFlags = Pop();
PARSEVALX(FieldFlags);
if (!ParseFieldList(pbLimit)) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefThermalZone()
{
PARSEOP();
if (Peek16() != ThermalZoneOp) {
return PARSEFAIL();
}
Pop16();
if (!ParsePkgLength()) {
return Error();
}
UINT8 *pbLimit = m_pbPkgLimit;
if (!ParseNameString()) {
return Error();
}
if (!ParseObjectList(pbLimit)) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefLoad()
{
PARSEOP();
if (Peek16() != LoadOp) {
return PARSEFAIL();
}
Pop16();
if (!ParseNameString()) {
return Error();
}
if (!ParseDDBHandleObject()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefRelease()
{
PARSEOP();
if (Peek16() != ReleaseOp) {
return PARSEFAIL();
}
Pop16();
if (!ParseMutexObject()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefReset()
{
PARSEOP();
if (Peek16() != ResetOp) {
return PARSEFAIL();
}
Pop16();
if (!ParseEventObject()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefSignal()
{
PARSEOP();
if (Peek16() != SignalOp) {
return PARSEFAIL();
}
Pop16();
if (!ParseEventObject()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefUnload()
{
PARSEOP();
if (Peek16() != UnloadOp) {
return PARSEFAIL();
}
Pop16();
if (!ParseDDBHandleObject()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefCondRefOf()
{
PARSEOP();
if (Peek16() != CondRefOfOp) {
return PARSEFAIL();
}
Pop16();
if (!ParseSuperName()) {
return Error();
}
if (!ParseTarget()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefLoadTable()
{
PARSEOP();
if (Peek16() != LoadTableOp) {
return PARSEFAIL();
}
Pop16();
if (!ParseTermArg()) {
return Error();
}
if (!ParseTermArg()) {
return Error();
}
if (!ParseTermArg()) {
return Error();
}
if (!ParseTermArg()) {
return Error();
}
if (!ParseTermArg()) {
return Error();
}
if (!ParseTermArg()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefToBCD()
{
PARSEOP();
if (Peek16() != ToBCDOp) {
return PARSEFAIL();
}
Pop16();
if (!ParseOperand()) {
return Error();
}
if (!ParseTarget()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefWait()
{
PARSEOP();
if (Peek16() != WaitOp) {
return PARSEFAIL();
}
Pop16();
if (!ParseEventObject()) {
return Error();
}
if (!ParseOperand()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefMutex()
{
PARSEOP();
if (Peek16() != MutexOp) {
return PARSEFAIL();
}
Pop16();
if (!ParseNameString()) {
return PARSEFAIL();
}
UINT8 SyncFlags = Pop();
PARSEVALX(SyncFlags);
return PARSEGOOD();
}
bool ParseDefPowerRes()
{
PARSEOP();
if (Peek16() != PowerResOp) {
return PARSEFAIL();
}
Pop16();
if (!ParsePkgLength()) {
return Error();
}
UINT8 *pbLimit = m_pbPkgLimit;
if (!ParseNameString()) {
return Error();
}
UINT8 SystemLevel = Pop();
PARSEVALX(SystemLevel);
UINT16 ResourceOrder = Pop16();
PARSEVALX(ResourceOrder);
if (!ParseObjectList(pbLimit)) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefProcessor()
{
PARSEOP();
if (Peek16() != ProcessorOp) {
return PARSEFAIL();
}
Pop16();
if (!ParsePkgLength()) {
return Error();
}
UINT8 *pbLimit = m_pbPkgLimit;
if (!ParseNameString()) {
return Error();
}
UINT8 ProcId = Pop();
PARSEVALX(ProcId);
UINT32 PblkAddr = Pop32();
PARSEVALX(PblkAddr);
UINT32 PblkLen = Pop();
PARSEVALX(PblkLen);
if (!ParseObjectList(pbLimit)) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefMethod()
{
PARSEOP();
if (Peek() != MethodOp) {
return PARSEFAIL();
}
Pop();
if (!ParsePkgLength()) {
return Error();
}
UINT8 *pbLimit = m_pbPkgLimit;
if (!ParseNameString()) {
return Error();
}
UINT8 MethodFlags = Pop();
PARSEVALX(MethodFlags);
if (!ParseTermList(pbLimit)) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefAcquire()
{
PARSEOP();
if (Peek16() != AcquireOp) {
return PARSEFAIL();
}
Pop16();
if (!ParseMutexObject()) {
return PARSEFAIL();
}
UINT16 Timeout = Pop16();
PARSEVALX(Timeout);
return PARSEGOOD();
}
bool ParseDefPackage()
{
PARSEOP();
if (Peek() != PackageOp) {
return PARSEFAIL();
}
Pop();
if (!ParsePkgLength()) {
return Error();
}
UINT8 *pbLimit = m_pbPkgLimit;
UINT8 NumElements = Pop();
PARSEVALX(NumElements);
if (!ParsePackageElementList(pbLimit)) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefVarPackage()
{
PARSEOP();
if (Peek() != VarPackageOp) {
return PARSEFAIL();
}
Pop();
if (!ParsePkgLength()) {
return Error();
}
UINT8 *pbLimit = m_pbPkgLimit;
if (!ParseTermArgInteger()) {
return Error();
}
// TermArg=>Integer;
if (!ParsePackageElementList(pbLimit)) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefCreateField()
{
PARSEOP();
if (Peek16() != CreateFieldOp) {
return PARSEFAIL();
}
Pop16();
if (!ParseTermArgBuffer()) {
return Error();
}
if (!ParseTermArgInteger()) {
return Error();
}
//BitIndex := TermArg=>Integer
if (!ParseTermArgInteger()) {
return Error();
}
//NumBits := TermArg=>Integer
if (!ParseNameString()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefSleep()
{
PARSEOP();
if (Peek16() != SleepOp) {
return PARSEFAIL();
}
Pop16();
if (!ParseTermArgInteger()) {
return Error();
}
//MsecTime := TermArg=>Integer
return PARSEGOOD();
}
bool ParseDefStall()
{
PARSEOP();
if (Peek16() != StallOp) {
return PARSEFAIL();
}
Pop16();
if (!ParseTermArgByteData()) {
return Error();
}
//UsecTime := TermArg=>ByteData
return PARSEGOOD();
}
bool ParseDefFromBCD()
{
PARSEOP();
if (Peek16() != FromBCDOp) {
return PARSEFAIL();
}
Pop16();
if (!ParseTermArgInteger()) {
return Error();
}
//BCDValue := TermArg=>Integer
if (!ParseTarget()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefShiftLeft()
{
PARSEOP();
if (Peek() != ShiftLeftOp) {
return PARSEFAIL();
}
Pop();
if (!ParseOperand()) {
return Error();
}
if (!ParseTermArgInteger()) {
return Error();
}
//ShiftCount := TermArg=>Integer
if (!ParseTarget()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefToString()
{
PARSEOP();
if (Peek() != ToStringOp) {
return PARSEFAIL();
}
Pop();
if (!ParseTermArg()) {
return Error();
}
if (!ParseTermArgInteger()) {
return Error();
}
//LengthArg := TermArg=>Integer
if (!ParseTarget()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefMid()
{
PARSEOP();
if (Peek() != MidOp) {
return PARSEFAIL();
}
Pop();
if (!ParseTermArg()) {
return Error();
}
//MidObj := TermArg=>Buffer|String
if (!ParseTermArg()) {
return Error();
}
if (!ParseTermArg()) {
return Error();
}
if (!ParseTarget()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefCreateBitField()
{
PARSEOP();
if (Peek() != CreateBitFieldOp) {
return PARSEFAIL();
}
Pop();
if (!ParseTermArgBuffer()) {
return Error();
}
//SourceBuff := TermArg=>Buffer
if (!ParseTermArgInteger()) {
return Error();
}
//BitIndex := TermArg=>Integer
if (!ParseNameString()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefCreateByteField()
{
PARSEOP();
if (Peek() != CreateByteFieldOp) {
return PARSEFAIL();
}
Pop();
if (!ParseTermArgBuffer()) {
return Error();
}
//SourceBuff := TermArg=>Buffer
if (!ParseTermArgInteger()) {
return Error();
}
//ByteIndex := TermArg=>Integer
if (!ParseNameString()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefReturn()
{
PARSEOP();
if (Peek() != ReturnOp) {
return PARSEFAIL();
}
Pop();
if (!ParseTermArg()) {
return Error();
}
//ArgObject := TermArg=>DataRefObject
return PARSEGOOD();
}
bool ParseDefAdd()
{
PARSEOP();
if (Peek() != AddOp) {
return PARSEFAIL();
}
Pop();
if (!ParseOperand()) {
return Error();
}
if (!ParseTermArgInteger()) {
return Error();
}
//Operand := TermArg=>Integer
if (!ParseTarget()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefBuffer()
{
PARSEOP();
if (Peek() != BufferOp) {
return PARSEFAIL();
}
Pop();
if (!ParsePkgLength()) {
return Error();
}
UINT8 *pbLimit = m_pbPkgLimit;
if (!ParseTermArgInteger()) {
return Error();
}
//BufferSize := TermArg=>Integer
// Skip over data.
m_pbStream = pbLimit;
return PARSEGOOD();
}
bool ParseDefConcat()
{
PARSEOP();
if (Peek() != ConcatOp) {
return PARSEFAIL();
}
Pop();
if (!ParseTermArgComputationalData()) {
return Error();
}
//Data := TermArg=>ComputationalData
if (!ParseTermArgComputationalData()) {
return Error();
}
//Data := TermArg=>ComputationalData
if (!ParseTarget()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefConcatRes()
{
PARSEOP();
if (Peek() != ConcatResOp) {
return PARSEFAIL();
}
Pop();
if (!ParseTermArgBuffer()) {
return Error();
}
//BufData := TermArg=>Buffer
if (!ParseTermArgBuffer()) {
return Error();
}
//BufData := TermArg=>Buffer
if (!ParseTarget()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefDivide()
{
PARSEOP();
if (Peek() != DivideOp) {
return PARSEFAIL();
}
Pop();
if (!ParseTermArgInteger()) {
return Error();
}
//Dividend := TermArg=>Integer
if (!ParseTermArgInteger()) {
return Error();
}
//Divisor := TermArg=>Integer
if (!ParseTarget()) {
return Error();
}
// Remainder
if (!ParseTarget()) {
return Error();
}
// Quotient
return PARSEGOOD();
}
bool ParseDefIndex()
{
PARSEOP();
if (Peek() != IndexOp) {
return PARSEFAIL();
}
Pop();
if (!ParseTermArg()) {
return Error();
}
//BuffPkgStrObj := TermArg=>Buffer, Package or String
if (!ParseTermArgInteger()) {
return Error();
}
//IndexValue := TermArg=>Integer
if (!ParseTarget()) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefDerefOf()
{
PARSEOP();
if (Peek() != DerefOfOp) {
return PARSEFAIL();
}
Pop();
if (!ParseTermArg()) {
return Error();
}
//ObjReference := TermArg=>ObjectReference|String
return PARSEGOOD();
}
bool ParseDefOpRegion()
{
PARSEOP();
if (Peek16() != OpRegionOp) {
return PARSEFAIL();
}
Pop16();
if (!ParseNameString()) {
return Error();
}
UINT RegionSpace = Pop();
PARSEVALX(RegionSpace);
if (!ParseTermArgInteger()) {
return Error();
}
//RegionOffset := TermArg=>Integer
if (!ParseTermArgInteger()) {
return Error();
}
//RegionLen := TermArg=>Integer
return PARSEGOOD();
}
bool ParseDefFatal()
{
PARSEOP();
if (Peek16() != FatalOp) {
return PARSEFAIL();
}
Pop16();
UINT8 FatalType = Pop();
PARSEVALX(FatalType);
UINT32 FatalCode = Pop32();
PARSEVALX(FatalCode);
if (!ParseTermArgInteger()) {
return Error();
}
//FatalArg := TermArg=>Integer
return PARSEGOOD();
}
bool ParseDefNotify()
{
PARSEOP();
if (Peek() != NotifyOp) {
return PARSEFAIL();
}
Pop();
if (!ParseSuperName()) {
return Error();
}
//NotifyObject := SuperName=>ThermalZone|Processor|Device
if (!ParseTermArgInteger()) {
return Error();
}
//NotifyValue := TermArg=>Integer
return PARSEGOOD();
}
bool ParseDefMatch()
{
PARSEOP();
if (Peek() != MatchOp) {
return PARSEFAIL();
}
Pop();
if (!ParseTermArg()) {
return Error();
}
//SearchPkg := TermArg=>Package
UINT8 MatchOpcode1 = Pop();
PARSEVALX(MatchOpcode1);
if (!ParseOperand()) {
return Error();
}
UINT8 MatchOpcode2 = Pop();
PARSEVALX(MatchOpcode2);
if (!ParseOperand()) {
return Error();
}
if (!ParseTermArgInteger()) {
return Error();
}
//StartIndex := TermArg=>Integer
return PARSEGOOD();
}
bool ParseDefScope()
{
PARSEOP();
if (Peek() != ScopeOp) {
return PARSEFAIL();
}
Pop();
if (!ParsePkgLength()) {
return Error();
}
UINT8* pbLimit = m_pbPkgLimit;
if (!ParseNameString()) {
return Error();
}
if (!ParseTermList(pbLimit)) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefBankField()
{
PARSEOP();
if (Peek16() != BankFieldOp) {
return PARSEFAIL();
}
Pop16();
if (!ParsePkgLength()) {
return Error();
}
UINT8 *pbLimit = m_pbPkgLimit;
if (!ParseNameString()) {
return Error();
}
if (!ParseNameString()) {
return Error();
}
if (!ParseTermArgInteger()) {
return Error();
}
// BankValue := TermArg=>Integer
UINT8 FieldFlags = Pop();
PARSEVALX(FieldFlags);
if (!ParseFieldList(pbLimit)) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefIfElse()
{
PARSEOP();
if (Peek() != IfOp) {
return PARSEFAIL();
}
if (!ParsePkgLength()) {
return Error();
}
UINT8 *pbLimit = m_pbPkgLimit;
if (!ParsePredicate()) {
return Error();
}
if (!ParseTermList(pbLimit)) {
return Error();
}
ParseDefElse();
return PARSEGOOD();
}
bool ParseDefElse()
{
PARSEOP();
if (Peek() != ElseOp) {
return PARSEFAIL();
}
Pop();
if (!ParsePkgLength()) {
return Error();
}
UINT8 *pbLimit = m_pbPkgLimit;
if (!ParseTermList(pbLimit)) {
return Error();
}
return PARSEGOOD();
}
bool ParseDefLNot()
{
PARSEOP();
if (Peek() != LnotOp) {
return PARSEFAIL();
}
Pop();
switch (Peek()) {
case LlessOp:
case LgreaterOp:
case LequalOp:
Pop();
if (!ParseOperand()) {
return Error();
}
if (!ParseOperand()) {
return Error();
}
return PARSEGOOD();
default:
if (!ParseOperand()) {
return Error();
}
return PARSEGOOD();
}
return PARSEFAIL();
}
public:
bool Parse()
{
PARSEOP();
return ParseTermList(m_pbLimit);
}
};
Parser::ParseOp::ParseOpValues Parser::ParseOp::s_rStack[128];
int Parser::ParseOp::s_nStack;
Parser::ParseOp::ParseOpValues Parser::ParseOp::s_rTrace[512];
int Parser::ParseOp::s_nTrace;
Parser *Parser::s_pCurrent = NULL;
#endif
}