init
This commit is contained in:
commit
988524bb8f
|
@ -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
|
|
@ -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)
|
Loading…
Reference in New Issue