From 017d069d20866ed50f3422ade69d6cb60ea7522b Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Aug 2018 13:17:41 +0100 Subject: hw/arm/iotkit: Wire up the dualtimer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now we have a model of the CMSDK dual timer, we can wire it up in the IoTKit. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20180820141116.9118-5-peter.maydell@linaro.org --- hw/arm/iotkit.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'hw/arm/iotkit.c') diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c index 8cadc8b160..130d013909 100644 --- a/hw/arm/iotkit.c +++ b/hw/arm/iotkit.c @@ -139,7 +139,7 @@ static void iotkit_init(Object *obj) sysbus_init_child_obj(obj, "timer1", &s->timer1, sizeof(s->timer1), TYPE_CMSDK_APB_TIMER); sysbus_init_child_obj(obj, "dualtimer", &s->dualtimer, sizeof(s->dualtimer), - TYPE_UNIMPLEMENTED_DEVICE); + TYPE_CMSDK_APB_DUALTIMER); object_initialize_child(obj, "ppc-irq-orgate", &s->ppc_irq_orgate, sizeof(s->ppc_irq_orgate), TYPE_OR_IRQ, &error_abort, NULL); @@ -390,13 +390,15 @@ static void iotkit_realize(DeviceState *dev, Error **errp) return; } - qdev_prop_set_string(DEVICE(&s->dualtimer), "name", "Dual timer"); - qdev_prop_set_uint64(DEVICE(&s->dualtimer), "size", 0x1000); + + qdev_prop_set_uint32(DEVICE(&s->dualtimer), "pclk-frq", s->mainclk_frq); object_property_set_bool(OBJECT(&s->dualtimer), true, "realized", &err); if (err) { error_propagate(errp, err); return; } + sysbus_connect_irq(SYS_BUS_DEVICE(&s->dualtimer), 0, + qdev_get_gpio_in(DEVICE(&s->armv7m), 5)); mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->dualtimer), 0); object_property_set_link(OBJECT(&s->apb_ppc0), OBJECT(mr), "port[2]", &err); if (err) { -- cgit 1.4.1 From d61e4e1ff721ff8ab611f8a81442f8af192c0961 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Aug 2018 13:17:42 +0100 Subject: hw/arm/iotkit: Wire up the watchdogs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The IoTKit includes three different instances of the CMSDK APB watchdog; create and wire them up. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20180820141116.9118-7-peter.maydell@linaro.org --- hw/arm/iotkit.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++--- include/hw/arm/iotkit.h | 6 +++++ 2 files changed, 61 insertions(+), 3 deletions(-) (limited to 'hw/arm/iotkit.c') diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c index 130d013909..5cedfa0357 100644 --- a/hw/arm/iotkit.c +++ b/hw/arm/iotkit.c @@ -19,6 +19,9 @@ #include "hw/misc/unimp.h" #include "hw/arm/arm.h" +/* Clock frequency in HZ of the 32KHz "slow clock" */ +#define S32KCLK (32 * 1000) + /* Create an alias region of @size bytes starting at @base * which mirrors the memory starting at @orig. */ @@ -140,6 +143,15 @@ static void iotkit_init(Object *obj) TYPE_CMSDK_APB_TIMER); sysbus_init_child_obj(obj, "dualtimer", &s->dualtimer, sizeof(s->dualtimer), TYPE_CMSDK_APB_DUALTIMER); + sysbus_init_child_obj(obj, "s32kwatchdog", &s->s32kwatchdog, + sizeof(s->s32kwatchdog), TYPE_CMSDK_APB_WATCHDOG); + sysbus_init_child_obj(obj, "nswatchdog", &s->nswatchdog, + sizeof(s->nswatchdog), TYPE_CMSDK_APB_WATCHDOG); + sysbus_init_child_obj(obj, "swatchdog", &s->swatchdog, + sizeof(s->swatchdog), TYPE_CMSDK_APB_WATCHDOG); + object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate, + sizeof(s->nmi_orgate), TYPE_OR_IRQ, + &error_abort, NULL); object_initialize_child(obj, "ppc-irq-orgate", &s->ppc_irq_orgate, sizeof(s->ppc_irq_orgate), TYPE_OR_IRQ, &error_abort, NULL); @@ -510,12 +522,52 @@ static void iotkit_realize(DeviceState *dev, Error **errp) create_unimplemented_device("SYSINFO", 0x40020000, 0x1000); create_unimplemented_device("SYSCONTROL", 0x50021000, 0x1000); - create_unimplemented_device("S32KWATCHDOG", 0x5002e000, 0x1000); + + /* This OR gate wires together outputs from the secure watchdogs to NMI */ + object_property_set_int(OBJECT(&s->nmi_orgate), 2, "num-lines", &err); + if (err) { + error_propagate(errp, err); + return; + } + object_property_set_bool(OBJECT(&s->nmi_orgate), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + qdev_connect_gpio_out(DEVICE(&s->nmi_orgate), 0, + qdev_get_gpio_in_named(DEVICE(&s->armv7m), "NMI", 0)); + + qdev_prop_set_uint32(DEVICE(&s->s32kwatchdog), "wdogclk-frq", S32KCLK); + object_property_set_bool(OBJECT(&s->s32kwatchdog), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32kwatchdog), 0, + qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 0)); + sysbus_mmio_map(SYS_BUS_DEVICE(&s->s32kwatchdog), 0, 0x5002e000); /* 0x40080000 .. 0x4008ffff : IoTKit second Base peripheral region */ - create_unimplemented_device("NS watchdog", 0x40081000, 0x1000); - create_unimplemented_device("S watchdog", 0x50081000, 0x1000); + qdev_prop_set_uint32(DEVICE(&s->nswatchdog), "wdogclk-frq", s->mainclk_frq); + object_property_set_bool(OBJECT(&s->nswatchdog), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + sysbus_connect_irq(SYS_BUS_DEVICE(&s->nswatchdog), 0, + qdev_get_gpio_in(DEVICE(&s->armv7m), 1)); + sysbus_mmio_map(SYS_BUS_DEVICE(&s->nswatchdog), 0, 0x40081000); + + qdev_prop_set_uint32(DEVICE(&s->swatchdog), "wdogclk-frq", s->mainclk_frq); + object_property_set_bool(OBJECT(&s->swatchdog), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + sysbus_connect_irq(SYS_BUS_DEVICE(&s->swatchdog), 0, + qdev_get_gpio_in(DEVICE(&s->nmi_orgate), 1)); + sysbus_mmio_map(SYS_BUS_DEVICE(&s->swatchdog), 0, 0x50081000); for (i = 0; i < ARRAY_SIZE(s->ppc_irq_splitter); i++) { Object *splitter = OBJECT(&s->ppc_irq_splitter[i]); diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h index 3e6d806e35..776d049708 100644 --- a/include/hw/arm/iotkit.h +++ b/include/hw/arm/iotkit.h @@ -57,6 +57,7 @@ #include "hw/misc/tz-mpc.h" #include "hw/timer/cmsdk-apb-timer.h" #include "hw/timer/cmsdk-apb-dualtimer.h" +#include "hw/watchdog/cmsdk-apb-watchdog.h" #include "hw/misc/unimp.h" #include "hw/or-irq.h" #include "hw/core/split-irq.h" @@ -87,10 +88,15 @@ typedef struct IoTKit { SplitIRQ ppc_irq_splitter[NUM_PPCS]; SplitIRQ mpc_irq_splitter[IOTS_NUM_EXP_MPC + IOTS_NUM_MPC]; qemu_or_irq mpc_irq_orgate; + qemu_or_irq nmi_orgate; CMSDKAPBDualTimer dualtimer; UnimplementedDeviceState s32ktimer; + CMSDKAPBWatchdog s32kwatchdog; + CMSDKAPBWatchdog nswatchdog; + CMSDKAPBWatchdog swatchdog; + MemoryRegion container; MemoryRegion alias1; MemoryRegion alias2; -- cgit 1.4.1 From e2d203baba7bf202a64ee321c2754fe918ab909e Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Aug 2018 13:17:42 +0100 Subject: hw/arm/iotkit: Wire up the S32KTIMER MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The IoTKit has a CMSDK timer device that runs on the S32KCLK. Create this and wire it up. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20180820141116.9118-8-peter.maydell@linaro.org --- hw/arm/iotkit.c | 9 +++++---- include/hw/arm/iotkit.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'hw/arm/iotkit.c') diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c index 5cedfa0357..cb0ec456f3 100644 --- a/hw/arm/iotkit.c +++ b/hw/arm/iotkit.c @@ -141,6 +141,8 @@ static void iotkit_init(Object *obj) TYPE_CMSDK_APB_TIMER); sysbus_init_child_obj(obj, "timer1", &s->timer1, sizeof(s->timer1), TYPE_CMSDK_APB_TIMER); + sysbus_init_child_obj(obj, "s32ktimer", &s->s32ktimer, sizeof(s->s32ktimer), + TYPE_CMSDK_APB_TIMER); sysbus_init_child_obj(obj, "dualtimer", &s->dualtimer, sizeof(s->dualtimer), TYPE_CMSDK_APB_DUALTIMER); sysbus_init_child_obj(obj, "s32kwatchdog", &s->s32kwatchdog, @@ -166,8 +168,6 @@ static void iotkit_init(Object *obj) TYPE_SPLIT_IRQ, &error_abort, NULL); g_free(name); } - sysbus_init_child_obj(obj, "s32ktimer", &s->s32ktimer, sizeof(s->s32ktimer), - TYPE_UNIMPLEMENTED_DEVICE); } static void iotkit_exp_irq(void *opaque, int n, int level) @@ -476,13 +476,14 @@ static void iotkit_realize(DeviceState *dev, Error **errp) /* Devices behind APB PPC1: * 0x4002f000: S32K timer */ - qdev_prop_set_string(DEVICE(&s->s32ktimer), "name", "S32KTIMER"); - qdev_prop_set_uint64(DEVICE(&s->s32ktimer), "size", 0x1000); + qdev_prop_set_uint32(DEVICE(&s->s32ktimer), "pclk-frq", S32KCLK); object_property_set_bool(OBJECT(&s->s32ktimer), true, "realized", &err); if (err) { error_propagate(errp, err); return; } + sysbus_connect_irq(SYS_BUS_DEVICE(&s->s32ktimer), 0, + qdev_get_gpio_in(DEVICE(&s->armv7m), 2)); mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->s32ktimer), 0); object_property_set_link(OBJECT(&s->apb_ppc1), OBJECT(mr), "port[0]", &err); if (err) { diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h index 776d049708..0f5c510170 100644 --- a/include/hw/arm/iotkit.h +++ b/include/hw/arm/iotkit.h @@ -83,6 +83,7 @@ typedef struct IoTKit { TZMPC mpc; CMSDKAPBTIMER timer0; CMSDKAPBTIMER timer1; + CMSDKAPBTIMER s32ktimer; qemu_or_irq ppc_irq_orgate; SplitIRQ sec_resp_splitter; SplitIRQ ppc_irq_splitter[NUM_PPCS]; @@ -91,7 +92,6 @@ typedef struct IoTKit { qemu_or_irq nmi_orgate; CMSDKAPBDualTimer dualtimer; - UnimplementedDeviceState s32ktimer; CMSDKAPBWatchdog s32kwatchdog; CMSDKAPBWatchdog nswatchdog; -- cgit 1.4.1 From 06e65af39b451c6abe863986a9c60d69bde7718d Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Aug 2018 13:17:43 +0100 Subject: hw/misc/iotkit: Wire up the sysctl and sysinfo register blocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Wire up the system control element's register banks (sysctl and sysinfo). This is the last of the previously completely unimplemented components in the IoTKit. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20180820141116.9118-11-peter.maydell@linaro.org --- hw/arm/iotkit.c | 26 ++++++++++++++++++-------- include/hw/arm/iotkit.h | 6 +++++- 2 files changed, 23 insertions(+), 9 deletions(-) (limited to 'hw/arm/iotkit.c') diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c index cb0ec456f3..f8276b5425 100644 --- a/hw/arm/iotkit.c +++ b/hw/arm/iotkit.c @@ -16,7 +16,6 @@ #include "hw/sysbus.h" #include "hw/registerfields.h" #include "hw/arm/iotkit.h" -#include "hw/misc/unimp.h" #include "hw/arm/arm.h" /* Clock frequency in HZ of the 32KHz "slow clock" */ @@ -151,6 +150,10 @@ static void iotkit_init(Object *obj) sizeof(s->nswatchdog), TYPE_CMSDK_APB_WATCHDOG); sysbus_init_child_obj(obj, "swatchdog", &s->swatchdog, sizeof(s->swatchdog), TYPE_CMSDK_APB_WATCHDOG); + sysbus_init_child_obj(obj, "iotkit-sysctl", &s->sysctl, + sizeof(s->sysctl), TYPE_IOTKIT_SYSCTL); + sysbus_init_child_obj(obj, "iotkit-sysinfo", &s->sysinfo, + sizeof(s->sysinfo), TYPE_IOTKIT_SYSINFO); object_initialize_child(obj, "nmi-orgate", &s->nmi_orgate, sizeof(s->nmi_orgate), TYPE_OR_IRQ, &error_abort, NULL); @@ -516,13 +519,20 @@ static void iotkit_realize(DeviceState *dev, Error **errp) qdev_get_gpio_in_named(dev_apb_ppc1, "cfg_sec_resp", 0)); - /* Using create_unimplemented_device() maps the stub into the - * system address space rather than into our container, but the - * overall effect to the guest is the same. - */ - create_unimplemented_device("SYSINFO", 0x40020000, 0x1000); - - create_unimplemented_device("SYSCONTROL", 0x50021000, 0x1000); + object_property_set_bool(OBJECT(&s->sysinfo), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + /* System information registers */ + sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysinfo), 0, 0x40020000); + /* System control registers */ + object_property_set_bool(OBJECT(&s->sysctl), true, "realized", &err); + if (err) { + error_propagate(errp, err); + return; + } + sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysctl), 0, 0x50021000); /* This OR gate wires together outputs from the secure watchdogs to NMI */ object_property_set_int(OBJECT(&s->nmi_orgate), 2, "num-lines", &err); diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h index 0f5c510170..426dc326a0 100644 --- a/include/hw/arm/iotkit.h +++ b/include/hw/arm/iotkit.h @@ -58,7 +58,8 @@ #include "hw/timer/cmsdk-apb-timer.h" #include "hw/timer/cmsdk-apb-dualtimer.h" #include "hw/watchdog/cmsdk-apb-watchdog.h" -#include "hw/misc/unimp.h" +#include "hw/misc/iotkit-sysctl.h" +#include "hw/misc/iotkit-sysinfo.h" #include "hw/or-irq.h" #include "hw/core/split-irq.h" @@ -97,6 +98,9 @@ typedef struct IoTKit { CMSDKAPBWatchdog nswatchdog; CMSDKAPBWatchdog swatchdog; + IoTKitSysCtl sysctl; + IoTKitSysCtl sysinfo; + MemoryRegion container; MemoryRegion alias1; MemoryRegion alias2; -- cgit 1.4.1 From 132b475a73574d8c6a7fa678716f2eead1002939 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Fri, 24 Aug 2018 13:17:44 +0100 Subject: hw/arm/iotkit: Wire up the lines for MSCs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The IoTKit doesn't have any MSCs itself but it does need some wiring to connect the external signals from MSCs in the outer board model up to the registers and the NVIC IRQ line. We also need to expose a MemoryRegion corresponding to the AHB bus, so that MSCs in the outer board model can use that as their downstream port. (In the FPGA this is the "AHB Slave Expansion" ports shown in the block diagram in the AN505 documentation.) Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Message-id: 20180820141116.9118-14-peter.maydell@linaro.org Reviewed-by: Richard Henderson --- hw/arm/iotkit.c | 15 +++++++++++++++ include/hw/arm/iotkit.h | 8 ++++++++ 2 files changed, 23 insertions(+) (limited to 'hw/arm/iotkit.c') diff --git a/hw/arm/iotkit.c b/hw/arm/iotkit.c index f8276b5425..8742200fb4 100644 --- a/hw/arm/iotkit.c +++ b/hw/arm/iotkit.c @@ -667,6 +667,21 @@ static void iotkit_realize(DeviceState *dev, Error **errp) iotkit_forward_sec_resp_cfg(s); + /* Forward the MSC related signals */ + qdev_pass_gpios(dev_secctl, dev, "mscexp_status"); + qdev_pass_gpios(dev_secctl, dev, "mscexp_clear"); + qdev_pass_gpios(dev_secctl, dev, "mscexp_ns"); + qdev_connect_gpio_out_named(dev_secctl, "msc_irq", 0, + qdev_get_gpio_in(DEVICE(&s->armv7m), 11)); + + /* + * Expose our container region to the board model; this corresponds + * to the AHB Slave Expansion ports which allow bus master devices + * (eg DMA controllers) in the board model to make transactions into + * devices in the IoTKit. + */ + sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->container); + system_clock_scale = NANOSECONDS_PER_SECOND / s->mainclk_frq; } diff --git a/include/hw/arm/iotkit.h b/include/hw/arm/iotkit.h index 426dc326a0..3a8ee63908 100644 --- a/include/hw/arm/iotkit.h +++ b/include/hw/arm/iotkit.h @@ -28,6 +28,9 @@ * + QOM property "EXP_NUMIRQ" sets the number of expansion interrupts * + Named GPIO inputs "EXP_IRQ" 0..n are the expansion interrupts, which * are wired to the NVIC lines 32 .. n+32 + * + sysbus MMIO region 0 is the "AHB Slave Expansion" which allows + * bus master devices in the board model to make transactions into + * all the devices and memory areas in the IoTKit * Controlling up to 4 AHB expansion PPBs which a system using the IoTKit * might provide: * + named GPIO outputs apb_ppcexp{0,1,2,3}_nonsec[0..15] @@ -45,6 +48,11 @@ * Controlling each of the 16 expansion MPCs which a system using the IoTKit * might provide: * + named GPIO inputs mpcexp_status[0..15] + * Controlling each of the 16 expansion MSCs which a system using the IoTKit + * might provide: + * + named GPIO inputs mscexp_status[0..15] + * + named GPIO outputs mscexp_clear[0..15] + * + named GPIO outputs mscexp_ns[0..15] */ #ifndef IOTKIT_H -- cgit 1.4.1