Skip to content

Commit

Permalink
add support for CSR device groups
Browse files Browse the repository at this point in the history
sbourdeauducq committed Jun 28, 2017
1 parent 2d3f62f commit b1704cf
Showing 3 changed files with 88 additions and 45 deletions.
3 changes: 2 additions & 1 deletion misoc/integration/builder.py
Original file line number Diff line number Diff line change
@@ -89,6 +89,7 @@ def _generate_includes(self):
memory_regions = self.soc.get_memory_regions()
flash_boot_address = getattr(self.soc, "flash_boot_address", None)
csr_regions = self.soc.get_csr_regions()
csr_groups = self.soc.get_csr_groups()
constants = self.soc.get_constants()
if isinstance(self.soc, soc_sdram.SoCSDRAM) and self.soc._sdram_phy:
sdram_phy_settings = self.soc._sdram_phy[0].settings
@@ -123,7 +124,7 @@ def define(k, v):
with WriteGenerated(generated_dir, "mem.rs") as f:
f.write(cpu_interface.get_mem_rust(memory_regions, flash_boot_address))
with WriteGenerated(generated_dir, "csr.rs") as f:
f.write(cpu_interface.get_csr_rust(csr_regions, constants))
f.write(cpu_interface.get_csr_rust(csr_regions, csr_groups, constants))
with WriteGenerated(generated_dir, "rust-cfg") as f:
f.write(cpu_interface.get_rust_cfg(csr_regions, constants))

126 changes: 82 additions & 44 deletions misoc/integration/cpu_interface.py
Original file line number Diff line number Diff line change
@@ -61,7 +61,11 @@ def get_mem_rust(regions, flash_boot_address):
return r


def _get_rw_functions_c(reg_name, reg_base, nwords, busword, read_only, with_access_functions):
def is_readonly(csr):
return isinstance(csr, CSRStatus)


def _get_rw_functions_c(reg_name, reg_base, nwords, busword, read_only):
r = ""

r += "#define CSR_"+reg_name.upper()+"_ADDR "+hex(reg_base)+"\n"
@@ -79,33 +83,31 @@ def _get_rw_functions_c(reg_name, reg_base, nwords, busword, read_only, with_acc
else:
ctype = "unsigned char"

if with_access_functions:
r += "static inline "+ctype+" "+reg_name+"_read(void) {\n"
if size > 1:
r += "\t"+ctype+" r = MMPTR("+hex(reg_base)+");\n"
for byte in range(1, nwords):
r += "\tr <<= "+str(busword)+";\n\tr |= MMPTR("+hex(reg_base+4*byte)+");\n"
r += "\treturn r;\n}\n"
else:
r += "\treturn MMPTR("+hex(reg_base)+");\n}\n"

if not read_only:
r += "static inline void "+reg_name+"_write("+ctype+" value) {\n"
for word in range(nwords):
shift = (nwords-word-1)*busword
if shift:
value_shifted = "value >> "+str(shift)
else:
value_shifted = "value"
r += "\tMMPTR("+hex(reg_base+4*word)+") = "+value_shifted+";\n"
r += "}\n"
r += "static inline "+ctype+" "+reg_name+"_read(void) {\n"
if size > 1:
r += "\t"+ctype+" r = MMPTR("+hex(reg_base)+");\n"
for byte in range(1, nwords):
r += "\tr <<= "+str(busword)+";\n\tr |= MMPTR("+hex(reg_base+4*byte)+");\n"
r += "\treturn r;\n}\n"
else:
r += "\treturn MMPTR("+hex(reg_base)+");\n}\n"

if not read_only:
r += "static inline void "+reg_name+"_write("+ctype+" value) {\n"
for word in range(nwords):
shift = (nwords-word-1)*busword
if shift:
value_shifted = "value >> "+str(shift)
else:
value_shifted = "value"
r += "\tMMPTR("+hex(reg_base+4*word)+") = "+value_shifted+";\n"
r += "}\n"
return r


def get_csr_header(regions, constants, with_access_functions=True):
def get_csr_header(regions, constants):
r = "#ifndef __GENERATED_CSR_H\n#define __GENERATED_CSR_H\n"
if with_access_functions:
r += "#include <hw/common.h>\n"
r += "#include <hw/common.h>\n"
for name, origin, busword, obj in regions:
if isinstance(obj, Memory):
r += "#define CSR_"+name.upper()+"_BASE "+hex(origin)+"\n"
@@ -114,7 +116,7 @@ def get_csr_header(regions, constants, with_access_functions=True):
r += "#define CSR_"+name.upper()+"_BASE "+hex(origin)+"\n"
for csr in obj:
nr = (csr.size + busword - 1)//busword
r += _get_rw_functions_c(name + "_" + csr.name, origin, nr, busword, isinstance(csr, CSRStatus), with_access_functions)
r += _get_rw_functions_c(name + "_" + csr.name, origin, nr, busword, is_readonly(csr))
origin += 4*nr

r += "\n/* constants */\n"
@@ -136,26 +138,30 @@ def get_csr_header(regions, constants, with_access_functions=True):
return r


def _get_rw_functions_rs(reg_name, reg_base, nwords, busword, read_only):
r = ""

r += " pub const "+reg_name.upper()+"_ADDR: *mut u32 = "+hex(reg_base)+" as *mut u32;\n"
r += " pub const "+reg_name.upper()+"_SIZE: usize = "+str(nwords)+";\n\n"

size = nwords*busword
def _get_rstype(size):
if size > 64:
return r
return None
elif size > 32:
rstype = "u64"
return "u64"
elif size > 16:
rstype = "u32"
return "u32"
elif size > 8:
rstype = "u16"
return "u16"
elif size > 1:
rstype = "u8"
return "u8"
else:
rstype = "bool"
return "bool"


def _get_rw_functions_rs(reg_name, reg_base, nwords, busword, read_only):
r = ""

r += " pub const "+reg_name.upper()+"_ADDR: *mut u32 = "+hex(reg_base)+" as *mut u32;\n"
r += " pub const "+reg_name.upper()+"_SIZE: usize = "+str(nwords)+";\n\n"

rstype = _get_rstype(nwords*busword)
if rstype is None:
return r
rsname = reg_name.upper()+"_ADDR"

r += " #[inline(always)]\n"
@@ -185,7 +191,14 @@ def _get_rw_functions_rs(reg_name, reg_base, nwords, busword, read_only):
return r


def get_csr_rust(regions, constants, with_access_functions=True):
def _region_by_name(regions, search_name):
for name, origin, busword, obj in regions:
if name == search_name:
return origin, busword, obj
raise KeyError


def get_csr_rust(regions, groups, constants):
r = "// Include this file as:\n"
r += "// include!(concat!(env!(\"BUILDINC_DIRECTORY\"), \"/generated/csr.rs\"));\n"
r += "#[allow(dead_code)]\n"
@@ -198,12 +211,37 @@ def get_csr_rust(regions, constants, with_access_functions=True):
r += " pub mod "+name+" {\n"
r += " use core::ptr::{read_volatile, write_volatile};\n\n"
for csr in obj:
nr = (csr.size + busword - 1)//busword
r += _get_rw_functions_rs(csr.name, origin, nr, busword,
isinstance(csr, CSRStatus))
origin += 4*nr
nwords = (csr.size + busword - 1)//busword
r += _get_rw_functions_rs(csr.name, origin, nwords, busword,
is_readonly(csr))
origin += 4*nwords
r += " }\n\n"

for group_name, group_members in groups:
if group_members:
struct_name = group_name.capitalize() + "Struct"

csrs = _region_by_name(regions, group_members[0])[2]
r += " pub struct " + struct_name + " {\n"
for csr in csrs:
nwords = (csr.size + busword - 1)//busword
rstype = _get_rstype(nwords*busword)
r += " pub " + csr.name + "_read: fn() -> " + rstype + ",\n"
if not is_readonly(csr):
r += " pub " + csr.name + "_write: fn(" + rstype + "),\n";
r += " };\n\n"

r += (" pub static " + group_name.upper() +
": [" + struct_name + "; " + str(len(group_members)) + "] = [\n")
for member in group_members:
r += " " + struct_name + " {\n"
for csr in csrs:
r += " " + csr.name + "_read: " + member + "::" + csr.name + "_read,\n"
if not is_readonly(csr):
r += " " + csr.name + "_write: " + member + "::" + csr.name + "_write,\n"
r += " },\n"
r += " ];\n\n"

for name, value in constants:
if value is None:
value = "1"
@@ -239,6 +277,6 @@ def get_csr_csv(regions):
if not isinstance(obj, Memory):
for csr in obj:
nr = (csr.size + busword - 1)//busword
r += "{}_{},0x{:08x},{},{}\n".format(name, csr.name, origin, nr, "ro" if isinstance(csr, CSRStatus) else "rw")
r += "{}_{},0x{:08x},{},{}\n".format(name, csr.name, origin, nr, "ro" if is_readonly(csr) else "rw")
origin += 4*nr
return r
4 changes: 4 additions & 0 deletions misoc/integration/soc_core.py
Original file line number Diff line number Diff line change
@@ -66,6 +66,7 @@ def __init__(self, platform, clk_freq,
"timer0",
"tmpu"
]
self.csr_groups = []
self.interrupt_devices = []

if cpu_type == "lm32":
@@ -156,6 +157,9 @@ def add_csr_region(self, name, origin, busword, obj):
def get_csr_regions(self):
return self._csr_regions

def get_csr_groups(self):
return self.csr_groups

def get_constants(self):
r = []
for nr, name in enumerate(self.interrupt_devices):

0 comments on commit b1704cf

Please sign in to comment.