From 60da7d6bfd63be9435a055cec3ab0c19c6b1a21b Mon Sep 17 00:00:00 2001 From: Junjie Mao Date: Fri, 16 Jul 2021 14:47:31 +0800 Subject: [PATCH] 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 --- .../board_inspector/acpiparser/aml/context.py | 6 +- .../acpiparser/aml/datatypes.py | 58 +++-- .../board_inspector/acpiparser/aml/grammar.py | 191 +++++++++------- .../acpiparser/aml/interpreter.py | 34 +-- .../board_inspector/acpiparser/aml/parser.py | 214 +++++++++++------- .../board_inspector/acpiparser/aml/tree.py | 77 +++---- .../acpiparser/aml/visitors.py | 13 +- .../board_inspector/acpiparser/dsdt.py | 3 +- 8 files changed, 328 insertions(+), 268 deletions(-) diff --git a/misc/config_tools/board_inspector/acpiparser/aml/context.py b/misc/config_tools/board_inspector/acpiparser/aml/context.py index 72ba78701..44f5d0d60 100644 --- a/misc/config_tools/board_inspector/acpiparser/aml/context.py +++ b/misc/config_tools/board_inspector/acpiparser/aml/context.py @@ -57,13 +57,13 @@ class OperationFieldDecl(NamedDecl): print(f"{self.name}: {self.__class__.__name__}, {self.length} bits") class AliasDecl(NamedDecl): - def __init__(self, name, target, tree): + def __init__(self, name, source, tree): super().__init__(name, tree) self.name = name - self.target = target + self.source = source 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): def __init__(self, name, nargs, tree): diff --git a/misc/config_tools/board_inspector/acpiparser/aml/datatypes.py b/misc/config_tools/board_inspector/acpiparser/aml/datatypes.py index bff149a3d..9c154d29c 100644 --- a/misc/config_tools/board_inspector/acpiparser/aml/datatypes.py +++ b/misc/config_tools/board_inspector/acpiparser/aml/datatypes.py @@ -48,10 +48,10 @@ class BufferBase(Object): self.__length = length 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__) - def write(self, norm_idx, value, bit_width): + def write(self, byte_idx, value, bit_width): return NotImplementedError(self.__class__.__name__) def create_field(self, name, offset, bitwidth, access_width): @@ -69,23 +69,23 @@ class BufferBase(Object): # Bits out of byte boundary 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) if bit_count > bit_remaining: bit_count = bit_remaining 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 bit_idx += bit_count bit_remaining -= bit_count while bit_remaining > 0: - norm_idx = floor(bit_idx / access_width) - bit_count = access_width if bit_remaining >= access_width else bit_remaining + byte_idx = bit_idx // 8 + bit_count = min(access_width, bit_remaining) 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 bit_idx += bit_count bit_remaining -= bit_count @@ -100,9 +100,9 @@ class BufferBase(Object): 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" - # Bits out of byte boundary + # Bits out of access_width boundary 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) if 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_keep = ((1 << access_width) - 1) - mask_of_write 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 bit_idx += bit_count bit_remaining -= bit_count while bit_remaining > 0: - norm_idx = floor(bit_idx / access_width) - bit_count = access_width if bit_remaining >= access_width else bit_remaining + byte_idx = bit_idx // 8 + bit_count = min(access_width, bit_remaining) mask_of_write = self.bitmask(bit_count - 1, 0) mask_of_keep = ((1 << access_width) - 1) - mask_of_write 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 bit_idx += bit_count @@ -142,16 +142,14 @@ class Buffer(BufferBase): def data(self): return bytes(self.__data) - def read(self, norm_idx, bit_width): + def read(self, byte_idx, bit_width): acc = 0 - byte_width = bit_width // 8 - offset = norm_idx * byte_width - return int.from_bytes(self.__data[offset : (offset + byte_width)], sys.byteorder) + byte_width = min(bit_width // 8, len(self.__data) - byte_idx) + return int.from_bytes(self.__data[byte_idx : (byte_idx + byte_width)], sys.byteorder) - def write(self, norm_idx, value, bit_width): - byte_width = bit_width // 8 - offset = norm_idx * byte_width - self.__data[offset : (offset + byte_width)] = value.to_bytes(byte_width, sys.byteorder) + def write(self, byte_idx, value, bit_width): + byte_width = min(bit_width // 8, len(self.__data) - byte_idx) + self.__data[byte_idx : (byte_idx + byte_width)] = value.to_bytes(byte_width, sys.byteorder) def get(self): return self.__data @@ -175,18 +173,16 @@ class StreamIOBuffer(BufferBase): self.__stream = stream self.__base = base - def read(self, norm_idx, bit_width): + def read(self, byte_idx, bit_width): byte_width = bit_width // 8 - address = norm_idx * byte_width - self.__stream.seek(self.__base + address) + self.__stream.seek(self.__base + byte_idx) data = self.__stream.read(byte_width) 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 byte_width = bit_width // 8 - address = norm_idx * byte_width - self.__stream.seek(self.__base + address) + self.__stream.seek(self.__base + byte_idx) self.__stream.write(value.to_bytes(byte_width, sys.byteorder)) class IndexedIOBuffer(BufferBase): @@ -196,12 +192,12 @@ class IndexedIOBuffer(BufferBase): self.__index_register = index_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" - self.__index_register.set(Integer(norm_idx, 8)) + self.__index_register.set(Integer(byte_idx, 8)) 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 assert False, "Cannot write to indexed I/O buffers" @@ -274,7 +270,7 @@ class Integer(Object): class Method(Object): def __init__(self, tree): self.tree = tree - self.name = tree.children[1].children + self.name = tree.children[1].value self.body = tree.children[3] class PredefinedMethod(Object): diff --git a/misc/config_tools/board_inspector/acpiparser/aml/grammar.py b/misc/config_tools/board_inspector/acpiparser/aml/grammar.py index d6f57c741..fd40cf7f5 100644 --- a/misc/config_tools/board_inspector/acpiparser/aml/grammar.py +++ b/misc/config_tools/board_inspector/acpiparser/aml/grammar.py @@ -136,15 +136,15 @@ AML_DATA_REGION_OP = 0x885b AMLCode = ("DefBlockHeader", "TermObj*") DefBlockHeader = ("TableSignature", "TableLength", "SpecCompliance", "CheckSum", "OemID", "OemTableID", "OemRevision", "CreatorID", "CreatorRevision") -TableSignature = ("DWordData",) -TableLength = ("DWordData",) -SpecCompliance = ("ByteData",) -CheckSum = ("ByteData",) -OemID = ("TWordData",) -OemTableID = ("QWordData",) -OemRevision = ("DWordData",) -CreatorID = ("DWordData",) -CreatorRevision = ("DWordData",) +TableSignature = ["DWordData"] +TableLength = ["DWordData"] +SpecCompliance = ["ByteData"] +CheckSum = ["ByteData"] +OemID = ["TWordData"] +OemTableID = ["QWordData"] +OemRevision = ["DWordData"] +CreatorID = ["DWordData"] +CreatorRevision = ["DWordData"] ################################################################################ # 20.2.2 Name Objects Encoding @@ -202,7 +202,7 @@ TermArg = ["ExpressionOpcode", "DataObject", "ArgObj", "LocalObj"] NameSpaceModifierObj = ["DefAlias", "DefName", "DefScope"] -DefAlias = (AML_ALIAS_OP, "NameString", "NameString") +DefAlias = (AML_ALIAS_OP, "NameString:SourceObject", "NameString:AliasObject") DefName = (AML_NAME_OP, "NameString", "DataRefObject") DefScope = (AML_SCOPE_OP, "PkgLength", "NameString", "TermList") @@ -214,68 +214,68 @@ NamedObj = ["DefBankField", "DefCreateBitField", "DefCreateByteField", "DefCreat "DefField", "DefIndexField", "DefMethod", "DefMutex", "DefOpRegion", "DefPowerRes", "DefProcessor", "DefThermalZone"] -DefBankField = (AML_BANK_FIELD_OP, "PkgLength", "NameString", "NameString", "BankValue", "FieldFlags", "FieldList") -BankValue = ("TermArg",) -FieldFlags = ("ByteData",) +DefBankField = (AML_BANK_FIELD_OP, "PkgLength", "NameString:RegionName", "NameString:BankName", "BankValue", "FieldFlags", "FieldList") +BankValue = ["TermArg"] +FieldFlags = ["ByteData"] FieldList = ("FieldElement*",) NamedField = ("NameSeg", "FieldLength") ReservedField = (AML_RESERVED_FIELD_PREFIX, "FieldLength") AccessField = (AML_ACCESS_FIELD_PREFIX, "AccessType", "AccessAttrib") -AccessType = ("ByteData",) -AccessAttrib = ("ByteData",) -ConnectFieldDef = ["NameString", "BufferData"] +AccessType = ["ByteData"] +AccessAttrib = ["ByteData"] +ConnectFieldDef = ["NameString"] # FIXME: ACPI spec allows "BufferData" here but does not define what "BufferData" is ConnectField = (AML_CONNECT_FIELD_PREFIX, "ConnectFieldDef") DefCreateBitField = (AML_CREATE_BIT_FIELD_OP, "SourceBuff", "BitIndex", "NameString") -SourceBuff = ("TermArg",) -BitIndex = ("TermArg",) +SourceBuff = ["TermArg"] +BitIndex = ["TermArg"] DefCreateByteField = (AML_CREATE_BYTE_FIELD_OP, "SourceBuff", "ByteIndex", "NameString") -ByteIndex = ("TermArg",) +ByteIndex = ["TermArg"] DefCreateDWordField = (AML_CREATE_DWORD_FIELD_OP, "SourceBuff", "ByteIndex", "NameString") DefCreateField = (AML_CREATE_FIELD_OP, "SourceBuff", "BitIndex", "NumBits", "NameString") -NumBits = ("TermArg",) +NumBits = ["TermArg"] DefCreateQWordField = (AML_CREATE_QWORD_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") DefEvent = (AML_EVENT_OP, "NameString") DefExternal = (AML_EXTERNAL_OP, "NameString", "ObjectType", "ArgumentCount") -ObjectType = ("ByteData",) -ArgumentCount = ("ByteData",) +ObjectType = ["ByteData"] +ArgumentCount = ["ByteData"] 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") -MethodFlags = ("ByteData",) +MethodFlags = ["ByteData"] DefMutex = (AML_MUTEX_OP, "NameString", "SyncFlags") -SyncFlags = ("ByteData",) +SyncFlags = ["ByteData"] DefOpRegion = (AML_REGION_OP, "NameString", "RegionSpace", "RegionOffset", "RegionLen") -RegionSpace = ("ByteData",) -RegionOffset = ("TermArg",) -RegionLen = ("TermArg",) +RegionSpace = ["ByteData"] +RegionOffset = ["TermArg"] +RegionLen = ["TermArg"] DefPowerRes = (AML_POWER_RESOURCE_OP, "PkgLength", "NameString", "SystemLevel", "ResourceOrder", "TermList") -SystemLevel = ("ByteData",) -ResourceOrder = ("WordData",) +SystemLevel = ["ByteData"] +ResourceOrder = ["WordData"] DefProcessor = (AML_PROCESSOR_OP, "PkgLength", "NameString", "ProcID", "PblkAddr", "PblkLen", "TermList") -ProcID = ("ByteData",) -PblkAddr = ("DWordData",) -PblkLen = ("ByteData",) +ProcID = ["ByteData"] +PblkAddr = ["DWordData"] +PblkLen = ["ByteData"] DefThermalZone = (AML_THERMAL_ZONE_OP, "PkgLength", "NameString", "TermList") ExtendedAccessField = (AML_EXTENDED_ACCESS_FIELD_PREFIX, "AccessType", "ExtendedAccessAttrib", "AccessLength") -ExtendedAccessAttrib = ("ByteData",) -AccessLength = ("ByteData",) +ExtendedAccessAttrib = ["ByteData"] +AccessLength = ["ByteData"] FieldElement = ["NamedField", "ReservedField", "AccessField", "ExtendedAccessField", "ConnectField"] # 20.2.5.3 Statement Opcodes Encoding @@ -293,35 +293,35 @@ DefContinue = (AML_CONTINUE_OP,) DefElse = (AML_ELSE_OP, "PkgLength", "TermList") DefFatal = (AML_FATAL_OP, "FatalType", "FatalCode", "FataArg") -FatalType = ("ByteData",) -FatalCode = ("DWordData",) -FatalArg = ("TermArg",) +FatalType = ["ByteData"] +FatalCode = ["DWordData"] +FatalArg = ["TermArg"] DefIfElse = (AML_IF_OP, "PkgLength", "Predicate", "TermList", "DefElse?") -Predicate = ("TermArg",) +Predicate = ["TermArg"] DefNoop = (AML_NOOP_OP,) DefNotify = (AML_NOTIFY_OP, "NotifyObject", "NotifyValue") -NotifyObject = ("SuperName",) -NotifyValue = ("TermArg",) +NotifyObject = ["SuperName"] +NotifyValue = ["TermArg"] DefRelease = (AML_RELEASE_OP, "MutexObject") -MutexObject = ("SuperName",) +MutexObject = ["SuperName"] DefReset = (AML_RESET_OP, "EventObject") -EventObject = ("SuperName",) +EventObject = ["SuperName"] DefReturn = (AML_RETURN_OP, "ArgObject") -ArgObject = ("TermArg",) +ArgObject = ["TermArg"] DefSignal = (AML_SIGNAL_OP, "EventObject") DefSleep = (AML_SLEEP_OP, "MsecTime") -MsecTime = ("TermArg",) +MsecTime = ["TermArg"] DefStall = (AML_STALL_OP, "UsecTime") -UsecTime = ("TermArg",) +UsecTime = ["TermArg"] DefUnload = (AML_UNLOAD_OP, "Target") @@ -342,21 +342,21 @@ ExpressionOpcode = ["DefAcquire", "DefAdd", "DefAnd", "DefBuffer", "DefConcat", ReferenceTypeOpcode = ["DefRefOf", "DefDerefOf", "DefIndex"] 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"] -DefAnd = (AML_AND_OP, "Operand", "Operand", "Target") +DefAnd = (AML_AND_OP, "Operand:LeftOperand", "Operand:RightOperand", "Target") DefBuffer = (AML_BUFFER_OP, "PkgLength", "BufferSize", "ByteList") -BufferSize = ("TermArg",) +BufferSize = ["TermArg"] -DefConcat = (AML_CONCAT_OP, "Data", "Data", "Target") -Data = ("TermArg",) +DefConcat = (AML_CONCAT_OP, "Data:Data1", "Data:Data2", "Target") +Data = ["TermArg"] -DefConcatRes = (AML_CONCAT_RES_OP, "BufData", "BufData", "Target") -BufData = ("TermArg",) +DefConcatRes = (AML_CONCAT_RES_OP, "BufData:BufData1", "BufData:BufData2", "Target") +BufData = ["TermArg"] DefCondRefOf = (AML_CONDITIONAL_REF_OF_OP, "SuperName", "Target") @@ -365,80 +365,80 @@ DefCopyObject = (AML_COPY_OBJECT_OP, "TermArg", "SimpleName") DefDecrement = (AML_DECREMENT_OP, "SuperName") DefDerefOf = (AML_DEREF_OF_OP, "ObjReference") -ObjReference = ("TermArg",) +ObjReference = ["TermArg"] DefDivide = (AML_DIVIDE_OP, "Dividend", "Divisor", "Remainder", "Quotient") -Dividend = ("TermArg",) -Divisor = ("TermArg",) -Remainder = ("Target",) -Quotient = ("Target",) +Dividend = ["TermArg"] +Divisor = ["TermArg"] +Remainder = ["Target"] +Quotient = ["Target"] DefFindSetLeftBit = (AML_FIND_SET_LEFT_BIT_OP, "Operand", "Target") DefFindSetRightBit = (AML_FIND_SET_RIGHT_BIT_OP, "Operand", "Target") DefFromBCD = (AML_FROM_BCD_OP, "BCDValue", "Target") -BCDValue = ("TermArg",) +BCDValue = ["TermArg"] DefIncrement = (AML_INCREMENT_OP, "SuperName") DefIndex = (AML_INDEX_OP, "BuffPkgStrObj", "IndexValue", "Target") -BuffPkgStrObj = ("TermArg",) -IndexValue = ("TermArg",) +BuffPkgStrObj = ["TermArg"] +IndexValue = ["TermArg"] -DefLAnd = (AML_LAND_OP, "Operand", "Operand") -DefLEqual = (AML_LEQUAL_OP, "Operand", "Operand") -DefLGreater = (AML_LGREATER_OP, "Operand", "Operand") +DefLAnd = (AML_LAND_OP, "Operand:LeftOperand", "Operand:RightOperand") +DefLEqual = (AML_LEQUAL_OP, "Operand:LeftOperand", "Operand:RightOperand") +DefLGreater = (AML_LGREATER_OP, "Operand:LeftOperand", "Operand:RightOperand") # 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) DefLNot = (AML_LNOT_OP, "Operand") # DefLNotEqual is equivalent to (AML_LNOT_OP, DefLEqual) 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") -SearchPkg = ("TermArg",) -MatchOpcode = ("ByteData",) -StartIndex = ("TermArg",) +DefMatch = (AML_MATCH_OP, "SearchPkg", "MatchOpcode:MatchOpcode1", "Operand:Operand1", "MatchOpcode:MatchOpcode2", "Operand:Operand2", "StartIndex") +SearchPkg = ["TermArg"] +MatchOpcode = ["ByteData"] +StartIndex = ["TermArg"] -DefMid = (AML_MID_OP, "MidObj", "TermArg", "TermArg", "Target") -MidObj = ("TermArg",) +DefMid = (AML_MID_OP, "MidObj", "TermArg:Source", "TermArg:Index", "Target") +MidObj = ["TermArg"] 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") -DefNOr = (AML_NOR_OP, "Operand", "Operand", "Target") +DefNAnd = (AML_NAND_OP, "Operand:LeftOperand", "Operand:RightOperand", "Target") +DefNOr = (AML_NOR_OP, "Operand:LeftOperand", "Operand:RightOperand", "Target") DefNot = (AML_NOT_OP, "Operand", "Target") DefObjectType = (AML_OBJECT_TYPE_OP, "ObjectTypeContent") 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") DefVarPackage = (AML_VAR_PACKAGE_OP, "PkgLength", "VarNumElements", "PackageElementList") -NumElements = ("ByteData",) -VarNumElements = ("TermArg",) +NumElements = ["ByteData"] +VarNumElements = ["TermArg"] PackageElementList = ("PackageElement*",) PackageElement = ["DataRefObject", "NameString"] DefRefOf = (AML_REF_OF_OP, "SuperName") DefShiftLeft = (AML_SHIFT_LEFT_OP, "Operand", "ShiftCount", "Target") -ShiftCount = ("TermArg",) +ShiftCount = ["TermArg"] DefShiftRight = (AML_SHIFT_RIGHT_OP, "Operand", "ShiftCount", "Target") DefSizeOf = (AML_SIZE_OF_OP, "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,) @@ -453,11 +453,11 @@ DefToHexString = (AML_TO_HEX_STRING_OP, "Operand", "Target") DefToInteger = (AML_TO_INTEGER_OP, "Operand", "Target") DefToString = (AML_TO_STRING_OP, "TermArg", "LengthArg", "Target") -LengthArg = ("TermArg",) +LengthArg = ["TermArg"] 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 @@ -492,3 +492,24 @@ Local7Op = (AML_LOCAL7_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) diff --git a/misc/config_tools/board_inspector/acpiparser/aml/interpreter.py b/misc/config_tools/board_inspector/acpiparser/aml/interpreter.py index d78e080e9..5b1a9665b 100644 --- a/misc/config_tools/board_inspector/acpiparser/aml/interpreter.py +++ b/misc/config_tools/board_inspector/acpiparser/aml/interpreter.py @@ -86,9 +86,13 @@ class ConcreteInterpreter(Interpreter): def interpret_method_call(self, name, *args): 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) pseudo_invocation = Tree("MethodInvocation", [name_string]) + pseudo_invocation.register_structure(("NameString", "TermArg*")) + pseudo_invocation.complete_parsing() try: val = self.interpret(pseudo_invocation) except: @@ -118,7 +122,7 @@ class ConcreteInterpreter(Interpreter): return None def NameString(self, tree): - name = tree.children + name = tree.value obj = self.context.lookup_binding(name) if not obj: sym = self.context.lookup_symbol(name) @@ -133,7 +137,7 @@ class ConcreteInterpreter(Interpreter): # 20.2.3 Data Objects Encoding def ByteList(self, tree): - return RawDataBuffer(tree.children) + return RawDataBuffer(tree.value) def ByteConst(self, tree): return self.interpret(tree.children[0]) @@ -148,19 +152,19 @@ class ConcreteInterpreter(Interpreter): return self.interpret(tree.children[0]) def String(self, tree): - return String(tree.children) + return String(tree.value) def ByteData(self, tree): - return Integer(tree.children) + return Integer(tree.value) def WordData(self, tree): - return Integer(tree.children) + return Integer(tree.value) def DWordData(self, tree): - return Integer(tree.children) + return Integer(tree.value) def QWordData(self, tree): - return Integer(tree.children) + return Integer(tree.value) def ZeroOp(self, tree): return Integer(0x00) @@ -210,7 +214,7 @@ class ConcreteInterpreter(Interpreter): return Integer(value.fn(args)) else: 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 # 20.2.5.1 Namespace Modifier Objects Encoding @@ -219,7 +223,7 @@ class ConcreteInterpreter(Interpreter): def DefName(self, tree): self.context.change_scope(tree.children[0].scope) - name = tree.children[0].children + name = tree.children[0].value obj = self.context.lookup_binding(name) if not obj: obj = self.interpret(tree.children[1]) @@ -229,7 +233,7 @@ class ConcreteInterpreter(Interpreter): # 20.2.5.2 Named Objects Encoding 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)) assert isinstance(sym, OperationFieldDecl) 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]) assert isinstance(buf, Buffer) 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: buf.create_field(name, index, bitwidth, 8) else: @@ -283,13 +287,13 @@ class ConcreteInterpreter(Interpreter): return self.create_field(tree, numbits, 3) def DefDevice(self, tree): - name = tree.children[1].children + name = tree.children[1].value fullpath = self.context.realpath(tree.scope, name) sym = self.context.lookup_symbol(fullpath) return Device(sym) 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 def DefField(self, tree): @@ -300,7 +304,7 @@ class ConcreteInterpreter(Interpreter): return Method(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)) space = self.interpret(tree.children[1]).get() diff --git a/misc/config_tools/board_inspector/acpiparser/aml/parser.py b/misc/config_tools/board_inspector/acpiparser/aml/parser.py index f993c71dc..2af685f35 100644 --- a/misc/config_tools/board_inspector/acpiparser/aml/parser.py +++ b/misc/config_tools/board_inspector/acpiparser/aml/parser.py @@ -56,7 +56,8 @@ class Factory: self.mark_end() return tree - def opcodes(self): + @property + def decoder(self): raise NotImplementedError ################################################################################ @@ -66,17 +67,20 @@ class Factory: class NameSegFactory(Factory): def __init__(self): super().__init__() - self.__opcodes = [] + self.__decoder = {} for i in range(ord('A'), ord('Z') + 1): - self.__opcodes.append(i) - self.__opcodes.append(ord('_')) + self.__decoder[i] = self + self.__decoder[ord('_')] = self self.label = "NameSeg" 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): - return self.__opcodes + @property + def decoder(self): + return self.__decoder NameSeg = NameSegFactory() @@ -84,12 +88,14 @@ class NameStringFactory(Factory): def __init__(self): super().__init__() self.label = "NameString" - self.__opcodes = [] + self.__decoder = {} for i in range(ord('A'), ord('Z') + 1): - self.__opcodes.append(i) - self.__opcodes.extend([ord('_'), ord('\\'), ord('^'), grammar.AML_DUAL_NAME_PREFIX, grammar.AML_MULTI_NAME_PREFIX]) + self.__decoder[i] = self + 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): + tree.register_structure(("value",)) acc = "" # Namespace prefixes @@ -117,10 +123,12 @@ class NameStringFactory(Factory): stream.seek(-1) acc += stream.get_fixed_length_string(4) - tree.children = acc + tree.append_child(acc) + tree.complete_parsing() - def opcodes(self): - return self.__opcodes + @property + def decoder(self): + return self.__decoder NameString = NameStringFactory() @@ -135,12 +143,11 @@ class ConstDataFactory(Factory): self.width = width 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 - def opcodes(self): - return None - ByteData = ConstDataFactory("ByteData", 1) WordData = ConstDataFactory("WordData", 2) DWordData = ConstDataFactory("DWordData", 4) @@ -155,11 +162,14 @@ class StringFactory(Factory): def match(self, context, stream, tree): 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 - def opcodes(self): - return [grammar.AML_STRING_PREFIX] + @property + def decoder(self): + return {grammar.AML_STRING_PREFIX: self} String = StringFactory() @@ -169,7 +179,9 @@ class ByteListFactory(Factory): self.label = "ByteList" 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() ByteList = ByteListFactory() @@ -200,10 +212,12 @@ class PkgLengthFactory(Factory): byte_count = pkg_lead_byte >> 6 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: - remaining = tree.children - byte_count - 1 + remaining = tree.value - byte_count - 1 stream.push_scope(remaining) tree.package_range = (stream.current, remaining) return tree @@ -218,27 +232,33 @@ FieldLength = PkgLengthFactory("FieldLength", False) class MethodInvocationFactory(Factory): def __init__(self): super().__init__() - self.__opcodes = None + self.__decoder = None self.label = "MethodInvocation" def match(self, context, stream, tree): + tree.register_structure(("NameString", "TermArg*")) + child_namestring = Tree() globals()["NameString"].parse(context, 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)): for i in range(0, sym.nargs): child_arg = Tree() globals()["TermArg"].parse(context, child_arg) tree.append_child(child_arg) + tree.complete_parsing() return tree - def opcodes(self): - if not self.__opcodes: - self.__opcodes = globals()["NameString"].opcodes() - return self.__opcodes + @property + def decoder(self): + if not self.__decoder: + self.__decoder = {} + for k in globals()["NameString"].decoder.keys(): + self.__decoder[k] = self + return self.__decoder MethodInvocation = MethodInvocationFactory() @@ -250,15 +270,31 @@ class SequenceFactory(Factory): def __init__(self, label, seq): super().__init__() self.label = label - self.seq = seq - self.__opcodes = None + # 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: + # + # ":" + # + # 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): + 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 # peek the next opcode in such cases. if stream.at_end() and \ (self.seq[0][-1] in ["*", "?"]): stream.pop_scope() + tree.complete_parsing() return tree opcode, opcode_width = stream.peek_opcode() @@ -268,6 +304,7 @@ class SequenceFactory(Factory): # cleanup actions upon exceptions. to_recover_from_deferred_mode = False to_pop_stream_scope = False + completed = True for i,elem in enumerate(self.seq): pos = stream.current @@ -288,7 +325,7 @@ class SequenceFactory(Factory): factory = globals()[elem] if not stream.at_end(): sub_opcode, _ = stream.peek_opcode() - if sub_opcode in factory.opcodes(): + if sub_opcode in factory.decoder.keys(): child = Tree() factory.parse(context, child) tree.append_child(child) @@ -312,7 +349,7 @@ class SequenceFactory(Factory): context.enter_deferred_mode() to_recover_from_deferred_mode = True 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: if to_pop_stream_scope: stream.pop_scope(force=True) @@ -321,49 +358,54 @@ class SequenceFactory(Factory): tree.context_scope = context.get_scope() tree.factory = SequenceFactory(f"{self.label}.deferred", self.seq[i:]) stream.seek(package_end, absolute=True) + completed = False break else: raise e + if completed: + tree.complete_parsing() + if to_recover_from_deferred_mode: context.exit_deferred_mode() return tree - def opcodes(self): - if not self.__opcodes: + @property + def decoder(self): + if not self.__decoder: if isinstance(self.seq[0], int): - self.__opcodes = [self.seq[0]] + self.__decoder = {self.seq[0]: self} else: - self.__opcodes = globals()[self.seq[0]].opcodes() - return self.__opcodes + self.__decoder = {} + for k in globals()[self.seq[0]].decoder.keys(): + self.__decoder[k] = self + return self.__decoder class OptionFactory(Factory): def __init__(self, label, opts): super().__init__() self.label = label self.opts = opts - self.__opcodes = None + self.__decoder = None def match(self, context, stream, tree): 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: - factory = globals()[opt] - matched_opcodes = factory.opcodes() - if matched_opcodes is None or opcode in matched_opcodes: - 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 = [] + @property + def decoder(self): + if not self.__decoder: + self.__decoder = {} for opt in self.opts: - self.__opcodes.extend(globals()[opt].opcodes()) - return self.__opcodes + self.__decoder.update(globals()[opt].decoder) + return self.__decoder class DeferredExpansion(Transformer): def __init__(self, context): @@ -390,6 +432,7 @@ class DeferredExpansion(Transformer): tree.children.extend(aux_tree.children) tree.deferred_range = None tree.factory = None + tree.complete_parsing() 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)) @@ -402,9 +445,9 @@ class DeferredExpansion(Transformer): ################################################################################ def DefAlias_hook_post(context, tree): - target = tree.children[0].children - name = tree.children[1].children - sym = AliasDecl(name, target, tree) + source = tree.SourceObject.value + alias = tree.AliasObject.value + sym = AliasDecl(alias, source, tree) context.register_symbol(sym) def DefName_hook_named(context, tree, name): @@ -419,32 +462,32 @@ def DefScope_hook_post(context, tree): def DefCreateBitField_hook_named(context, tree, name): - name = tree.children[2].children + name = tree.children[2].value sym = FieldDecl(name, 1, tree) context.register_symbol(sym) def DefCreateByteField_hook_named(context, tree, name): - name = tree.children[2].children + name = tree.children[2].value sym = FieldDecl(name, 8, tree) context.register_symbol(sym) def DefCreateDWordField_hook_named(context, tree, name): - name = tree.children[2].children + name = tree.children[2].value sym = FieldDecl(name, 32, tree) context.register_symbol(sym) def DefCreateField_hook_named(context, tree, name): - name = tree.children[3].children + name = tree.children[3].value sym = FieldDecl(name, 0, tree) context.register_symbol(sym) def DefCreateQWordField_hook_named(context, tree, name): - name = tree.children[2].children + name = tree.children[2].value sym = FieldDecl(name, 64, tree) context.register_symbol(sym) def DefCreateWordField_hook_named(context, tree, name): - name = tree.children[2].children + name = tree.children[2].value sym = FieldDecl(name, 16, tree) context.register_symbol(sym) @@ -457,9 +500,9 @@ def DefDevice_hook_post(context, tree): context.pop_scope() def DefExternal_hook_post(context, tree): - name = tree.children[0].children - ty = tree.children[1].children[0].children - nargs = tree.children[2].children[0].children + name = tree.NameString.value + ty = tree.ObjectType.value + nargs = tree.ArgumentCount.value if ty == 0x8: # an external method sym = MethodDecl(name, nargs, tree) @@ -479,52 +522,50 @@ access_width_map = { def DefField_hook_post(context, tree): # Update the fields with region & offset info - region_name = context.lookup_symbol(tree.children[1].children).name - flags = tree.children[2].children[0].children + region_name = context.lookup_symbol(tree.NameString.value).name + flags = tree.FieldFlags.value access_width = access_width_map[flags & 0xF] - fields = tree.children[3].children + fields = tree.FieldList.FieldElements bit_offset = 0 for field in fields: - field = field.children[0] if field.label == "NamedField": - name = field.children[0].children - length = field.children[1].children + name = field.NameSeg.value + length = field.FieldLength.value sym = context.lookup_symbol(name) assert isinstance(sym, OperationFieldDecl) sym.set_location(region_name, bit_offset, access_width) bit_offset += length elif field.label == "ReservedField": - length = field.children[0].children + length = field.FieldLength.value bit_offset += length else: break def DefIndexField_hook_post(context, tree): # Update the fields with region & offset info - index_register = context.lookup_symbol(tree.children[1].children) - data_register = context.lookup_symbol(tree.children[2].children) - flags = tree.children[3].children[0].children + index_register = context.lookup_symbol(tree.IndexName.value) + data_register = context.lookup_symbol(tree.DataName.value) + flags = tree.FieldFlags.value access_width = access_width_map[flags & 0xF] - fields = tree.children[4].children + fields = tree.FieldList.FieldElements bit_offset = 0 for field in fields: - field = field.children[0] if field.label == "NamedField": - name = field.children[0].children - length = field.children[1].children + name = field.NameSeg.value + length = field.FieldLength.value sym = context.lookup_symbol(name) assert isinstance(sym, OperationFieldDecl) sym.set_indexed_location(index_register, data_register, bit_offset, access_width) bit_offset += length elif field.label == "ReservedField": - length = field.children[0].children + length = field.FieldLength.value bit_offset += length else: break def NamedField_hook_post(context, tree): - name = tree.children[0].children - length = tree.children[1].children + name = tree.NameSeg.value + length = tree.FieldLength.value sym = OperationFieldDecl(name, length, tree) context.register_symbol(sym) @@ -534,8 +575,9 @@ def DefMethod_hook_named(context, tree, name): def DefMethod_hook_post(context, tree): context.pop_scope() if len(tree.children) >= 3: - name = tree.children[1].children - flags = tree.children[2].children[0].children + # Parsing of the method may be deferred. Do not use named fields to access its children. + name = tree.children[1].value + flags = tree.children[2].value nargs = flags & 0x7 sym = MethodDecl(name, nargs, tree) context.register_symbol(sym) diff --git a/misc/config_tools/board_inspector/acpiparser/aml/tree.py b/misc/config_tools/board_inspector/acpiparser/aml/tree.py index ae2ecbcb8..d33159222 100644 --- a/misc/config_tools/board_inspector/acpiparser/aml/tree.py +++ b/misc/config_tools/board_inspector/acpiparser/aml/tree.py @@ -13,6 +13,8 @@ class Tree: self.children = copy(children) self.scope = None + self.structure = None + self.package_range = None self.deferred_range = None @@ -22,6 +24,26 @@ class Tree: def append_child(self, 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: def __init__(self): self.depth = 0 @@ -35,12 +57,11 @@ class Visitor: def visit_topdown(self, tree): self.__visit(tree) - if isinstance(tree.children, list): - self.depth += 1 - for child in tree.children: - if isinstance(child, Tree): - self.visit_topdown(child) - self.depth -= 1 + self.depth += 1 + for child in tree.children: + if isinstance(child, Tree): + self.visit_topdown(child) + self.depth -= 1 class Transformer: def __init__(self): @@ -57,45 +78,21 @@ class Transformer: def transform_topdown(self, tree): new_tree = self.__transform(tree) - if isinstance(new_tree.children, list): - self.depth += 1 - for i, child in enumerate(tree.children): - if isinstance(child, Tree): - tree.children[i] = self.transform_topdown(child) - self.depth -= 1 + self.depth += 1 + for i, child in enumerate(tree.children): + if isinstance(child, Tree): + tree.children[i] = self.transform_topdown(child) + self.depth -= 1 return new_tree def transform_bottomup(self, tree): - if isinstance(tree.children, list): - self.depth += 1 - for i, child in enumerate(tree.children): - if isinstance(child, Tree): - tree.children[i] = self.transform_bottomup(child) - self.depth -= 1 + self.depth += 1 + for i, child in enumerate(tree.children): + if isinstance(child, Tree): + tree.children[i] = self.transform_bottomup(child) + self.depth -= 1 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: def __init__(self, context): self.context = context diff --git a/misc/config_tools/board_inspector/acpiparser/aml/visitors.py b/misc/config_tools/board_inspector/acpiparser/aml/visitors.py index b85476f29..d94de1beb 100644 --- a/misc/config_tools/board_inspector/acpiparser/aml/visitors.py +++ b/misc/config_tools/board_inspector/acpiparser/aml/visitors.py @@ -13,11 +13,12 @@ class PrintLayoutVisitor(Visitor): def default(self, tree): indent = " " * self.depth print(f"{indent}{tree.label}", end="") - if isinstance(tree.children, int): - print(f" = {hex(tree.children)}", end="") - elif isinstance(tree.children, str): - if self.__is_printable(tree.children): - print(f" = '{tree.children}'", end="") + if hasattr(tree, "value"): + if isinstance(tree.value, int): + print(f" = {hex(tree.value)}", end="") + elif isinstance(tree.value, str): + if self.__is_printable(tree.value): + print(f" = '{tree.value}'", end="") if tree.deferred_range: print(f" (deferred at {hex(tree.deferred_range[0])}, length {hex(tree.deferred_range[1])})", end="") if tree.factory: @@ -39,7 +40,7 @@ class ConditionallyUnregisterSymbolVisitor(Visitor): def f(tree): if self.conditionally_hidden: scope = tree.scope - name = tree.children[name_string_idx].children + name = tree.children[name_string_idx].value realpath = self.context.realpath(scope, name) self.context.unregister_object(realpath) return f diff --git a/misc/config_tools/board_inspector/acpiparser/dsdt.py b/misc/config_tools/board_inspector/acpiparser/dsdt.py index 4af22c106..9f3eba813 100644 --- a/misc/config_tools/board_inspector/acpiparser/dsdt.py +++ b/misc/config_tools/board_inspector/acpiparser/dsdt.py @@ -8,7 +8,7 @@ import logging from acpiparser.aml.stream import Stream 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.interpreter import ConcreteInterpreter from acpiparser.aml.visitors import ConditionallyUnregisterSymbolVisitor @@ -29,7 +29,6 @@ def DSDT(val): tree = Tree() AMLCode.parse(context, tree) tree = DeferredExpansion(context).transform_topdown(tree) - tree = FlattenTransformer().transform_bottomup(tree) trees.append(tree) except Exception as e: context.current_stream.dump()