Add Zephyr DTS overlay generator
This commit is contained in:
parent
d9c67dd763
commit
fcbebde302
|
@ -0,0 +1,182 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Copyright (c) 2019-2021 Antmicro <www.antmicro.com>
|
||||||
|
# Copyright (c) 2021 Henk Vergonet <henk.vergonet@gmail.com>
|
||||||
|
#
|
||||||
|
# Zephyr DTS & config overlay generator for LiteX SoC.
|
||||||
|
#
|
||||||
|
# This script parses LiteX 'csr.json' file and generates DTS and config
|
||||||
|
# files overlay for Zephyr.
|
||||||
|
|
||||||
|
# Changelog:
|
||||||
|
# - 2021-07-05 Henk Vergonet <henk.vergonet@gmail.com>
|
||||||
|
# removed dependency on intermediate interpretation layers
|
||||||
|
# switch to JSON csr
|
||||||
|
# fix uart size parameter
|
||||||
|
# - 2021-07-15 Henk Vergonet <henk.vergonet@gmail.com>
|
||||||
|
# added identifier_mem handler as dna0
|
||||||
|
# added spiflash as spi0
|
||||||
|
#
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
# 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)
|
||||||
|
|
||||||
|
|
||||||
|
# DTS handlers
|
||||||
|
def disabled_handler(name, parm, csr):
|
||||||
|
return " status = \"disabled\";\n"
|
||||||
|
|
||||||
|
|
||||||
|
def ram_handler(name, parm, csr):
|
||||||
|
return dts_reg(" ".join([
|
||||||
|
hex(csr['memories'][name]['base']),
|
||||||
|
hex(csr['memories'][name]['size'])]))
|
||||||
|
|
||||||
|
|
||||||
|
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'])]))
|
||||||
|
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)
|
||||||
|
return dtsi
|
||||||
|
|
||||||
|
|
||||||
|
def peripheral_handler(name, parm, csr):
|
||||||
|
dtsi = dts_reg(" ".join([
|
||||||
|
hex(csr['csr_bases'][name]),
|
||||||
|
hex(parm['size'])]))
|
||||||
|
try:
|
||||||
|
dtsi += dts_intr(name, csr)
|
||||||
|
except KeyError as e:
|
||||||
|
print(' dtsi key', e, 'not found, no interrupt override')
|
||||||
|
return dtsi
|
||||||
|
|
||||||
|
|
||||||
|
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': {
|
||||||
|
'handler': ram_handler,
|
||||||
|
'alias': 'ram0',
|
||||||
|
},
|
||||||
|
'identifier_mem': {
|
||||||
|
'handler': peripheral_handler,
|
||||||
|
'alias': 'dna0',
|
||||||
|
'size': 0x100,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def generate_dts_config(csr):
|
||||||
|
dts = cnf = ''
|
||||||
|
|
||||||
|
for name, parm in overlay_handlers.items():
|
||||||
|
print('Generating overlay for:',name)
|
||||||
|
enable = 'y'
|
||||||
|
dtsi = dts_open(name, parm)
|
||||||
|
|
||||||
|
try:
|
||||||
|
dtsi += parm['handler'](name, parm, csr)
|
||||||
|
except KeyError as e:
|
||||||
|
print(' dtsi key', e, 'not found, disable', name)
|
||||||
|
enable = 'n'
|
||||||
|
dtsi += disabled_handler(name, parm, csr)
|
||||||
|
|
||||||
|
dtsi += dts_close()
|
||||||
|
dts += dtsi
|
||||||
|
if 'config_entry' in parm:
|
||||||
|
cnf += ' -DCONFIG_' + parm['config_entry'] + '=' + enable
|
||||||
|
|
||||||
|
for name, value in csr['csr_bases'].items():
|
||||||
|
if name not in overlay_handlers.keys():
|
||||||
|
print('No overlay handler for:', name, 'at', hex(value))
|
||||||
|
|
||||||
|
return dts, cnf
|
||||||
|
|
||||||
|
|
||||||
|
# helpers
|
||||||
|
def print_or_save(filepath, lines):
|
||||||
|
""" Prints given string on standard output or to the file.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
filepath (string): path to the file lines should be written to
|
||||||
|
or '-' to write to a standard output
|
||||||
|
lines (string): content to be printed/written
|
||||||
|
"""
|
||||||
|
if filepath == '-':
|
||||||
|
print(lines)
|
||||||
|
else:
|
||||||
|
with open(filepath, 'w') as f:
|
||||||
|
f.write(lines)
|
||||||
|
|
||||||
|
|
||||||
|
def parse_args():
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('conf_file',
|
||||||
|
help='JSON configuration generated by LiteX')
|
||||||
|
parser.add_argument('--dts', action='store', required=True,
|
||||||
|
help='Output DTS overlay file')
|
||||||
|
parser.add_argument('--config', action='store', required=True,
|
||||||
|
help='Output config overlay file')
|
||||||
|
return parser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
args = parse_args()
|
||||||
|
|
||||||
|
with open(args.conf_file) as f:
|
||||||
|
csr = json.load(f)
|
||||||
|
dts, config = generate_dts_config(csr)
|
||||||
|
|
||||||
|
print_or_save(args.dts, dts)
|
||||||
|
print_or_save(args.config, config)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
Loading…
Reference in New Issue