aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/arm/iotkit.c74
-rw-r--r--include/hw/arm/iotkit.h6
2 files changed, 80 insertions, 0 deletions
diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c
index 160e40c744..133d5bb34f 100644
--- a/hw/arm/iotkit.c
+++ b/hw/arm/iotkit.c
@@ -131,6 +131,18 @@ static void iotkit_init(Object *obj)
init_sysbus_child(obj, "apb-ppc1", &s->apb_ppc1, sizeof(s->apb_ppc1),
TYPE_TZ_PPC);
init_sysbus_child(obj, "mpc", &s->mpc, sizeof(s->mpc), TYPE_TZ_MPC);
+ object_initialize(&s->mpc_irq_orgate, sizeof(s->mpc_irq_orgate),
+ TYPE_OR_IRQ);
+ object_property_add_child(obj, "mpc-irq-orgate",
+ OBJECT(&s->mpc_irq_orgate), &error_abort);
+ for (i = 0; i < ARRAY_SIZE(s->mpc_irq_splitter); i++) {
+ char *name = g_strdup_printf("mpc-irq-splitter-%d", i);
+ SplitIRQ *splitter = &s->mpc_irq_splitter[i];
+
+ object_initialize(splitter, sizeof(*splitter), TYPE_SPLIT_IRQ);
+ object_property_add_child(obj, name, OBJECT(splitter), &error_abort);
+ g_free(name);
+ }
init_sysbus_child(obj, "timer0", &s->timer0, sizeof(s->timer0),
TYPE_CMSDK_APB_TIMER);
init_sysbus_child(obj, "timer1", &s->timer1, sizeof(s->timer1),
@@ -163,6 +175,12 @@ static void iotkit_exp_irq(void *opaque, int n, int level)
qemu_set_irq(s->exp_irqs[n], level);
}
+static void iotkit_mpcexp_status(void *opaque, int n, int level)
+{
+ IoTKit *s = IOTKIT(opaque);
+ qemu_set_irq(s->mpcexp_status_in[n], level);
+}
+
static void iotkit_realize(DeviceState *dev, Error **errp)
{
IoTKit *s = IOTKIT(dev);
@@ -328,6 +346,22 @@ static void iotkit_realize(DeviceState *dev, Error **errp)
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->mpc),
0));
+ /* We must OR together lines from the MPC splitters to go to the NVIC */
+ object_property_set_int(OBJECT(&s->mpc_irq_orgate),
+ IOTS_NUM_EXP_MPC + IOTS_NUM_MPC, "num-lines", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+ object_property_set_bool(OBJECT(&s->mpc_irq_orgate), true,
+ "realized", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+ qdev_connect_gpio_out(DEVICE(&s->mpc_irq_orgate), 0,
+ qdev_get_gpio_in(DEVICE(&s->armv7m), 9));
+
/* Devices behind APB PPC0:
* 0x40000000: timer0
* 0x40001000: timer1
@@ -536,6 +570,46 @@ static void iotkit_realize(DeviceState *dev, Error **errp)
g_free(gpioname);
}
+ /* Wire up the splitters for the MPC IRQs */
+ for (i = 0; i < IOTS_NUM_EXP_MPC + IOTS_NUM_MPC; i++) {
+ SplitIRQ *splitter = &s->mpc_irq_splitter[i];
+ DeviceState *dev_splitter = DEVICE(splitter);
+
+ object_property_set_int(OBJECT(splitter), 2, "num-lines", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+ object_property_set_bool(OBJECT(splitter), true, "realized", &err);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+
+ if (i < IOTS_NUM_EXP_MPC) {
+ /* Splitter input is from GPIO input line */
+ s->mpcexp_status_in[i] = qdev_get_gpio_in(dev_splitter, 0);
+ qdev_connect_gpio_out(dev_splitter, 0,
+ qdev_get_gpio_in_named(dev_secctl,
+ "mpcexp_status", i));
+ } else {
+ /* Splitter input is from our own MPC */
+ qdev_connect_gpio_out_named(DEVICE(&s->mpc), "irq", 0,
+ qdev_get_gpio_in(dev_splitter, 0));
+ qdev_connect_gpio_out(dev_splitter, 0,
+ qdev_get_gpio_in_named(dev_secctl,
+ "mpc_status", 0));
+ }
+
+ qdev_connect_gpio_out(dev_splitter, 1,
+ qdev_get_gpio_in(DEVICE(&s->mpc_irq_orgate), i));
+ }
+ /* Create GPIO inputs which will pass the line state for our
+ * mpcexp_irq inputs to the correct splitter devices.
+ */
+ qdev_init_gpio_in_named(dev, iotkit_mpcexp_status, "mpcexp_status",
+ IOTS_NUM_EXP_MPC);
+
iotkit_forward_sec_resp_cfg(s);
system_clock_scale = NANOSECONDS_PER_SECOND / s->mainclk_frq;
diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h
index b21cf1ab9d..2cddde55dd 100644
--- a/include/hw/arm/iotkit.h
+++ b/include/hw/arm/iotkit.h
@@ -42,6 +42,9 @@
* + named GPIO outputs ahb_ppcexp{0,1,2,3}_irq_enable
* + named GPIO outputs ahb_ppcexp{0,1,2,3}_irq_clear
* + named GPIO inputs ahb_ppcexp{0,1,2,3}_irq_status
+ * Controlling each of the 16 expansion MPCs which a system using the IoTKit
+ * might provide:
+ * + named GPIO inputs mpcexp_status[0..15]
*/
#ifndef IOTKIT_H
@@ -81,6 +84,8 @@ typedef struct IoTKit {
qemu_or_irq ppc_irq_orgate;
SplitIRQ sec_resp_splitter;
SplitIRQ ppc_irq_splitter[NUM_PPCS];
+ SplitIRQ mpc_irq_splitter[IOTS_NUM_EXP_MPC + IOTS_NUM_MPC];
+ qemu_or_irq mpc_irq_orgate;
UnimplementedDeviceState dualtimer;
UnimplementedDeviceState s32ktimer;
@@ -99,6 +104,7 @@ typedef struct IoTKit {
qemu_irq nsc_cfg_in;
qemu_irq irq_status_in[NUM_EXTERNAL_PPCS];
+ qemu_irq mpcexp_status_in[IOTS_NUM_EXP_MPC];
uint32_t nsccfg;