(no changes since v3)
Changes in v3:
- Configure and instantiate the shared SiFive L2CC
- Map the register, LIM, and Zero windows exposed by the controller
- Remove the external RAM allocations and l2-lim link
- Keep the PolarFire master count and modeled Zero aperture unchanged
include/hw/riscv/microchip_pfsoc.h | 2 ++
hw/riscv/microchip_pfsoc.c | 45 ++++++++++--------------------
hw/riscv/Kconfig | 1 +
3 files changed, 17 insertions(+), 31 deletions(-)
diff --git a/include/hw/riscv/microchip_pfsoc.h
b/include/hw/riscv/microchip_pfsoc.h
index 612fd2b69c..18f5003850 100644
--- a/include/hw/riscv/microchip_pfsoc.h
+++ b/include/hw/riscv/microchip_pfsoc.h
@@ -27,6 +27,7 @@
#include "hw/cpu/cluster.h"
#include "hw/dma/sifive_pdma.h"
#include "hw/misc/mchp_pfsoc_dmc.h"
+#include "hw/misc/sifive_l2cc.h"
#include "hw/misc/mchp_pfsoc_ioscb.h"
#include "hw/misc/mchp_pfsoc_sysreg.h"
#include "hw/net/cadence_gem.h"
@@ -43,6 +44,7 @@ typedef struct MicrochipPFSoCState {
RISCVHartArrayState e_cpus;
RISCVHartArrayState u_cpus;
DeviceState *plic;
+ SiFiveL2CCState l2cc;
MchpPfSoCDdrSgmiiPhyState ddr_sgmii_phy;
MchpPfSoCDdrCfgState ddr_cfg;
MchpPfSoCIoscbState ioscb;
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
index 8106dbb3ad..d0d8c8f84c 100644
--- a/hw/riscv/microchip_pfsoc.c
+++ b/hw/riscv/microchip_pfsoc.c
@@ -174,6 +174,12 @@ static void microchip_pfsoc_soc_instance_init(Object *obj)
object_initialize_child(obj, "dma-controller", &s->dma,
TYPE_SIFIVE_PDMA);
+ object_initialize_child(obj, "l2-cache-controller", &s->l2cc,
+ TYPE_SIFIVE_L2CC);
+ qdev_prop_set_uint32(DEVICE(&s->l2cc), "num-masters", 15);
+ qdev_prop_set_uint64(DEVICE(&s->l2cc), "zero-size",
+ microchip_pfsoc_memmap[MICROCHIP_PFSOC_L2ZERO].size);
+
object_initialize_child(obj, "sysreg", &s->sysreg,
TYPE_MCHP_PFSOC_SYSREG);
@@ -200,8 +206,6 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
MemoryRegion *system_memory = get_system_memory();
MemoryRegion *rsvd0_mem = g_new(MemoryRegion, 1);
MemoryRegion *e51_dtim_mem = g_new(MemoryRegion, 1);
- MemoryRegion *l2lim_mem = g_new(MemoryRegion, 1);
- MemoryRegion *l2zero_mem = g_new(MemoryRegion, 1);
MemoryRegion *envm_data = g_new(MemoryRegion, 1);
MemoryRegion *qspi_xip_mem = g_new(MemoryRegion, 1);
char *plic_hart_config;
@@ -260,35 +264,14 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev,
Error **errp)
RISCV_ACLINT_DEFAULT_MTIMECMP, RISCV_ACLINT_DEFAULT_MTIME,
iks->clint_timebase_freq, false);
- /* L2 cache controller */
- create_unimplemented_device("microchip.pfsoc.l2cc",
- memmap[MICROCHIP_PFSOC_L2CC].base, memmap[MICROCHIP_PFSOC_L2CC].size);
-
- /*
- * Add L2-LIM at reset size.
- * This should be reduced in size as the L2 Cache Controller WayEnable
- * register is incremented. Unfortunately I don't see a nice (or any) way
- * to handle reducing or blocking out the L2 LIM while still allowing it
- * be re returned to all enabled after a reset. For the time being, just
- * leave it enabled all the time. This won't break anything, but will be
- * too generous to misbehaving guests.
- */
- memory_region_init_ram(l2lim_mem, NULL, "microchip.pfsoc.l2lim",
- memmap[MICROCHIP_PFSOC_L2LIM].size, &error_fatal);
- memory_region_add_subregion(system_memory,
- memmap[MICROCHIP_PFSOC_L2LIM].base,
- l2lim_mem);
-
- /*
- * HSS decompresses into the L2 zero-device window and executes there.
- * Model it as RAM because QEMU does not model the backing L2 cache.
- */
- memory_region_init_ram(l2zero_mem, NULL, "microchip.pfsoc.l2zero",
- memmap[MICROCHIP_PFSOC_L2ZERO].size,
- &error_fatal);
- memory_region_add_subregion(system_memory,
- memmap[MICROCHIP_PFSOC_L2ZERO].base,
- l2zero_mem);
+ /* The L2CC owns the SRAM backing and both software-visible windows */
+ sysbus_realize(SYS_BUS_DEVICE(&s->l2cc), errp);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->l2cc), SIFIVE_L2CC_MMIO_REGS,
+ memmap[MICROCHIP_PFSOC_L2CC].base);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->l2cc), SIFIVE_L2CC_MMIO_LIM,
+ memmap[MICROCHIP_PFSOC_L2LIM].base);
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->l2cc), SIFIVE_L2CC_MMIO_ZERO,
+ memmap[MICROCHIP_PFSOC_L2ZERO].base);
/* create PLIC hart topology configuration string */
plic_hart_config = riscv_plic_hart_config_string(ms->smp.cpus);
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
index d06ac26648..46a499f70f 100644
--- a/hw/riscv/Kconfig
+++ b/hw/riscv/Kconfig
@@ -21,6 +21,7 @@ config MICROCHIP_PFSOC
select MCHP_PFSOC_MMUART
select MCHP_PFSOC_SYSREG
select RISCV_ACLINT
+ select SIFIVE_L2CC
select SIFIVE_PDMA
select SIFIVE_PLIC
select UNIMP