master
pca006132 2020-07-28 16:09:24 +08:00
commit 988524bb8f
3 changed files with 109 additions and 0 deletions

4
README Normal file
View File

@ -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

92
main.py Normal file
View File

@ -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<id>\w+)\s+'
r'(?P<address>0x[0-9A-F]+)\s+'
r'(?P<size>\d+)\s+'
r'(?P<type>\w+)\s+'
r'(?P<reset_value>0x[0-9A-F]+)\s+'
r'(?P<description>.+)$')
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<u32>; {padding // 4}],')
else:
code.append(f'unused{reserved_id}: [RO<u8>; {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}<u{size}>,"
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)

13
shell.nix Normal file
View File

@ -0,0 +1,13 @@
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell ({
buildInputs = (with pkgs; [
poppler_utils
(
python3.withPackages (ps: with ps; [regex])
)
]);
shellHook = ''
echo ========================
cat ./README
'';
})