This commit adds two MemoryRegion aliases to support PSP access to SSP SDRAM through shared memory remapping, as defined by the default SCU configuration.
The SSP exposes two DRAM aliases: - remap1 maps PSP DRAM at 0x400000000 (32MB) to SSP SDRAM offset 0x2000000 - remap2 maps PSP DRAM at 0x42c000000 (32MB) to SSP SDRAM offset 0x0 These regions correspond to the default SCU register values, which control the mapping between PSP and coprocessor memory windows. Set SSP CPUID 4 and bumps the SCU VMState version to 3. Signed-off-by: Jamin Lin <[email protected]> --- include/hw/misc/aspeed_scu.h | 5 +++++ hw/arm/aspeed_ast27x0-fc.c | 2 ++ hw/arm/aspeed_ast27x0-ssp.c | 6 ++++++ hw/arm/aspeed_ast27x0.c | 4 ++++ hw/misc/aspeed_scu.c | 38 ++++++++++++++++++++++++++++++++++-- 5 files changed, 53 insertions(+), 2 deletions(-) diff --git a/include/hw/misc/aspeed_scu.h b/include/hw/misc/aspeed_scu.h index 9e28bd4d2e..6f7f7d2766 100644 --- a/include/hw/misc/aspeed_scu.h +++ b/include/hw/misc/aspeed_scu.h @@ -39,6 +39,10 @@ struct AspeedSCUState { uint32_t hw_strap1; uint32_t hw_strap2; uint32_t hw_prot_key; + + MemoryRegion dram_remap_alias[3]; + MemoryRegion *dram; + int ssp_cpuid; }; #define AST2400_A0_SILICON_REV 0x02000303U @@ -73,6 +77,7 @@ struct AspeedSCUClass { uint32_t nr_regs; bool clkin_25Mhz; const MemoryRegionOps *ops; + void (*dram_remap)(AspeedSCUState *s); }; #define ASPEED_SCU_PROT_KEY 0x1688A8A8 diff --git a/hw/arm/aspeed_ast27x0-fc.c b/hw/arm/aspeed_ast27x0-fc.c index 0502a137f3..b788e6ca2a 100644 --- a/hw/arm/aspeed_ast27x0-fc.c +++ b/hw/arm/aspeed_ast27x0-fc.c @@ -101,6 +101,8 @@ static bool ast2700fc_ca35_init(MachineState *machine, Error **errp) sc->uarts_num, serial_hd(1)); aspeed_soc_uart_set_chr(soc->uart, ASPEED_DEV_UART7, sc->uarts_base, sc->uarts_num, serial_hd(2)); + object_property_set_int(OBJECT(&s->ca35), "ssp-cpuid", 4, + &error_abort); if (!qdev_realize(DEVICE(&s->ca35), NULL, errp)) { return false; } diff --git a/hw/arm/aspeed_ast27x0-ssp.c b/hw/arm/aspeed_ast27x0-ssp.c index cba59ae11a..cf1339e2c7 100644 --- a/hw/arm/aspeed_ast27x0-ssp.c +++ b/hw/arm/aspeed_ast27x0-ssp.c @@ -198,6 +198,12 @@ static void aspeed_soc_ast27x0ssp_realize(DeviceState *dev_soc, Error **errp) memory_region_add_subregion(s->memory, sc->memmap[ASPEED_DEV_SCU], &s->scu_alias); + /* SDRAM remap alias used by PSP to access SSP SDRAM */ + memory_region_add_subregion(&s->sdram, 0, &s->scu->dram_remap_alias[1]); + memory_region_add_subregion(&s->sdram, + memory_region_size(&s->scu->dram_remap_alias[1]), + &s->scu->dram_remap_alias[0]); + /* INTC */ if (!sysbus_realize(SYS_BUS_DEVICE(&a->intc[0]), errp)) { return; diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c index 74a004adca..ae8b22fc1c 100644 --- a/hw/arm/aspeed_ast27x0.c +++ b/hw/arm/aspeed_ast27x0.c @@ -389,6 +389,8 @@ static void aspeed_soc_ast2700_init(Object *obj) "hw-strap1"); object_property_add_alias(obj, "hw-prot-key", OBJECT(&s->scu), "hw-prot-key"); + object_property_add_alias(obj, "ssp-cpuid", OBJECT(&s->scu), + "ssp-cpuid"); object_initialize_child(obj, "scuio", &s->scuio, TYPE_ASPEED_2700_SCUIO); qdev_prop_set_uint32(DEVICE(&s->scuio), "silicon-rev", @@ -740,6 +742,8 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp) sc->memmap[ASPEED_DEV_VBOOTROM], &s->vbootrom); /* SCU */ + object_property_set_link(OBJECT(&s->scu), "dram", OBJECT(s->dram_mr), + &error_abort); if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) { return; } diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c index 6829efa2dc..4b74e5adcb 100644 --- a/hw/misc/aspeed_scu.c +++ b/hw/misc/aspeed_scu.c @@ -20,6 +20,7 @@ #include "qemu/guest-random.h" #include "qemu/module.h" #include "trace.h" +#include "qemu/units.h" #define TO_REG(offset) ((offset) >> 2) @@ -602,12 +603,20 @@ static void aspeed_scu_realize(DeviceState *dev, Error **errp) TYPE_ASPEED_SCU, SCU_IO_REGION_SIZE); sysbus_init_mmio(sbd, &s->iomem); + + if (asc->dram_remap) { + if (!s->dram) { + error_setg(errp, TYPE_ASPEED_SCU ": 'dram' link not set"); + return; + } + asc->dram_remap(s); + } } static const VMStateDescription vmstate_aspeed_scu = { .name = "aspeed.scu", - .version_id = 2, - .minimum_version_id = 2, + .version_id = 3, + .minimum_version_id = 3, .fields = (const VMStateField[]) { VMSTATE_UINT32_ARRAY(regs, AspeedSCUState, ASPEED_AST2600_SCU_NR_REGS), VMSTATE_END_OF_LIST() @@ -619,6 +628,9 @@ static const Property aspeed_scu_properties[] = { DEFINE_PROP_UINT32("hw-strap1", AspeedSCUState, hw_strap1, 0), DEFINE_PROP_UINT32("hw-strap2", AspeedSCUState, hw_strap2, 0), DEFINE_PROP_UINT32("hw-prot-key", AspeedSCUState, hw_prot_key, 0), + DEFINE_PROP_INT32("ssp-cpuid", AspeedSCUState, ssp_cpuid, -1), + DEFINE_PROP_LINK("dram", AspeedSCUState, dram, TYPE_MEMORY_REGION, + MemoryRegion *), }; static void aspeed_scu_class_init(ObjectClass *klass, const void *data) @@ -872,6 +884,27 @@ static const TypeInfo aspeed_2600_scu_info = { .class_init = aspeed_2600_scu_class_init, }; +static void aspeed_2700_scu_dram_remap_alias_init(AspeedSCUState *s) +{ + if (s->ssp_cpuid > 0) { + /* + * The SSP coprocessor uses two memory aliases (remap1 and remap2) + * to access shared memory regions in the PSP DRAM: + * + * - remap1 maps PSP DRAM at 0x400000000 (size: 32MB) to SSP SDRAM + * offset 0x2000000 + * - remap2 maps PSP DRAM at 0x42c000000 (size: 32MB) to SSP SDRAM + * offset 0x0 + */ + memory_region_init_alias(&s->dram_remap_alias[0], OBJECT(s), + "ssp.dram.remap1", s->dram, + 0, 32 * MiB); + memory_region_init_alias(&s->dram_remap_alias[1], OBJECT(s), + "ssp.dram.remap2", s->dram, + 0x2c000000, 32 * MiB); + } +} + static uint64_t aspeed_ast2700_scu_read(void *opaque, hwaddr offset, unsigned size) { @@ -982,6 +1015,7 @@ static void aspeed_2700_scu_class_init(ObjectClass *klass, const void *data) asc->nr_regs = ASPEED_AST2700_SCU_NR_REGS; asc->clkin_25Mhz = true; asc->ops = &aspeed_ast2700_scu_ops; + asc->dram_remap = aspeed_2700_scu_dram_remap_alias_init; } static uint64_t aspeed_ast2700_scuio_read(void *opaque, hwaddr offset, -- 2.43.0
