Update litex_json2dts_zephyr

Changes in Zephyr require updated script to generate correct overlay.

This commit splits CSR regions that were being added to overlay as
single register into separate registers with names.

It also prints their size in bytes instead of used subregisters.

I also added LITEX_CSR_DATA_WIDTH to generated config parameters.

To limit code duplication, I added functions used for indenting text.
Additionally, I updated formatting functions to take list of registers
and then format it, instead of just surrounding already formatted text
with braces.
This commit is contained in:
Michal Sieron 2022-05-26 09:54:43 +02:00
parent 36ea82546f
commit cd5148d961
1 changed files with 124 additions and 29 deletions

View File

@ -22,49 +22,146 @@ import argparse
import json
def get_registers_of(name, csr):
registers = csr['csr_registers']
return [
{
**params,
# describe size in bytes, not number of subregisters
'size': params['size'] * 4,
'name': r[len(name) + 1:],
}
for r, params in registers.items() if r.startswith(name)
]
# Indentation helpers
INDENT_STR = ' '
def indent(line, levels=1):
return INDENT_STR * levels + line
def indent_all(text, levels=1):
return '\n'.join(map(indent, text.splitlines()))
def indent_all_but_first(text, levels=1):
lines = text.splitlines()
indented = indent_all('\n'.join(lines[1:]), levels)
if indented:
return lines[0] + '\n' + indented
else:
return lines[0]
# DTS formatting
def dts_open(name, parm): return "&{} {{\n".format(parm.get('alias', name))
def dts_close(): return "};\n"
def dts_intr(name, csr): return " interrupts = <{} 0>;\n".format(
hex(csr['constants'][name + '_interrupt']))
def dts_reg(regs): return " reg = <{}>;\n".format(regs)
def dts_open(name, parm):
return "&{} {{\n".format(parm.get('alias', name))
def dts_close():
return "};\n"
def dts_intr(name, csr):
return indent("interrupts = <{} 0>;\n".format(
hex(csr['constants'][name + '_interrupt'])
))
def dts_reg(regs):
dtsi = 'reg = <'
formatted_registers = '\n'.join(
'0x{:x} 0x{:x}'.format(reg['addr'], reg['size'])
for reg in regs
)
dtsi += indent_all_but_first(formatted_registers)
dtsi += '>;'
return indent_all(dtsi) + '\n'
def dts_reg_names(regs):
dtsi = 'reg-names = '
formatted_registers = ',\n'.join(
'"{}"'.format(reg['name'])
for reg in regs
)
dtsi += indent_all_but_first(formatted_registers)
dtsi += ';'
return indent_all(dtsi) + '\n'
# DTS handlers
def disabled_handler(name, parm, csr):
return " status = \"disabled\";\n"
return indent('status = "disabled";\n')
def ram_handler(name, parm, csr):
return dts_reg(" ".join([
hex(csr['memories'][name]['base']),
hex(csr['memories'][name]['size'])]))
mem_reg = {
'addr': csr['memories'][name]['base'],
'size': csr['memories'][name]['size'],
}
return dts_reg([mem_reg])
def ethmac_handler(name, parm, csr):
dtsi = dts_reg(" ".join([
hex(csr['csr_bases'][name]),
hex(parm['size']),
hex(csr['memories'][name]['base']),
hex(csr['memories'][name]['size'])]))
rx_registers = get_registers_of(name + '_sram_writer', csr)
for reg in rx_registers:
reg['name'] = 'rx_' + reg['name']
tx_registers = get_registers_of(name + '_sram_reader', csr)
for reg in tx_registers:
reg['name'] = 'tx_' + reg['name']
eth_buffers = {
'name': 'buffers',
'addr': csr['memories'][name]['base'],
'size': csr['memories'][name]['size'],
'type': csr['memories'][name]['type'],
}
registers = rx_registers + tx_registers + [eth_buffers]
dtsi = dts_reg(registers)
dtsi += dts_reg_names(registers)
dtsi += dts_intr(name, csr)
return dtsi
def i2c_handler(name, parm, csr):
dtsi = dts_reg(" ".join([
hex(csr['csr_bases'][name]),
hex(parm['size']),
hex(csr['csr_bases'][name] + parm['size']),
hex(parm['size'])]))
dtsi += dts_intr(name, csr)
registers = get_registers_of(name, csr)
if len(registers) == 0:
raise KeyError
for reg in registers:
if reg["name"] == "w":
reg["name"] = "write"
elif reg["name"] == "r":
reg["name"] = "read"
dtsi = dts_reg(registers)
dtsi += dts_reg_names(registers)
return dtsi
def peripheral_handler(name, parm, csr):
dtsi = dts_reg(" ".join([
hex(csr['csr_bases'][name]),
hex(parm['size'])]))
registers = get_registers_of(name, csr)
if len(registers) == 0:
raise KeyError
dtsi = dts_reg(registers)
dtsi += dts_reg_names(registers)
try:
dtsi += dts_intr(name, csr)
except KeyError as e:
@ -76,29 +173,24 @@ overlay_handlers = {
'uart': {
'handler': peripheral_handler,
'alias': 'uart0',
'size': 0x20,
'config_entry': 'UART_LITEUART'
},
'timer0': {
'handler': peripheral_handler,
'size': 0x40,
'config_entry': 'LITEX_TIMER'
},
'ethmac': {
'handler': ethmac_handler,
'alias': 'eth0',
'size': 0x80,
'config_entry': 'ETH_LITEETH'
},
'spiflash': {
'handler': peripheral_handler,
'alias': 'spi0',
'size': 12,
'config_entry': 'SPI_LITESPI'
},
'i2c0' : {
'handler': i2c_handler,
'size': 0x4,
'config_entry': 'I2C_LITEX'
},
'main_ram': {
@ -108,7 +200,6 @@ overlay_handlers = {
'identifier_mem': {
'handler': peripheral_handler,
'alias': 'dna0',
'size': 0x100,
}
}
@ -137,6 +228,10 @@ def generate_dts_config(csr):
if name not in overlay_handlers.keys():
print('No overlay handler for:', name, 'at', hex(value))
cnf += ' -DCONFIG_LITEX_CSR_DATA_WIDTH={}'.format(
csr['constants']['config_csr_data_width'],
)
return dts, cnf