mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-08-17 15:51:34 +00:00
board_inspector: improve readability and performance of AML parser
This patch refines the AML parser to improve its readability and performance in the following ways. 1. A Tree object now has the parts of the corresponding object being member fields. As an example, a Tree with label `DefMethod` now has members `NameString`, `MethodFlags` and `TermList`. 2. It is now possible to assign names each part of an object. The grammar is updated to assign different names to the parts with the same type in the same object. 3. Invocation to intermediate factories is now skipped. As an example, when parsing a ByteConst that acts as a ByteIndex, the original implementation invokes the following factories in sequence: ByteIndex -> TermArg -> DataObject -> ComputationalData -> ByteConst The factories TermArg, DataObject and ComputationalData does nothing but forward the parsing to the next-level factory according to the opcode of the next object. With this patch, the invocation sequence becomes: ByteIndex -> ByteConst i.e. ByteIndex directly passes to ByteConst which can parse the next opcode. Tracked-On: #6298 Signed-off-by: Junjie Mao <junjie.mao@intel.com>
This commit is contained in:
parent
d325966612
commit
3bcb3146ad
@ -57,13 +57,13 @@ class OperationFieldDecl(NamedDecl):
|
|||||||
print(f"{self.name}: {self.__class__.__name__}, {self.length} bits")
|
print(f"{self.name}: {self.__class__.__name__}, {self.length} bits")
|
||||||
|
|
||||||
class AliasDecl(NamedDecl):
|
class AliasDecl(NamedDecl):
|
||||||
def __init__(self, name, target, tree):
|
def __init__(self, name, source, tree):
|
||||||
super().__init__(name, tree)
|
super().__init__(name, tree)
|
||||||
self.name = name
|
self.name = name
|
||||||
self.target = target
|
self.source = source
|
||||||
|
|
||||||
def dump(self):
|
def dump(self):
|
||||||
print(f"{self.name}: {self.__class__.__name__}, aliasing {self.target}")
|
print(f"{self.name}: {self.__class__.__name__}, aliasing {self.source}")
|
||||||
|
|
||||||
class MethodDecl(NamedDecl):
|
class MethodDecl(NamedDecl):
|
||||||
def __init__(self, name, nargs, tree):
|
def __init__(self, name, nargs, tree):
|
||||||
|
@ -48,10 +48,10 @@ class BufferBase(Object):
|
|||||||
self.__length = length
|
self.__length = length
|
||||||
self.__fields = {} # name -> (offset, bitwidth, access_width)
|
self.__fields = {} # name -> (offset, bitwidth, access_width)
|
||||||
|
|
||||||
def read(self, norm_idx, bit_width):
|
def read(self, byte_idx, bit_width):
|
||||||
return NotImplementedError(self.__class__.__name__)
|
return NotImplementedError(self.__class__.__name__)
|
||||||
|
|
||||||
def write(self, norm_idx, value, bit_width):
|
def write(self, byte_idx, value, bit_width):
|
||||||
return NotImplementedError(self.__class__.__name__)
|
return NotImplementedError(self.__class__.__name__)
|
||||||
|
|
||||||
def create_field(self, name, offset, bitwidth, access_width):
|
def create_field(self, name, offset, bitwidth, access_width):
|
||||||
@ -69,23 +69,24 @@ class BufferBase(Object):
|
|||||||
|
|
||||||
# Bits out of byte boundary
|
# Bits out of byte boundary
|
||||||
if bit_idx % access_width > 0:
|
if bit_idx % access_width > 0:
|
||||||
norm_idx = floor(bit_idx / access_width)
|
# byte_idx shall be (access_width // 8)-byte aligned
|
||||||
|
byte_idx = (bit_idx // access_width) * (access_width // 8)
|
||||||
bit_count = (access_width - bit_idx % access_width)
|
bit_count = (access_width - bit_idx % access_width)
|
||||||
if bit_count > bit_remaining:
|
if bit_count > bit_remaining:
|
||||||
bit_count = bit_remaining
|
bit_count = bit_remaining
|
||||||
|
|
||||||
mask = self.bitmask(bit_idx % access_width + bit_count - 1, bit_idx % access_width)
|
mask = self.bitmask(bit_idx % access_width + bit_count - 1, bit_idx % access_width)
|
||||||
acc = (self.read(norm_idx, access_width) & mask) >> (bit_idx % access_width)
|
acc = (self.read(byte_idx, access_width) & mask) >> (bit_idx % access_width)
|
||||||
acc_bit_count += bit_count
|
acc_bit_count += bit_count
|
||||||
bit_idx += bit_count
|
bit_idx += bit_count
|
||||||
bit_remaining -= bit_count
|
bit_remaining -= bit_count
|
||||||
|
|
||||||
while bit_remaining > 0:
|
while bit_remaining > 0:
|
||||||
norm_idx = floor(bit_idx / access_width)
|
byte_idx = bit_idx // 8
|
||||||
bit_count = access_width if bit_remaining >= access_width else bit_remaining
|
bit_count = min(access_width, bit_remaining)
|
||||||
|
|
||||||
mask = self.bitmask(bit_count - 1, 0)
|
mask = self.bitmask(bit_count - 1, 0)
|
||||||
acc |= (self.read(norm_idx, access_width) & mask) << acc_bit_count
|
acc |= (self.read(byte_idx, access_width) & mask) << acc_bit_count
|
||||||
acc_bit_count += bit_count
|
acc_bit_count += bit_count
|
||||||
bit_idx += bit_count
|
bit_idx += bit_count
|
||||||
bit_remaining -= bit_count
|
bit_remaining -= bit_count
|
||||||
@ -100,9 +101,9 @@ class BufferBase(Object):
|
|||||||
assert offset + bitwidth <= self.__length * 8, \
|
assert offset + bitwidth <= self.__length * 8, \
|
||||||
f"Buffer overflow: attempt to access field {name} at bit {offset + bitwidth} while the buffer has only {len(self.__data) * 8} bits"
|
f"Buffer overflow: attempt to access field {name} at bit {offset + bitwidth} while the buffer has only {len(self.__data) * 8} bits"
|
||||||
|
|
||||||
# Bits out of byte boundary
|
# Bits out of access_width boundary
|
||||||
if bit_idx % access_width > 0:
|
if bit_idx % access_width > 0:
|
||||||
norm_idx = floor(bit_idx / access_width)
|
byte_idx = (bit_idx // access_width) * (access_width // 8)
|
||||||
bit_count = (access_width - bit_idx % access_width)
|
bit_count = (access_width - bit_idx % access_width)
|
||||||
if bit_count > bit_remaining:
|
if bit_count > bit_remaining:
|
||||||
bit_count = bit_remaining
|
bit_count = bit_remaining
|
||||||
@ -110,20 +111,20 @@ class BufferBase(Object):
|
|||||||
mask_of_write = self.bitmask(bit_idx % access_width + bit_count - 1, bit_idx % access_width)
|
mask_of_write = self.bitmask(bit_idx % access_width + bit_count - 1, bit_idx % access_width)
|
||||||
mask_of_keep = ((1 << access_width) - 1) - mask_of_write
|
mask_of_keep = ((1 << access_width) - 1) - mask_of_write
|
||||||
v = (value & ((1 << bit_count) - 1)) << (bit_idx % access_width)
|
v = (value & ((1 << bit_count) - 1)) << (bit_idx % access_width)
|
||||||
self.write(norm_idx, (v & mask_of_write) | (self.read(norm_idx, access_width) & mask_of_keep), access_width)
|
self.write(byte_idx, (v & mask_of_write) | (self.read(byte_idx, access_width) & mask_of_keep), access_width)
|
||||||
|
|
||||||
value >>= bit_count
|
value >>= bit_count
|
||||||
bit_idx += bit_count
|
bit_idx += bit_count
|
||||||
bit_remaining -= bit_count
|
bit_remaining -= bit_count
|
||||||
|
|
||||||
while bit_remaining > 0:
|
while bit_remaining > 0:
|
||||||
norm_idx = floor(bit_idx / access_width)
|
byte_idx = bit_idx // 8
|
||||||
bit_count = access_width if bit_remaining >= access_width else bit_remaining
|
bit_count = min(access_width, bit_remaining)
|
||||||
|
|
||||||
mask_of_write = self.bitmask(bit_count - 1, 0)
|
mask_of_write = self.bitmask(bit_count - 1, 0)
|
||||||
mask_of_keep = ((1 << access_width) - 1) - mask_of_write
|
mask_of_keep = ((1 << access_width) - 1) - mask_of_write
|
||||||
v = (value & ((1 << bit_count) - 1))
|
v = (value & ((1 << bit_count) - 1))
|
||||||
self.write(norm_idx, (v & mask_of_write) | (self.read(norm_idx, access_width) & mask_of_keep), access_width)
|
self.write(byte_idx, (v & mask_of_write) | (self.read(byte_idx, access_width) & mask_of_keep), access_width)
|
||||||
|
|
||||||
value >>= bit_count
|
value >>= bit_count
|
||||||
bit_idx += bit_count
|
bit_idx += bit_count
|
||||||
@ -142,16 +143,14 @@ class Buffer(BufferBase):
|
|||||||
def data(self):
|
def data(self):
|
||||||
return bytes(self.__data)
|
return bytes(self.__data)
|
||||||
|
|
||||||
def read(self, norm_idx, bit_width):
|
def read(self, byte_idx, bit_width):
|
||||||
acc = 0
|
acc = 0
|
||||||
byte_width = bit_width // 8
|
byte_width = min(bit_width // 8, len(self.__data) - byte_idx)
|
||||||
offset = norm_idx * byte_width
|
return int.from_bytes(self.__data[byte_idx : (byte_idx + byte_width)], sys.byteorder)
|
||||||
return int.from_bytes(self.__data[offset : (offset + byte_width)], sys.byteorder)
|
|
||||||
|
|
||||||
def write(self, norm_idx, value, bit_width):
|
def write(self, byte_idx, value, bit_width):
|
||||||
byte_width = bit_width // 8
|
byte_width = min(bit_width // 8, len(self.__data) - byte_idx)
|
||||||
offset = norm_idx * byte_width
|
self.__data[byte_idx : (byte_idx + byte_width)] = value.to_bytes(byte_width, sys.byteorder)
|
||||||
self.__data[offset : (offset + byte_width)] = value.to_bytes(byte_width, sys.byteorder)
|
|
||||||
|
|
||||||
def get(self):
|
def get(self):
|
||||||
return self.__data
|
return self.__data
|
||||||
@ -175,17 +174,15 @@ class StreamIOBuffer(BufferBase):
|
|||||||
self.__stream = stream
|
self.__stream = stream
|
||||||
self.__base = base
|
self.__base = base
|
||||||
|
|
||||||
def read(self, norm_idx, bit_width):
|
def read(self, byte_idx, bit_width):
|
||||||
byte_width = bit_width // 8
|
byte_width = bit_width // 8
|
||||||
address = norm_idx * byte_width
|
self.__stream.seek(self.__base + byte_idx)
|
||||||
self.__stream.seek(self.__base + address)
|
|
||||||
data = self.__stream.read(byte_width)
|
data = self.__stream.read(byte_width)
|
||||||
return int.from_bytes(data, sys.byteorder)
|
return int.from_bytes(data, sys.byteorder)
|
||||||
|
|
||||||
def write(self, norm_idx, value, bit_width):
|
def write(self, byte_idx, value, bit_width):
|
||||||
byte_width = bit_width // 8
|
byte_width = bit_width // 8
|
||||||
address = norm_idx * byte_width
|
self.__stream.seek(self.__base + byte_idx)
|
||||||
self.__stream.seek(self.__base + address)
|
|
||||||
self.__stream.write(value.to_bytes(byte_width, sys.byteorder))
|
self.__stream.write(value.to_bytes(byte_width, sys.byteorder))
|
||||||
|
|
||||||
class IndexedIOBuffer(BufferBase):
|
class IndexedIOBuffer(BufferBase):
|
||||||
@ -195,12 +192,12 @@ class IndexedIOBuffer(BufferBase):
|
|||||||
self.__index_register = index_register
|
self.__index_register = index_register
|
||||||
self.__data_register = data_register
|
self.__data_register = data_register
|
||||||
|
|
||||||
def read(self, norm_idx, bit_width):
|
def read(self, byte_idx, bit_width):
|
||||||
assert bit_width == 8, f"Indexed I/O buffers can only be read one byte at a time"
|
assert bit_width == 8, f"Indexed I/O buffers can only be read one byte at a time"
|
||||||
self.__index_register.set(Integer(norm_idx, 8))
|
self.__index_register.set(Integer(byte_idx, 8))
|
||||||
return self.__data_register.get()
|
return self.__data_register.get()
|
||||||
|
|
||||||
def write(self, norm_idx, value, bit_width):
|
def write(self, byte_idx, value, bit_width):
|
||||||
# Do not allow writes to indexed I/O buffer
|
# Do not allow writes to indexed I/O buffer
|
||||||
assert False, "Cannot write to indexed I/O buffers"
|
assert False, "Cannot write to indexed I/O buffers"
|
||||||
|
|
||||||
@ -273,7 +270,7 @@ class Integer(Object):
|
|||||||
class Method(Object):
|
class Method(Object):
|
||||||
def __init__(self, tree):
|
def __init__(self, tree):
|
||||||
self.tree = tree
|
self.tree = tree
|
||||||
self.name = tree.children[1].children
|
self.name = tree.children[1].value
|
||||||
self.body = tree.children[3]
|
self.body = tree.children[3]
|
||||||
|
|
||||||
class PredefinedMethod(Object):
|
class PredefinedMethod(Object):
|
||||||
|
@ -136,15 +136,15 @@ AML_DATA_REGION_OP = 0x885b
|
|||||||
|
|
||||||
AMLCode = ("DefBlockHeader", "TermObj*")
|
AMLCode = ("DefBlockHeader", "TermObj*")
|
||||||
DefBlockHeader = ("TableSignature", "TableLength", "SpecCompliance", "CheckSum", "OemID", "OemTableID", "OemRevision", "CreatorID", "CreatorRevision")
|
DefBlockHeader = ("TableSignature", "TableLength", "SpecCompliance", "CheckSum", "OemID", "OemTableID", "OemRevision", "CreatorID", "CreatorRevision")
|
||||||
TableSignature = ("DWordData",)
|
TableSignature = ["DWordData"]
|
||||||
TableLength = ("DWordData",)
|
TableLength = ["DWordData"]
|
||||||
SpecCompliance = ("ByteData",)
|
SpecCompliance = ["ByteData"]
|
||||||
CheckSum = ("ByteData",)
|
CheckSum = ["ByteData"]
|
||||||
OemID = ("TWordData",)
|
OemID = ["TWordData"]
|
||||||
OemTableID = ("QWordData",)
|
OemTableID = ["QWordData"]
|
||||||
OemRevision = ("DWordData",)
|
OemRevision = ["DWordData"]
|
||||||
CreatorID = ("DWordData",)
|
CreatorID = ["DWordData"]
|
||||||
CreatorRevision = ("DWordData",)
|
CreatorRevision = ["DWordData"]
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# 20.2.2 Name Objects Encoding
|
# 20.2.2 Name Objects Encoding
|
||||||
@ -202,7 +202,7 @@ TermArg = ["ExpressionOpcode", "DataObject", "ArgObj", "LocalObj"]
|
|||||||
|
|
||||||
NameSpaceModifierObj = ["DefAlias", "DefName", "DefScope"]
|
NameSpaceModifierObj = ["DefAlias", "DefName", "DefScope"]
|
||||||
|
|
||||||
DefAlias = (AML_ALIAS_OP, "NameString", "NameString")
|
DefAlias = (AML_ALIAS_OP, "NameString:SourceObject", "NameString:AliasObject")
|
||||||
DefName = (AML_NAME_OP, "NameString", "DataRefObject")
|
DefName = (AML_NAME_OP, "NameString", "DataRefObject")
|
||||||
DefScope = (AML_SCOPE_OP, "PkgLength", "NameString", "TermList")
|
DefScope = (AML_SCOPE_OP, "PkgLength", "NameString", "TermList")
|
||||||
|
|
||||||
@ -214,68 +214,68 @@ NamedObj = ["DefBankField", "DefCreateBitField", "DefCreateByteField", "DefCreat
|
|||||||
"DefField", "DefIndexField", "DefMethod", "DefMutex", "DefOpRegion", "DefPowerRes", "DefProcessor",
|
"DefField", "DefIndexField", "DefMethod", "DefMutex", "DefOpRegion", "DefPowerRes", "DefProcessor",
|
||||||
"DefThermalZone"]
|
"DefThermalZone"]
|
||||||
|
|
||||||
DefBankField = (AML_BANK_FIELD_OP, "PkgLength", "NameString", "NameString", "BankValue", "FieldFlags", "FieldList")
|
DefBankField = (AML_BANK_FIELD_OP, "PkgLength", "NameString:RegionName", "NameString:BankName", "BankValue", "FieldFlags", "FieldList")
|
||||||
BankValue = ("TermArg",)
|
BankValue = ["TermArg"]
|
||||||
FieldFlags = ("ByteData",)
|
FieldFlags = ["ByteData"]
|
||||||
FieldList = ("FieldElement*",)
|
FieldList = ("FieldElement*",)
|
||||||
NamedField = ("NameSeg", "FieldLength")
|
NamedField = ("NameSeg", "FieldLength")
|
||||||
ReservedField = (AML_RESERVED_FIELD_PREFIX, "FieldLength")
|
ReservedField = (AML_RESERVED_FIELD_PREFIX, "FieldLength")
|
||||||
AccessField = (AML_ACCESS_FIELD_PREFIX, "AccessType", "AccessAttrib")
|
AccessField = (AML_ACCESS_FIELD_PREFIX, "AccessType", "AccessAttrib")
|
||||||
AccessType = ("ByteData",)
|
AccessType = ["ByteData"]
|
||||||
AccessAttrib = ("ByteData",)
|
AccessAttrib = ["ByteData"]
|
||||||
ConnectFieldDef = ["NameString", "BufferData"]
|
ConnectFieldDef = ["NameString"] # FIXME: ACPI spec allows "BufferData" here but does not define what "BufferData" is
|
||||||
ConnectField = (AML_CONNECT_FIELD_PREFIX, "ConnectFieldDef")
|
ConnectField = (AML_CONNECT_FIELD_PREFIX, "ConnectFieldDef")
|
||||||
|
|
||||||
DefCreateBitField = (AML_CREATE_BIT_FIELD_OP, "SourceBuff", "BitIndex", "NameString")
|
DefCreateBitField = (AML_CREATE_BIT_FIELD_OP, "SourceBuff", "BitIndex", "NameString")
|
||||||
SourceBuff = ("TermArg",)
|
SourceBuff = ["TermArg"]
|
||||||
BitIndex = ("TermArg",)
|
BitIndex = ["TermArg"]
|
||||||
DefCreateByteField = (AML_CREATE_BYTE_FIELD_OP, "SourceBuff", "ByteIndex", "NameString")
|
DefCreateByteField = (AML_CREATE_BYTE_FIELD_OP, "SourceBuff", "ByteIndex", "NameString")
|
||||||
ByteIndex = ("TermArg",)
|
ByteIndex = ["TermArg"]
|
||||||
DefCreateDWordField = (AML_CREATE_DWORD_FIELD_OP, "SourceBuff", "ByteIndex", "NameString")
|
DefCreateDWordField = (AML_CREATE_DWORD_FIELD_OP, "SourceBuff", "ByteIndex", "NameString")
|
||||||
DefCreateField = (AML_CREATE_FIELD_OP, "SourceBuff", "BitIndex", "NumBits", "NameString")
|
DefCreateField = (AML_CREATE_FIELD_OP, "SourceBuff", "BitIndex", "NumBits", "NameString")
|
||||||
NumBits = ("TermArg",)
|
NumBits = ["TermArg"]
|
||||||
DefCreateQWordField = (AML_CREATE_QWORD_FIELD_OP, "SourceBuff", "ByteIndex", "NameString")
|
DefCreateQWordField = (AML_CREATE_QWORD_FIELD_OP, "SourceBuff", "ByteIndex", "NameString")
|
||||||
DefCreateWordField = (AML_CREATE_WORD_FIELD_OP, "SourceBuff", "ByteIndex", "NameString")
|
DefCreateWordField = (AML_CREATE_WORD_FIELD_OP, "SourceBuff", "ByteIndex", "NameString")
|
||||||
|
|
||||||
DefDataRegion = (AML_DATA_REGION_OP, "NameString", "TermArg", "TermArg", "TermArg")
|
DefDataRegion = (AML_DATA_REGION_OP, "NameString", "TermArg:Signature", "TermArg:OEMID", "TermArg:OEMTableID")
|
||||||
|
|
||||||
DefDevice = (AML_DEVICE_OP, "PkgLength", "NameString", "TermList")
|
DefDevice = (AML_DEVICE_OP, "PkgLength", "NameString", "TermList")
|
||||||
|
|
||||||
DefEvent = (AML_EVENT_OP, "NameString")
|
DefEvent = (AML_EVENT_OP, "NameString")
|
||||||
|
|
||||||
DefExternal = (AML_EXTERNAL_OP, "NameString", "ObjectType", "ArgumentCount")
|
DefExternal = (AML_EXTERNAL_OP, "NameString", "ObjectType", "ArgumentCount")
|
||||||
ObjectType = ("ByteData",)
|
ObjectType = ["ByteData"]
|
||||||
ArgumentCount = ("ByteData",)
|
ArgumentCount = ["ByteData"]
|
||||||
|
|
||||||
DefField = (AML_FIELD_OP, "PkgLength", "NameString", "FieldFlags", "FieldList")
|
DefField = (AML_FIELD_OP, "PkgLength", "NameString", "FieldFlags", "FieldList")
|
||||||
|
|
||||||
DefIndexField = (AML_INDEX_FIELD_OP, "PkgLength", "NameString", "NameString", "FieldFlags", "FieldList")
|
DefIndexField = (AML_INDEX_FIELD_OP, "PkgLength", "NameString:IndexName", "NameString:DataName", "FieldFlags", "FieldList")
|
||||||
|
|
||||||
DefMethod = (AML_METHOD_OP, "PkgLength", "NameString", "MethodFlags", "TermList")
|
DefMethod = (AML_METHOD_OP, "PkgLength", "NameString", "MethodFlags", "TermList")
|
||||||
MethodFlags = ("ByteData",)
|
MethodFlags = ["ByteData"]
|
||||||
|
|
||||||
DefMutex = (AML_MUTEX_OP, "NameString", "SyncFlags")
|
DefMutex = (AML_MUTEX_OP, "NameString", "SyncFlags")
|
||||||
SyncFlags = ("ByteData",)
|
SyncFlags = ["ByteData"]
|
||||||
|
|
||||||
DefOpRegion = (AML_REGION_OP, "NameString", "RegionSpace", "RegionOffset", "RegionLen")
|
DefOpRegion = (AML_REGION_OP, "NameString", "RegionSpace", "RegionOffset", "RegionLen")
|
||||||
RegionSpace = ("ByteData",)
|
RegionSpace = ["ByteData"]
|
||||||
RegionOffset = ("TermArg",)
|
RegionOffset = ["TermArg"]
|
||||||
RegionLen = ("TermArg",)
|
RegionLen = ["TermArg"]
|
||||||
|
|
||||||
DefPowerRes = (AML_POWER_RESOURCE_OP, "PkgLength", "NameString", "SystemLevel", "ResourceOrder", "TermList")
|
DefPowerRes = (AML_POWER_RESOURCE_OP, "PkgLength", "NameString", "SystemLevel", "ResourceOrder", "TermList")
|
||||||
SystemLevel = ("ByteData",)
|
SystemLevel = ["ByteData"]
|
||||||
ResourceOrder = ("WordData",)
|
ResourceOrder = ["WordData"]
|
||||||
|
|
||||||
DefProcessor = (AML_PROCESSOR_OP, "PkgLength", "NameString", "ProcID", "PblkAddr", "PblkLen", "TermList")
|
DefProcessor = (AML_PROCESSOR_OP, "PkgLength", "NameString", "ProcID", "PblkAddr", "PblkLen", "TermList")
|
||||||
ProcID = ("ByteData",)
|
ProcID = ["ByteData"]
|
||||||
PblkAddr = ("DWordData",)
|
PblkAddr = ["DWordData"]
|
||||||
PblkLen = ("ByteData",)
|
PblkLen = ["ByteData"]
|
||||||
|
|
||||||
DefThermalZone = (AML_THERMAL_ZONE_OP, "PkgLength", "NameString", "TermList")
|
DefThermalZone = (AML_THERMAL_ZONE_OP, "PkgLength", "NameString", "TermList")
|
||||||
|
|
||||||
ExtendedAccessField = (AML_EXTENDED_ACCESS_FIELD_PREFIX, "AccessType", "ExtendedAccessAttrib", "AccessLength")
|
ExtendedAccessField = (AML_EXTENDED_ACCESS_FIELD_PREFIX, "AccessType", "ExtendedAccessAttrib", "AccessLength")
|
||||||
ExtendedAccessAttrib = ("ByteData",)
|
ExtendedAccessAttrib = ["ByteData"]
|
||||||
AccessLength = ("ByteData",)
|
AccessLength = ["ByteData"]
|
||||||
FieldElement = ["NamedField", "ReservedField", "AccessField", "ExtendedAccessField", "ConnectField"]
|
FieldElement = ["NamedField", "ReservedField", "AccessField", "ExtendedAccessField", "ConnectField"]
|
||||||
|
|
||||||
# 20.2.5.3 Statement Opcodes Encoding
|
# 20.2.5.3 Statement Opcodes Encoding
|
||||||
@ -293,35 +293,35 @@ DefContinue = (AML_CONTINUE_OP,)
|
|||||||
DefElse = (AML_ELSE_OP, "PkgLength", "TermList")
|
DefElse = (AML_ELSE_OP, "PkgLength", "TermList")
|
||||||
|
|
||||||
DefFatal = (AML_FATAL_OP, "FatalType", "FatalCode", "FataArg")
|
DefFatal = (AML_FATAL_OP, "FatalType", "FatalCode", "FataArg")
|
||||||
FatalType = ("ByteData",)
|
FatalType = ["ByteData"]
|
||||||
FatalCode = ("DWordData",)
|
FatalCode = ["DWordData"]
|
||||||
FatalArg = ("TermArg",)
|
FatalArg = ["TermArg"]
|
||||||
|
|
||||||
DefIfElse = (AML_IF_OP, "PkgLength", "Predicate", "TermList", "DefElse?")
|
DefIfElse = (AML_IF_OP, "PkgLength", "Predicate", "TermList", "DefElse?")
|
||||||
Predicate = ("TermArg",)
|
Predicate = ["TermArg"]
|
||||||
|
|
||||||
DefNoop = (AML_NOOP_OP,)
|
DefNoop = (AML_NOOP_OP,)
|
||||||
|
|
||||||
DefNotify = (AML_NOTIFY_OP, "NotifyObject", "NotifyValue")
|
DefNotify = (AML_NOTIFY_OP, "NotifyObject", "NotifyValue")
|
||||||
NotifyObject = ("SuperName",)
|
NotifyObject = ["SuperName"]
|
||||||
NotifyValue = ("TermArg",)
|
NotifyValue = ["TermArg"]
|
||||||
|
|
||||||
DefRelease = (AML_RELEASE_OP, "MutexObject")
|
DefRelease = (AML_RELEASE_OP, "MutexObject")
|
||||||
MutexObject = ("SuperName",)
|
MutexObject = ["SuperName"]
|
||||||
|
|
||||||
DefReset = (AML_RESET_OP, "EventObject")
|
DefReset = (AML_RESET_OP, "EventObject")
|
||||||
EventObject = ("SuperName",)
|
EventObject = ["SuperName"]
|
||||||
|
|
||||||
DefReturn = (AML_RETURN_OP, "ArgObject")
|
DefReturn = (AML_RETURN_OP, "ArgObject")
|
||||||
ArgObject = ("TermArg",)
|
ArgObject = ["TermArg"]
|
||||||
|
|
||||||
DefSignal = (AML_SIGNAL_OP, "EventObject")
|
DefSignal = (AML_SIGNAL_OP, "EventObject")
|
||||||
|
|
||||||
DefSleep = (AML_SLEEP_OP, "MsecTime")
|
DefSleep = (AML_SLEEP_OP, "MsecTime")
|
||||||
MsecTime = ("TermArg",)
|
MsecTime = ["TermArg"]
|
||||||
|
|
||||||
DefStall = (AML_STALL_OP, "UsecTime")
|
DefStall = (AML_STALL_OP, "UsecTime")
|
||||||
UsecTime = ("TermArg",)
|
UsecTime = ["TermArg"]
|
||||||
|
|
||||||
DefUnload = (AML_UNLOAD_OP, "Target")
|
DefUnload = (AML_UNLOAD_OP, "Target")
|
||||||
|
|
||||||
@ -342,21 +342,21 @@ ExpressionOpcode = ["DefAcquire", "DefAdd", "DefAnd", "DefBuffer", "DefConcat",
|
|||||||
ReferenceTypeOpcode = ["DefRefOf", "DefDerefOf", "DefIndex"]
|
ReferenceTypeOpcode = ["DefRefOf", "DefDerefOf", "DefIndex"]
|
||||||
|
|
||||||
DefAcquire = (AML_ACQUIRE_OP, "MutexObject", "Timeout")
|
DefAcquire = (AML_ACQUIRE_OP, "MutexObject", "Timeout")
|
||||||
Timeout = ("WordData",)
|
Timeout = ["WordData"]
|
||||||
|
|
||||||
DefAdd = (AML_ADD_OP, "Operand", "Operand", "Target")
|
DefAdd = (AML_ADD_OP, "Operand:LeftOperand", "Operand:RightOperand", "Target")
|
||||||
Operand = ["TermArg"]
|
Operand = ["TermArg"]
|
||||||
|
|
||||||
DefAnd = (AML_AND_OP, "Operand", "Operand", "Target")
|
DefAnd = (AML_AND_OP, "Operand:LeftOperand", "Operand:RightOperand", "Target")
|
||||||
|
|
||||||
DefBuffer = (AML_BUFFER_OP, "PkgLength", "BufferSize", "ByteList")
|
DefBuffer = (AML_BUFFER_OP, "PkgLength", "BufferSize", "ByteList")
|
||||||
BufferSize = ("TermArg",)
|
BufferSize = ["TermArg"]
|
||||||
|
|
||||||
DefConcat = (AML_CONCAT_OP, "Data", "Data", "Target")
|
DefConcat = (AML_CONCAT_OP, "Data:Data1", "Data:Data2", "Target")
|
||||||
Data = ("TermArg",)
|
Data = ["TermArg"]
|
||||||
|
|
||||||
DefConcatRes = (AML_CONCAT_RES_OP, "BufData", "BufData", "Target")
|
DefConcatRes = (AML_CONCAT_RES_OP, "BufData:BufData1", "BufData:BufData2", "Target")
|
||||||
BufData = ("TermArg",)
|
BufData = ["TermArg"]
|
||||||
|
|
||||||
DefCondRefOf = (AML_CONDITIONAL_REF_OF_OP, "SuperName", "Target")
|
DefCondRefOf = (AML_CONDITIONAL_REF_OF_OP, "SuperName", "Target")
|
||||||
|
|
||||||
@ -365,80 +365,80 @@ DefCopyObject = (AML_COPY_OBJECT_OP, "TermArg", "SimpleName")
|
|||||||
DefDecrement = (AML_DECREMENT_OP, "SuperName")
|
DefDecrement = (AML_DECREMENT_OP, "SuperName")
|
||||||
|
|
||||||
DefDerefOf = (AML_DEREF_OF_OP, "ObjReference")
|
DefDerefOf = (AML_DEREF_OF_OP, "ObjReference")
|
||||||
ObjReference = ("TermArg",)
|
ObjReference = ["TermArg"]
|
||||||
|
|
||||||
DefDivide = (AML_DIVIDE_OP, "Dividend", "Divisor", "Remainder", "Quotient")
|
DefDivide = (AML_DIVIDE_OP, "Dividend", "Divisor", "Remainder", "Quotient")
|
||||||
Dividend = ("TermArg",)
|
Dividend = ["TermArg"]
|
||||||
Divisor = ("TermArg",)
|
Divisor = ["TermArg"]
|
||||||
Remainder = ("Target",)
|
Remainder = ["Target"]
|
||||||
Quotient = ("Target",)
|
Quotient = ["Target"]
|
||||||
|
|
||||||
DefFindSetLeftBit = (AML_FIND_SET_LEFT_BIT_OP, "Operand", "Target")
|
DefFindSetLeftBit = (AML_FIND_SET_LEFT_BIT_OP, "Operand", "Target")
|
||||||
DefFindSetRightBit = (AML_FIND_SET_RIGHT_BIT_OP, "Operand", "Target")
|
DefFindSetRightBit = (AML_FIND_SET_RIGHT_BIT_OP, "Operand", "Target")
|
||||||
|
|
||||||
DefFromBCD = (AML_FROM_BCD_OP, "BCDValue", "Target")
|
DefFromBCD = (AML_FROM_BCD_OP, "BCDValue", "Target")
|
||||||
BCDValue = ("TermArg",)
|
BCDValue = ["TermArg"]
|
||||||
|
|
||||||
DefIncrement = (AML_INCREMENT_OP, "SuperName")
|
DefIncrement = (AML_INCREMENT_OP, "SuperName")
|
||||||
|
|
||||||
DefIndex = (AML_INDEX_OP, "BuffPkgStrObj", "IndexValue", "Target")
|
DefIndex = (AML_INDEX_OP, "BuffPkgStrObj", "IndexValue", "Target")
|
||||||
BuffPkgStrObj = ("TermArg",)
|
BuffPkgStrObj = ["TermArg"]
|
||||||
IndexValue = ("TermArg",)
|
IndexValue = ["TermArg"]
|
||||||
|
|
||||||
DefLAnd = (AML_LAND_OP, "Operand", "Operand")
|
DefLAnd = (AML_LAND_OP, "Operand:LeftOperand", "Operand:RightOperand")
|
||||||
DefLEqual = (AML_LEQUAL_OP, "Operand", "Operand")
|
DefLEqual = (AML_LEQUAL_OP, "Operand:LeftOperand", "Operand:RightOperand")
|
||||||
DefLGreater = (AML_LGREATER_OP, "Operand", "Operand")
|
DefLGreater = (AML_LGREATER_OP, "Operand:LeftOperand", "Operand:RightOperand")
|
||||||
# DefLGreaterEqual is equivalent to (AML_LNOT_OP, DefLLess)
|
# DefLGreaterEqual is equivalent to (AML_LNOT_OP, DefLLess)
|
||||||
DefLLess = (AML_LLESS_OP, "Operand", "Operand")
|
DefLLess = (AML_LLESS_OP, "Operand:LeftOperand", "Operand:RightOperand")
|
||||||
# DefLLessEqual is equivalent to (AML_LNOT_OP, DefLGreater)
|
# DefLLessEqual is equivalent to (AML_LNOT_OP, DefLGreater)
|
||||||
DefLNot = (AML_LNOT_OP, "Operand")
|
DefLNot = (AML_LNOT_OP, "Operand")
|
||||||
# DefLNotEqual is equivalent to (AML_LNOT_OP, DefLEqual)
|
# DefLNotEqual is equivalent to (AML_LNOT_OP, DefLEqual)
|
||||||
|
|
||||||
DefLoad = (AML_LOAD_OP, "NameString", "Target")
|
DefLoad = (AML_LOAD_OP, "NameString", "Target")
|
||||||
|
|
||||||
DefLoadTable = (AML_LOAD_TABLE_OP, "TermArg", "TermArg", "TermArg", "TermArg", "TermArg", "TermArg")
|
DefLoadTable = (AML_LOAD_TABLE_OP, "TermArg:Signature", "TermArg:OEMID", "TermArg:TableID", "TermArg:RootPath", "TermArg:ParameterPath", "TermArg:ParameterData")
|
||||||
|
|
||||||
DefLOr = (AML_LOR_OP, "Operand", "Operand")
|
DefLOr = (AML_LOR_OP, "Operand:LeftOperand", "Operand:RightOperand")
|
||||||
|
|
||||||
DefMatch = (AML_MATCH_OP, "SearchPkg", "MatchOpcode", "Operand", "MatchOpcode", "Operand", "StartIndex")
|
DefMatch = (AML_MATCH_OP, "SearchPkg", "MatchOpcode:MatchOpcode1", "Operand:Operand1", "MatchOpcode:MatchOpcode2", "Operand:Operand2", "StartIndex")
|
||||||
SearchPkg = ("TermArg",)
|
SearchPkg = ["TermArg"]
|
||||||
MatchOpcode = ("ByteData",)
|
MatchOpcode = ["ByteData"]
|
||||||
StartIndex = ("TermArg",)
|
StartIndex = ["TermArg"]
|
||||||
|
|
||||||
DefMid = (AML_MID_OP, "MidObj", "TermArg", "TermArg", "Target")
|
DefMid = (AML_MID_OP, "MidObj", "TermArg:Source", "TermArg:Index", "Target")
|
||||||
MidObj = ("TermArg",)
|
MidObj = ["TermArg"]
|
||||||
|
|
||||||
DefMod = (AML_MOD_OP, "Dividend", "Divisor", "Target")
|
DefMod = (AML_MOD_OP, "Dividend", "Divisor", "Target")
|
||||||
|
|
||||||
DefMultiply = (AML_MULTIPLY_OP, "Operand", "Operand", "Target")
|
DefMultiply = (AML_MULTIPLY_OP, "Operand:LeftOperand", "Operand:RightOperand", "Target")
|
||||||
|
|
||||||
DefNAnd = (AML_NAND_OP, "Operand", "Operand", "Target")
|
DefNAnd = (AML_NAND_OP, "Operand:LeftOperand", "Operand:RightOperand", "Target")
|
||||||
DefNOr = (AML_NOR_OP, "Operand", "Operand", "Target")
|
DefNOr = (AML_NOR_OP, "Operand:LeftOperand", "Operand:RightOperand", "Target")
|
||||||
DefNot = (AML_NOT_OP, "Operand", "Target")
|
DefNot = (AML_NOT_OP, "Operand", "Target")
|
||||||
|
|
||||||
DefObjectType = (AML_OBJECT_TYPE_OP, "ObjectTypeContent")
|
DefObjectType = (AML_OBJECT_TYPE_OP, "ObjectTypeContent")
|
||||||
ObjectTypeContent = ["SimpleName", "DebugObj", "DefRefof", "DefDerefof", "DefIndex"]
|
ObjectTypeContent = ["SimpleName", "DebugObj", "DefRefof", "DefDerefof", "DefIndex"]
|
||||||
|
|
||||||
DefOr = (AML_OR_OP, "Operand", "Operand", "Target")
|
DefOr = (AML_OR_OP, "Operand:LeftOperand", "Operand:RightOperand", "Target")
|
||||||
|
|
||||||
DefPackage = (AML_PACKAGE_OP, "PkgLength", "NumElements", "PackageElementList")
|
DefPackage = (AML_PACKAGE_OP, "PkgLength", "NumElements", "PackageElementList")
|
||||||
DefVarPackage = (AML_VAR_PACKAGE_OP, "PkgLength", "VarNumElements", "PackageElementList")
|
DefVarPackage = (AML_VAR_PACKAGE_OP, "PkgLength", "VarNumElements", "PackageElementList")
|
||||||
NumElements = ("ByteData",)
|
NumElements = ["ByteData"]
|
||||||
VarNumElements = ("TermArg",)
|
VarNumElements = ["TermArg"]
|
||||||
PackageElementList = ("PackageElement*",)
|
PackageElementList = ("PackageElement*",)
|
||||||
PackageElement = ["DataRefObject", "NameString"]
|
PackageElement = ["DataRefObject", "NameString"]
|
||||||
|
|
||||||
DefRefOf = (AML_REF_OF_OP, "SuperName")
|
DefRefOf = (AML_REF_OF_OP, "SuperName")
|
||||||
|
|
||||||
DefShiftLeft = (AML_SHIFT_LEFT_OP, "Operand", "ShiftCount", "Target")
|
DefShiftLeft = (AML_SHIFT_LEFT_OP, "Operand", "ShiftCount", "Target")
|
||||||
ShiftCount = ("TermArg",)
|
ShiftCount = ["TermArg"]
|
||||||
DefShiftRight = (AML_SHIFT_RIGHT_OP, "Operand", "ShiftCount", "Target")
|
DefShiftRight = (AML_SHIFT_RIGHT_OP, "Operand", "ShiftCount", "Target")
|
||||||
|
|
||||||
DefSizeOf = (AML_SIZE_OF_OP, "SuperName")
|
DefSizeOf = (AML_SIZE_OF_OP, "SuperName")
|
||||||
|
|
||||||
DefStore = (AML_STORE_OP, "TermArg", "SuperName")
|
DefStore = (AML_STORE_OP, "TermArg", "SuperName")
|
||||||
|
|
||||||
DefSubtract = (AML_SUBTRACT_OP, "Operand", "Operand", "Target")
|
DefSubtract = (AML_SUBTRACT_OP, "Operand:LeftOperand", "Operand:RightOperand", "Target")
|
||||||
|
|
||||||
DefTimer = (AML_TIMER_OP,)
|
DefTimer = (AML_TIMER_OP,)
|
||||||
|
|
||||||
@ -453,11 +453,11 @@ DefToHexString = (AML_TO_HEX_STRING_OP, "Operand", "Target")
|
|||||||
DefToInteger = (AML_TO_INTEGER_OP, "Operand", "Target")
|
DefToInteger = (AML_TO_INTEGER_OP, "Operand", "Target")
|
||||||
|
|
||||||
DefToString = (AML_TO_STRING_OP, "TermArg", "LengthArg", "Target")
|
DefToString = (AML_TO_STRING_OP, "TermArg", "LengthArg", "Target")
|
||||||
LengthArg = ("TermArg",)
|
LengthArg = ["TermArg"]
|
||||||
|
|
||||||
DefWait = (AML_WAIT_OP, "EventObject", "Operand")
|
DefWait = (AML_WAIT_OP, "EventObject", "Operand")
|
||||||
|
|
||||||
DefXOr = (AML_XOR_OP, "Operand", "Operand", "Target")
|
DefXOr = (AML_XOR_OP, "Operand:LeftOperand", "Operand:RightOperand", "Target")
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# 20.2.6 Miscellaneous Objects Encoding
|
# 20.2.6 Miscellaneous Objects Encoding
|
||||||
@ -492,3 +492,24 @@ Local7Op = (AML_LOCAL7_OP,)
|
|||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
DebugObj = (AML_DEBUG_OP,)
|
DebugObj = (AML_DEBUG_OP,)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Helper methods
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
def __get_spec(sym, fn):
|
||||||
|
spec = globals()[sym]
|
||||||
|
if isinstance(spec, tuple):
|
||||||
|
return tuple(map(fn, spec))
|
||||||
|
else:
|
||||||
|
return spec
|
||||||
|
|
||||||
|
def get_definition(sym):
|
||||||
|
def __get_definition(elem):
|
||||||
|
return elem.split(":")[0] if isinstance(elem, str) else elem
|
||||||
|
return __get_spec(sym, __get_definition)
|
||||||
|
|
||||||
|
def get_names(sym):
|
||||||
|
def __get_names(elem):
|
||||||
|
return elem.split(":")[-1] if isinstance(elem, str) else elem
|
||||||
|
return __get_spec(sym, __get_names)
|
||||||
|
@ -86,9 +86,13 @@ class ConcreteInterpreter(Interpreter):
|
|||||||
|
|
||||||
def interpret_method_call(self, name, *args):
|
def interpret_method_call(self, name, *args):
|
||||||
stack_depth_before = len(self.stack)
|
stack_depth_before = len(self.stack)
|
||||||
name_string = Tree("NameString", name)
|
name_string = Tree("NameString", [name])
|
||||||
|
name_string.register_structure(("value",))
|
||||||
|
name_string.complete_parsing()
|
||||||
name_string.scope = self.context.parent(name)
|
name_string.scope = self.context.parent(name)
|
||||||
pseudo_invocation = Tree("MethodInvocation", [name_string])
|
pseudo_invocation = Tree("MethodInvocation", [name_string])
|
||||||
|
pseudo_invocation.register_structure(("NameString", "TermArg*"))
|
||||||
|
pseudo_invocation.complete_parsing()
|
||||||
try:
|
try:
|
||||||
val = self.interpret(pseudo_invocation)
|
val = self.interpret(pseudo_invocation)
|
||||||
except:
|
except:
|
||||||
@ -118,7 +122,7 @@ class ConcreteInterpreter(Interpreter):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def NameString(self, tree):
|
def NameString(self, tree):
|
||||||
name = tree.children
|
name = tree.value
|
||||||
obj = self.context.lookup_binding(name)
|
obj = self.context.lookup_binding(name)
|
||||||
if not obj:
|
if not obj:
|
||||||
sym = self.context.lookup_symbol(name)
|
sym = self.context.lookup_symbol(name)
|
||||||
@ -133,7 +137,7 @@ class ConcreteInterpreter(Interpreter):
|
|||||||
|
|
||||||
# 20.2.3 Data Objects Encoding
|
# 20.2.3 Data Objects Encoding
|
||||||
def ByteList(self, tree):
|
def ByteList(self, tree):
|
||||||
return RawDataBuffer(tree.children)
|
return RawDataBuffer(tree.value)
|
||||||
|
|
||||||
def ByteConst(self, tree):
|
def ByteConst(self, tree):
|
||||||
return self.interpret(tree.children[0])
|
return self.interpret(tree.children[0])
|
||||||
@ -148,19 +152,19 @@ class ConcreteInterpreter(Interpreter):
|
|||||||
return self.interpret(tree.children[0])
|
return self.interpret(tree.children[0])
|
||||||
|
|
||||||
def String(self, tree):
|
def String(self, tree):
|
||||||
return String(tree.children)
|
return String(tree.value)
|
||||||
|
|
||||||
def ByteData(self, tree):
|
def ByteData(self, tree):
|
||||||
return Integer(tree.children)
|
return Integer(tree.value)
|
||||||
|
|
||||||
def WordData(self, tree):
|
def WordData(self, tree):
|
||||||
return Integer(tree.children)
|
return Integer(tree.value)
|
||||||
|
|
||||||
def DWordData(self, tree):
|
def DWordData(self, tree):
|
||||||
return Integer(tree.children)
|
return Integer(tree.value)
|
||||||
|
|
||||||
def QWordData(self, tree):
|
def QWordData(self, tree):
|
||||||
return Integer(tree.children)
|
return Integer(tree.value)
|
||||||
|
|
||||||
def ZeroOp(self, tree):
|
def ZeroOp(self, tree):
|
||||||
return Integer(0x00)
|
return Integer(0x00)
|
||||||
@ -210,7 +214,7 @@ class ConcreteInterpreter(Interpreter):
|
|||||||
return Integer(value.fn(args))
|
return Integer(value.fn(args))
|
||||||
else:
|
else:
|
||||||
assert value == None or isinstance(value, Object), \
|
assert value == None or isinstance(value, Object), \
|
||||||
f"{tree.children[0].children} evaluates to a non-object value {value}"
|
f"{tree.children[0]} evaluates to a non-object value {value}"
|
||||||
return value
|
return value
|
||||||
|
|
||||||
# 20.2.5.1 Namespace Modifier Objects Encoding
|
# 20.2.5.1 Namespace Modifier Objects Encoding
|
||||||
@ -219,7 +223,7 @@ class ConcreteInterpreter(Interpreter):
|
|||||||
|
|
||||||
def DefName(self, tree):
|
def DefName(self, tree):
|
||||||
self.context.change_scope(tree.children[0].scope)
|
self.context.change_scope(tree.children[0].scope)
|
||||||
name = tree.children[0].children
|
name = tree.children[0].value
|
||||||
obj = self.context.lookup_binding(name)
|
obj = self.context.lookup_binding(name)
|
||||||
if not obj:
|
if not obj:
|
||||||
obj = self.interpret(tree.children[1])
|
obj = self.interpret(tree.children[1])
|
||||||
@ -229,7 +233,7 @@ class ConcreteInterpreter(Interpreter):
|
|||||||
|
|
||||||
# 20.2.5.2 Named Objects Encoding
|
# 20.2.5.2 Named Objects Encoding
|
||||||
def NamedField(self, tree):
|
def NamedField(self, tree):
|
||||||
name = tree.children[0].children
|
name = tree.children[0].value
|
||||||
sym = self.context.lookup_symbol(self.context.realpath(tree.scope, name))
|
sym = self.context.lookup_symbol(self.context.realpath(tree.scope, name))
|
||||||
assert isinstance(sym, OperationFieldDecl)
|
assert isinstance(sym, OperationFieldDecl)
|
||||||
assert sym.region, f"Field {sym.name} does not belong to any operation region."
|
assert sym.region, f"Field {sym.name} does not belong to any operation region."
|
||||||
@ -253,7 +257,7 @@ class ConcreteInterpreter(Interpreter):
|
|||||||
buf = self.interpret(tree.children[0])
|
buf = self.interpret(tree.children[0])
|
||||||
assert isinstance(buf, Buffer)
|
assert isinstance(buf, Buffer)
|
||||||
index = self.interpret(tree.children[1]).get()
|
index = self.interpret(tree.children[1]).get()
|
||||||
name = tree.children[name_idx].children
|
name = tree.children[name_idx].value
|
||||||
if bitwidth == 1 or name_idx == 3:
|
if bitwidth == 1 or name_idx == 3:
|
||||||
buf.create_field(name, index, bitwidth, 8)
|
buf.create_field(name, index, bitwidth, 8)
|
||||||
else:
|
else:
|
||||||
@ -283,13 +287,13 @@ class ConcreteInterpreter(Interpreter):
|
|||||||
return self.create_field(tree, numbits, 3)
|
return self.create_field(tree, numbits, 3)
|
||||||
|
|
||||||
def DefDevice(self, tree):
|
def DefDevice(self, tree):
|
||||||
name = tree.children[1].children
|
name = tree.children[1].value
|
||||||
fullpath = self.context.realpath(tree.scope, name)
|
fullpath = self.context.realpath(tree.scope, name)
|
||||||
sym = self.context.lookup_symbol(fullpath)
|
sym = self.context.lookup_symbol(fullpath)
|
||||||
return Device(sym)
|
return Device(sym)
|
||||||
|
|
||||||
def DefExternal(self, tree):
|
def DefExternal(self, tree):
|
||||||
logging.info(f"The loaded tables do not have a definition of {tree.children[0].children}")
|
logging.info(f"The loaded tables do not have a definition of {tree.children[0].value}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def DefField(self, tree):
|
def DefField(self, tree):
|
||||||
@ -300,7 +304,7 @@ class ConcreteInterpreter(Interpreter):
|
|||||||
return Method(tree)
|
return Method(tree)
|
||||||
|
|
||||||
def DefOpRegion(self, tree):
|
def DefOpRegion(self, tree):
|
||||||
name = tree.children[0].children
|
name = tree.children[0].value
|
||||||
sym = self.context.lookup_symbol(self.context.realpath(tree.scope, name))
|
sym = self.context.lookup_symbol(self.context.realpath(tree.scope, name))
|
||||||
|
|
||||||
space = self.interpret(tree.children[1]).get()
|
space = self.interpret(tree.children[1]).get()
|
||||||
|
@ -56,7 +56,8 @@ class Factory:
|
|||||||
self.mark_end()
|
self.mark_end()
|
||||||
return tree
|
return tree
|
||||||
|
|
||||||
def opcodes(self):
|
@property
|
||||||
|
def decoder(self):
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
@ -66,17 +67,20 @@ class Factory:
|
|||||||
class NameSegFactory(Factory):
|
class NameSegFactory(Factory):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.__opcodes = []
|
self.__decoder = {}
|
||||||
for i in range(ord('A'), ord('Z') + 1):
|
for i in range(ord('A'), ord('Z') + 1):
|
||||||
self.__opcodes.append(i)
|
self.__decoder[i] = self
|
||||||
self.__opcodes.append(ord('_'))
|
self.__decoder[ord('_')] = self
|
||||||
self.label = "NameSeg"
|
self.label = "NameSeg"
|
||||||
|
|
||||||
def match(self, context, stream, tree):
|
def match(self, context, stream, tree):
|
||||||
tree.children = stream.get_fixed_length_string(4)
|
tree.register_structure(("value",))
|
||||||
|
tree.append_child(stream.get_fixed_length_string(4))
|
||||||
|
tree.complete_parsing()
|
||||||
|
|
||||||
def opcodes(self):
|
@property
|
||||||
return self.__opcodes
|
def decoder(self):
|
||||||
|
return self.__decoder
|
||||||
|
|
||||||
NameSeg = NameSegFactory()
|
NameSeg = NameSegFactory()
|
||||||
|
|
||||||
@ -84,12 +88,14 @@ class NameStringFactory(Factory):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.label = "NameString"
|
self.label = "NameString"
|
||||||
self.__opcodes = []
|
self.__decoder = {}
|
||||||
for i in range(ord('A'), ord('Z') + 1):
|
for i in range(ord('A'), ord('Z') + 1):
|
||||||
self.__opcodes.append(i)
|
self.__decoder[i] = self
|
||||||
self.__opcodes.extend([ord('_'), ord('\\'), ord('^'), grammar.AML_DUAL_NAME_PREFIX, grammar.AML_MULTI_NAME_PREFIX])
|
for i in [ord('_'), ord('\\'), ord('^'), grammar.AML_DUAL_NAME_PREFIX, grammar.AML_MULTI_NAME_PREFIX]:
|
||||||
|
self.__decoder[i] = self
|
||||||
|
|
||||||
def match(self, context, stream, tree):
|
def match(self, context, stream, tree):
|
||||||
|
tree.register_structure(("value",))
|
||||||
acc = ""
|
acc = ""
|
||||||
|
|
||||||
# Namespace prefixes
|
# Namespace prefixes
|
||||||
@ -117,10 +123,12 @@ class NameStringFactory(Factory):
|
|||||||
stream.seek(-1)
|
stream.seek(-1)
|
||||||
acc += stream.get_fixed_length_string(4)
|
acc += stream.get_fixed_length_string(4)
|
||||||
|
|
||||||
tree.children = acc
|
tree.append_child(acc)
|
||||||
|
tree.complete_parsing()
|
||||||
|
|
||||||
def opcodes(self):
|
@property
|
||||||
return self.__opcodes
|
def decoder(self):
|
||||||
|
return self.__decoder
|
||||||
|
|
||||||
NameString = NameStringFactory()
|
NameString = NameStringFactory()
|
||||||
|
|
||||||
@ -135,12 +143,11 @@ class ConstDataFactory(Factory):
|
|||||||
self.width = width
|
self.width = width
|
||||||
|
|
||||||
def match(self, context, stream, tree):
|
def match(self, context, stream, tree):
|
||||||
tree.children = stream.get_integer(self.width)
|
tree.register_structure(("value",))
|
||||||
|
tree.append_child(stream.get_integer(self.width))
|
||||||
|
tree.complete_parsing()
|
||||||
return tree
|
return tree
|
||||||
|
|
||||||
def opcodes(self):
|
|
||||||
return None
|
|
||||||
|
|
||||||
ByteData = ConstDataFactory("ByteData", 1)
|
ByteData = ConstDataFactory("ByteData", 1)
|
||||||
WordData = ConstDataFactory("WordData", 2)
|
WordData = ConstDataFactory("WordData", 2)
|
||||||
DWordData = ConstDataFactory("DWordData", 4)
|
DWordData = ConstDataFactory("DWordData", 4)
|
||||||
@ -155,11 +162,14 @@ class StringFactory(Factory):
|
|||||||
def match(self, context, stream, tree):
|
def match(self, context, stream, tree):
|
||||||
assert stream.get_opcode()[0] == grammar.AML_STRING_PREFIX
|
assert stream.get_opcode()[0] == grammar.AML_STRING_PREFIX
|
||||||
|
|
||||||
tree.children = stream.get_string()
|
tree.register_structure(("value",))
|
||||||
|
tree.append_child(stream.get_string())
|
||||||
|
tree.complete_parsing()
|
||||||
return tree
|
return tree
|
||||||
|
|
||||||
def opcodes(self):
|
@property
|
||||||
return [grammar.AML_STRING_PREFIX]
|
def decoder(self):
|
||||||
|
return {grammar.AML_STRING_PREFIX: self}
|
||||||
|
|
||||||
String = StringFactory()
|
String = StringFactory()
|
||||||
|
|
||||||
@ -169,7 +179,9 @@ class ByteListFactory(Factory):
|
|||||||
self.label = "ByteList"
|
self.label = "ByteList"
|
||||||
|
|
||||||
def match(self, context, stream, tree):
|
def match(self, context, stream, tree):
|
||||||
tree.children = stream.get_buffer()
|
tree.register_structure(("value",))
|
||||||
|
tree.append_child(stream.get_buffer())
|
||||||
|
tree.complete_parsing()
|
||||||
stream.pop_scope()
|
stream.pop_scope()
|
||||||
|
|
||||||
ByteList = ByteListFactory()
|
ByteList = ByteListFactory()
|
||||||
@ -200,10 +212,12 @@ class PkgLengthFactory(Factory):
|
|||||||
byte_count = pkg_lead_byte >> 6
|
byte_count = pkg_lead_byte >> 6
|
||||||
assert byte_count <= 3
|
assert byte_count <= 3
|
||||||
|
|
||||||
tree.children = self.get_package_length(byte_count, stream.get_integer(byte_count + 1))
|
tree.register_structure(("value",))
|
||||||
|
tree.append_child(self.get_package_length(byte_count, stream.get_integer(byte_count + 1)))
|
||||||
|
tree.complete_parsing()
|
||||||
|
|
||||||
if self.create_new_scope:
|
if self.create_new_scope:
|
||||||
remaining = tree.children - byte_count - 1
|
remaining = tree.value - byte_count - 1
|
||||||
stream.push_scope(remaining)
|
stream.push_scope(remaining)
|
||||||
tree.package_range = (stream.current, remaining)
|
tree.package_range = (stream.current, remaining)
|
||||||
return tree
|
return tree
|
||||||
@ -218,27 +232,33 @@ FieldLength = PkgLengthFactory("FieldLength", False)
|
|||||||
class MethodInvocationFactory(Factory):
|
class MethodInvocationFactory(Factory):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.__opcodes = None
|
self.__decoder = None
|
||||||
self.label = "MethodInvocation"
|
self.label = "MethodInvocation"
|
||||||
|
|
||||||
def match(self, context, stream, tree):
|
def match(self, context, stream, tree):
|
||||||
|
tree.register_structure(("NameString", "TermArg*"))
|
||||||
|
|
||||||
child_namestring = Tree()
|
child_namestring = Tree()
|
||||||
globals()["NameString"].parse(context, child_namestring)
|
globals()["NameString"].parse(context, child_namestring)
|
||||||
tree.append_child(child_namestring)
|
tree.append_child(child_namestring)
|
||||||
|
|
||||||
sym = context.lookup_symbol(child_namestring.children)
|
sym = context.lookup_symbol(child_namestring.value)
|
||||||
if isinstance(sym, (MethodDecl, PredefinedMethodDecl)):
|
if isinstance(sym, (MethodDecl, PredefinedMethodDecl)):
|
||||||
for i in range(0, sym.nargs):
|
for i in range(0, sym.nargs):
|
||||||
child_arg = Tree()
|
child_arg = Tree()
|
||||||
globals()["TermArg"].parse(context, child_arg)
|
globals()["TermArg"].parse(context, child_arg)
|
||||||
tree.append_child(child_arg)
|
tree.append_child(child_arg)
|
||||||
|
|
||||||
|
tree.complete_parsing()
|
||||||
return tree
|
return tree
|
||||||
|
|
||||||
def opcodes(self):
|
@property
|
||||||
if not self.__opcodes:
|
def decoder(self):
|
||||||
self.__opcodes = globals()["NameString"].opcodes()
|
if not self.__decoder:
|
||||||
return self.__opcodes
|
self.__decoder = {}
|
||||||
|
for k in globals()["NameString"].decoder.keys():
|
||||||
|
self.__decoder[k] = self
|
||||||
|
return self.__decoder
|
||||||
|
|
||||||
MethodInvocation = MethodInvocationFactory()
|
MethodInvocation = MethodInvocationFactory()
|
||||||
|
|
||||||
@ -250,15 +270,31 @@ class SequenceFactory(Factory):
|
|||||||
def __init__(self, label, seq):
|
def __init__(self, label, seq):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.label = label
|
self.label = label
|
||||||
|
# Some objects in ACPI AML have multiple occurrences of the same type of object in the grammar. In order to
|
||||||
|
# refer to these different occurrences, the grammar module uses the following notation to give names to each of
|
||||||
|
# them:
|
||||||
|
#
|
||||||
|
# "<object type>:<alias name>"
|
||||||
|
#
|
||||||
|
# The grammar module provides the get_definition() and get_names() methods to get the specification solely in
|
||||||
|
# object types or alias names, respectively. For objects without aliases, the type is reused as the name.
|
||||||
|
try:
|
||||||
|
self.seq = grammar.get_definition(label)
|
||||||
|
self.structure = grammar.get_names(label)
|
||||||
|
except KeyError:
|
||||||
self.seq = seq
|
self.seq = seq
|
||||||
self.__opcodes = None
|
self.structure = seq
|
||||||
|
self.__decoder = None
|
||||||
|
|
||||||
def match(self, context, stream, tree):
|
def match(self, context, stream, tree):
|
||||||
|
tree.register_structure(self.structure)
|
||||||
|
|
||||||
# When a TermList is empty, the stream has already come to the end of the current scope here. Do not attempt to
|
# When a TermList is empty, the stream has already come to the end of the current scope here. Do not attempt to
|
||||||
# peek the next opcode in such cases.
|
# peek the next opcode in such cases.
|
||||||
if stream.at_end() and \
|
if stream.at_end() and \
|
||||||
(self.seq[0][-1] in ["*", "?"]):
|
(self.seq[0][-1] in ["*", "?"]):
|
||||||
stream.pop_scope()
|
stream.pop_scope()
|
||||||
|
tree.complete_parsing()
|
||||||
return tree
|
return tree
|
||||||
|
|
||||||
opcode, opcode_width = stream.peek_opcode()
|
opcode, opcode_width = stream.peek_opcode()
|
||||||
@ -268,6 +304,7 @@ class SequenceFactory(Factory):
|
|||||||
# cleanup actions upon exceptions.
|
# cleanup actions upon exceptions.
|
||||||
to_recover_from_deferred_mode = False
|
to_recover_from_deferred_mode = False
|
||||||
to_pop_stream_scope = False
|
to_pop_stream_scope = False
|
||||||
|
completed = True
|
||||||
|
|
||||||
for i,elem in enumerate(self.seq):
|
for i,elem in enumerate(self.seq):
|
||||||
pos = stream.current
|
pos = stream.current
|
||||||
@ -288,7 +325,7 @@ class SequenceFactory(Factory):
|
|||||||
factory = globals()[elem]
|
factory = globals()[elem]
|
||||||
if not stream.at_end():
|
if not stream.at_end():
|
||||||
sub_opcode, _ = stream.peek_opcode()
|
sub_opcode, _ = stream.peek_opcode()
|
||||||
if sub_opcode in factory.opcodes():
|
if sub_opcode in factory.decoder.keys():
|
||||||
child = Tree()
|
child = Tree()
|
||||||
factory.parse(context, child)
|
factory.parse(context, child)
|
||||||
tree.append_child(child)
|
tree.append_child(child)
|
||||||
@ -312,7 +349,7 @@ class SequenceFactory(Factory):
|
|||||||
context.enter_deferred_mode()
|
context.enter_deferred_mode()
|
||||||
to_recover_from_deferred_mode = True
|
to_recover_from_deferred_mode = True
|
||||||
elif child.label == "NameString":
|
elif child.label == "NameString":
|
||||||
self.hook_named(context, tree, child.children)
|
self.hook_named(context, tree, child.value)
|
||||||
except (DecodeError, DeferLater, ScopeMismatch, UndefinedSymbol) as e:
|
except (DecodeError, DeferLater, ScopeMismatch, UndefinedSymbol) as e:
|
||||||
if to_pop_stream_scope:
|
if to_pop_stream_scope:
|
||||||
stream.pop_scope(force=True)
|
stream.pop_scope(force=True)
|
||||||
@ -321,49 +358,54 @@ class SequenceFactory(Factory):
|
|||||||
tree.context_scope = context.get_scope()
|
tree.context_scope = context.get_scope()
|
||||||
tree.factory = SequenceFactory(f"{self.label}.deferred", self.seq[i:])
|
tree.factory = SequenceFactory(f"{self.label}.deferred", self.seq[i:])
|
||||||
stream.seek(package_end, absolute=True)
|
stream.seek(package_end, absolute=True)
|
||||||
|
completed = False
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
if completed:
|
||||||
|
tree.complete_parsing()
|
||||||
|
|
||||||
if to_recover_from_deferred_mode:
|
if to_recover_from_deferred_mode:
|
||||||
context.exit_deferred_mode()
|
context.exit_deferred_mode()
|
||||||
return tree
|
return tree
|
||||||
|
|
||||||
def opcodes(self):
|
@property
|
||||||
if not self.__opcodes:
|
def decoder(self):
|
||||||
|
if not self.__decoder:
|
||||||
if isinstance(self.seq[0], int):
|
if isinstance(self.seq[0], int):
|
||||||
self.__opcodes = [self.seq[0]]
|
self.__decoder = {self.seq[0]: self}
|
||||||
else:
|
else:
|
||||||
self.__opcodes = globals()[self.seq[0]].opcodes()
|
self.__decoder = {}
|
||||||
return self.__opcodes
|
for k in globals()[self.seq[0]].decoder.keys():
|
||||||
|
self.__decoder[k] = self
|
||||||
|
return self.__decoder
|
||||||
|
|
||||||
class OptionFactory(Factory):
|
class OptionFactory(Factory):
|
||||||
def __init__(self, label, opts):
|
def __init__(self, label, opts):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.label = label
|
self.label = label
|
||||||
self.opts = opts
|
self.opts = opts
|
||||||
self.__opcodes = None
|
self.__decoder = None
|
||||||
|
|
||||||
def match(self, context, stream, tree):
|
def match(self, context, stream, tree):
|
||||||
opcode, _ = stream.peek_opcode()
|
opcode, _ = stream.peek_opcode()
|
||||||
|
try:
|
||||||
for opt in self.opts:
|
if len(self.opts) == 1:
|
||||||
factory = globals()[opt]
|
globals()[self.opts[0]].parse(context, tree)
|
||||||
matched_opcodes = factory.opcodes()
|
else:
|
||||||
if matched_opcodes is None or opcode in matched_opcodes:
|
self.decoder[opcode].parse(context, tree)
|
||||||
child = Tree()
|
|
||||||
tree.append_child(child)
|
|
||||||
factory.parse(context, child)
|
|
||||||
return tree
|
return tree
|
||||||
|
except KeyError:
|
||||||
raise DecodeError(opcode, self.label)
|
raise DecodeError(opcode, self.label)
|
||||||
|
|
||||||
def opcodes(self):
|
@property
|
||||||
if not self.__opcodes:
|
def decoder(self):
|
||||||
self.__opcodes = []
|
if not self.__decoder:
|
||||||
|
self.__decoder = {}
|
||||||
for opt in self.opts:
|
for opt in self.opts:
|
||||||
self.__opcodes.extend(globals()[opt].opcodes())
|
self.__decoder.update(globals()[opt].decoder)
|
||||||
return self.__opcodes
|
return self.__decoder
|
||||||
|
|
||||||
class DeferredExpansion(Transformer):
|
class DeferredExpansion(Transformer):
|
||||||
def __init__(self, context):
|
def __init__(self, context):
|
||||||
@ -390,6 +432,7 @@ class DeferredExpansion(Transformer):
|
|||||||
tree.children.extend(aux_tree.children)
|
tree.children.extend(aux_tree.children)
|
||||||
tree.deferred_range = None
|
tree.deferred_range = None
|
||||||
tree.factory = None
|
tree.factory = None
|
||||||
|
tree.complete_parsing()
|
||||||
except (DecodeError, DeferLater, ScopeMismatch, UndefinedSymbol) as e:
|
except (DecodeError, DeferLater, ScopeMismatch, UndefinedSymbol) as e:
|
||||||
logging.debug(f"expansion of {tree.label} at {hex(tree.deferred_range[0])} failed due to: " + str(e))
|
logging.debug(f"expansion of {tree.label} at {hex(tree.deferred_range[0])} failed due to: " + str(e))
|
||||||
|
|
||||||
@ -402,9 +445,9 @@ class DeferredExpansion(Transformer):
|
|||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
def DefAlias_hook_post(context, tree):
|
def DefAlias_hook_post(context, tree):
|
||||||
target = tree.children[0].children
|
source = tree.SourceObject.value
|
||||||
name = tree.children[1].children
|
alias = tree.AliasObject.value
|
||||||
sym = AliasDecl(name, target, tree)
|
sym = AliasDecl(alias, source, tree)
|
||||||
context.register_symbol(sym)
|
context.register_symbol(sym)
|
||||||
|
|
||||||
def DefName_hook_named(context, tree, name):
|
def DefName_hook_named(context, tree, name):
|
||||||
@ -419,32 +462,32 @@ def DefScope_hook_post(context, tree):
|
|||||||
|
|
||||||
|
|
||||||
def DefCreateBitField_hook_named(context, tree, name):
|
def DefCreateBitField_hook_named(context, tree, name):
|
||||||
name = tree.children[2].children
|
name = tree.children[2].value
|
||||||
sym = FieldDecl(name, 1, tree)
|
sym = FieldDecl(name, 1, tree)
|
||||||
context.register_symbol(sym)
|
context.register_symbol(sym)
|
||||||
|
|
||||||
def DefCreateByteField_hook_named(context, tree, name):
|
def DefCreateByteField_hook_named(context, tree, name):
|
||||||
name = tree.children[2].children
|
name = tree.children[2].value
|
||||||
sym = FieldDecl(name, 8, tree)
|
sym = FieldDecl(name, 8, tree)
|
||||||
context.register_symbol(sym)
|
context.register_symbol(sym)
|
||||||
|
|
||||||
def DefCreateDWordField_hook_named(context, tree, name):
|
def DefCreateDWordField_hook_named(context, tree, name):
|
||||||
name = tree.children[2].children
|
name = tree.children[2].value
|
||||||
sym = FieldDecl(name, 32, tree)
|
sym = FieldDecl(name, 32, tree)
|
||||||
context.register_symbol(sym)
|
context.register_symbol(sym)
|
||||||
|
|
||||||
def DefCreateField_hook_named(context, tree, name):
|
def DefCreateField_hook_named(context, tree, name):
|
||||||
name = tree.children[3].children
|
name = tree.children[3].value
|
||||||
sym = FieldDecl(name, 0, tree)
|
sym = FieldDecl(name, 0, tree)
|
||||||
context.register_symbol(sym)
|
context.register_symbol(sym)
|
||||||
|
|
||||||
def DefCreateQWordField_hook_named(context, tree, name):
|
def DefCreateQWordField_hook_named(context, tree, name):
|
||||||
name = tree.children[2].children
|
name = tree.children[2].value
|
||||||
sym = FieldDecl(name, 64, tree)
|
sym = FieldDecl(name, 64, tree)
|
||||||
context.register_symbol(sym)
|
context.register_symbol(sym)
|
||||||
|
|
||||||
def DefCreateWordField_hook_named(context, tree, name):
|
def DefCreateWordField_hook_named(context, tree, name):
|
||||||
name = tree.children[2].children
|
name = tree.children[2].value
|
||||||
sym = FieldDecl(name, 16, tree)
|
sym = FieldDecl(name, 16, tree)
|
||||||
context.register_symbol(sym)
|
context.register_symbol(sym)
|
||||||
|
|
||||||
@ -457,9 +500,9 @@ def DefDevice_hook_post(context, tree):
|
|||||||
context.pop_scope()
|
context.pop_scope()
|
||||||
|
|
||||||
def DefExternal_hook_post(context, tree):
|
def DefExternal_hook_post(context, tree):
|
||||||
name = tree.children[0].children
|
name = tree.NameString.value
|
||||||
ty = tree.children[1].children[0].children
|
ty = tree.ObjectType.value
|
||||||
nargs = tree.children[2].children[0].children
|
nargs = tree.ArgumentCount.value
|
||||||
|
|
||||||
if ty == 0x8: # an external method
|
if ty == 0x8: # an external method
|
||||||
sym = MethodDecl(name, nargs, tree)
|
sym = MethodDecl(name, nargs, tree)
|
||||||
@ -479,52 +522,50 @@ access_width_map = {
|
|||||||
|
|
||||||
def DefField_hook_post(context, tree):
|
def DefField_hook_post(context, tree):
|
||||||
# Update the fields with region & offset info
|
# Update the fields with region & offset info
|
||||||
region_name = context.lookup_symbol(tree.children[1].children).name
|
region_name = context.lookup_symbol(tree.NameString.value).name
|
||||||
flags = tree.children[2].children[0].children
|
flags = tree.FieldFlags.value
|
||||||
access_width = access_width_map[flags & 0xF]
|
access_width = access_width_map[flags & 0xF]
|
||||||
fields = tree.children[3].children
|
fields = tree.FieldList.FieldElements
|
||||||
bit_offset = 0
|
bit_offset = 0
|
||||||
for field in fields:
|
for field in fields:
|
||||||
field = field.children[0]
|
|
||||||
if field.label == "NamedField":
|
if field.label == "NamedField":
|
||||||
name = field.children[0].children
|
name = field.NameSeg.value
|
||||||
length = field.children[1].children
|
length = field.FieldLength.value
|
||||||
sym = context.lookup_symbol(name)
|
sym = context.lookup_symbol(name)
|
||||||
assert isinstance(sym, OperationFieldDecl)
|
assert isinstance(sym, OperationFieldDecl)
|
||||||
sym.set_location(region_name, bit_offset, access_width)
|
sym.set_location(region_name, bit_offset, access_width)
|
||||||
bit_offset += length
|
bit_offset += length
|
||||||
elif field.label == "ReservedField":
|
elif field.label == "ReservedField":
|
||||||
length = field.children[0].children
|
length = field.FieldLength.value
|
||||||
bit_offset += length
|
bit_offset += length
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
def DefIndexField_hook_post(context, tree):
|
def DefIndexField_hook_post(context, tree):
|
||||||
# Update the fields with region & offset info
|
# Update the fields with region & offset info
|
||||||
index_register = context.lookup_symbol(tree.children[1].children)
|
index_register = context.lookup_symbol(tree.IndexName.value)
|
||||||
data_register = context.lookup_symbol(tree.children[2].children)
|
data_register = context.lookup_symbol(tree.DataName.value)
|
||||||
flags = tree.children[3].children[0].children
|
flags = tree.FieldFlags.value
|
||||||
access_width = access_width_map[flags & 0xF]
|
access_width = access_width_map[flags & 0xF]
|
||||||
fields = tree.children[4].children
|
fields = tree.FieldList.FieldElements
|
||||||
bit_offset = 0
|
bit_offset = 0
|
||||||
for field in fields:
|
for field in fields:
|
||||||
field = field.children[0]
|
|
||||||
if field.label == "NamedField":
|
if field.label == "NamedField":
|
||||||
name = field.children[0].children
|
name = field.NameSeg.value
|
||||||
length = field.children[1].children
|
length = field.FieldLength.value
|
||||||
sym = context.lookup_symbol(name)
|
sym = context.lookup_symbol(name)
|
||||||
assert isinstance(sym, OperationFieldDecl)
|
assert isinstance(sym, OperationFieldDecl)
|
||||||
sym.set_indexed_location(index_register, data_register, bit_offset, access_width)
|
sym.set_indexed_location(index_register, data_register, bit_offset, access_width)
|
||||||
bit_offset += length
|
bit_offset += length
|
||||||
elif field.label == "ReservedField":
|
elif field.label == "ReservedField":
|
||||||
length = field.children[0].children
|
length = field.FieldLength.value
|
||||||
bit_offset += length
|
bit_offset += length
|
||||||
else:
|
else:
|
||||||
break
|
break
|
||||||
|
|
||||||
def NamedField_hook_post(context, tree):
|
def NamedField_hook_post(context, tree):
|
||||||
name = tree.children[0].children
|
name = tree.NameSeg.value
|
||||||
length = tree.children[1].children
|
length = tree.FieldLength.value
|
||||||
sym = OperationFieldDecl(name, length, tree)
|
sym = OperationFieldDecl(name, length, tree)
|
||||||
context.register_symbol(sym)
|
context.register_symbol(sym)
|
||||||
|
|
||||||
@ -534,8 +575,9 @@ def DefMethod_hook_named(context, tree, name):
|
|||||||
def DefMethod_hook_post(context, tree):
|
def DefMethod_hook_post(context, tree):
|
||||||
context.pop_scope()
|
context.pop_scope()
|
||||||
if len(tree.children) >= 3:
|
if len(tree.children) >= 3:
|
||||||
name = tree.children[1].children
|
# Parsing of the method may be deferred. Do not use named fields to access its children.
|
||||||
flags = tree.children[2].children[0].children
|
name = tree.children[1].value
|
||||||
|
flags = tree.children[2].value
|
||||||
nargs = flags & 0x7
|
nargs = flags & 0x7
|
||||||
sym = MethodDecl(name, nargs, tree)
|
sym = MethodDecl(name, nargs, tree)
|
||||||
context.register_symbol(sym)
|
context.register_symbol(sym)
|
||||||
|
@ -13,6 +13,8 @@ class Tree:
|
|||||||
self.children = copy(children)
|
self.children = copy(children)
|
||||||
self.scope = None
|
self.scope = None
|
||||||
|
|
||||||
|
self.structure = None
|
||||||
|
|
||||||
self.package_range = None
|
self.package_range = None
|
||||||
|
|
||||||
self.deferred_range = None
|
self.deferred_range = None
|
||||||
@ -22,6 +24,26 @@ class Tree:
|
|||||||
def append_child(self, child):
|
def append_child(self, child):
|
||||||
self.children.append(child)
|
self.children.append(child)
|
||||||
|
|
||||||
|
def register_structure(self, structure):
|
||||||
|
self.structure = structure
|
||||||
|
|
||||||
|
def complete_parsing(self):
|
||||||
|
i = 0
|
||||||
|
for elem in self.structure:
|
||||||
|
if isinstance(elem, str):
|
||||||
|
if elem.endswith("?"):
|
||||||
|
if i < len(self.children):
|
||||||
|
setattr(self, elem[:-1], self.children[i])
|
||||||
|
else:
|
||||||
|
setattr(self, elem[:-1], None)
|
||||||
|
break
|
||||||
|
elif elem.endswith("*"):
|
||||||
|
setattr(self, elem[:-1] + "s", self.children[i:])
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
setattr(self, elem, self.children[i])
|
||||||
|
i += 1
|
||||||
|
|
||||||
class Visitor:
|
class Visitor:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.depth = 0
|
self.depth = 0
|
||||||
@ -35,7 +57,6 @@ class Visitor:
|
|||||||
|
|
||||||
def visit_topdown(self, tree):
|
def visit_topdown(self, tree):
|
||||||
self.__visit(tree)
|
self.__visit(tree)
|
||||||
if isinstance(tree.children, list):
|
|
||||||
self.depth += 1
|
self.depth += 1
|
||||||
for child in tree.children:
|
for child in tree.children:
|
||||||
if isinstance(child, Tree):
|
if isinstance(child, Tree):
|
||||||
@ -57,7 +78,6 @@ class Transformer:
|
|||||||
|
|
||||||
def transform_topdown(self, tree):
|
def transform_topdown(self, tree):
|
||||||
new_tree = self.__transform(tree)
|
new_tree = self.__transform(tree)
|
||||||
if isinstance(new_tree.children, list):
|
|
||||||
self.depth += 1
|
self.depth += 1
|
||||||
for i, child in enumerate(tree.children):
|
for i, child in enumerate(tree.children):
|
||||||
if isinstance(child, Tree):
|
if isinstance(child, Tree):
|
||||||
@ -66,7 +86,6 @@ class Transformer:
|
|||||||
return new_tree
|
return new_tree
|
||||||
|
|
||||||
def transform_bottomup(self, tree):
|
def transform_bottomup(self, tree):
|
||||||
if isinstance(tree.children, list):
|
|
||||||
self.depth += 1
|
self.depth += 1
|
||||||
for i, child in enumerate(tree.children):
|
for i, child in enumerate(tree.children):
|
||||||
if isinstance(child, Tree):
|
if isinstance(child, Tree):
|
||||||
@ -74,28 +93,6 @@ class Transformer:
|
|||||||
self.depth -= 1
|
self.depth -= 1
|
||||||
return self.__transform(tree)
|
return self.__transform(tree)
|
||||||
|
|
||||||
single_operand_op = ["MethodInvocation"]
|
|
||||||
for sym in dir(grammar):
|
|
||||||
# Ignore builtin members and opcode constants
|
|
||||||
if sym.startswith("__") or (sym.upper() == sym):
|
|
||||||
continue
|
|
||||||
|
|
||||||
definition = getattr(grammar, sym)
|
|
||||||
if isinstance(definition, tuple) and\
|
|
||||||
isinstance(definition[0], int) and\
|
|
||||||
len(definition) == 2:
|
|
||||||
single_operand_op.append(sym)
|
|
||||||
|
|
||||||
class FlattenTransformer(Transformer):
|
|
||||||
def default(self, tree):
|
|
||||||
if tree.label not in single_operand_op and \
|
|
||||||
isinstance(tree.children, list) and \
|
|
||||||
len(tree.children) == 1 and \
|
|
||||||
not tree.deferred_range:
|
|
||||||
return tree.children[0]
|
|
||||||
else:
|
|
||||||
return tree
|
|
||||||
|
|
||||||
class Interpreter:
|
class Interpreter:
|
||||||
def __init__(self, context):
|
def __init__(self, context):
|
||||||
self.context = context
|
self.context = context
|
||||||
|
@ -13,11 +13,12 @@ class PrintLayoutVisitor(Visitor):
|
|||||||
def default(self, tree):
|
def default(self, tree):
|
||||||
indent = " " * self.depth
|
indent = " " * self.depth
|
||||||
print(f"{indent}{tree.label}", end="")
|
print(f"{indent}{tree.label}", end="")
|
||||||
if isinstance(tree.children, int):
|
if hasattr(tree, "value"):
|
||||||
print(f" = {hex(tree.children)}", end="")
|
if isinstance(tree.value, int):
|
||||||
elif isinstance(tree.children, str):
|
print(f" = {hex(tree.value)}", end="")
|
||||||
if self.__is_printable(tree.children):
|
elif isinstance(tree.value, str):
|
||||||
print(f" = '{tree.children}'", end="")
|
if self.__is_printable(tree.value):
|
||||||
|
print(f" = '{tree.value}'", end="")
|
||||||
if tree.deferred_range:
|
if tree.deferred_range:
|
||||||
print(f" (deferred at {hex(tree.deferred_range[0])}, length {hex(tree.deferred_range[1])})", end="")
|
print(f" (deferred at {hex(tree.deferred_range[0])}, length {hex(tree.deferred_range[1])})", end="")
|
||||||
if tree.factory:
|
if tree.factory:
|
||||||
@ -39,7 +40,7 @@ class ConditionallyUnregisterSymbolVisitor(Visitor):
|
|||||||
def f(tree):
|
def f(tree):
|
||||||
if self.conditionally_hidden:
|
if self.conditionally_hidden:
|
||||||
scope = tree.scope
|
scope = tree.scope
|
||||||
name = tree.children[name_string_idx].children
|
name = tree.children[name_string_idx].value
|
||||||
realpath = self.context.realpath(scope, name)
|
realpath = self.context.realpath(scope, name)
|
||||||
self.context.unregister_object(realpath)
|
self.context.unregister_object(realpath)
|
||||||
return f
|
return f
|
||||||
|
@ -8,7 +8,7 @@ import logging
|
|||||||
|
|
||||||
from acpiparser.aml.stream import Stream
|
from acpiparser.aml.stream import Stream
|
||||||
from acpiparser.aml.parser import AMLCode, DeferredExpansion
|
from acpiparser.aml.parser import AMLCode, DeferredExpansion
|
||||||
from acpiparser.aml.tree import Tree, FlattenTransformer
|
from acpiparser.aml.tree import Tree
|
||||||
from acpiparser.aml.context import Context
|
from acpiparser.aml.context import Context
|
||||||
from acpiparser.aml.interpreter import ConcreteInterpreter
|
from acpiparser.aml.interpreter import ConcreteInterpreter
|
||||||
from acpiparser.aml.visitors import ConditionallyUnregisterSymbolVisitor
|
from acpiparser.aml.visitors import ConditionallyUnregisterSymbolVisitor
|
||||||
@ -29,7 +29,6 @@ def DSDT(val):
|
|||||||
tree = Tree()
|
tree = Tree()
|
||||||
AMLCode.parse(context, tree)
|
AMLCode.parse(context, tree)
|
||||||
tree = DeferredExpansion(context).transform_topdown(tree)
|
tree = DeferredExpansion(context).transform_topdown(tree)
|
||||||
tree = FlattenTransformer().transform_bottomup(tree)
|
|
||||||
trees.append(tree)
|
trees.append(tree)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
context.current_stream.dump()
|
context.current_stream.dump()
|
||||||
|
Loading…
Reference in New Issue
Block a user