mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-07-05 11:36:50 +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. Tracked-On: #6298 Signed-off-by: Junjie Mao <junjie.mao@intel.com>
This commit is contained in:
parent
6e79479a0a
commit
60da7d6bfd
@ -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,23 @@ 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 = bit_idx // 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 +100,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 // 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 +110,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 +142,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,18 +173,16 @@ 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):
|
||||||
# Do not allow writes to stream I/O buffer unless the base is explicitly marked as writable
|
# Do not allow writes to stream I/O buffer unless the base is explicitly marked as writable
|
||||||
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):
|
||||||
@ -196,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"
|
||||||
|
|
||||||
@ -274,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
|
||||||
self.seq = seq
|
# Some objects in ACPI AML have multiple occurrences of the same type of object in the grammar. In order to
|
||||||
self.__opcodes = None
|
# 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.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:
|
||||||
|
if len(self.opts) == 1:
|
||||||
|
globals()[self.opts[0]].parse(context, tree)
|
||||||
|
else:
|
||||||
|
self.decoder[opcode].parse(context, tree)
|
||||||
|
return tree
|
||||||
|
except KeyError:
|
||||||
|
raise DecodeError(opcode, self.label)
|
||||||
|
|
||||||
for opt in self.opts:
|
@property
|
||||||
factory = globals()[opt]
|
def decoder(self):
|
||||||
matched_opcodes = factory.opcodes()
|
if not self.__decoder:
|
||||||
if matched_opcodes is None or opcode in matched_opcodes:
|
self.__decoder = {}
|
||||||
child = Tree()
|
|
||||||
tree.append_child(child)
|
|
||||||
factory.parse(context, child)
|
|
||||||
return tree
|
|
||||||
|
|
||||||
raise DecodeError(opcode, self.label)
|
|
||||||
|
|
||||||
def opcodes(self):
|
|
||||||
if not self.__opcodes:
|
|
||||||
self.__opcodes = []
|
|
||||||
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,12 +57,11 @@ 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):
|
self.visit_topdown(child)
|
||||||
self.visit_topdown(child)
|
self.depth -= 1
|
||||||
self.depth -= 1
|
|
||||||
|
|
||||||
class Transformer:
|
class Transformer:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -57,45 +78,21 @@ 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):
|
tree.children[i] = self.transform_topdown(child)
|
||||||
tree.children[i] = self.transform_topdown(child)
|
self.depth -= 1
|
||||||
self.depth -= 1
|
|
||||||
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):
|
tree.children[i] = self.transform_bottomup(child)
|
||||||
tree.children[i] = self.transform_bottomup(child)
|
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