-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #15 from antmicro/zephyr_dts
Add script generating DTS overlay for Zephyr
- Loading branch information
Showing
1 changed file
with
179 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
#!/usr/bin/env python3 | ||
""" | ||
Copyright (c) 2019 Antmicro | ||
Zephyr DTS overlay generator for LiteX SoC. | ||
This script parses LiteX 'csr.csv' file and generates DTS file overlay | ||
for Zephyr. | ||
""" | ||
|
||
import argparse | ||
|
||
from litex.configuration import Configuration | ||
|
||
configuration = None | ||
|
||
|
||
def disabled_handler(name): | ||
return """ | ||
&{} {{ | ||
status = "disabled"; | ||
}}; | ||
""".format(name) | ||
|
||
|
||
def ram_handler(region, **kw): | ||
|
||
result = """ | ||
&ram0 {{ | ||
reg = <0x{address} {size}>; | ||
}}; | ||
""".format(address=hex(region['address'])[2:], size=hex(region['size'])) | ||
|
||
return result | ||
|
||
|
||
def ethmac_handler(peripheral, **kw): | ||
buf = kw['buffer']() | ||
|
||
result = """ | ||
&{} {{ | ||
""".format(kw['reference']) | ||
|
||
result += """ | ||
reg = <{} {} {} {}>; | ||
""".format(hex(peripheral['address']), | ||
hex(kw['size']), | ||
hex(buf['address']), | ||
hex(buf['size'])) | ||
|
||
if 'constants' in peripheral: | ||
if 'interrupt' in peripheral['constants']: | ||
irq_no = int(peripheral['constants']['interrupt'], 0) | ||
result += """ | ||
interrupts = <{} 0>; | ||
""".format(hex(irq_no)) | ||
|
||
result += """ | ||
}; | ||
""" | ||
return result | ||
|
||
|
||
def peripheral_handler(peripheral, **kw): | ||
result = """ | ||
&{} {{ | ||
""".format(kw['reference']) | ||
|
||
result += """ | ||
reg = <{} {}>; | ||
""".format(hex(peripheral['address']), | ||
hex(kw['size'])) | ||
|
||
if 'constants' in peripheral: | ||
if 'interrupt' in peripheral['constants']: | ||
irq_no = int(peripheral['constants']['interrupt'], 0) | ||
result += """ | ||
interrupts = <{} 0>; | ||
""".format(hex(irq_no)) | ||
|
||
result += """ | ||
}; | ||
""" | ||
return result | ||
|
||
|
||
def generate_dts(): | ||
peripheral_handlers = { | ||
'uart': { | ||
'handler': peripheral_handler, | ||
'reference': 'uart0', | ||
'size': 0x18 | ||
}, | ||
'timer0': { | ||
'handler': peripheral_handler, | ||
'reference': 'timer0', | ||
'size': 0x40 | ||
}, | ||
'ethmac': { | ||
'handler': ethmac_handler, | ||
'reference': 'eth0', | ||
'size': 0x6c, | ||
'buffer': lambda: configuration.mem_regions['ethmac'] | ||
} | ||
} | ||
|
||
mem_region_handler = { | ||
'main_ram': { | ||
'handler': ram_handler, | ||
} | ||
} | ||
|
||
result = "" | ||
|
||
for name, peripheral in configuration.peripherals.items(): | ||
if name not in peripheral_handlers: | ||
print('Skipping unsupported peripheral `{}` at {}' | ||
.format(name, hex(peripheral['address']))) | ||
continue | ||
|
||
h = peripheral_handlers[name] | ||
result += h['handler'](peripheral, **h) | ||
|
||
# disable all known, but not present devices | ||
for name, handler in peripheral_handlers.items(): | ||
if name in configuration.peripherals.keys(): | ||
# this has already been generated | ||
continue | ||
result += disabled_handler(handler['reference']) | ||
|
||
print(configuration.mem_regions) | ||
for name, mem_region in configuration.mem_regions.items(): | ||
if name not in mem_region_handler: | ||
print('Skipping unsupported mem_region `{}` at {}' | ||
.format(name, hex(mem_region['address']))) | ||
continue | ||
|
||
h = mem_region_handler[name] | ||
result += h['handler'](mem_region, **h) | ||
|
||
return result | ||
|
||
|
||
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='CSV configuration generated by LiteX') | ||
parser.add_argument('--dts', action='store', required=True, | ||
help='Output DTS overlay file') | ||
args = parser.parse_args() | ||
|
||
return args | ||
|
||
|
||
def main(): | ||
global configuration | ||
args = parse_args() | ||
|
||
configuration = Configuration(args.conf_file) | ||
print_or_save(args.dts, generate_dts()) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |