hw/arm/armsse: Give each CPU its own view of memory

Give each CPU its own container memory region. This is necessary
for two reasons:
 * some devices are instantiated one per CPU and the CPU sees only
   its own device
 * since a memory region can only be put into one container, we must
   give each armv7m object a different MemoryRegion as its 'memory'
   property, or a dual-CPU configuration will assert on realize when
   the second armv7m object tries to put the MR into a container when
   it is already in the first armv7m object's container

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20190121185118.18550-13-peter.maydell@linaro.org
This commit is contained in:
Peter Maydell 2019-02-01 14:55:42 +00:00
parent 91c1e9fcbd
commit d847ca5128
2 changed files with 30 additions and 2 deletions

View File

@ -153,6 +153,15 @@ static void armsse_init(Object *obj)
qdev_prop_set_string(DEVICE(&s->armv7m[i]), "cpu-type",
ARM_CPU_TYPE_NAME("cortex-m33"));
g_free(name);
name = g_strdup_printf("arm-sse-cpu-container%d", i);
memory_region_init(&s->cpu_container[i], obj, name, UINT64_MAX);
g_free(name);
if (i > 0) {
name = g_strdup_printf("arm-sse-container-alias%d", i);
memory_region_init_alias(&s->container_alias[i - 1], obj,
name, &s->container, 0, UINT64_MAX);
g_free(name);
}
}
sysbus_init_child_obj(obj, "secctl", &s->secctl, sizeof(s->secctl),
@ -332,7 +341,7 @@ static void armsse_realize(DeviceState *dev, Error **errp)
* 0x50000000..0x5fffffff alias of 0x40000000..0x4fffffff
*/
memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -1);
memory_region_add_subregion_overlap(&s->container, 0, s->board_memory, -2);
for (i = 0; i < info->num_cpus; i++) {
DeviceState *cpudev = DEVICE(&s->armv7m[i]);
@ -373,7 +382,16 @@ static void armsse_realize(DeviceState *dev, Error **errp)
return;
}
}
object_property_set_link(cpuobj, OBJECT(&s->container), "memory", &err);
if (i > 0) {
memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
&s->container_alias[i - 1], -1);
} else {
memory_region_add_subregion_overlap(&s->cpu_container[i], 0,
&s->container, -1);
}
object_property_set_link(cpuobj, OBJECT(&s->cpu_container[i]),
"memory", &err);
if (err) {
error_propagate(errp, err);
return;

View File

@ -135,7 +135,17 @@ typedef struct ARMSSE {
IoTKitSysCtl sysctl;
IoTKitSysCtl sysinfo;
/*
* 'container' holds all devices seen by all CPUs.
* 'cpu_container[i]' is the view that CPU i has: this has the
* per-CPU devices of that CPU, plus as the background 'container'
* (or an alias of it, since we can only use it directly once).
* container_alias[i] is the alias of 'container' used by CPU i+1;
* CPU 0 can use 'container' directly.
*/
MemoryRegion container;
MemoryRegion container_alias[SSE_MAX_CPUS - 1];
MemoryRegion cpu_container[SSE_MAX_CPUS];
MemoryRegion alias1;
MemoryRegion alias2;
MemoryRegion alias3;