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

3551 lines
100 KiB
C++

///////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//////////////////////////////////////////////////////////////////////////////
//
namespace ACPI
{
#pragma pack(push, 1)
struct GAS // Generic Address Structure
{
UINT8 SpaceId;
UINT8 RegisterBitWidth;
UINT8 RegisterBitOffset;
UINT8 AddressSize;
UINT64 Address;
const char * Space()
{
static char szBuffer[4];
switch (SpaceId) {
case 0: return "Mem";
case 1: return "I/O";
case 2: return "PCI";
case 3: return "Emb";
case 4: return "SMB";
case 0x7f: return "Fix";
default:
sprintf(szBuffer, "x%02x", SpaceId);
return szBuffer;
}
}
const char * String()
{
static char szBuffer[8][40];
static int nBuffer = 0;
char *psz = szBuffer[nBuffer++];
sprintf(psz, "[%-3.3s %02x:%02x:%04x %016lx]",
Space(),
RegisterBitWidth,
RegisterBitOffset,
AddressSize,
Address);
return psz;
}
};
struct RSDP // Root System Description Pointer
{
CHAR Signature[8];
UINT8 Checksum;
CHAR OemId[6];
UINT8 Revision;
UINT32 RsdtAddress;
UINT32 RsdtLength;
UINT64 XsdtAddress;
UINT8 ExtendedChecksum;
UINT8 Reserved[3];
};
struct SDT // Common System Description Table Header
{
CHAR Signature[4];
UINT32 Length;
UINT8 Revision;
UINT8 Checksum;
CHAR OemId[6];
CHAR OemTableId[8];
UINT32 OemRevision;
CHAR CreatorId[4];
UINT32 CreatorRevision;
bool IsValid() const
{
UINT8 checksum = 0;
PUINT8 pbData = (PUINT8)this;
PUINT8 pbLimit = pbData + Length;
while (pbData < pbLimit) {
checksum += *pbData++;
}
return (checksum == 0);
}
void Print() const
{
printf(" %c%c%c%c %5d bytes V%d "
"%c%c%c%c%c%c %c%c%c%c%c%c%c%c %4x %c%c%c%c %x %s\n",
Signature[0],
Signature[1],
Signature[2],
Signature[3],
Length,
Revision,
OemId[0],
OemId[1],
OemId[2],
OemId[3],
OemId[4],
OemId[5],
OemTableId[0],
OemTableId[1],
OemTableId[2],
OemTableId[3],
OemTableId[4],
OemTableId[5],
OemTableId[6],
OemTableId[7],
OemRevision,
CreatorId[0],
CreatorId[1],
CreatorId[2],
CreatorId[3],
CreatorRevision,
IsValid() ? "valid" : "invalid");
}
};
struct RSDT : SDT // Root System Description Table
{
UINT32 SdtAddress[1];
};
struct XSDT : SDT // Extended System Description Table
{
UINT64 SdtAddress[1];
};
struct FADT : SDT // Fixed ACPI Description Table
{
UINT32 FacsAddress;
UINT32 DsdtAddress;
UINT8 Reserved1;
UINT8 PreferredPowerProfile;
UINT16 SciInterrupt;
UINT32 SmiPort;
UINT8 SmiAcpiEnable;
UINT8 SmiAcpiDisable;
UINT8 SmiS4Bios;
UINT8 SmiProcStateControl;
UINT32 PM1aEventBlock;
UINT32 PM1bEventBlock;
UINT32 PM1aControlBlock;
UINT32 PM1bControlBlock;
UINT32 PM2ControlBlock;
UINT32 PMTimerBlock;
UINT32 GPE0Block;
UINT32 GPE1Block;
UINT8 PM1EventLength;
UINT8 PM1ControlLength;
UINT8 PM2ControlLength;
UINT8 PMTimerLength;
UINT8 GPE0Length;
UINT8 GPE1Length;
UINT8 GPE1Base;
UINT8 SmiCstChange;
UINT16 C2Milliseconds;
UINT16 C3Milliseconds;
UINT16 FlushSize;
UINT16 FlushStride;
UINT8 DutyOffset;
UINT8 DutyWidth;
UINT8 DayAlarmOffset; // See Section 4.7.2.4
UINT8 MonthAlarmOffset;
UINT8 CenturyOffset;
UINT16 IAPCBootFlags; // See Table 5-10
UINT8 Reserved2;
UINT32 Flags; // See Table 5-9
GAS ResetPort; // See Section 4.7.3.6
UINT8 ResetValue;
UINT8 Reserved3[3];
};
struct FADT3 : FADT
{
// Revision 3 or greater FADT...
UINT64 XFacsAddress;
UINT64 XDsdtAddress;
GAS XPM1aEventBlock;
GAS XPM1bEventBlock;
GAS XPM1aControlBock;
GAS XPM1bControlBock;
GAS XPM2ControlBlock;
GAS XPMTimerBlock;
GAS XGPE0Block;
GAS XGPE1Block;
};
struct FACS // Firmware ACPI Control Structure
{
CHAR Signature[4];
UINT32 Length;
UINT32 HardwareSignature;
UINT32 OSWakeVector; // NB: _far real mode address.
UINT32 GlobalLock;
UINT32 Flags; // See Table 5-12.
UINT64 XOSWakeVector; // Preferred Protected Mode vector.
UINT8 Version;
UINT8 Reserved;
};
struct DSDT : SDT // Differentiated System Description Table
{
UINT8 AmlCode[1];
};
struct SSDT : SDT // Secondary System Description Table
{
UINT8 AmlCode[1];
};
struct APIC : SDT // Multiple APIC Description Table
{
UINT32 LocalApicAddress;
UINT32 Flags;
UINT8 Structs[2];
};
struct APIC_PROC // Processor Local APIC
{
UINT8 Type; // == 0x00
UINT8 Length;
UINT8 ProcId;
UINT8 ApicId;
UINT32 Flags;
};
struct APIC_IO // I/O APIC
{
UINT8 Type; // == 0x01
UINT8 Length;
UINT8 ApicId;
UINT8 Reserved;
UINT32 Address;
UINT32 GlobalInterruptBase;
};
struct APIC_INT_OVERRIDE // Interrupt Source Override
{
UINT8 Type; // == 0x02
UINT8 Length;
UINT8 Bus;
UINT8 SrcIrq;
UINT32 GlobalInterrupt;
UINT16 Flags;
};
struct APIC_NMI_SOURCE // Non-maskable Interrupt Sources
{
UINT8 Type; // == 0x03
UINT8 Length;
UINT16 Flags;
UINT32 GlobalInterrupt;
};
struct APIC_LOCAL_NMI // Local APIC NMI
{
UINT8 Type; // == 0x04
UINT8 Length;
UINT8 ProcId;
UINT16 Flags;
UINT8 LocalIrq;
};
struct APIC_LOCAL_OVERRIDE // Local APIC Address Override
{
UINT8 Type; // == 0x05
UINT8 Length;
UINT16 Reserved;
UINT64 LocalApicAddress;
};
struct APIC_SIO // I/O SAPIC
{
UINT8 Type; // == 0x06
UINT8 Length;
UINT8 ApicId;
UINT8 Reserved;
UINT32 GlobalInterruptBase;
UINT64 Address;
};
struct APIC_SPROC // Processor Local SAPIC
{
UINT8 Type; // == 0x07
UINT8 Length;
UINT8 ProcId;
UINT8 ApicId;
UINT8 ApicEid;
UINT8 Reserved[3];
UINT32 Flags;
};
struct APIC_PMI // Platform Interrupt Sources
{
UINT8 Type; // == 0x08
UINT8 Length;
UINT16 Flags;
UINT8 InterruptType;
UINT8 ProcessorId;
UINT8 ProcessorEid;
UINT8 SapicVector;
UINT32 GlobalInterrupt;
UINT32 Reserved;
};
#pragma pack(pop)
#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
}
void Acpi(void * rsdp)
{
ACPI::RSDP *pRsdp = (ACPI::RSDP *)rsdp;
if (pRsdp->Revision >= 2) {
printf(" ACPI V%d %c%c%c%c%c%c %08x(%d) %08lx\n",
pRsdp->Revision,
pRsdp->OemId[0],
pRsdp->OemId[1],
pRsdp->OemId[2],
pRsdp->OemId[3],
pRsdp->OemId[4],
pRsdp->OemId[5],
pRsdp->RsdtAddress,
pRsdp->RsdtLength,
pRsdp->XsdtAddress);
}
else {
printf(" ACPI V%d %c%c%c%c%c%c %08x(%d)\n",
pRsdp->Revision,
pRsdp->OemId[0],
pRsdp->OemId[1],
pRsdp->OemId[2],
pRsdp->OemId[3],
pRsdp->OemId[4],
pRsdp->OemId[5],
pRsdp->RsdtAddress,
pRsdp->RsdtLength);
}
ACPI::RSDT *pRsdt = (ACPI::RSDT *)pRsdp->RsdtAddress;
if (!pRsdt->IsValid()) {
Yellow();
printf("ACPI RSDT is invalid.\n");
Halt();
}
UINT nEntries = ((pRsdt->Length - offsetof(ACPI::RSDT, SdtAddress)) / sizeof(UINT32));
//ACPI::SDT **pEntries =(ACPI::SDT **)pRsdt->SdtAddress;
UINT32 *pEntries =(UINT32 *)pRsdt->SdtAddress;
printf(" RSDT[%u]\n", nEntries);
for (UINT n = 0; n < nEntries; n++) {
// ACPI::SDT * pTable = pEntries[n];
UINT32 temp = pEntries[n];
ACPI::SDT * pTable = (ACPI::SDT *) temp;
pTable->Print();
if (!pTable->IsValid()) {
continue;
}
if (pTable->Signature[0] == 'F' &&
pTable->Signature[1] == 'A' &&
pTable->Signature[2] == 'C' &&
pTable->Signature[3] == 'P') {
ACPI::FADT *pFadt = (ACPI::FADT *)pTable;
printf(" FACS: %08x, DSDT: %08x, Profile: %d (sizeof=%d)\n",
pFadt->FacsAddress,
pFadt->DsdtAddress,
pFadt->PreferredPowerProfile,
sizeof(*pFadt));
printf(" SCI: %04x, SMI: %08x (En %02x/Di %02x/S4 %02x/PS %02x/CS %02x)\n",
pFadt->SciInterrupt,
pFadt->SmiPort,
pFadt->SmiAcpiEnable,
pFadt->SmiAcpiDisable,
pFadt->SmiS4Bios,
pFadt->SmiProcStateControl,
pFadt->SmiCstChange);
printf(" PM1 Event %08x/%08x:%02x Control %08x/%08x:%02x\n",
pFadt->PM1aEventBlock,
pFadt->PM1bEventBlock,
pFadt->PM1EventLength,
pFadt->PM1aControlBlock,
pFadt->PM1bControlBlock,
pFadt->PM1ControlLength);
printf(" PM2 Control %08x:%02x, PM Timer: %08x:%02x\n",
pFadt->PM2ControlBlock,
pFadt->PM2ControlLength,
pFadt->PMTimerBlock,
pFadt->PMTimerLength);
printf(" GP0 %08x:%02x GP1 %08x:%02x:%02x\n",
pFadt->GPE0Block,
pFadt->GPE0Length,
pFadt->GPE1Block,
pFadt->GPE1Length,
pFadt->GPE1Base);
printf(" C2: %4d, C3: %4d\n",
pFadt->C2Milliseconds,
pFadt->C3Milliseconds);
printf(" Flush: Size:%d, Stride:%d, Duty: Offset:%d, Width:%d\n",
pFadt->FlushSize,
pFadt->FlushStride,
pFadt->DutyOffset,
pFadt->DutyWidth);
printf(" Alarm: Day:%d, Month:%d, Century:%d\n",
pFadt->DayAlarmOffset,
pFadt->MonthAlarmOffset,
pFadt->CenturyOffset);
printf(" IA-PC Boot Flags: %04x", pFadt->IAPCBootFlags);
if (pFadt->IAPCBootFlags & 0x1) { printf(" Legacy"); }
if (pFadt->IAPCBootFlags & 0x2) { printf(" 8042"); }
printf("\n");
printf(" Flags: %08x", pFadt->Flags);
if (pFadt->Flags & 0x1) { printf(" WBINVD"); }
if (pFadt->Flags & 0x2) { printf(" Flush"); }
if (pFadt->Flags & 0x4) { printf(" C1"); }
if (pFadt->Flags & 0x8) { printf(" MP"); }
if (pFadt->Flags & 0x10) { printf(" noPower"); }
if (pFadt->Flags & 0x20) { printf(" noSleep"); }
if (pFadt->Flags & 0x40) { printf(" noRTC"); }
if (pFadt->Flags & 0x80) { printf(" S4"); }
if (pFadt->Flags & 0x100) { printf(" T32"); }
if (pFadt->Flags & 0x200) { printf(" Dock"); }
if (pFadt->Flags & 0x400) { printf(" Reset"); }
if (pFadt->Flags & 0x800) { printf(" Sealed"); }
if (pFadt->Flags & 0x1000) { printf(" Headless"); }
if (pFadt->Flags & 0x2000) { printf(" SwSlp"); }
printf("\n");
printf(" Reset: %s, Value:%d\n",
pFadt->ResetPort.String(),
pFadt->ResetValue);
ACPI::FACS * pFacs = (ACPI::FACS *)pFadt->FacsAddress;
if (pFacs != NULL) {
printf(" FACS: %c%c%c%c %4d bytes, V%d\n",
pFacs->Signature[0],
pFacs->Signature[1],
pFacs->Signature[2],
pFacs->Signature[3],
pFacs->Length,
pFacs->Version);
printf(" HwSign: %08x, Lock: %08x\n",
pFacs->HardwareSignature,
pFacs->GlobalLock);
printf(" OsWake: %08x, XWake: %016lx\n",
pFacs->OSWakeVector,
pFacs->XOSWakeVector);
printf(" Flags: %08x", pFacs->Flags);
if (pFacs->Flags & 0x01) { printf("S4"); }
printf("\n");
}
ACPI::DSDT * pDsdt = (ACPI::DSDT *)pFadt->DsdtAddress;
if (pDsdt != NULL) {
pDsdt->Print();
PUINT8 pbData = pDsdt->AmlCode;
UINT cbData = pDsdt->Length - offsetof(ACPI::DSDT, AmlCode);
Dump(pbData, cbData <= 128 ? cbData : 128);
#if 0
printf("----0----\n");
ACPI::Parser parser(pbData, cbData);
printf("----1----\n");
parser.Parse();
printf("----2----\n");
#endif
}
}
if (pTable->Signature[0] == 'O' &&
pTable->Signature[1] == 'E' &&
pTable->Signature[2] == 'M' &&
pTable->Signature[3] == 'B') {
}
if (pTable->Signature[0] == 'S' &&
pTable->Signature[1] == 'S' &&
pTable->Signature[2] == 'D' &&
pTable->Signature[3] == 'T') {
ACPI::SSDT * pSsdt = (ACPI::SSDT *)pTable;
PUINT8 pbData = pSsdt->AmlCode;
UINT cbData = pSsdt->Length - offsetof(ACPI::SSDT, AmlCode);
Dump(pbData, cbData <= 128 ? cbData : 128);
#if 0
ACPI::Parser parser(pbData, cbData);
parser.Parse();
#endif
}
if (pTable->Signature[0] == 'A' &&
pTable->Signature[1] == 'P' &&
pTable->Signature[2] == 'I' &&
pTable->Signature[3] == 'C') {
ACPI::APIC * pApic = (ACPI::APIC *)pTable;
printf(" LocalApic: %08x, Flag=%08x\n",
pApic->LocalApicAddress, pApic->Flags);
UINT8 * pbBegin = pApic->Structs;
UINT8 * pbLimit = ((UINT8 *)pApic) + pApic->Length;
for (; pbBegin < pbLimit; pbBegin += pbBegin[1]) {
printf(" %4d: ", pbBegin - (UINT8 *)pApic);
switch (pbBegin[0]) {
case 0x00:
{
ACPI::APIC_PROC * p = (ACPI::APIC_PROC *)pbBegin;
printf("Proc Proc=%02x Apic=%02x Flags=%08x\n",
p->ProcId, p->ApicId, p->Flags);
break;
}
case 0x01:
{
ACPI::APIC_IO * p = (ACPI::APIC_IO *)pbBegin;
printf("I/O Apic=%02x Addr=%08x Glob=%08x\n",
p->ApicId, p->Address, p->GlobalInterruptBase);
break;
}
case 0x02:
{
ACPI::APIC_INT_OVERRIDE * p = (ACPI::APIC_INT_OVERRIDE *)pbBegin;
printf("Over Bus=%02x Irq=%02x Glob=%08x Flags=%04x\n",
p->Bus, p->SrcIrq, p->GlobalInterrupt, p->Flags);
break;
}
case 0x03:
{
ACPI::APIC_NMI_SOURCE * p = (ACPI::APIC_NMI_SOURCE *)pbBegin;
printf("NmiS Flags=%04x Glob=%08x\n",
p->Flags, p->GlobalInterrupt);
break;
}
case 0x04:
{
ACPI::APIC_LOCAL_NMI * p = (ACPI::APIC_LOCAL_NMI *)pbBegin;
printf("NmiL Proc=%02x Flags=%04x Irq=%02x\n",
p->ProcId, p->Flags, p->LocalIrq);
break;
}
case 0x05:
{
ACPI::APIC_LOCAL_OVERRIDE * p = (ACPI::APIC_LOCAL_OVERRIDE *)pbBegin;
printf("Over Addr=%016lx\n",
p->LocalApicAddress);
break;
}
default:
printf("Unknown Type: %02x\n", pbBegin[0]);
break;
}
}
}
}
}
#if 0
void main()
{
////////////////////////////////////////////////////////////// Check ACPI.
//
if (bi->AcpiRsdp32 == 0) {
Yellow();
printf("Hardware does not support ACPI.\n");
Halt();
}
Acpi(bi->AcpiRsdp32);
Halt();
}
#endif