From 93b29bb359c077e0a525a9740dad8effa8d4b2dd Mon Sep 17 00:00:00 2001 From: Robert Schilling Date: Thu, 23 May 2024 12:15:07 +0200 Subject: [PATCH] [topgen] Generically filter for MMIO region visible devices Add a new subspace entry to the address spaces to group multple address to the same address space. For this subspace, the range is computed and added as a definition to the C and Rust collateral. Signed-off-by: Robert Schilling --- .../data/autogen/top_darjeeling.gen.hjson | 57 +++++++++++++++ hw/top_darjeeling/data/top_darjeeling.hjson | 57 ++++++++++++++- .../sw/autogen/chip/top_darjeeling.rs | 6 +- .../sw/autogen/chip/top_darjeeling_memory.rs | 6 +- hw/top_darjeeling/sw/autogen/top_darjeeling.h | 4 +- .../sw/autogen/top_darjeeling_memory.h | 4 +- .../data/autogen/top_earlgrey.gen.hjson | 58 +++++++++++++++ hw/top_earlgrey/data/top_earlgrey.hjson | 58 ++++++++++++++- util/topgen/c.py | 52 +------------- util/topgen/lib.py | 70 +++++++++++++++++++ util/topgen/rust.py | 51 +------------- util/topgen/templates/toplevel.h.tpl | 17 +++-- util/topgen/templates/toplevel.rs.tpl | 17 +++-- util/topgen/templates/toplevel_memory.h.tpl | 17 +++-- util/topgen/templates/toplevel_memory.rs.tpl | 17 +++-- util/topgen/validate.py | 2 +- 16 files changed, 357 insertions(+), 136 deletions(-) diff --git a/hw/top_darjeeling/data/autogen/top_darjeeling.gen.hjson b/hw/top_darjeeling/data/autogen/top_darjeeling.gen.hjson index 226faefaad6a0..9b70e961527ce 100644 --- a/hw/top_darjeeling/data/autogen/top_darjeeling.gen.hjson +++ b/hw/top_darjeeling/data/autogen/top_darjeeling.gen.hjson @@ -454,6 +454,63 @@ { name: hart desc: The main address space, shared between the CPU and DM + subspaces: + [ + { + name: mmio + desc: + ''' + MMIO region excludes any memory that is separate from the module configuration + space, i.e. ROM, main SRAM, and mbx SRAM are excluded but retention SRAM or + spi_device are included. + ''' + nodes: + [ + uart0 + gpio + spi_device + i2c0 + rv_timer + otp_ctrl + lc_ctrl.regs + alert_handler + spi_host0 + pwrmgr_aon + rstmgr_aon + clkmgr_aon + pinmux_aon + aon_timer_aon + ast + sensor_ctrl + soc_proxy.core + sram_ctrl_ret_aon + rv_plic + aes + hmac + otbn + keymgr_dpe + csrng + edn0 + edn1 + sram_ctrl_main.regs + sram_ctrl_mbox.regs + rom_ctrl0.regs + rom_ctrl1.regs + dma + mbx0.core + mbx1.core + mbx2.core + mbx3.core + mbx4.core + mbx5.core + mbx6.core + mbx_jtag.core + mbx_pcie0.core + mbx_pcie1.core + rv_core_ibex + ] + } + ] } { name: soc_mbx diff --git a/hw/top_darjeeling/data/top_darjeeling.hjson b/hw/top_darjeeling/data/top_darjeeling.hjson index ec2c11cc675a8..5edee7aafac7a 100644 --- a/hw/top_darjeeling/data/top_darjeeling.hjson +++ b/hw/top_darjeeling/data/top_darjeeling.hjson @@ -166,7 +166,62 @@ // all peripherals, though not every peripheral will be accessible to every // host in that address space--Access privileges are separate from addresses. addr_spaces: [ - { name: "hart", desc: "The main address space, shared between the CPU and DM"}, + { name: "hart" + desc: "The main address space, shared between the CPU and DM" + subspaces: [ + { name: "mmio", + desc: ''' + MMIO region excludes any memory that is separate from the module configuration + space, i.e. ROM, main SRAM, and mbx SRAM are excluded but retention SRAM or + spi_device are included. + ''' + nodes: [ + "uart0", + "gpio", + "spi_device", + "i2c0", + "rv_timer", + "otp_ctrl", + "lc_ctrl.regs", + "alert_handler", + "spi_host0", + "pwrmgr_aon", + "rstmgr_aon", + "clkmgr_aon", + "pinmux_aon", + "aon_timer_aon", + "ast" + "sensor_ctrl", + "soc_proxy.core", + "sram_ctrl_ret_aon", + "rv_plic", + "aes", + "hmac", + "otbn", + "keymgr_dpe" + "csrng", + "edn0", + "edn1", + "sram_ctrl_main.regs", + "sram_ctrl_mbox.regs", + "rom_ctrl0.regs", + "rom_ctrl1.regs", + "dma", + "mbx0.core", + "mbx1.core", + "mbx2.core", + "mbx3.core", + "mbx4.core", + "mbx5.core", + "mbx6.core", + "mbx_jtag.core", + "mbx_pcie0.core", + "mbx_pcie1.core", + "rv_core_ibex" + ], + }, + ] + } { name: "soc_mbx", desc: "SoC address space for mailbox access"}, { name: "soc_dbg", desc: "SoC address space for debug module interfaces"}, ] diff --git a/hw/top_darjeeling/sw/autogen/chip/top_darjeeling.rs b/hw/top_darjeeling/sw/autogen/chip/top_darjeeling.rs index 2798bf4982658..681d8f176b8ed 100644 --- a/hw/top_darjeeling/sw/autogen/chip/top_darjeeling.rs +++ b/hw/top_darjeeling/sw/autogen/chip/top_darjeeling.rs @@ -2745,7 +2745,7 @@ pub enum TopDarjeelingHintableClocks { /// MMIO Region /// /// MMIO region excludes any memory that is separate from the module -/// configuration space, i.e. ROM, main SRAM, and flash are excluded but -/// retention SRAM, spi_device memory, or usbdev memory are included. +/// configuration space, i.e. ROM, main SRAM, and mbx SRAM are excluded but +/// retention SRAM or spi_device are included. pub const TOP_DARJEELING_MMIO_BASE_ADDR: usize = 0x21100000; -pub const TOP_DARJEELING_MMIO_SIZE_BYTES: usize = 0xF400020; +pub const TOP_DARJEELING_MMIO_SIZE_BYTES: usize = 0xF501000; diff --git a/hw/top_darjeeling/sw/autogen/chip/top_darjeeling_memory.rs b/hw/top_darjeeling/sw/autogen/chip/top_darjeeling_memory.rs index 1216ec9816016..a4b693258a85d 100644 --- a/hw/top_darjeeling/sw/autogen/chip/top_darjeeling_memory.rs +++ b/hw/top_darjeeling/sw/autogen/chip/top_darjeeling_memory.rs @@ -734,7 +734,7 @@ pub const TOP_DARJEELING_RV_CORE_IBEX_CFG_SIZE_BYTES: usize = 0x800; /// MMIO Region /// /// MMIO region excludes any memory that is separate from the module -/// configuration space, i.e. ROM, main SRAM, and flash are excluded but -/// retention SRAM, spi_device memory, or usbdev memory are included. +/// configuration space, i.e. ROM, main SRAM, and mbx SRAM are excluded but +/// retention SRAM or spi_device are included. pub const TOP_DARJEELING_MMIO_BASE_ADDR: usize = 0x21100000; -pub const TOP_DARJEELING_MMIO_SIZE_BYTES: usize = 0xF400020; +pub const TOP_DARJEELING_MMIO_SIZE_BYTES: usize = 0xF501000; diff --git a/hw/top_darjeeling/sw/autogen/top_darjeeling.h b/hw/top_darjeeling/sw/autogen/top_darjeeling.h index 391c067a9445f..03605bfcf85bc 100644 --- a/hw/top_darjeeling/sw/autogen/top_darjeeling.h +++ b/hw/top_darjeeling/sw/autogen/top_darjeeling.h @@ -1675,8 +1675,8 @@ typedef enum top_darjeeling_hintable_clocks { * MMIO Region * * MMIO region excludes any memory that is separate from the module - * configuration space, i.e. ROM, main SRAM, and flash are excluded but - * retention SRAM, spi_device memory, or usbdev memory are included. + * configuration space, i.e. ROM, main SRAM, and mbx SRAM are excluded but + * retention SRAM or spi_device are included. */ #define TOP_DARJEELING_MMIO_BASE_ADDR 0x21100000u #define TOP_DARJEELING_MMIO_SIZE_BYTES 0xF501000u diff --git a/hw/top_darjeeling/sw/autogen/top_darjeeling_memory.h b/hw/top_darjeeling/sw/autogen/top_darjeeling_memory.h index 552e2be44067d..5c700b539d992 100644 --- a/hw/top_darjeeling/sw/autogen/top_darjeeling_memory.h +++ b/hw/top_darjeeling/sw/autogen/top_darjeeling_memory.h @@ -983,8 +983,8 @@ * MMIO Region * * MMIO region excludes any memory that is separate from the module - * configuration space, i.e. ROM, main SRAM, and flash are excluded but - * retention SRAM, spi_device memory, or usbdev memory are included. + * configuration space, i.e. ROM, main SRAM, and mbx SRAM are excluded but + * retention SRAM or spi_device are included. */ #define TOP_DARJEELING_MMIO_BASE_ADDR 0x21100000 #define TOP_DARJEELING_MMIO_SIZE_BYTES 0xF501000 diff --git a/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson b/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson index c82d7060678c7..b72682ab0c272 100644 --- a/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson +++ b/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson @@ -524,6 +524,64 @@ { name: hart desc: The main address space, shared between the CPU and DM + subspaces: + [ + { + name: mmio + desc: + ''' + MMIO region excludes any memory that is separate from the module configuration + space, i.e. ROM, main SRAM, and flash are excluded but retention SRAM, spi_device + memory, or usbdev memory are included. + ''' + nodes: + [ + uart0 + uart1 + uart2 + uart3 + gpio + spi_device + i2c0 + i2c1 + i2c2 + pattgen + rv_timer + otp_ctrl + lc_ctrl + alert_handler + spi_host0 + spi_host1 + usbdev + pwrmgr_aon + rstmgr_aon + clkmgr_aon + sysrst_ctrl_aon + adc_ctrl_aon + pwm_aon + pinmux_aon + aon_timer_aon + ast + sensor_ctrl + sram_ctrl_ret_aon + flash_ctrl.core + flash_ctrl.prim + rv_plic + aes + hmac + kmac + otbn + keymgr + csrng + entropy_src + edn0 + edn1 + sram_ctrl_main.regs + rom_ctrl0.regs + rv_core_ibex + ] + } + ] } ] module: diff --git a/hw/top_earlgrey/data/top_earlgrey.hjson b/hw/top_earlgrey/data/top_earlgrey.hjson index fe30cc4ed3480..fb55da31fb856 100644 --- a/hw/top_earlgrey/data/top_earlgrey.hjson +++ b/hw/top_earlgrey/data/top_earlgrey.hjson @@ -171,7 +171,63 @@ // all peripherals, though not every peripheral will be accessible to every // host in that address space--Access privileges are separate from addresses. addr_spaces: [ - { name: "hart", desc: "The main address space, shared between the CPU and DM"}, + { name: "hart", + desc: "The main address space, shared between the CPU and DM" + subspaces: [ + { name: "mmio", + desc: ''' + MMIO region excludes any memory that is separate from the module configuration + space, i.e. ROM, main SRAM, and flash are excluded but retention SRAM, spi_device + memory, or usbdev memory are included. + ''' + nodes: [ + "uart0", + "uart1", + "uart2", + "uart3", + "gpio", + "spi_device", + "i2c0", + "i2c1", + "i2c2", + "pattgen", + "rv_timer" + "otp_ctrl", + "lc_ctrl", + "alert_handler", + "spi_host0", + "spi_host1", + "usbdev", + "pwrmgr_aon", + "rstmgr_aon", + "clkmgr_aon", + "sysrst_ctrl_aon", + "adc_ctrl_aon", + "pwm_aon", + "pinmux_aon", + "aon_timer_aon", + "ast", + "sensor_ctrl", + "sram_ctrl_ret_aon", + "flash_ctrl.core", + "flash_ctrl.prim", + "rv_plic", + "aes", + "hmac", + "kmac", + "otbn", + "keymgr", + "csrng", + "entropy_src", + "edn0" + "edn1", + "sram_ctrl_main.regs" + "rom_ctrl0.regs", + "rv_core_ibex" + ] + } + ] + }, ] // `module` defines the peripherals. diff --git a/util/topgen/c.py b/util/topgen/c.py index ad7f1c42f49fa..aeb1d65c6d225 100644 --- a/util/topgen/c.py +++ b/util/topgen/c.py @@ -10,32 +10,11 @@ from mako.template import Template from reggen.ip_block import IpBlock -from .lib import Name, get_base_and_size +from .lib import Name, get_base_and_size, MemoryRegion, init_subranges C_FILE_EXTENSIONS = (".c", ".h", ".cc", ".inc") -class MemoryRegion(object): - def __init__(self, name: Name, base_addr: int, size_bytes: int): - assert isinstance(base_addr, int) - self.name = name - self.base_addr = base_addr - self.size_bytes = size_bytes - self.size_words = (size_bytes + 3) // 4 - - def base_addr_name(self): - return self.name + Name(["base", "addr"]) - - def offset_name(self): - return self.name + Name(["offset"]) - - def size_bytes_name(self): - return self.name + Name(["size", "bytes"]) - - def size_words_name(self): - return self.name + Name(["size", "words"]) - - class CEnum(object): def __init__(self, name): self.name = name @@ -123,7 +102,7 @@ def __init__(self, top_info, name_to_block: Dict[str, IpBlock]): self._init_rstmgr_sw_rsts() self._init_pwrmgr_reset_requests() self._init_clkmgr_clocks() - self._init_mmio_region() + self.subranges = init_subranges(self.top, self._top_name, self.devices(), self.addr_space) def devices(self) -> List[Tuple[Tuple[str, Optional[str]], MemoryRegion]]: '''Return a list of MemoryRegion objects for devices on the bus @@ -510,30 +489,3 @@ def _init_clkmgr_clocks(self): self.clkmgr_gateable_clocks = gateable_clocks self.clkmgr_hintable_clocks = hintable_clocks - - def _init_mmio_region(self): - """ - Computes the bounds of the MMIO region. - - MMIO region excludes any memory that is separate from the module configuration - space, i.e. ROM, main SRAM, and flash are excluded but retention SRAM, - spi_device memory, or usbdev memory are included. - """ - memories = [region.base_addr for (_, region) in self.memories()] - # TODO(#14345): Remove the hardcoded "rv_dm" name check below. - # TODO: we need a cleaner way to define which buses are visible - # by the CPU and which ones are not. For now, exclude every - # interface with the name `dbg`, since that is attached to the - # debug bus which is not connected to the CPU LSU. - regions = [ - region for ((dev_name, if_name), region) in self.devices() - if (dev_name == "sram_ctrl_ret_aon" and if_name == 'ram') or - (region.base_addr not in memories and dev_name != "rv_dm" and - (if_name is None or if_name != 'dbg')) - ] - # Note: The memory interface of the retention RAM is in the MMIO address space, - # which we prefer since it reduces the number of ePMP regions we need. - mmio = range(min([r.base_addr for r in regions]), - max([r.base_addr + r.size_bytes for r in regions])) - self.mmio = MemoryRegion(self._top_name + Name(["mmio"]), mmio.start, - mmio.stop - mmio.start) diff --git a/util/topgen/lib.py b/util/topgen/lib.py index 9286ea806468e..1d7df4472f5ff 100644 --- a/util/topgen/lib.py +++ b/util/topgen/lib.py @@ -85,6 +85,27 @@ def remove_part(self, part_to_remove: str) -> "Name": return Name([p for p in self.parts if p != part_to_remove]) +class MemoryRegion(object): + def __init__(self, name: Name, base_addr: int, size_bytes: int): + assert isinstance(base_addr, int) + self.name = name + self.base_addr = base_addr + self.size_bytes = size_bytes + self.size_words = (size_bytes + 3) // 4 + + def base_addr_name(self): + return self.name + Name(["base", "addr"]) + + def offset_name(self): + return self.name + Name(["offset"]) + + def size_bytes_name(self): + return self.name + Name(["size", "bytes"]) + + def size_words_name(self): + return self.name + Name(["size", "words"]) + + def is_ipcfg(ip: Path) -> bool: # return bool log.info("IP Path: %s" % repr(ip)) ip_name = ip.parents[1].name @@ -566,3 +587,52 @@ def is_lc_ctrl(modules): return True return False + + +def get_addr_space(top, addr_space_name): + """Returns the address dict for a given address space name""" + for addr_space in top['addr_spaces']: + if addr_space['name'] == addr_space_name: + return addr_space + assert False, "Address space not found" + + +def get_device_ranges(devices, device_name): + ranges = {} + for (dev_name, if_name), range in devices: + if dev_name == device_name: + ranges[if_name] = range + return ranges + + +def init_subranges(top, top_name, devices, addr_space_name): + """ + Computes the bounds of all subspace regions of a given address space. + """ + subspace_regions = [] + addr_space = get_addr_space(top, addr_space_name) + for subspace in addr_space.get('subspaces', []): + regions = [] + for node in subspace['nodes']: + # Get the dot-delimited interface name. If no interface name is given, all device + # interfaces are considered for this subspace range. + split_dev = node.rsplit('.', 1) + dev_name = split_dev[0] + if_name = None + if len(split_dev) > 1: + if_name = split_dev[1] + + ranges = get_device_ranges(devices, dev_name) + if if_name: + # Only a single interface, if name contained an interface name + regions.append(ranges[if_name]) + else: + # All interfaces + regions += list(ranges.values()) + + subspace_range = range(min([r.base_addr for r in regions]), + max([r.base_addr + r.size_bytes for r in regions])) + subspace_region = MemoryRegion(top_name + Name([subspace['name']]), subspace_range.start, + subspace_range.stop - subspace_range.start) + subspace_regions.append((subspace['name'], subspace['desc'], subspace_region)) + return subspace_regions diff --git a/util/topgen/rust.py b/util/topgen/rust.py index 6fe1e6e0fc554..2b985f984b31e 100644 --- a/util/topgen/rust.py +++ b/util/topgen/rust.py @@ -9,32 +9,11 @@ from mako.template import Template from reggen.ip_block import IpBlock -from .lib import Name, get_base_and_size +from .lib import Name, get_base_and_size, MemoryRegion, init_subranges RUST_FILE_EXTENSIONS = (".rs") -class MemoryRegion(object): - def __init__(self, name: Name, base_addr: int, size_bytes: int): - assert isinstance(base_addr, int) - self.name = name - self.base_addr = base_addr - self.size_bytes = size_bytes - self.size_words = (size_bytes + 3) // 4 - - def base_addr_name(self): - return self.name + Name(["base", "addr"]) - - def offset_name(self): - return self.name + Name(["offset"]) - - def size_bytes_name(self): - return self.name + Name(["size", "bytes"]) - - def size_words_name(self): - return self.name + Name(["size", "words"]) - - class RustEnum(object): def __init__(self, top_name, name, repr_type=None): self.name = top_name + name @@ -214,7 +193,7 @@ def __init__(self, top_info, name_to_block: Dict[str, IpBlock], version_stamp: D self._init_rstmgr_sw_rsts() self._init_pwrmgr_reset_requests() self._init_clkmgr_clocks() - self._init_mmio_region() + self.subranges = init_subranges(self.top, self._top_name, self.devices(), self.addr_space) def devices(self) -> List[Tuple[Tuple[str, Optional[str]], MemoryRegion]]: '''Return a list of MemoryRegion objects for devices on the bus @@ -597,29 +576,3 @@ def _init_clkmgr_clocks(self): self.clkmgr_gateable_clocks = gateable_clocks self.clkmgr_hintable_clocks = hintable_clocks - - def _init_mmio_region(self): - """ - Computes the bounds of the MMIO region. - - MMIO region excludes any memory that is separate from the module configuration - space, i.e. ROM, main SRAM, and flash are excluded but retention SRAM, - spi_device memory, or usbdev memory are included. - """ - memories = [region.base_addr for (_, region) in self.memories()] - # TODO(#14345): Remove the hardcoded "rv_dm" name check below. - # TODO: we need a cleaner way to define which buses are visible - # by the CPU and which ones are not. For now, exclude every - # interface with the name `dbg`, since that is attached to the - # debug bus which is not connected to the CPU LSU. - regions = [ - region for ((dev_name, if_name), region) in self.devices() - if region.base_addr not in memories and dev_name != "rv_dm" and - (if_name is None or if_name != 'dbg') - ] - # Note: The memory interface of the retention RAM is in the MMIO address space, - # which we prefer since it reduces the number of ePMP regions we need. - mmio = range(min([r.base_addr for r in regions]), - max([r.base_addr + r.size_bytes for r in regions])) - self.mmio = MemoryRegion(self._top_name + Name(["mmio"]), mmio.start, - mmio.stop - mmio.start) diff --git a/util/topgen/templates/toplevel.h.tpl b/util/topgen/templates/toplevel.h.tpl index 74b85614cd201..e57ad68525efd 100644 --- a/util/topgen/templates/toplevel.h.tpl +++ b/util/topgen/templates/toplevel.h.tpl @@ -1,6 +1,9 @@ // Copyright lowRISC contributors. // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 +<% +import textwrap +%>\ #ifndef ${helper.header_macro_prefix}_TOP_${top["name"].upper()}_H_ #define ${helper.header_macro_prefix}_TOP_${top["name"].upper()}_H_ @@ -234,15 +237,17 @@ ${helper.clkmgr_gateable_clocks.render()} */ ${helper.clkmgr_hintable_clocks.render()} +% for (subspace_name, description, subspace_range) in helper.subranges: /** - * MMIO Region + * ${subspace_name.upper()} Region * - * MMIO region excludes any memory that is separate from the module - * configuration space, i.e. ROM, main SRAM, and flash are excluded but - * retention SRAM, spi_device memory, or usbdev memory are included. +% for l in textwrap.wrap(description, 77, break_long_words=False): + * ${l} +% endfor */ -#define ${helper.mmio.base_addr_name().as_c_define()} ${"0x{:X}u".format(helper.mmio.base_addr)} -#define ${helper.mmio.size_bytes_name().as_c_define()} ${"0x{:X}u".format(helper.mmio.size_bytes)} +#define ${subspace_range.base_addr_name().as_c_define()} ${"0x{:X}u".format(subspace_range.base_addr)} +#define ${subspace_range.size_bytes_name().as_c_define()} ${"0x{:X}u".format(subspace_range.size_bytes)} +% endfor // Header Extern Guard #ifdef __cplusplus diff --git a/util/topgen/templates/toplevel.rs.tpl b/util/topgen/templates/toplevel.rs.tpl index 9971eead9efae..9b56017ec97a2 100644 --- a/util/topgen/templates/toplevel.rs.tpl +++ b/util/topgen/templates/toplevel.rs.tpl @@ -1,6 +1,9 @@ // Copyright lowRISC contributors. // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 +<% +import textwrap +%>\ ${helper.file_header.render()} // This file was generated automatically. // Please do not modify content of this file directly. @@ -171,10 +174,12 @@ ${helper.clkmgr_gateable_clocks.render()} /// but the clock manager is in control of whether the clock actually is stopped. ${helper.clkmgr_hintable_clocks.render()} -/// MMIO Region +% for (subspace_name, description, subspace_range) in helper.subranges: +/// ${subspace_name.upper()} Region /// -/// MMIO region excludes any memory that is separate from the module -/// configuration space, i.e. ROM, main SRAM, and flash are excluded but -/// retention SRAM, spi_device memory, or usbdev memory are included. -pub const ${helper.mmio.base_addr_name().as_rust_const()}: usize = ${"0x{:X}".format(helper.mmio.base_addr)}; -pub const ${helper.mmio.size_bytes_name().as_rust_const()}: usize = ${"0x{:X}".format(helper.mmio.size_bytes)}; +% for l in textwrap.wrap(description, 76, break_long_words=False): +/// ${l} +% endfor +pub const ${subspace_range.base_addr_name().as_rust_const()}: usize = ${"0x{:X}".format(subspace_range.base_addr)}; +pub const ${subspace_range.size_bytes_name().as_rust_const()}: usize = ${"0x{:X}".format(subspace_range.size_bytes)}; +% endfor diff --git a/util/topgen/templates/toplevel_memory.h.tpl b/util/topgen/templates/toplevel_memory.h.tpl index bd3c73e1117dd..b4de7877e931a 100644 --- a/util/topgen/templates/toplevel_memory.h.tpl +++ b/util/topgen/templates/toplevel_memory.h.tpl @@ -1,6 +1,9 @@ // Copyright lowRISC contributors. // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 +<% +import textwrap +%>\ #ifndef ${helper.header_macro_prefix}_TOP_${top["name"].upper()}_MEMORY_H_ #define ${helper.header_macro_prefix}_TOP_${top["name"].upper()}_MEMORY_H_ @@ -100,15 +103,17 @@ #define ${size_bytes_name} ${hex_size_bytes} % endfor +% for (subspace_name, description, subspace_range) in helper.subranges: /** - * MMIO Region + * ${subspace_name.upper()} Region * - * MMIO region excludes any memory that is separate from the module - * configuration space, i.e. ROM, main SRAM, and flash are excluded but - * retention SRAM, spi_device memory, or usbdev memory are included. +% for l in textwrap.wrap(description, 77, break_long_words=False): + * ${l} +% endfor */ -#define ${helper.mmio.base_addr_name().as_c_define()} ${"0x{:X}".format(helper.mmio.base_addr)} -#define ${helper.mmio.size_bytes_name().as_c_define()} ${"0x{:X}".format(helper.mmio.size_bytes)} +#define ${subspace_range.base_addr_name().as_c_define()} ${"0x{:X}".format(subspace_range.base_addr)} +#define ${subspace_range.size_bytes_name().as_c_define()} ${"0x{:X}".format(subspace_range.size_bytes)} +% endfor #endif // __ASSEMBLER__ diff --git a/util/topgen/templates/toplevel_memory.rs.tpl b/util/topgen/templates/toplevel_memory.rs.tpl index 0bf6e3097a189..332f7b2cf1ac7 100644 --- a/util/topgen/templates/toplevel_memory.rs.tpl +++ b/util/topgen/templates/toplevel_memory.rs.tpl @@ -1,6 +1,9 @@ // Copyright lowRISC contributors. // Licensed under the Apache License, Version 2.0, see LICENSE for details. // SPDX-License-Identifier: Apache-2.0 +<% +import textwrap +%>\ ${helper.file_header.render()} // This file was generated automatically. // Please do not modify content of this file directly. @@ -70,10 +73,12 @@ pub const ${base_addr_name}: usize = ${hex_base_addr}; pub const ${size_bytes_name}: usize = ${hex_size_bytes}; % endfor -/// MMIO Region +% for (subspace_name, description, subspace_range) in helper.subranges: +/// ${subspace_name.upper()} Region /// -/// MMIO region excludes any memory that is separate from the module -/// configuration space, i.e. ROM, main SRAM, and flash are excluded but -/// retention SRAM, spi_device memory, or usbdev memory are included. -pub const ${helper.mmio.base_addr_name().as_c_define()}: usize = ${"0x{:X}".format(helper.mmio.base_addr)}; -pub const ${helper.mmio.size_bytes_name().as_c_define()}: usize = ${"0x{:X}".format(helper.mmio.size_bytes)}; +% for l in textwrap.wrap(description, 76, break_long_words=False): +/// ${l} +% endfor +pub const ${subspace_range.base_addr_name().as_c_define()}: usize = ${"0x{:X}".format(subspace_range.base_addr)}; +pub const ${subspace_range.size_bytes_name().as_c_define()}: usize = ${"0x{:X}".format(subspace_range.size_bytes)}; +% endfor diff --git a/util/topgen/validate.py b/util/topgen/validate.py index da214c7257320..d57ff65446872 100644 --- a/util/topgen/validate.py +++ b/util/topgen/validate.py @@ -41,7 +41,7 @@ 'type': ['s', 'type of hjson. Shall be "top" always'], 'clocks': ['g', 'group of clock properties'], 'resets': ['l', 'list of resets'], - 'addr_spaces': ['ln', 'list of address spaces'], + 'addr_spaces': ['g', 'list of address spaces'], 'module': ['l', 'list of modules to instantiate'], 'memory': ['l', 'list of memories. At least one memory ' 'is needed to run the software'],