From 25c004dbe72020b552f353a3ae5b0ab9aa920349 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Sat, 11 Oct 2025 17:59:40 -0500 Subject: [PATCH] regs: add parse_packets --- regs/.gitignore | 3 +- regs/3d_registers.py | 4 +- regs/build.sh | 4 +- regs/parse_packets.py | 91 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 regs/parse_packets.py diff --git a/regs/.gitignore b/regs/.gitignore index ac7dc36..8b658f9 100644 --- a/regs/.gitignore +++ b/regs/.gitignore @@ -1,3 +1,4 @@ pvs_dst.py pvs_src.py -pvs_dst_bits.py \ No newline at end of file +pvs_dst_bits.py +registers_lookup.py \ No newline at end of file diff --git a/regs/3d_registers.py b/regs/3d_registers.py index 522ae63..5de8099 100644 --- a/regs/3d_registers.py +++ b/regs/3d_registers.py @@ -1,4 +1,6 @@ -with open('3d_registers.txt') as f: +import sys + +with open(sys.argv[1]) as f: lines = f.read().split('\n') def parse_reg_value(value): diff --git a/regs/build.sh b/regs/build.sh index 7031397..b298a3e 100644 --- a/regs/build.sh +++ b/regs/build.sh @@ -2,4 +2,6 @@ set -eux python parse_pvs.py PVS_DST pvs_opcode_and_destination_operand.txt > pvs_dst.py python parse_pvs.py PVS_SRC pvs_source_operand.txt > pvs_src.py -python parse_pvs_bits.py regs/pvs_opcode_and_destination_operand_bits.txt > pvs_dst_bits.py +python parse_pvs_bits.py pvs_opcode_and_destination_operand_bits.txt > pvs_dst_bits.py + +python 3d_registers.py 3d_registers.txt > registers_lookup.py diff --git a/regs/parse_packets.py b/regs/parse_packets.py new file mode 100644 index 0000000..29d7a2e --- /dev/null +++ b/regs/parse_packets.py @@ -0,0 +1,91 @@ +import sys +from registers_lookup import registers_lookup + +with open(sys.argv[1]) as f: + values = [ + int(s.strip(), 16) + for s in f.read().strip().split(",") + ] + +undocumented_registers = { + 0x1720: "RADEON_WAIT_UNTIL", + 0x2184: "VAP_VSM_VTX_ASSM", +} + +class Parser: + def __init__(self, values): + self.ix = 0 + self.values = values + + def peek(self): + return self.values[self.ix] + + def consume(self): + value = self.peek() + self.ix += 1 + return value + + def skip(self): + self.ix += 1 + + def packet_type_0(self): + header = self.consume() + count = (header >> 16) & 0x3fff + one_reg = (header >> 15) & 0b1 + reserved = (header >> 13) & 0b11 + base_index = (header >> 0) & 0x1fff + assert reserved == 0, header + if one_reg: + print(f"type 0: {base_index:04x} {count} ONE_REG") + else: + print(f"type 0: {base_index:04x} {count}") + while count >= 0: + address = base_index << 2 + value = self.consume() + #print(f" {address:04x} = {value:08x}") + if address in registers_lookup: + print(f" {registers_lookup[address]} = {value:08x}") + else: + print(f" {undocumented_registers[address]} = {value:08x}") + count -= 1 + if not one_reg: + base_index += 1 + + def packet_type_1(self): + header = self.consume() + assert False, header + + def packet_type_2(self): + print("type 2") + self.skip() + + def packet_type_3(self): + header = self.consume() + reserved = (header >> 0) & 0xff + assert reserved == 0, header + it_opcode = (header >> 8) & 0xff + count = (header >> 16) & 0x3fff + + print(f"type 3: op:{it_opcode:02x} count:{count:04x}") + while count >= 0: + value = self.consume() + print(f" {value:08x}") + count -= 1 + + def packet(self): + value = self.peek() + packet_type = (value >> 30) & 0b11 + if packet_type == 0: + self.packet_type_0() + elif packet_type == 1: + self.packet_type_1() + elif packet_type == 2: + self.packet_type_2() + elif packet_type == 3: + self.packet_type_3() + else: + assert False + +parser = Parser(values) +while parser.ix < len(values): + parser.packet()