From 988524bb8f80d2eda969da9cc3c57c66144f132e Mon Sep 17 00:00:00 2001 From: pca006132 Date: Tue, 28 Jul 2020 16:09:24 +0800 Subject: [PATCH] init --- README | 4 +++ main.py | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ shell.nix | 13 ++++++++ 3 files changed, 109 insertions(+) create mode 100644 README create mode 100644 main.py create mode 100644 shell.nix diff --git a/README b/README new file mode 100644 index 0000000..ccbfbbc --- /dev/null +++ b/README @@ -0,0 +1,4 @@ +A simple script for parsing TRM register definition... + +Example Usage: +pdftotext -f 1431 -l 1434 -layout ug585-Zynq-7000-TRM.pdf - | python main.py 0x1000 0x1FFC diff --git a/main.py b/main.py new file mode 100644 index 0000000..83bdeb6 --- /dev/null +++ b/main.py @@ -0,0 +1,92 @@ +import re +import sys + +def parse_registers(lines): + """Parse register entry from `pdftotext -layout output` from TRM table""" + fields = ['id', 'address', 'size', 'type', 'reset_value', 'description'] + + ENTRY_PATTERN = re.compile(r'^' + r'(?P\w+)\s+' + r'(?P
0x[0-9A-F]+)\s+' + r'(?P\d+)\s+' + r'(?P\w+)\s+' + r'(?P0x[0-9A-F]+)\s+' + r'(?P.+)$') + prev = None + registers = [] + for line in lines: + if len(line.strip()) == 0: + if prev is not None: + registers.append(prev['reg']) + prev = None + continue + + match = ENTRY_PATTERN.search(line.strip()) + if match is not None: + if prev is not None: + registers.append(prev['reg']) + starts = [match.span(v)[0] for v in fields] + [len(line)] + prev = { + 'reg': {v: match.group(v) for v in fields}, + 'starts': starts + } + elif prev is not None: + for i, field in enumerate(fields): + v = line[prev['starts'][i]:prev['starts'][i + 1]].strip() + if len(v) == 0: + continue + if prev['reg'][field][-1] not in ['-', '_']: + v = ' ' + v + prev['reg'][field] += v + + if prev is not None: + registers.append(prev['reg']) + + return registers + +def emit_rust(base_addr, ending_addr, registers): + current_addr = base_addr + reserved_id = 0 + code = [] + for reg in registers: + addr = int(reg['address'], 16) + if addr > ending_addr: + break + if addr < base_addr: + continue + padding = addr - current_addr + if padding > 0: + if padding % 4 == 0: + code.append(f'unused{reserved_id}: [RO; {padding // 4}],') + else: + code.append(f'unused{reserved_id}: [RO; {padding}],') + reserved_id += 1 + access = '' + unknown = False + if reg['type'] == 'ro': + access = 'RO' + elif reg['type'] == 'wo': + access = 'WO' + elif reg['type'] in ['rw', 'mixed']: + access = 'RW' + else: + access = reg['type'] + unknown = True + size = int(reg['size']) + if size not in [8, 16, 32]: + unknown = True + current_addr += padding + size // 8 + line = f"pub {reg['id'].lower()}: {access}," + if unknown: + line = '// FIXME: ' + line + code.append(f"/// {reg['description']}") + code.append(line) + return code + +if len(sys.argv) != 3: + print("Pipe pdftotext to stdin, and give starting and ending address" + "(inclusive) for the registers") + exit() + +for line in emit_rust(int(sys.argv[1], 0), int(sys.argv[2], 0), parse_registers(sys.stdin)): + print(line) diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..d536b53 --- /dev/null +++ b/shell.nix @@ -0,0 +1,13 @@ +{ pkgs ? import {} }: +pkgs.mkShell ({ + buildInputs = (with pkgs; [ + poppler_utils + ( + python3.withPackages (ps: with ps; [regex]) + ) + ]); + shellHook = '' + echo ======================== + cat ./README + ''; +})