From 6bb9699ecdc26c2f8ac34e22a53d60a1e94f8af2 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 | 93 +++++++++++++++++++ hw/top_darjeeling/data/top_darjeeling.hjson | 93 +++++++++++++++---- .../xbar_dbg/data/autogen/xbar_dbg.gen.hjson | 2 + .../data/autogen/xbar_main.gen.hjson | 7 ++ .../xbar_mbx/data/autogen/xbar_mbx.gen.hjson | 9 ++ .../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 | 68 ++++++++++++++ hw/top_earlgrey/data/top_earlgrey.hjson | 68 ++++++++++++-- .../data/autogen/xbar_main.gen.hjson | 5 + util/tlgen/validate.py | 3 + util/topgen.py | 8 +- util/topgen/c.py | 52 +---------- util/topgen/lib.py | 74 +++++++++++++++ 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 | 7 +- 22 files changed, 465 insertions(+), 163 deletions(-) diff --git a/hw/top_darjeeling/data/autogen/top_darjeeling.gen.hjson b/hw/top_darjeeling/data/autogen/top_darjeeling.gen.hjson index 226faefaad6a09..f8a4e0267a36c3 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 + sensor_ctrl + soc_proxy.core + sram_ctrl_ret_aon + rv_dm.regs + 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 @@ -3750,6 +3807,7 @@ ctn: { hart: 0x40000000 + cpu_visible: false } } attr: reggen_top @@ -4267,14 +4325,17 @@ mem: { hart: 0x00040000 + cpu_visible: false } regs: { hart: 0x21200000 + cpu_visible: false } dbg: { soc_dbg: 0x00000000 + cpu_visible: false } } param_decl: @@ -6092,6 +6153,7 @@ ram: { hart: 0x10000000 + cpu_visible: false } } memory: @@ -6299,6 +6361,7 @@ ram: { hart: 0x11000000 + cpu_visible: false } } memory: @@ -6490,6 +6553,7 @@ rom: { hart: 0x00008000 + cpu_visible: false } regs: { @@ -6672,6 +6736,7 @@ rom: { hart: 0x00020000 + cpu_visible: false } regs: { @@ -7022,6 +7087,7 @@ soc: { soc_mbx: 0x01465000 + cpu_visible: false } } clock_connections: @@ -7158,6 +7224,7 @@ soc: { soc_mbx: 0x01465100 + cpu_visible: false } } clock_connections: @@ -7294,6 +7361,7 @@ soc: { soc_mbx: 0x01465200 + cpu_visible: false } } clock_connections: @@ -7430,6 +7498,7 @@ soc: { soc_mbx: 0x01465300 + cpu_visible: false } } clock_connections: @@ -7566,6 +7635,7 @@ soc: { soc_mbx: 0x01465400 + cpu_visible: false } } clock_connections: @@ -7702,6 +7772,7 @@ soc: { soc_mbx: 0x01465500 + cpu_visible: false } } clock_connections: @@ -7838,6 +7909,7 @@ soc: { soc_mbx: 0x01465600 + cpu_visible: false } } clock_connections: @@ -7974,6 +8046,7 @@ soc: { soc_dbg: 0x1000 + cpu_visible: false } } clock_connections: @@ -8110,6 +8183,7 @@ soc: { soc_mbx: 0x01460100 + cpu_visible: false } } clock_connections: @@ -8246,6 +8320,7 @@ soc: { soc_mbx: 0x01460200 + cpu_visible: false } } clock_connections: @@ -9990,6 +10065,7 @@ base_addrs: { hart: 0x21200000 + cpu_visible: 0x0 } size_byte: 0x4 } @@ -10012,6 +10088,7 @@ base_addrs: { hart: 0x40000 + cpu_visible: 0x0 } size_byte: 0x1000 } @@ -10034,6 +10111,7 @@ base_addrs: { hart: 0x8000 + cpu_visible: 0x0 } size_byte: 0x8000 } @@ -10078,6 +10156,7 @@ base_addrs: { hart: 0x20000 + cpu_visible: 0x0 } size_byte: 0x10000 } @@ -10165,6 +10244,7 @@ base_addrs: { hart: 0x40000000 + cpu_visible: 0x0 } size_byte: 0x40000000 } @@ -10429,6 +10509,7 @@ base_addrs: { hart: 0x10000000 + cpu_visible: 0x0 } size_byte: 0x10000 } @@ -10471,6 +10552,7 @@ base_addrs: { hart: 0x11000000 + cpu_visible: 0x0 } size_byte: 0x1000 } @@ -12250,6 +12332,7 @@ base_addrs: { soc_mbx: 0x1465000 + cpu_visible: 0x0 } size_byte: 0x20 } @@ -12272,6 +12355,7 @@ base_addrs: { soc_mbx: 0x1465100 + cpu_visible: 0x0 } size_byte: 0x20 } @@ -12294,6 +12378,7 @@ base_addrs: { soc_mbx: 0x1465200 + cpu_visible: 0x0 } size_byte: 0x20 } @@ -12316,6 +12401,7 @@ base_addrs: { soc_mbx: 0x1465300 + cpu_visible: 0x0 } size_byte: 0x20 } @@ -12338,6 +12424,7 @@ base_addrs: { soc_mbx: 0x1465400 + cpu_visible: 0x0 } size_byte: 0x20 } @@ -12360,6 +12447,7 @@ base_addrs: { soc_mbx: 0x1465500 + cpu_visible: 0x0 } size_byte: 0x20 } @@ -12382,6 +12470,7 @@ base_addrs: { soc_mbx: 0x1465600 + cpu_visible: 0x0 } size_byte: 0x20 } @@ -12404,6 +12493,7 @@ base_addrs: { soc_mbx: 0x1460100 + cpu_visible: 0x0 } size_byte: 0x20 } @@ -12426,6 +12516,7 @@ base_addrs: { soc_mbx: 0x1460200 + cpu_visible: 0x0 } size_byte: 0x20 } @@ -12635,6 +12726,7 @@ base_addrs: { soc_dbg: 0x0 + cpu_visible: 0x0 } size_byte: 0x200 } @@ -12656,6 +12748,7 @@ base_addrs: { soc_dbg: 0x1000 + cpu_visible: 0x0 } size_byte: 0x20 } diff --git a/hw/top_darjeeling/data/top_darjeeling.hjson b/hw/top_darjeeling/data/top_darjeeling.hjson index ec2c11cc675a83..51905ef18fdf9a 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", + "sensor_ctrl", + "soc_proxy.core", + "sram_ctrl_ret_aon", + "rv_dm.regs", + "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"}, ] @@ -526,7 +581,7 @@ domain: ["Aon", "0"], base_addrs: { core: {hart: "0x22030000"}, - ctn: {hart: "0x40000000"}, + ctn: {hart: "0x40000000", cpu_visible: false}, }, attr: "reggen_top", memory: { @@ -573,9 +628,9 @@ reset_connections: {rst_ni: "sys"}, // Note that this module also contains a bus host. base_addrs: { - mem: {hart: "0x00040000"}, - regs: {hart: "0x21200000"}, - dbg: {soc_dbg: "0x00000000"}, + mem: {hart: "0x00040000", cpu_visible: false}, + regs: {hart: "0x21200000", cpu_visible: false}, + dbg: {soc_dbg: "0x00000000", cpu_visible: false}, }, param_decl: { // NOTE THAT THIS IS A FEATURE FOR TEST CHIPS ONLY TO MITIGATE @@ -704,7 +759,7 @@ } base_addrs: { regs: {hart: "0x211c0000"}, - ram: {hart: "0x10000000"}, + ram: {hart: "0x10000000", cpu_visible: false}, }, // Memory regions must be associated with a dedicated // TL-UL device interface. @@ -729,7 +784,7 @@ } base_addrs: { regs: {hart: "0x211d0000"}, - ram: {hart: "0x11000000"}, + ram: {hart: "0x11000000", cpu_visible: false}, }, // Memory regions must be associated with a dedicated // TL-UL device interface. @@ -750,7 +805,7 @@ clock_group: "infra", reset_connections: {rst_ni: "lc"}, base_addrs: { - rom: {hart: "0x00008000"}, + rom: {hart: "0x00008000", cpu_visible: false}, regs: {hart: "0x211e0000"}, } memory: { @@ -776,7 +831,7 @@ // TODO(opentitan-integrated/issues/251): // This is not the final parameterization for Darjeeling. base_addrs: { - rom: {hart: "0x00020000"}, + rom: {hart: "0x00020000", cpu_visible: false}, regs: {hart: "0x211e1000"}, } memory: { @@ -808,7 +863,7 @@ reset_connections: {rst_ni: "lc"}, base_addrs: { core: {hart: "0x22000000"}, - soc: {soc_mbx: "0x01465000"}, + soc: {soc_mbx: "0x01465000", cpu_visible: false}, }, }, { name: "mbx1", @@ -818,7 +873,7 @@ reset_connections: {rst_ni: "lc"}, base_addrs: { core: {hart: "0x22000100"}, - soc: {soc_mbx: "0x01465100"}, + soc: {soc_mbx: "0x01465100", cpu_visible: false}, }, }, { name: "mbx2", @@ -828,7 +883,7 @@ reset_connections: {rst_ni: "lc"}, base_addrs: { core: {hart: "0x22000200"}, - soc: {soc_mbx: "0x01465200"}, + soc: {soc_mbx: "0x01465200", cpu_visible: false}, }, }, { name: "mbx3", @@ -838,7 +893,7 @@ reset_connections: {rst_ni: "lc"}, base_addrs: { core: {hart: "0x22000300"}, - soc: {soc_mbx: "0x01465300"}, + soc: {soc_mbx: "0x01465300", cpu_visible: false}, }, }, { name: "mbx4", @@ -848,7 +903,7 @@ reset_connections: {rst_ni: "lc"}, base_addrs: { core: {hart: "0x22000400"}, - soc: {soc_mbx: "0x01465400"}, + soc: {soc_mbx: "0x01465400", cpu_visible: false}, }, }, { name: "mbx5", @@ -858,7 +913,7 @@ reset_connections: {rst_ni: "lc"}, base_addrs: { core: {hart: "0x22000500"}, - soc: {soc_mbx: "0x01465500"}, + soc: {soc_mbx: "0x01465500", cpu_visible: false}, }, }, { name: "mbx6", @@ -868,7 +923,7 @@ reset_connections: {rst_ni: "lc"}, base_addrs: { core: {hart: "0x22000600"}, - soc: {soc_mbx: "0x01465600"}, + soc: {soc_mbx: "0x01465600", cpu_visible: false}, }, }, { name: "mbx_jtag", @@ -878,7 +933,7 @@ reset_connections: {rst_ni: "lc"}, base_addrs: { core: {hart: "0x22000800"}, - soc: {soc_dbg: "0x1000"}, + soc: {soc_dbg: "0x1000", cpu_visible: false}, }, }, { name: "mbx_pcie0", @@ -888,7 +943,7 @@ reset_connections: {rst_ni: "lc"}, base_addrs: { core: {hart: "0x22040000"}, - soc: {soc_mbx: "0x01460100"}, + soc: {soc_mbx: "0x01460100", cpu_visible: false}, }, }, { name: "mbx_pcie1", @@ -898,7 +953,7 @@ reset_connections: {rst_ni: "lc"}, base_addrs: { core: {hart: "0x22040100"}, - soc: {soc_mbx: "0x01460200"}, + soc: {soc_mbx: "0x01460200", cpu_visible: false}, }, }, { name: "rv_core_ibex", diff --git a/hw/top_darjeeling/ip/xbar_dbg/data/autogen/xbar_dbg.gen.hjson b/hw/top_darjeeling/ip/xbar_dbg/data/autogen/xbar_dbg.gen.hjson index fcd9f4222436ad..18feff182ce633 100644 --- a/hw/top_darjeeling/ip/xbar_dbg/data/autogen/xbar_dbg.gen.hjson +++ b/hw/top_darjeeling/ip/xbar_dbg/data/autogen/xbar_dbg.gen.hjson @@ -74,6 +74,7 @@ base_addrs: { soc_dbg: 0x0 + cpu_visible: 0x0 } size_byte: 0x200 } @@ -95,6 +96,7 @@ base_addrs: { soc_dbg: 0x1000 + cpu_visible: 0x0 } size_byte: 0x20 } diff --git a/hw/top_darjeeling/ip/xbar_main/data/autogen/xbar_main.gen.hjson b/hw/top_darjeeling/ip/xbar_main/data/autogen/xbar_main.gen.hjson index 40675ea7b5e81e..0f6b76df206f72 100644 --- a/hw/top_darjeeling/ip/xbar_main/data/autogen/xbar_main.gen.hjson +++ b/hw/top_darjeeling/ip/xbar_main/data/autogen/xbar_main.gen.hjson @@ -236,6 +236,7 @@ base_addrs: { hart: 0x21200000 + cpu_visible: 0x0 } size_byte: 0x4 } @@ -258,6 +259,7 @@ base_addrs: { hart: 0x40000 + cpu_visible: 0x0 } size_byte: 0x1000 } @@ -280,6 +282,7 @@ base_addrs: { hart: 0x8000 + cpu_visible: 0x0 } size_byte: 0x8000 } @@ -324,6 +327,7 @@ base_addrs: { hart: 0x20000 + cpu_visible: 0x0 } size_byte: 0x10000 } @@ -411,6 +415,7 @@ base_addrs: { hart: 0x40000000 + cpu_visible: 0x0 } size_byte: 0x40000000 } @@ -675,6 +680,7 @@ base_addrs: { hart: 0x10000000 + cpu_visible: 0x0 } size_byte: 0x10000 } @@ -717,6 +723,7 @@ base_addrs: { hart: 0x11000000 + cpu_visible: 0x0 } size_byte: 0x1000 } diff --git a/hw/top_darjeeling/ip/xbar_mbx/data/autogen/xbar_mbx.gen.hjson b/hw/top_darjeeling/ip/xbar_mbx/data/autogen/xbar_mbx.gen.hjson index 4677829be8c2f0..5e2b2467381797 100644 --- a/hw/top_darjeeling/ip/xbar_mbx/data/autogen/xbar_mbx.gen.hjson +++ b/hw/top_darjeeling/ip/xbar_mbx/data/autogen/xbar_mbx.gen.hjson @@ -74,6 +74,7 @@ base_addrs: { soc_mbx: 0x1465000 + cpu_visible: 0x0 } size_byte: 0x20 } @@ -96,6 +97,7 @@ base_addrs: { soc_mbx: 0x1465100 + cpu_visible: 0x0 } size_byte: 0x20 } @@ -118,6 +120,7 @@ base_addrs: { soc_mbx: 0x1465200 + cpu_visible: 0x0 } size_byte: 0x20 } @@ -140,6 +143,7 @@ base_addrs: { soc_mbx: 0x1465300 + cpu_visible: 0x0 } size_byte: 0x20 } @@ -162,6 +166,7 @@ base_addrs: { soc_mbx: 0x1465400 + cpu_visible: 0x0 } size_byte: 0x20 } @@ -184,6 +189,7 @@ base_addrs: { soc_mbx: 0x1465500 + cpu_visible: 0x0 } size_byte: 0x20 } @@ -206,6 +212,7 @@ base_addrs: { soc_mbx: 0x1465600 + cpu_visible: 0x0 } size_byte: 0x20 } @@ -228,6 +235,7 @@ base_addrs: { soc_mbx: 0x1460100 + cpu_visible: 0x0 } size_byte: 0x20 } @@ -250,6 +258,7 @@ base_addrs: { soc_mbx: 0x1460200 + cpu_visible: 0x0 } size_byte: 0x20 } diff --git a/hw/top_darjeeling/sw/autogen/chip/top_darjeeling.rs b/hw/top_darjeeling/sw/autogen/chip/top_darjeeling.rs index 2798bf4982658f..39be6a47e782a1 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 1216ec9816016f..87e5a66fd5a3bf 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 391c067a9445f8..62d23c4b61c2be 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 552e2be44067d7..9904cee477965f 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 c82d7060678c78..9116a9981c55fe 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: @@ -5013,6 +5071,7 @@ mem: { hart: 0x20000000 + cpu_visible: false } } param_decl: @@ -5456,10 +5515,12 @@ mem: { hart: 0x00010000 + cpu_visible: false } regs: { hart: 0x41200000 + cpu_visible: false } } generate_dif: false @@ -7405,6 +7466,7 @@ ram: { hart: 0x10000000 + cpu_visible: false } } memory: @@ -7598,6 +7660,7 @@ rom: { hart: 0x00008000 + cpu_visible: false } regs: { @@ -9257,6 +9320,7 @@ base_addrs: { hart: 0x41200000 + cpu_visible: 0x0 } size_byte: 0x4 } @@ -9279,6 +9343,7 @@ base_addrs: { hart: 0x10000 + cpu_visible: 0x0 } size_byte: 0x1000 } @@ -9301,6 +9366,7 @@ base_addrs: { hart: 0x8000 + cpu_visible: 0x0 } size_byte: 0x8000 } @@ -9484,6 +9550,7 @@ base_addrs: { hart: 0x20000000 + cpu_visible: 0x0 } size_byte: 0x100000 } @@ -9769,6 +9836,7 @@ base_addrs: { hart: 0x10000000 + cpu_visible: 0x0 } size_byte: 0x20000 } diff --git a/hw/top_earlgrey/data/top_earlgrey.hjson b/hw/top_earlgrey/data/top_earlgrey.hjson index fe30cc4ed34803..2c85dfc91a9091 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. @@ -670,7 +726,7 @@ base_addrs: { core: {hart: "0x41000000"}, prim: {hart: "0x41008000"}, - mem: {hart: "0x20000000"} + mem: {hart: "0x20000000", cpu_visible: false} } param_decl: { ProgFifoDepth: "4", @@ -702,8 +758,8 @@ } // Note that this module also contains a bus host. base_addrs: { - mem: {hart: "0x00010000"}, - regs: {hart: "0x41200000"} + mem: {hart: "0x00010000", cpu_visible: false}, + regs: {hart: "0x41200000", cpu_visible: false} }, generate_dif: "False" }, @@ -833,7 +889,7 @@ } base_addrs: { regs: {hart: "0x411C0000"}, - ram: {hart: "0x10000000"} + ram: {hart: "0x10000000", cpu_visible: false} }, // Memory regions must be associated with a dedicated // TL-UL device interface. @@ -854,7 +910,7 @@ clock_group: "infra", reset_connections: {rst_ni: "lc"}, base_addrs: { - rom: {hart: "0x00008000"}, + rom: {hart: "0x00008000", cpu_visible: false}, regs: {hart: "0x411e0000"} } memory: { diff --git a/hw/top_earlgrey/ip/xbar_main/data/autogen/xbar_main.gen.hjson b/hw/top_earlgrey/ip/xbar_main/data/autogen/xbar_main.gen.hjson index 3d05eba5ec375c..e4b74214d8777a 100644 --- a/hw/top_earlgrey/ip/xbar_main/data/autogen/xbar_main.gen.hjson +++ b/hw/top_earlgrey/ip/xbar_main/data/autogen/xbar_main.gen.hjson @@ -177,6 +177,7 @@ base_addrs: { hart: 0x41200000 + cpu_visible: 0x0 } size_byte: 0x4 } @@ -199,6 +200,7 @@ base_addrs: { hart: 0x10000 + cpu_visible: 0x0 } size_byte: 0x1000 } @@ -221,6 +223,7 @@ base_addrs: { hart: 0x8000 + cpu_visible: 0x0 } size_byte: 0x8000 } @@ -404,6 +407,7 @@ base_addrs: { hart: 0x20000000 + cpu_visible: 0x0 } size_byte: 0x100000 } @@ -689,6 +693,7 @@ base_addrs: { hart: 0x10000000 + cpu_visible: 0x0 } size_byte: 0x20000 } diff --git a/util/tlgen/validate.py b/util/tlgen/validate.py index 96893e6b2f78b7..d10e06d63a0b09 100644 --- a/util/tlgen/validate.py +++ b/util/tlgen/validate.py @@ -314,6 +314,9 @@ def validate(obj: OrderedDict) -> Xbar: # OrderedDict -> Xbar # ASID, but downstream xbar-to-xbar edges only support one ASID. for addr in nodeobj["addr_range"]: for asid, base_addr in addr["base_addrs"].items(): + if asid == "cpu_visible": + continue + addr_range = addr_ranges.setdefault(asid, []) address_from = int(base_addr, 0) size = int(addr["size_byte"], 0) diff --git a/util/topgen.py b/util/topgen.py index e442352d14d8dd..bd5435218b5302 100755 --- a/util/topgen.py +++ b/util/topgen.py @@ -7,6 +7,7 @@ import argparse import logging as log import shutil +import subprocess import sys import tempfile from collections import OrderedDict @@ -689,7 +690,7 @@ def generate_top_ral(topname: str, top: Dict[str, object], for if_name in block.reg_blocks.keys(): if_addr = { asid: int(addr, 0) - for (asid, addr) in module["base_addrs"][if_name].items() + for (asid, addr) in module["base_addrs"][if_name].items() if asid != "cpu_visible" } if_addrs[(inst_name, if_name)] = if_addr @@ -1360,10 +1361,11 @@ def render_template(template_path: str, rendered_path: Path, c_helper.header_path = str(rel_header_path) # "toplevel.c.tpl" -> "sw/autogen/top_{topname}.c" + c_path = cformat_dir / f"top_{topname}.c" render_template(TOPGEN_TEMPLATE_PATH / "toplevel.c.tpl", - cformat_dir / f"top_{topname}.c", + c_path, helper=c_helper) - + # "toplevel_memory.ld.tpl" -> "sw/autogen/top_{topname}_memory.ld" render_template(TOPGEN_TEMPLATE_PATH / "toplevel_memory.ld.tpl", cformat_dir / f"top_{topname}_memory.ld", diff --git a/util/topgen/c.py b/util/topgen/c.py index ad7f1c42f49fa6..aeb1d65c6d2253 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 9286ea806468ef..99068927cfc1f6 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,56 @@ 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 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. + """ + subspace_regions = [] + addr_space = get_addr_space(top, addr_space_name) + for subspace in addr_space.get('subspaces', []): + regions = [] + for node in subspace['nodes']: + 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 + 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 + \ No newline at end of file diff --git a/util/topgen/rust.py b/util/topgen/rust.py index 6fe1e6e0fc554b..2b985f984b31e4 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 74b85614cd201b..e57ad68525efdf 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 9971eead9efae6..9b56017ec97a23 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 bd3c73e1117dd0..b4de7877e931ac 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 0bf6e3097a1890..332f7b2cf1ac72 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 da214c72573209..efbb4caebd52f0 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'], @@ -285,7 +285,10 @@ class Flash: max_pages_per_bank = 1024 def __init__(self, mem, base_addrs): - self.base_addrs = {asid: int(base, 16) for (asid, base) in base_addrs.items()} + self.base_addrs = { + asid: int(base, 16) + for (asid, base) in base_addrs.items() if asid != "cpu_visible" + } self.banks = mem.get('banks', 2) self.pages_per_bank = mem.get('pages_per_bank', 8) self.program_resolution = mem.get('program_resolution', 128)