mirror of https://github.com/xqemu/xqemu.git
hw/arm/armsse: Make number of SRAM banks parameterised
The SSE-200 has four banks of SRAM, each with its own Memory Protection Controller, where the IoTKit has only one. Make the number of SRAM banks a field in ARMSSEInfo. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20190121185118.18550-10-peter.maydell@linaro.org
This commit is contained in:
parent
0a78d7ebf8
commit
f0cab7fe88
|
@ -20,11 +20,13 @@
|
||||||
|
|
||||||
struct ARMSSEInfo {
|
struct ARMSSEInfo {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
int sram_banks;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const ARMSSEInfo armsse_variants[] = {
|
static const ARMSSEInfo armsse_variants[] = {
|
||||||
{
|
{
|
||||||
.name = TYPE_IOTKIT,
|
.name = TYPE_IOTKIT,
|
||||||
|
.sram_banks = 1,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -118,8 +120,12 @@ static void armsse_forward_sec_resp_cfg(ARMSSE *s)
|
||||||
static void armsse_init(Object *obj)
|
static void armsse_init(Object *obj)
|
||||||
{
|
{
|
||||||
ARMSSE *s = ARMSSE(obj);
|
ARMSSE *s = ARMSSE(obj);
|
||||||
|
ARMSSEClass *asc = ARMSSE_GET_CLASS(obj);
|
||||||
|
const ARMSSEInfo *info = asc->info;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
assert(info->sram_banks <= MAX_SRAM_BANKS);
|
||||||
|
|
||||||
memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
|
memory_region_init(&s->container, obj, "armsse-container", UINT64_MAX);
|
||||||
|
|
||||||
sysbus_init_child_obj(obj, "armv7m", &s->armv7m, sizeof(s->armv7m),
|
sysbus_init_child_obj(obj, "armv7m", &s->armv7m, sizeof(s->armv7m),
|
||||||
|
@ -133,12 +139,17 @@ static void armsse_init(Object *obj)
|
||||||
TYPE_TZ_PPC);
|
TYPE_TZ_PPC);
|
||||||
sysbus_init_child_obj(obj, "apb-ppc1", &s->apb_ppc1, sizeof(s->apb_ppc1),
|
sysbus_init_child_obj(obj, "apb-ppc1", &s->apb_ppc1, sizeof(s->apb_ppc1),
|
||||||
TYPE_TZ_PPC);
|
TYPE_TZ_PPC);
|
||||||
sysbus_init_child_obj(obj, "mpc", &s->mpc, sizeof(s->mpc), TYPE_TZ_MPC);
|
for (i = 0; i < info->sram_banks; i++) {
|
||||||
|
char *name = g_strdup_printf("mpc%d", i);
|
||||||
|
sysbus_init_child_obj(obj, name, &s->mpc[i],
|
||||||
|
sizeof(s->mpc[i]), TYPE_TZ_MPC);
|
||||||
|
g_free(name);
|
||||||
|
}
|
||||||
object_initialize_child(obj, "mpc-irq-orgate", &s->mpc_irq_orgate,
|
object_initialize_child(obj, "mpc-irq-orgate", &s->mpc_irq_orgate,
|
||||||
sizeof(s->mpc_irq_orgate), TYPE_OR_IRQ,
|
sizeof(s->mpc_irq_orgate), TYPE_OR_IRQ,
|
||||||
&error_abort, NULL);
|
&error_abort, NULL);
|
||||||
|
|
||||||
for (i = 0; i < IOTS_NUM_EXP_MPC + 1; i++) {
|
for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
|
||||||
char *name = g_strdup_printf("mpc-irq-splitter-%d", i);
|
char *name = g_strdup_printf("mpc-irq-splitter-%d", i);
|
||||||
SplitIRQ *splitter = &s->mpc_irq_splitter[i];
|
SplitIRQ *splitter = &s->mpc_irq_splitter[i];
|
||||||
|
|
||||||
|
@ -199,6 +210,8 @@ static void armsse_mpcexp_status(void *opaque, int n, int level)
|
||||||
static void armsse_realize(DeviceState *dev, Error **errp)
|
static void armsse_realize(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
ARMSSE *s = ARMSSE(dev);
|
ARMSSE *s = ARMSSE(dev);
|
||||||
|
ARMSSEClass *asc = ARMSSE_GET_CLASS(dev);
|
||||||
|
const ARMSSEInfo *info = asc->info;
|
||||||
int i;
|
int i;
|
||||||
MemoryRegion *mr;
|
MemoryRegion *mr;
|
||||||
Error *err = NULL;
|
Error *err = NULL;
|
||||||
|
@ -335,35 +348,41 @@ static void armsse_realize(DeviceState *dev, Error **errp)
|
||||||
qdev_connect_gpio_out_named(dev_secctl, "sec_resp_cfg", 0,
|
qdev_connect_gpio_out_named(dev_secctl, "sec_resp_cfg", 0,
|
||||||
qdev_get_gpio_in(dev_splitter, 0));
|
qdev_get_gpio_in(dev_splitter, 0));
|
||||||
|
|
||||||
/* This RAM lives behind the Memory Protection Controller */
|
/* Each SRAM bank lives behind its own Memory Protection Controller */
|
||||||
memory_region_init_ram(&s->sram0, NULL, "armsse.sram0", 0x00008000, &err);
|
for (i = 0; i < info->sram_banks; i++) {
|
||||||
if (err) {
|
char *ramname = g_strdup_printf("armsse.sram%d", i);
|
||||||
error_propagate(errp, err);
|
SysBusDevice *sbd_mpc;
|
||||||
return;
|
|
||||||
|
memory_region_init_ram(&s->sram[i], NULL, ramname, 0x00008000, &err);
|
||||||
|
g_free(ramname);
|
||||||
|
if (err) {
|
||||||
|
error_propagate(errp, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
object_property_set_link(OBJECT(&s->mpc[i]), OBJECT(&s->sram[i]),
|
||||||
|
"downstream", &err);
|
||||||
|
if (err) {
|
||||||
|
error_propagate(errp, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
object_property_set_bool(OBJECT(&s->mpc[i]), true, "realized", &err);
|
||||||
|
if (err) {
|
||||||
|
error_propagate(errp, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Map the upstream end of the MPC into the right place... */
|
||||||
|
sbd_mpc = SYS_BUS_DEVICE(&s->mpc[i]);
|
||||||
|
memory_region_add_subregion(&s->container, 0x20000000 + i * 0x8000,
|
||||||
|
sysbus_mmio_get_region(sbd_mpc, 1));
|
||||||
|
/* ...and its register interface */
|
||||||
|
memory_region_add_subregion(&s->container, 0x50083000 + i * 0x1000,
|
||||||
|
sysbus_mmio_get_region(sbd_mpc, 0));
|
||||||
}
|
}
|
||||||
object_property_set_link(OBJECT(&s->mpc), OBJECT(&s->sram0),
|
|
||||||
"downstream", &err);
|
|
||||||
if (err) {
|
|
||||||
error_propagate(errp, err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
object_property_set_bool(OBJECT(&s->mpc), true, "realized", &err);
|
|
||||||
if (err) {
|
|
||||||
error_propagate(errp, err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
/* Map the upstream end of the MPC into the right place... */
|
|
||||||
memory_region_add_subregion(&s->container, 0x20000000,
|
|
||||||
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mpc),
|
|
||||||
1));
|
|
||||||
/* ...and its register interface */
|
|
||||||
memory_region_add_subregion(&s->container, 0x50083000,
|
|
||||||
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mpc),
|
|
||||||
0));
|
|
||||||
|
|
||||||
/* We must OR together lines from the MPC splitters to go to the NVIC */
|
/* We must OR together lines from the MPC splitters to go to the NVIC */
|
||||||
object_property_set_int(OBJECT(&s->mpc_irq_orgate),
|
object_property_set_int(OBJECT(&s->mpc_irq_orgate),
|
||||||
IOTS_NUM_EXP_MPC + 1, "num-lines", &err);
|
IOTS_NUM_EXP_MPC + info->sram_banks,
|
||||||
|
"num-lines", &err);
|
||||||
if (err) {
|
if (err) {
|
||||||
error_propagate(errp, err);
|
error_propagate(errp, err);
|
||||||
return;
|
return;
|
||||||
|
@ -636,7 +655,7 @@ static void armsse_realize(DeviceState *dev, Error **errp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wire up the splitters for the MPC IRQs */
|
/* Wire up the splitters for the MPC IRQs */
|
||||||
for (i = 0; i < IOTS_NUM_EXP_MPC + 1; i++) {
|
for (i = 0; i < IOTS_NUM_EXP_MPC + info->sram_banks; i++) {
|
||||||
SplitIRQ *splitter = &s->mpc_irq_splitter[i];
|
SplitIRQ *splitter = &s->mpc_irq_splitter[i];
|
||||||
DeviceState *dev_splitter = DEVICE(splitter);
|
DeviceState *dev_splitter = DEVICE(splitter);
|
||||||
|
|
||||||
|
@ -659,7 +678,8 @@ static void armsse_realize(DeviceState *dev, Error **errp)
|
||||||
"mpcexp_status", i));
|
"mpcexp_status", i));
|
||||||
} else {
|
} else {
|
||||||
/* Splitter input is from our own MPC */
|
/* Splitter input is from our own MPC */
|
||||||
qdev_connect_gpio_out_named(DEVICE(&s->mpc), "irq", 0,
|
qdev_connect_gpio_out_named(DEVICE(&s->mpc[i - IOTS_NUM_EXP_MPC]),
|
||||||
|
"irq", 0,
|
||||||
qdev_get_gpio_in(dev_splitter, 0));
|
qdev_get_gpio_in(dev_splitter, 0));
|
||||||
qdev_connect_gpio_out(dev_splitter, 0,
|
qdev_connect_gpio_out(dev_splitter, 0,
|
||||||
qdev_get_gpio_in_named(dev_secctl,
|
qdev_get_gpio_in_named(dev_secctl,
|
||||||
|
|
|
@ -90,6 +90,11 @@
|
||||||
#define NUM_EXTERNAL_PPCS (IOTS_NUM_AHB_EXP_PPC + IOTS_NUM_APB_EXP_PPC)
|
#define NUM_EXTERNAL_PPCS (IOTS_NUM_AHB_EXP_PPC + IOTS_NUM_APB_EXP_PPC)
|
||||||
#define NUM_PPCS (NUM_EXTERNAL_PPCS + 2)
|
#define NUM_PPCS (NUM_EXTERNAL_PPCS + 2)
|
||||||
|
|
||||||
|
#define MAX_SRAM_BANKS 4
|
||||||
|
#if MAX_SRAM_BANKS > IOTS_NUM_MPC
|
||||||
|
#error Too many SRAM banks
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct ARMSSE {
|
typedef struct ARMSSE {
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
SysBusDevice parent_obj;
|
SysBusDevice parent_obj;
|
||||||
|
@ -99,7 +104,7 @@ typedef struct ARMSSE {
|
||||||
IoTKitSecCtl secctl;
|
IoTKitSecCtl secctl;
|
||||||
TZPPC apb_ppc0;
|
TZPPC apb_ppc0;
|
||||||
TZPPC apb_ppc1;
|
TZPPC apb_ppc1;
|
||||||
TZMPC mpc;
|
TZMPC mpc[IOTS_NUM_MPC];
|
||||||
CMSDKAPBTIMER timer0;
|
CMSDKAPBTIMER timer0;
|
||||||
CMSDKAPBTIMER timer1;
|
CMSDKAPBTIMER timer1;
|
||||||
CMSDKAPBTIMER s32ktimer;
|
CMSDKAPBTIMER s32ktimer;
|
||||||
|
@ -123,7 +128,7 @@ typedef struct ARMSSE {
|
||||||
MemoryRegion alias1;
|
MemoryRegion alias1;
|
||||||
MemoryRegion alias2;
|
MemoryRegion alias2;
|
||||||
MemoryRegion alias3;
|
MemoryRegion alias3;
|
||||||
MemoryRegion sram0;
|
MemoryRegion sram[MAX_SRAM_BANKS];
|
||||||
|
|
||||||
qemu_irq *exp_irqs;
|
qemu_irq *exp_irqs;
|
||||||
qemu_irq ppc0_irq;
|
qemu_irq ppc0_irq;
|
||||||
|
|
Loading…
Reference in New Issue