From 185b5d22e221fdd63993e79887e4114ce0967e3c Mon Sep 17 00:00:00 2001 From: Junjie Mao Date: Mon, 9 Aug 2021 16:31:57 +0800 Subject: [PATCH] board-inspector: support buffer assignments and indexing The ACPI specification allows both assigning to buffers and indexing to a certain byte of a buffer using the Index operator. This patch adds the implementation of these two operations in the interpreter. Tracked-On: #6287 Signed-off-by: Junjie Mao --- .../acpiparser/aml/datatypes.py | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/misc/config_tools/board_inspector/acpiparser/aml/datatypes.py b/misc/config_tools/board_inspector/acpiparser/aml/datatypes.py index 50ead0b92..a69903a23 100644 --- a/misc/config_tools/board_inspector/acpiparser/aml/datatypes.py +++ b/misc/config_tools/board_inspector/acpiparser/aml/datatypes.py @@ -57,6 +57,9 @@ class BufferBase(Object): def create_field(self, name, offset, bitwidth, access_width): self.__fields[name] = (offset, bitwidth, access_width) + def field_bitwidth(self, name): + return self.__fields[name][1] + def read_field(self, name): offset, bitwidth, access_width = self.__fields[name] acc = 0 @@ -155,6 +158,11 @@ class Buffer(BufferBase): def get(self): return self.__data + def set(self, value): + data = value.to_buffer().get() + copy_length = min(len(data), len(self.__data)) + self.__data[:copy_length] = data[:copy_length] + def to_hex_string(self): result = ",".join(map(lambda x:hex(x)[2:], self.__data)) return String(result) @@ -218,6 +226,10 @@ class BufferField(Object): def to_integer(self): return Integer(self.get()) + def to_buffer(self): + bitwidth = self.__buf.field_bitwidth(self.__field) + return Buffer(self.get().to_bytes((bitwidth + 7) // 8, sys.byteorder)) + def to_string(self): return f"BufferField({self.__field})" @@ -291,8 +303,12 @@ class ObjectReference(Object): if self.__index is not None: if isinstance(self.__obj, Package): return self.__obj.elements[self.__index] + elif isinstance(self.__obj, Buffer): + name = f"byte_{hex(self.__index)[2:]}" + self.__obj.create_field(name, self.__index * 8, 8, 8) + return BufferField(self.__obj, name) else: - raise NotImplementedError + raise NotImplementedError(self.__obj.__class__.__name__) else: return self.__obj @@ -375,12 +391,18 @@ class OperationRegion(Object): def read_field(self, name): return self.__iobuf.read_field(name) + def field_bitwidth(self, name): + return self.__iobuf.field_bitwidth(name) + def write_field(self, name, value): # Do not allow writes to stream I/O buffer unless the base is explicitly marked as writable if name in self.__writable_fields: self.__iobuf.write_field(name, value) else: - logging.info(f"Skip writing 0x{value:0X} to I/O field {name}") + if isinstance(value, int): + logging.info(f"Skip writing 0x{value:0X} to I/O field {name}") + else: + logging.info(f"Skip writing {value} to I/O field {name}") def set_field_writable(self, name): self.__writable_fields.add(name)