Give the Atlantis SoC a 'memory' link property. The machine creates a container MemoryRegion, maps it at address 0 of system memory, and passes it to the SoC together with the machine RAM. The SoC maps devices into the 'memory' container instead of system memory, allowing TTAtlantisSoCState to be composed together with other SoCs in the future.
This prepares the machine for adding other microcontrollers that share the memory bus with the Ascalon complex (aka the Atlantis SoC), but with their own view of the address map. Signed-off-by: Joel Stanley <[email protected]> --- include/hw/riscv/tt_atlantis.h | 1 + hw/riscv/tt_atlantis.c | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/include/hw/riscv/tt_atlantis.h b/include/hw/riscv/tt_atlantis.h index 5d4e4d133bd9..3923308b7c89 100644 --- a/include/hw/riscv/tt_atlantis.h +++ b/include/hw/riscv/tt_atlantis.h @@ -53,6 +53,7 @@ struct TTAtlantisState { /*< public >*/ Notifier machine_done; + MemoryRegion soc_memory; TTAtlantisSoCState soc; }; diff --git a/hw/riscv/tt_atlantis.c b/hw/riscv/tt_atlantis.c index d2b29ff1a477..b78b4a5ea31e 100644 --- a/hw/riscv/tt_atlantis.c +++ b/hw/riscv/tt_atlantis.c @@ -503,8 +503,10 @@ static void tt_atlantis_soc_realize(DeviceState *dev, Error **errp) ram_addr_t lo_ram_size, ram_size; int hart_count = s->num_harts; - s->memory = get_system_memory(); - + if (!s->memory) { + error_setg(errp, "'memory' link is not set"); + return; + } if (!s->dram) { error_setg(errp, "'dram' link is not set"); return; @@ -523,6 +525,8 @@ static void tt_atlantis_soc_realize(DeviceState *dev, Error **errp) object_property_set_int(OBJECT(&s->cpus), "resetvec", s->memmap[TT_ATL_BOOTROM].base, &error_abort); + object_property_set_link(OBJECT(&s->cpus), "memory", OBJECT(s->memory), + &error_abort); if (!sysbus_realize(SYS_BUS_DEVICE(&s->cpus), errp)) { return; } @@ -614,6 +618,8 @@ static void tt_atlantis_soc_realize(DeviceState *dev, Error **errp) static const Property tt_atlantis_soc_props[] = { DEFINE_PROP_STRING("cpu-type", TTAtlantisSoCState, cpu_type), DEFINE_PROP_UINT32("num-harts", TTAtlantisSoCState, num_harts, 8), + DEFINE_PROP_LINK("memory", TTAtlantisSoCState, memory, + TYPE_MEMORY_REGION, MemoryRegion *), DEFINE_PROP_LINK("dram", TTAtlantisSoCState, dram, TYPE_MEMORY_REGION, MemoryRegion *), }; @@ -633,12 +639,19 @@ static void tt_atlantis_machine_init(MachineState *machine) TTAtlantisState *ams = TT_ATLANTIS_MACHINE(machine); TTAtlantisSoCState *s = &ams->soc; + memory_region_init(&ams->soc_memory, OBJECT(machine), + "tt-atlantis.soc-memory", UINT64_MAX); + memory_region_add_subregion(get_system_memory(), 0, &ams->soc_memory); + object_initialize_child(OBJECT(machine), "soc", &ams->soc, TYPE_TT_ATLANTIS_SOC); object_property_set_str(OBJECT(&ams->soc), "cpu-type", machine->cpu_type, &error_abort); object_property_set_int(OBJECT(&ams->soc), "num-harts", machine->smp.cpus, &error_abort); + + object_property_set_link(OBJECT(&ams->soc), "memory", + OBJECT(&ams->soc_memory), &error_abort); object_property_set_link(OBJECT(&ams->soc), "dram", OBJECT(machine->ram), &error_abort); qdev_realize(DEVICE(&ams->soc), NULL, &error_fatal); -- 2.47.3
