qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v3 1/6] armv7m: Allow entry information to be returned
       [not found] <cover.1560919807.git.alistair@alistair23.me>
@ 2019-06-19  4:53 ` Alistair Francis
  2019-06-21 16:23   ` Philippe Mathieu-Daudé
  2019-06-19  4:54 ` [Qemu-devel] [PATCH v3 2/6] target/arm: Allow setting M mode entry and sp Alistair Francis
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 9+ messages in thread
From: Alistair Francis @ 2019-06-19  4:53 UTC (permalink / raw)
  To: qemu-devel, peter.maydell; +Cc: alistair23

Allow the kernel's entry point information to be returned when loading a
kernel.

Signed-off-by: Alistair Francis <alistair@alistair23.me>
---
 hw/arm/armv7m.c       | 4 +++-
 include/hw/arm/boot.h | 4 +++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index b9efad6bac..8ee6291a47 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -304,7 +304,7 @@ static void armv7m_reset(void *opaque)
     cpu_reset(CPU(cpu));
 }
 
-void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size)
+uint64_t armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size)
 {
     int image_size;
     uint64_t entry;
@@ -351,6 +351,8 @@ void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size)
      * board must call this function!
      */
     qemu_register_reset(armv7m_reset, cpu);
+
+    return entry;
 }
 
 static Property bitband_properties[] = {
diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h
index c48cc4c2bc..4e4db0416c 100644
--- a/include/hw/arm/boot.h
+++ b/include/hw/arm/boot.h
@@ -29,11 +29,13 @@ typedef enum {
  * @kernel_filename: file to load
  * @mem_size: mem_size: maximum image size to load
  *
+ * returns: location of the kernel's entry point
+ *
  * Load the guest image for an ARMv7M system. This must be called by
  * any ARMv7M board. (This is necessary to ensure that the CPU resets
  * correctly on system reset, as well as for kernel loading.)
  */
-void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size);
+uint64_t armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size);
 
 /* arm_boot.c */
 struct arm_boot_info {
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH v3 2/6] target/arm: Allow setting M mode entry and sp
       [not found] <cover.1560919807.git.alistair@alistair23.me>
  2019-06-19  4:53 ` [Qemu-devel] [PATCH v3 1/6] armv7m: Allow entry information to be returned Alistair Francis
@ 2019-06-19  4:54 ` Alistair Francis
  2019-06-21 16:38   ` Philippe Mathieu-Daudé
  2019-06-19  4:54 ` [Qemu-devel] [PATCH v3 3/6] hw/misc: Add the STM32F4xx Sysconfig device Alistair Francis
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 9+ messages in thread
From: Alistair Francis @ 2019-06-19  4:54 UTC (permalink / raw)
  To: qemu-devel, peter.maydell; +Cc: alistair23

Add M mode initial entry PC and SP properties.

Signed-off-by: Alistair Francis <alistair@alistair23.me>
---
 target/arm/cpu.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 target/arm/cpu.h |  3 +++
 2 files changed, 50 insertions(+)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 376db154f0..1d83972ab1 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -301,6 +301,9 @@ static void arm_cpu_reset(CPUState *s)
              */
             initial_msp = ldl_p(rom);
             initial_pc = ldl_p(rom + 4);
+        } else if (cpu->init_sp || cpu->init_entry) {
+            initial_msp = cpu->init_sp;
+            initial_pc = cpu->init_entry;
         } else {
             /* Address zero not covered by a ROM blob, or the ROM blob
              * is in non-modifiable memory and this is a second reset after
@@ -801,6 +804,38 @@ static void arm_set_init_svtor(Object *obj, Visitor *v, const char *name,
     visit_type_uint32(v, name, &cpu->init_svtor, errp);
 }
 
+static void arm_get_init_sp(Object *obj, Visitor *v, const char *name,
+                            void *opaque, Error **errp)
+{
+    ARMCPU *cpu = ARM_CPU(obj);
+
+    visit_type_uint32(v, name, &cpu->init_sp, errp);
+}
+
+static void arm_set_init_sp(Object *obj, Visitor *v, const char *name,
+                            void *opaque, Error **errp)
+{
+    ARMCPU *cpu = ARM_CPU(obj);
+
+    visit_type_uint32(v, name, &cpu->init_sp, errp);
+}
+
+static void arm_get_init_entry(Object *obj, Visitor *v, const char *name,
+                            void *opaque, Error **errp)
+{
+    ARMCPU *cpu = ARM_CPU(obj);
+
+    visit_type_uint32(v, name, &cpu->init_entry, errp);
+}
+
+static void arm_set_init_entry(Object *obj, Visitor *v, const char *name,
+                            void *opaque, Error **errp)
+{
+    ARMCPU *cpu = ARM_CPU(obj);
+
+    visit_type_uint32(v, name, &cpu->init_entry, errp);
+}
+
 void arm_cpu_post_init(Object *obj)
 {
     ARMCPU *cpu = ARM_CPU(obj);
@@ -913,6 +948,18 @@ void arm_cpu_post_init(Object *obj)
         object_property_add(obj, "init-svtor", "uint32",
                             arm_get_init_svtor, arm_set_init_svtor,
                             NULL, NULL, &error_abort);
+    } else {
+        /*
+         * M profile: initial value of the SP and entry. We can't just use
+         * a simple DEFINE_PROP_UINT32 for this because we want to permit
+         * the property to be set after realize.
+         */
+        object_property_add(obj, "init-sp", "uint32",
+                            arm_get_init_sp, arm_set_init_sp,
+                            NULL, NULL, &error_abort);
+        object_property_add(obj, "init-entry", "uint32",
+                            arm_get_init_entry, arm_set_init_entry,
+                            NULL, NULL, &error_abort);
     }
 
     qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property,
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index f9da672be5..290fac19d3 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -805,6 +805,9 @@ struct ARMCPU {
      */
     uint32_t psci_conduit;
 
+    /* For M, initial value of the entry and SP */
+    uint32_t init_sp, init_entry;
+
     /* For v8M, initial value of the Secure VTOR */
     uint32_t init_svtor;
 
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH v3 3/6] hw/misc: Add the STM32F4xx Sysconfig device
       [not found] <cover.1560919807.git.alistair@alistair23.me>
  2019-06-19  4:53 ` [Qemu-devel] [PATCH v3 1/6] armv7m: Allow entry information to be returned Alistair Francis
  2019-06-19  4:54 ` [Qemu-devel] [PATCH v3 2/6] target/arm: Allow setting M mode entry and sp Alistair Francis
@ 2019-06-19  4:54 ` Alistair Francis
  2019-06-19  4:54 ` [Qemu-devel] [PATCH v3 4/6] hw/misc: Add the STM32F4xx EXTI device Alistair Francis
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 9+ messages in thread
From: Alistair Francis @ 2019-06-19  4:54 UTC (permalink / raw)
  To: qemu-devel, peter.maydell; +Cc: alistair23

Signed-off-by: Alistair Francis <alistair@alistair23.me>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
 default-configs/arm-softmmu.mak    |   1 +
 hw/arm/Kconfig                     |   9 ++
 hw/misc/Kconfig                    |   3 +
 hw/misc/Makefile.objs              |   1 +
 hw/misc/stm32f4xx_syscfg.c         | 168 +++++++++++++++++++++++++++++++++++++
 hw/misc/trace-events               |   6 ++
 include/hw/misc/stm32f4xx_syscfg.h |  61 ++++++++++++++
 7 files changed, 249 insertions(+)
 create mode 100644 hw/misc/stm32f4xx_syscfg.c
 create mode 100644 include/hw/misc/stm32f4xx_syscfg.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 1f2e0e7fde..645e6201bb 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -30,6 +30,7 @@ CONFIG_Z2=y
 CONFIG_COLLIE=y
 CONFIG_ASPEED_SOC=y
 CONFIG_NETDUINO2=y
+CONFIG_NETDUINOPLUS2=y
 CONFIG_MPS2=y
 CONFIG_RASPI=y
 CONFIG_DIGIC=y
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 9aced9d54d..c8d0ec997d 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -95,6 +95,10 @@ config NETDUINO2
     bool
     select STM32F205_SOC
 
+config NETDUINOPLUS2
+    bool
+    select STM32F405_SOC
+
 config NSERIES
     bool
     select OMAP
@@ -284,6 +288,11 @@ config STM32F205_SOC
     select STM32F2XX_ADC
     select STM32F2XX_SPI
 
+config STM32F405_SOC
+    bool
+    select ARM_V7M
+    select STM32F4XX_SYSCFG
+
 config XLNX_ZYNQMP_ARM
     bool
     select AHCI
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index 385e1b0cec..14fb04558a 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -82,6 +82,9 @@ config IMX
 config STM32F2XX_SYSCFG
     bool
 
+config STM32F4XX_SYSCFG
+    bool
+
 config MIPS_ITU
     bool
 
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 77b9df9796..d74c576072 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -57,6 +57,7 @@ obj-$(CONFIG_SLAVIO) += slavio_misc.o
 obj-$(CONFIG_ZYNQ) += zynq_slcr.o
 obj-$(CONFIG_ZYNQ) += zynq-xadc.o
 obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o
+obj-$(CONFIG_STM32F4XX_SYSCFG) += stm32f4xx_syscfg.o
 obj-$(CONFIG_MIPS_CPS) += mips_cmgcr.o
 obj-$(CONFIG_MIPS_CPS) += mips_cpc.o
 obj-$(CONFIG_MIPS_ITU) += mips_itu.o
diff --git a/hw/misc/stm32f4xx_syscfg.c b/hw/misc/stm32f4xx_syscfg.c
new file mode 100644
index 0000000000..b34fb34885
--- /dev/null
+++ b/hw/misc/stm32f4xx_syscfg.c
@@ -0,0 +1,168 @@
+/*
+ * STM32F4xx SYSCFG
+ *
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "trace.h"
+#include "hw/misc/stm32f4xx_syscfg.h"
+
+static void stm32f4xx_syscfg_reset(DeviceState *dev)
+{
+    STM32F4xxSyscfgState *s = STM32F4XX_SYSCFG(dev);
+
+    s->syscfg_memrmp = 0x00000000;
+    s->syscfg_pmc = 0x00000000;
+    s->syscfg_exticr[0] = 0x00000000;
+    s->syscfg_exticr[1] = 0x00000000;
+    s->syscfg_exticr[2] = 0x00000000;
+    s->syscfg_exticr[3] = 0x00000000;
+    s->syscfg_cmpcr = 0x00000000;
+}
+
+static void stm32f4xx_syscfg_set_irq(void *opaque, int irq, int level)
+{
+    STM32F4xxSyscfgState *s = opaque;
+    int icrreg = irq / 4;
+    int startbit = (irq & 3) * 4;
+    uint8_t config = config = irq / 16;
+
+    trace_stm32f4xx_syscfg_set_irq(irq / 16, irq % 16, level);
+
+    g_assert(icrreg < SYSCFG_NUM_EXTICR);
+
+    if (extract32(s->syscfg_exticr[icrreg], startbit, 4) == config) {
+       qemu_set_irq(s->gpio_out[irq], level);
+       trace_stm32f4xx_pulse_exti(irq);
+   }
+}
+
+static uint64_t stm32f4xx_syscfg_read(void *opaque, hwaddr addr,
+                                     unsigned int size)
+{
+    STM32F4xxSyscfgState *s = opaque;
+
+    trace_stm32f4xx_syscfg_read(addr);
+
+    switch (addr) {
+    case SYSCFG_MEMRMP:
+        return s->syscfg_memrmp;
+    case SYSCFG_PMC:
+        return s->syscfg_pmc;
+    case SYSCFG_EXTICR1...SYSCFG_EXTICR4:
+        return s->syscfg_exticr[addr / 4 - SYSCFG_EXTICR1 / 4];
+    case SYSCFG_CMPCR:
+        return s->syscfg_cmpcr;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
+        return 0;
+    }
+}
+
+static void stm32f4xx_syscfg_write(void *opaque, hwaddr addr,
+                       uint64_t val64, unsigned int size)
+{
+    STM32F4xxSyscfgState *s = opaque;
+    uint32_t value = val64;
+
+    trace_stm32f4xx_syscfg_write(value, addr);
+
+    switch (addr) {
+    case SYSCFG_MEMRMP:
+        qemu_log_mask(LOG_UNIMP,
+                      "%s: Changing the memory mapping isn't supported " \
+                      "in QEMU\n", __func__);
+        return;
+    case SYSCFG_PMC:
+        qemu_log_mask(LOG_UNIMP,
+                      "%s: Changing the memory mapping isn't supported " \
+                      "in QEMU\n", __func__);
+        return;
+    case SYSCFG_EXTICR1...SYSCFG_EXTICR4:
+        s->syscfg_exticr[addr / 4 - SYSCFG_EXTICR1 / 4] = (value & 0xFFFF);
+        return;
+    case SYSCFG_CMPCR:
+        s->syscfg_cmpcr = value;
+        return;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
+    }
+}
+
+static const MemoryRegionOps stm32f4xx_syscfg_ops = {
+    .read = stm32f4xx_syscfg_read,
+    .write = stm32f4xx_syscfg_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void stm32f4xx_syscfg_init(Object *obj)
+{
+    STM32F4xxSyscfgState *s = STM32F4XX_SYSCFG(obj);
+
+    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
+
+    memory_region_init_io(&s->mmio, obj, &stm32f4xx_syscfg_ops, s,
+                          TYPE_STM32F4XX_SYSCFG, 0x400);
+    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
+
+    qdev_init_gpio_in(DEVICE(obj), stm32f4xx_syscfg_set_irq, 16 * 9);
+    qdev_init_gpio_out(DEVICE(obj), s->gpio_out, 16);
+}
+
+static const VMStateDescription vmstate_stm32f4xx_syscfg = {
+    .name = TYPE_STM32F4XX_SYSCFG,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(syscfg_memrmp, STM32F4xxSyscfgState),
+        VMSTATE_UINT32(syscfg_pmc, STM32F4xxSyscfgState),
+        VMSTATE_UINT32_ARRAY(syscfg_exticr, STM32F4xxSyscfgState, SYSCFG_NUM_EXTICR),
+        VMSTATE_UINT32(syscfg_cmpcr, STM32F4xxSyscfgState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void stm32f4xx_syscfg_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->reset = stm32f4xx_syscfg_reset;
+    dc->vmsd = &vmstate_stm32f4xx_syscfg;
+}
+
+static const TypeInfo stm32f4xx_syscfg_info = {
+    .name          = TYPE_STM32F4XX_SYSCFG,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(STM32F4xxSyscfgState),
+    .instance_init = stm32f4xx_syscfg_init,
+    .class_init    = stm32f4xx_syscfg_class_init,
+};
+
+static void stm32f4xx_syscfg_register_types(void)
+{
+    type_register_static(&stm32f4xx_syscfg_info);
+}
+
+type_init(stm32f4xx_syscfg_register_types)
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index 47e1bccf71..276a0a8c92 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -84,6 +84,12 @@ mos6522_set_sr_int(void) "set sr_int"
 mos6522_write(uint64_t addr, uint64_t val) "reg=0x%"PRIx64 " val=0x%"PRIx64
 mos6522_read(uint64_t addr, unsigned val) "reg=0x%"PRIx64 " val=0x%x"
 
+# stm32f4xx_syscfg
+stm32f4xx_syscfg_set_irq(int gpio, int line, int level) "Interupt: GPIO: %d, Line: %d; Level: %d"
+stm32f4xx_pulse_exti(int irq) "Pulse EXTI: %d"
+stm32f4xx_syscfg_read(uint64_t addr) "reg read: addr: 0x%" PRIx64 " "
+stm32f4xx_syscfg_write(uint64_t addr, uint64_t data) "reg write: addr: 0x%" PRIx64 " val: 0x%" PRIx64 ""
+
 # tz-mpc.c
 tz_mpc_reg_read(uint32_t offset, uint64_t data, unsigned size) "TZ MPC regs read: offset 0x%x data 0x%" PRIx64 " size %u"
 tz_mpc_reg_write(uint32_t offset, uint64_t data, unsigned size) "TZ MPC regs write: offset 0x%x data 0x%" PRIx64 " size %u"
diff --git a/include/hw/misc/stm32f4xx_syscfg.h b/include/hw/misc/stm32f4xx_syscfg.h
new file mode 100644
index 0000000000..c62c6629e5
--- /dev/null
+++ b/include/hw/misc/stm32f4xx_syscfg.h
@@ -0,0 +1,61 @@
+/*
+ * STM32F4xx SYSCFG
+ *
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef HW_STM_SYSCFG_H
+#define HW_STM_SYSCFG_H
+
+#include "hw/sysbus.h"
+#include "hw/hw.h"
+
+#define SYSCFG_MEMRMP  0x00
+#define SYSCFG_PMC     0x04
+#define SYSCFG_EXTICR1 0x08
+#define SYSCFG_EXTICR2 0x0C
+#define SYSCFG_EXTICR3 0x10
+#define SYSCFG_EXTICR4 0x14
+#define SYSCFG_CMPCR   0x20
+
+#define TYPE_STM32F4XX_SYSCFG "stm32f4xx-syscfg"
+#define STM32F4XX_SYSCFG(obj) \
+    OBJECT_CHECK(STM32F4xxSyscfgState, (obj), TYPE_STM32F4XX_SYSCFG)
+
+#define SYSCFG_NUM_EXTICR 4
+
+typedef struct {
+    /* <private> */
+    SysBusDevice parent_obj;
+
+    /* <public> */
+    MemoryRegion mmio;
+
+    uint32_t syscfg_memrmp;
+    uint32_t syscfg_pmc;
+    uint32_t syscfg_exticr[SYSCFG_NUM_EXTICR];
+    uint32_t syscfg_cmpcr;
+
+    qemu_irq irq;
+    qemu_irq gpio_out[16];
+} STM32F4xxSyscfgState;
+
+#endif
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH v3 4/6] hw/misc: Add the STM32F4xx EXTI device
       [not found] <cover.1560919807.git.alistair@alistair23.me>
                   ` (2 preceding siblings ...)
  2019-06-19  4:54 ` [Qemu-devel] [PATCH v3 3/6] hw/misc: Add the STM32F4xx Sysconfig device Alistair Francis
@ 2019-06-19  4:54 ` Alistair Francis
  2019-06-19  4:54 ` [Qemu-devel] [PATCH v3 5/6] hw/arm: Add the STM32F4xx SoC Alistair Francis
  2019-06-19  4:54 ` [Qemu-devel] [PATCH v3 6/6] hw/arm: Add the Netduino Plus 2 Alistair Francis
  5 siblings, 0 replies; 9+ messages in thread
From: Alistair Francis @ 2019-06-19  4:54 UTC (permalink / raw)
  To: qemu-devel, peter.maydell; +Cc: alistair23

Signed-off-by: Alistair Francis <alistair@alistair23.me>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/Kconfig                   |   1 +
 hw/misc/Kconfig                  |   3 +
 hw/misc/Makefile.objs            |   1 +
 hw/misc/stm32f4xx_exti.c         | 187 +++++++++++++++++++++++++++++++++++++++
 hw/misc/trace-events             |   5 ++
 include/hw/misc/stm32f4xx_exti.h |  60 +++++++++++++
 6 files changed, 257 insertions(+)
 create mode 100644 hw/misc/stm32f4xx_exti.c
 create mode 100644 include/hw/misc/stm32f4xx_exti.h

diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index c8d0ec997d..25a98bf3de 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -292,6 +292,7 @@ config STM32F405_SOC
     bool
     select ARM_V7M
     select STM32F4XX_SYSCFG
+    select STM32F4XX_EXTI
 
 config XLNX_ZYNQMP_ARM
     bool
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index 14fb04558a..1ece536f79 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -85,6 +85,9 @@ config STM32F2XX_SYSCFG
 config STM32F4XX_SYSCFG
     bool
 
+config STM32F4XX_EXTI
+    bool
+
 config MIPS_ITU
     bool
 
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index d74c576072..af7a47e914 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -58,6 +58,7 @@ obj-$(CONFIG_ZYNQ) += zynq_slcr.o
 obj-$(CONFIG_ZYNQ) += zynq-xadc.o
 obj-$(CONFIG_STM32F2XX_SYSCFG) += stm32f2xx_syscfg.o
 obj-$(CONFIG_STM32F4XX_SYSCFG) += stm32f4xx_syscfg.o
+obj-$(CONFIG_STM32F4XX_EXTI) += stm32f4xx_exti.o
 obj-$(CONFIG_MIPS_CPS) += mips_cmgcr.o
 obj-$(CONFIG_MIPS_CPS) += mips_cpc.o
 obj-$(CONFIG_MIPS_ITU) += mips_itu.o
diff --git a/hw/misc/stm32f4xx_exti.c b/hw/misc/stm32f4xx_exti.c
new file mode 100644
index 0000000000..04ac82ae26
--- /dev/null
+++ b/hw/misc/stm32f4xx_exti.c
@@ -0,0 +1,187 @@
+/*
+ * STM32F4XX EXTI
+ *
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "trace.h"
+#include "hw/misc/stm32f4xx_exti.h"
+
+static void stm32f4xx_exti_reset(DeviceState *dev)
+{
+    STM32F4xxExtiState *s = STM32F4XX_EXTI(dev);
+
+    s->exti_imr = 0x00000000;
+    s->exti_emr = 0x00000000;
+    s->exti_rtsr = 0x00000000;
+    s->exti_ftsr = 0x00000000;
+    s->exti_swier = 0x00000000;
+    s->exti_pr = 0x00000000;
+}
+
+static void stm32f4xx_exti_set_irq(void *opaque, int irq, int level)
+{
+    STM32F4xxExtiState *s = opaque;
+
+    if (!((1 << irq) & s->exti_imr)) {
+        /* Interrupt is masked */
+        return;
+    }
+
+    trace_stm32f4xx_exti_set_irq(irq, level);
+
+    if (((1 << irq) & s->exti_rtsr) && level) {
+        /* Rising Edge */
+        qemu_irq_pulse(s->irq[irq]);
+        s->exti_pr |= 1 << irq;
+    }
+
+    if (((1 << irq) & s->exti_ftsr) && !level) {
+        /* Falling Edge */
+        qemu_irq_pulse(s->irq[irq]);
+        s->exti_pr |= 1 << irq;
+    }
+}
+
+static uint64_t stm32f4xx_exti_read(void *opaque, hwaddr addr,
+                                     unsigned int size)
+{
+    STM32F4xxExtiState *s = opaque;
+
+    trace_stm32f4xx_exti_read(addr);
+
+    switch (addr) {
+    case EXTI_IMR:
+        return s->exti_imr;
+    case EXTI_EMR:
+        return s->exti_emr;
+    case EXTI_RTSR:
+        return s->exti_rtsr;
+    case EXTI_FTSR:
+        return s->exti_ftsr;
+    case EXTI_SWIER:
+        return s->exti_swier;
+    case EXTI_PR:
+        return s->exti_pr;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "STM32F4XX_exti_read: Bad offset %x\n", (int)addr);
+        return 0;
+    }
+    return 0;
+}
+
+static void stm32f4xx_exti_write(void *opaque, hwaddr addr,
+                       uint64_t val64, unsigned int size)
+{
+    STM32F4xxExtiState *s = opaque;
+    uint32_t value = (uint32_t) val64;
+
+    trace_stm32f4xx_exti_write(addr, value);
+
+    switch (addr) {
+    case EXTI_IMR:
+        s->exti_imr = value;
+        return;
+    case EXTI_EMR:
+        s->exti_emr = value;
+        return;
+    case EXTI_RTSR:
+        s->exti_rtsr = value;
+        return;
+    case EXTI_FTSR:
+        s->exti_ftsr = value;
+        return;
+    case EXTI_SWIER:
+        s->exti_swier = value;
+        return;
+    case EXTI_PR:
+        /* This bit is cleared by writing a 1 to it */
+        s->exti_pr &= ~value;
+        return;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "STM32F4XX_exti_write: Bad offset %x\n", (int)addr);
+    }
+}
+
+static const MemoryRegionOps stm32f4xx_exti_ops = {
+    .read = stm32f4xx_exti_read,
+    .write = stm32f4xx_exti_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void stm32f4xx_exti_init(Object *obj)
+{
+    STM32F4xxExtiState *s = STM32F4XX_EXTI(obj);
+    int i;
+
+    for (i = 0; i < NUM_INTERRUPT_OUT_LINES; i++) {
+        sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq[i]);
+    }
+
+    memory_region_init_io(&s->mmio, obj, &stm32f4xx_exti_ops, s,
+                          TYPE_STM32F4XX_EXTI, 0x400);
+    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
+
+    qdev_init_gpio_in(DEVICE(obj), stm32f4xx_exti_set_irq,
+                      NUM_GPIO_EVENT_IN_LINES);
+}
+
+static const VMStateDescription vmstate_stm32f4xx_exti = {
+    .name = TYPE_STM32F4XX_EXTI,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(exti_imr, STM32F4xxExtiState),
+        VMSTATE_UINT32(exti_emr, STM32F4xxExtiState),
+        VMSTATE_UINT32(exti_rtsr, STM32F4xxExtiState),
+        VMSTATE_UINT32(exti_ftsr, STM32F4xxExtiState),
+        VMSTATE_UINT32(exti_swier, STM32F4xxExtiState),
+        VMSTATE_UINT32(exti_pr, STM32F4xxExtiState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void stm32f4xx_exti_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->reset = stm32f4xx_exti_reset;
+    dc->vmsd = &vmstate_stm32f4xx_exti;
+}
+
+static const TypeInfo stm32f4xx_exti_info = {
+    .name          = TYPE_STM32F4XX_EXTI,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(STM32F4xxExtiState),
+    .instance_init = stm32f4xx_exti_init,
+    .class_init    = stm32f4xx_exti_class_init,
+};
+
+static void stm32f4xx_exti_register_types(void)
+{
+    type_register_static(&stm32f4xx_exti_info);
+}
+
+type_init(stm32f4xx_exti_register_types)
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index 276a0a8c92..0cdeb80d65 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -90,6 +90,11 @@ stm32f4xx_pulse_exti(int irq) "Pulse EXTI: %d"
 stm32f4xx_syscfg_read(uint64_t addr) "reg read: addr: 0x%" PRIx64 " "
 stm32f4xx_syscfg_write(uint64_t addr, uint64_t data) "reg write: addr: 0x%" PRIx64 " val: 0x%" PRIx64 ""
 
+# stm32f4xx_exti
+stm32f4xx_exti_set_irq(int irq, int leve) "Set EXTI: %d to %d"
+stm32f4xx_exti_read(uint64_t addr) "reg read: addr: 0x%" PRIx64 " "
+stm32f4xx_exti_write(uint64_t addr, uint64_t data) "reg write: addr: 0x%" PRIx64 " val: 0x%" PRIx64 ""
+
 # tz-mpc.c
 tz_mpc_reg_read(uint32_t offset, uint64_t data, unsigned size) "TZ MPC regs read: offset 0x%x data 0x%" PRIx64 " size %u"
 tz_mpc_reg_write(uint32_t offset, uint64_t data, unsigned size) "TZ MPC regs write: offset 0x%x data 0x%" PRIx64 " size %u"
diff --git a/include/hw/misc/stm32f4xx_exti.h b/include/hw/misc/stm32f4xx_exti.h
new file mode 100644
index 0000000000..707036a41b
--- /dev/null
+++ b/include/hw/misc/stm32f4xx_exti.h
@@ -0,0 +1,60 @@
+/*
+ * STM32F4XX EXTI
+ *
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef HW_STM_EXTI_H
+#define HW_STM_EXTI_H
+
+#include "hw/sysbus.h"
+#include "hw/hw.h"
+
+#define EXTI_IMR   0x00
+#define EXTI_EMR   0x04
+#define EXTI_RTSR  0x08
+#define EXTI_FTSR  0x0C
+#define EXTI_SWIER 0x10
+#define EXTI_PR    0x14
+
+#define TYPE_STM32F4XX_EXTI "stm32f4xx-exti"
+#define STM32F4XX_EXTI(obj) \
+    OBJECT_CHECK(STM32F4xxExtiState, (obj), TYPE_STM32F4XX_EXTI)
+
+#define NUM_GPIO_EVENT_IN_LINES 16
+#define NUM_INTERRUPT_OUT_LINES 16
+
+typedef struct {
+    SysBusDevice parent_obj;
+
+    MemoryRegion mmio;
+
+    uint32_t exti_imr;
+    uint32_t exti_emr;
+    uint32_t exti_rtsr;
+    uint32_t exti_ftsr;
+    uint32_t exti_swier;
+    uint32_t exti_pr;
+
+    qemu_irq irq[NUM_INTERRUPT_OUT_LINES];
+} STM32F4xxExtiState;
+
+#endif
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH v3 5/6] hw/arm: Add the STM32F4xx SoC
       [not found] <cover.1560919807.git.alistair@alistair23.me>
                   ` (3 preceding siblings ...)
  2019-06-19  4:54 ` [Qemu-devel] [PATCH v3 4/6] hw/misc: Add the STM32F4xx EXTI device Alistair Francis
@ 2019-06-19  4:54 ` Alistair Francis
  2019-06-19  4:54 ` [Qemu-devel] [PATCH v3 6/6] hw/arm: Add the Netduino Plus 2 Alistair Francis
  5 siblings, 0 replies; 9+ messages in thread
From: Alistair Francis @ 2019-06-19  4:54 UTC (permalink / raw)
  To: qemu-devel, peter.maydell; +Cc: alistair23

Signed-off-by: Alistair Francis <alistair@alistair23.me>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
 MAINTAINERS                    |   8 ++
 hw/arm/Kconfig                 |   3 +
 hw/arm/Makefile.objs           |   1 +
 hw/arm/stm32f405_soc.c         | 301 +++++++++++++++++++++++++++++++++++++++++
 include/hw/arm/stm32f405_soc.h |  73 ++++++++++
 5 files changed, 386 insertions(+)
 create mode 100644 hw/arm/stm32f405_soc.c
 create mode 100644 include/hw/arm/stm32f405_soc.h

diff --git a/MAINTAINERS b/MAINTAINERS
index d32c5c2313..f917f3e693 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -806,6 +806,14 @@ F: hw/adc/*
 F: hw/ssi/stm32f2xx_spi.c
 F: include/hw/*/stm32*.h
 
+STM32F405
+M: Alistair Francis <alistair@alistair23.me>
+M: Peter Maydell <peter.maydell@linaro.org>
+S: Maintained
+F: hw/arm/stm32f405_soc.c
+F: hw/misc/stm32f4xx_syscfg.c
+F: hw/misc/stm32f4xx_exti.c
+
 Netduino 2
 M: Alistair Francis <alistair@alistair23.me>
 M: Peter Maydell <peter.maydell@linaro.org>
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 25a98bf3de..65a0923afe 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -294,6 +294,9 @@ config STM32F405_SOC
     select STM32F4XX_SYSCFG
     select STM32F4XX_EXTI
 
+config STM32F405_SOC
+    bool
+
 config XLNX_ZYNQMP_ARM
     bool
     select AHCI
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 994e67dd0d..4436c2e93e 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -35,6 +35,7 @@ obj-$(CONFIG_STRONGARM) += strongarm.o
 obj-$(CONFIG_ALLWINNER_A10) += allwinner-a10.o cubieboard.o
 obj-$(CONFIG_RASPI) += bcm2835_peripherals.o bcm2836.o raspi.o
 obj-$(CONFIG_STM32F205_SOC) += stm32f205_soc.o
+obj-$(CONFIG_STM32F405_SOC) += stm32f405_soc.o
 obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx-zynqmp.o xlnx-zcu102.o
 obj-$(CONFIG_XLNX_VERSAL) += xlnx-versal.o xlnx-versal-virt.o
 obj-$(CONFIG_FSL_IMX25) += fsl-imx25.o imx25_pdk.o
diff --git a/hw/arm/stm32f405_soc.c b/hw/arm/stm32f405_soc.c
new file mode 100644
index 0000000000..498bc1192c
--- /dev/null
+++ b/hw/arm/stm32f405_soc.c
@@ -0,0 +1,301 @@
+/*
+ * STM32F405 SoC
+ *
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu-common.h"
+#include "exec/address-spaces.h"
+#include "hw/arm/stm32f405_soc.h"
+#include "hw/misc/unimp.h"
+
+#define SYSCFG_ADD                     0x40013800
+static const uint32_t usart_addr[] = { 0x40011000, 0x40004400, 0x40004800,
+                                       0x40004C00, 0x40005000, 0x40011400,
+                                       0x40007800, 0x40007C00 };
+/* At the moment only Timer 2 to 5 are modelled */
+static const uint32_t timer_addr[] = { 0x40000000, 0x40000400,
+                                       0x40000800, 0x40000C00 };
+#define ADC_ADDR                       0x40012000
+static const uint32_t spi_addr[] =   { 0x40013000, 0x40003800, 0x40003C00,
+                                       0x40013400, 0x40015000, 0x40015400 };
+#define EXTI_ADDR                      0x40013C00
+
+#define SYSCFG_IRQ               71
+static const int usart_irq[] = { 37, 38, 39, 52, 53, 71, 82, 83 };
+static const int timer_irq[] = { 28, 29, 30, 50 };
+#define ADC_IRQ 18
+static const int spi_irq[] =   { 35, 36, 51, 0, 0, 0 };
+static const int exti_irq[] =  { 6, 7, 8, 9, 10, 23, 23, 23, 23, 23, 40,
+                                 40, 40, 40, 40, 40} ;
+
+
+static void stm32f405_soc_initfn(Object *obj)
+{
+    STM32F405State *s = STM32F405_SOC(obj);
+    int i;
+
+    sysbus_init_child_obj(obj, "armv7m", &s->armv7m, sizeof(s->armv7m),
+                          TYPE_ARMV7M);
+
+    sysbus_init_child_obj(obj, "syscfg", &s->syscfg, sizeof(s->syscfg),
+                          TYPE_STM32F4XX_SYSCFG);
+
+    for (i = 0; i < STM_NUM_USARTS; i++) {
+        sysbus_init_child_obj(obj, "usart[*]", &s->usart[i],
+                              sizeof(s->usart[i]), TYPE_STM32F2XX_USART);
+    }
+
+    for (i = 0; i < STM_NUM_TIMERS; i++) {
+        sysbus_init_child_obj(obj, "timer[*]", &s->timer[i],
+                              sizeof(s->timer[i]), TYPE_STM32F2XX_TIMER);
+    }
+
+    for (i = 0; i < STM_NUM_ADCS; i++) {
+        sysbus_init_child_obj(obj, "adc[*]", &s->adc[i], sizeof(s->adc[i]),
+                              TYPE_STM32F2XX_ADC);
+    }
+
+    for (i = 0; i < STM_NUM_SPIS; i++) {
+        sysbus_init_child_obj(obj, "spi[*]", &s->spi[i], sizeof(s->spi[i]),
+                              TYPE_STM32F2XX_SPI);
+    }
+
+    sysbus_init_child_obj(obj, "exti", &s->exti, sizeof(s->exti),
+                          TYPE_STM32F4XX_EXTI);
+}
+
+static void stm32f405_soc_realize(DeviceState *dev_soc, Error **errp)
+{
+    STM32F405State *s = STM32F405_SOC(dev_soc);
+    MemoryRegion *system_memory = get_system_memory();
+    DeviceState *dev, *armv7m;
+    SysBusDevice *busdev;
+    Error *err = NULL;
+    int i;
+
+    memory_region_init_ram(&s->flash, NULL, "STM32F405.flash", FLASH_SIZE,
+                           &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
+    memory_region_init_alias(&s->flash_alias, NULL, "STM32F405.flash.alias",
+                             &s->flash, 0, FLASH_SIZE);
+
+    memory_region_set_readonly(&s->flash, true);
+    memory_region_set_readonly(&s->flash_alias, true);
+
+    memory_region_add_subregion(system_memory, FLASH_BASE_ADDRESS, &s->flash);
+    memory_region_add_subregion(system_memory, 0, &s->flash_alias);
+
+    memory_region_init_ram(&s->sram, NULL, "STM32F405.sram", SRAM_SIZE,
+                           &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
+    memory_region_add_subregion(system_memory, SRAM_BASE_ADDRESS, &s->sram);
+
+    armv7m = DEVICE(&s->armv7m);
+    qdev_prop_set_uint32(armv7m, "num-irq", 96);
+    qdev_prop_set_string(armv7m, "cpu-type", s->cpu_type);
+    qdev_prop_set_bit(armv7m, "enable-bitband", true);
+    object_property_set_link(OBJECT(&s->armv7m), OBJECT(system_memory),
+                                     "memory", &error_abort);
+    object_property_set_bool(OBJECT(&s->armv7m), true, "realized", &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
+
+    /* System configuration controller */
+    dev = DEVICE(&s->syscfg);
+    object_property_set_bool(OBJECT(&s->syscfg), true, "realized", &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
+    busdev = SYS_BUS_DEVICE(dev);
+    sysbus_mmio_map(busdev, 0, SYSCFG_ADD);
+    sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(armv7m, SYSCFG_IRQ));
+
+    /* Attach UART (uses USART registers) and USART controllers */
+    for (i = 0; i < STM_NUM_USARTS; i++) {
+        dev = DEVICE(&(s->usart[i]));
+        qdev_prop_set_chr(dev, "chardev", serial_hd(i));
+        object_property_set_bool(OBJECT(&s->usart[i]), true, "realized", &err);
+        if (err != NULL) {
+            error_propagate(errp, err);
+            return;
+        }
+        busdev = SYS_BUS_DEVICE(dev);
+        sysbus_mmio_map(busdev, 0, usart_addr[i]);
+        sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(armv7m, usart_irq[i]));
+    }
+
+    /* Timer 2 to 5 */
+    for (i = 0; i < STM_NUM_TIMERS; i++) {
+        dev = DEVICE(&(s->timer[i]));
+        qdev_prop_set_uint64(dev, "clock-frequency", 1000000000);
+        object_property_set_bool(OBJECT(&s->timer[i]), true, "realized", &err);
+        if (err != NULL) {
+            error_propagate(errp, err);
+            return;
+        }
+        busdev = SYS_BUS_DEVICE(dev);
+        sysbus_mmio_map(busdev, 0, timer_addr[i]);
+        sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(armv7m, timer_irq[i]));
+    }
+
+    /* ADC device, the IRQs are ORed together */
+    object_initialize_child(OBJECT(s), "adc-orirq", &s->adc_irqs,
+                            sizeof(s->adc_irqs), TYPE_OR_IRQ,
+                            &err, NULL);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
+    object_property_set_int(OBJECT(&s->adc_irqs), STM_NUM_ADCS,
+                            "num-lines", &err);
+    object_property_set_bool(OBJECT(&s->adc_irqs), true, "realized", &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
+    qdev_connect_gpio_out(DEVICE(&s->adc_irqs), 0,
+                          qdev_get_gpio_in(armv7m, ADC_IRQ));
+
+    dev = DEVICE(&(s->adc[i]));
+    object_property_set_bool(OBJECT(&s->adc[i]), true, "realized", &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
+    busdev = SYS_BUS_DEVICE(dev);
+    sysbus_mmio_map(busdev, 0, ADC_ADDR);
+    sysbus_connect_irq(busdev, 0,
+                       qdev_get_gpio_in(DEVICE(&s->adc_irqs), i));
+
+    /* SPI devices */
+    for (i = 0; i < STM_NUM_SPIS; i++) {
+        dev = DEVICE(&(s->spi[i]));
+        object_property_set_bool(OBJECT(&s->spi[i]), true, "realized", &err);
+        if (err != NULL) {
+            error_propagate(errp, err);
+            return;
+        }
+        busdev = SYS_BUS_DEVICE(dev);
+        sysbus_mmio_map(busdev, 0, spi_addr[i]);
+        sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(armv7m, spi_irq[i]));
+    }
+
+    /* EXTI device */
+    dev = DEVICE(&s->exti);
+    object_property_set_bool(OBJECT(&s->exti), true, "realized", &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
+    busdev = SYS_BUS_DEVICE(dev);
+    sysbus_mmio_map(busdev, 0, EXTI_ADDR);
+    for (i = 0; i < 16; i++) {
+        sysbus_connect_irq(busdev, i, qdev_get_gpio_in(armv7m, exti_irq[i]));
+    }
+    for (i = 0; i < 16; i++) {
+        qdev_connect_gpio_out(DEVICE(&s->syscfg), i, qdev_get_gpio_in(dev, i));
+    }
+
+    create_unimplemented_device("timer[7]",    0x40001400, 0x400);
+    create_unimplemented_device("timer[12]",   0x40001800, 0x400);
+    create_unimplemented_device("timer[6]",    0x40001000, 0x400);
+    create_unimplemented_device("timer[13]",   0x40001C00, 0x400);
+    create_unimplemented_device("timer[14]",   0x40002000, 0x400);
+    create_unimplemented_device("RTC and BKP", 0x40002800, 0x400);
+    create_unimplemented_device("WWDG",        0x40002C00, 0x400);
+    create_unimplemented_device("IWDG",        0x40003000, 0x400);
+    create_unimplemented_device("I2S2ext",     0x40003000, 0x400);
+    create_unimplemented_device("I2S3ext",     0x40004000, 0x400);
+    create_unimplemented_device("I2C1",        0x40005400, 0x400);
+    create_unimplemented_device("I2C2",        0x40005800, 0x400);
+    create_unimplemented_device("I2C3",        0x40005C00, 0x400);
+    create_unimplemented_device("CAN1",        0x40006400, 0x400);
+    create_unimplemented_device("CAN2",        0x40006800, 0x400);
+    create_unimplemented_device("PWR",         0x40007000, 0x400);
+    create_unimplemented_device("DAC",         0x40007400, 0x400);
+    create_unimplemented_device("timer[1]",    0x40010000, 0x400);
+    create_unimplemented_device("timer[8]",    0x40010400, 0x400);
+    create_unimplemented_device("SDIO",        0x40012C00, 0x400);
+    create_unimplemented_device("timer[9]",    0x40014000, 0x400);
+    create_unimplemented_device("timer[10]",   0x40014400, 0x400);
+    create_unimplemented_device("timer[11]",   0x40014800, 0x400);
+    create_unimplemented_device("GPIOA",       0x40020000, 0x400);
+    create_unimplemented_device("GPIOB",       0x40020400, 0x400);
+    create_unimplemented_device("GPIOC",       0x40020800, 0x400);
+    create_unimplemented_device("GPIOD",       0x40020C00, 0x400);
+    create_unimplemented_device("GPIOE",       0x40021000, 0x400);
+    create_unimplemented_device("GPIOF",       0x40021400, 0x400);
+    create_unimplemented_device("GPIOG",       0x40021800, 0x400);
+    create_unimplemented_device("GPIOH",       0x40021C00, 0x400);
+    create_unimplemented_device("GPIOI",       0x40022000, 0x400);
+    create_unimplemented_device("CRC",         0x40023000, 0x400);
+    create_unimplemented_device("RCC",         0x40023800, 0x400);
+    create_unimplemented_device("Flash Int",   0x40023C00, 0x400);
+    create_unimplemented_device("BKPSRAM",     0x40024000, 0x400);
+    create_unimplemented_device("DMA1",        0x40026000, 0x400);
+    create_unimplemented_device("DMA2",        0x40026400, 0x400);
+    create_unimplemented_device("Ethernet",    0x40028000, 0x1400);
+    create_unimplemented_device("USB OTG HS",  0x40040000, 0x30000);
+    create_unimplemented_device("USB OTG FS",  0x50000000, 0x31000);
+    create_unimplemented_device("DCMI",        0x50050000, 0x400);
+    create_unimplemented_device("RNG",         0x50060800, 0x400);
+}
+
+static Property stm32f405_soc_properties[] = {
+    DEFINE_PROP_STRING("cpu-type", STM32F405State, cpu_type),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void stm32f405_soc_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = stm32f405_soc_realize;
+    dc->props = stm32f405_soc_properties;
+    /* No vmstate or reset required: device has no internal state */
+}
+
+static const TypeInfo stm32f405_soc_info = {
+    .name          = TYPE_STM32F405_SOC,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(STM32F405State),
+    .instance_init = stm32f405_soc_initfn,
+    .class_init    = stm32f405_soc_class_init,
+};
+
+static void stm32f405_soc_types(void)
+{
+    type_register_static(&stm32f405_soc_info);
+}
+
+type_init(stm32f405_soc_types)
diff --git a/include/hw/arm/stm32f405_soc.h b/include/hw/arm/stm32f405_soc.h
new file mode 100644
index 0000000000..1fe97f8c3a
--- /dev/null
+++ b/include/hw/arm/stm32f405_soc.h
@@ -0,0 +1,73 @@
+/*
+ * STM32F405 SoC
+ *
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#ifndef HW_ARM_STM32F405_SOC_H
+#define HW_ARM_STM32F405_SOC_H
+
+#include "hw/misc/stm32f4xx_syscfg.h"
+#include "hw/timer/stm32f2xx_timer.h"
+#include "hw/char/stm32f2xx_usart.h"
+#include "hw/adc/stm32f2xx_adc.h"
+#include "hw/misc/stm32f4xx_exti.h"
+#include "hw/or-irq.h"
+#include "hw/ssi/stm32f2xx_spi.h"
+#include "hw/arm/armv7m.h"
+
+#define TYPE_STM32F405_SOC "stm32f405-soc"
+#define STM32F405_SOC(obj) \
+    OBJECT_CHECK(STM32F405State, (obj), TYPE_STM32F405_SOC)
+
+#define STM_NUM_USARTS 7
+#define STM_NUM_TIMERS 4
+#define STM_NUM_ADCS 6
+#define STM_NUM_SPIS 6
+
+#define FLASH_BASE_ADDRESS 0x08000000
+#define FLASH_SIZE (1024 * 1024)
+#define SRAM_BASE_ADDRESS 0x20000000
+#define SRAM_SIZE (192 * 1024)
+
+typedef struct STM32F405State {
+    /*< private >*/
+    SysBusDevice parent_obj;
+    /*< public >*/
+
+    char *cpu_type;
+
+    ARMv7MState armv7m;
+
+    STM32F4xxSyscfgState syscfg;
+    STM32F4xxExtiState exti;
+    STM32F2XXUsartState usart[STM_NUM_USARTS];
+    STM32F2XXTimerState timer[STM_NUM_TIMERS];
+    qemu_or_irq adc_irqs;
+    STM32F2XXADCState adc[STM_NUM_ADCS];
+    STM32F2XXSPIState spi[STM_NUM_SPIS];
+
+    MemoryRegion sram;
+    MemoryRegion flash;
+    MemoryRegion flash_alias;
+} STM32F405State;
+
+#endif
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PATCH v3 6/6] hw/arm: Add the Netduino Plus 2
       [not found] <cover.1560919807.git.alistair@alistair23.me>
                   ` (4 preceding siblings ...)
  2019-06-19  4:54 ` [Qemu-devel] [PATCH v3 5/6] hw/arm: Add the STM32F4xx SoC Alistair Francis
@ 2019-06-19  4:54 ` Alistair Francis
  5 siblings, 0 replies; 9+ messages in thread
From: Alistair Francis @ 2019-06-19  4:54 UTC (permalink / raw)
  To: qemu-devel, peter.maydell; +Cc: alistair23

Signed-off-by: Alistair Francis <alistair@alistair23.me>
---
 MAINTAINERS            |  6 ++++++
 hw/arm/Kconfig         |  3 +++
 hw/arm/Makefile.objs   |  1 +
 hw/arm/netduinoplus2.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 68 insertions(+)
 create mode 100644 hw/arm/netduinoplus2.c

diff --git a/MAINTAINERS b/MAINTAINERS
index f917f3e693..243b6b1460 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -820,6 +820,12 @@ M: Peter Maydell <peter.maydell@linaro.org>
 S: Maintained
 F: hw/arm/netduino2.c
 
+Netduino Plus 2
+M: Alistair Francis <alistair@alistair23.me>
+M: Peter Maydell <peter.maydell@linaro.org>
+S: Maintained
+F: hw/arm/netduinoplus2.c
+
 SmartFusion2
 M: Subbaraya Sundeep <sundeep.lkml@gmail.com>
 M: Peter Maydell <peter.maydell@linaro.org>
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 65a0923afe..43e6e0c587 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -99,6 +99,9 @@ config NETDUINOPLUS2
     bool
     select STM32F405_SOC
 
+config NETDUINOPLUS2
+    bool
+
 config NSERIES
     bool
     select OMAP
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 4436c2e93e..75726540bc 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -11,6 +11,7 @@ obj-$(CONFIG_MAINSTONE) += mainstone.o
 obj-$(CONFIG_MICROBIT) += microbit.o
 obj-$(CONFIG_MUSICPAL) += musicpal.o
 obj-$(CONFIG_NETDUINO2) += netduino2.o
+obj-$(CONFIG_NETDUINOPLUS2) += netduinoplus2.o
 obj-$(CONFIG_NSERIES) += nseries.o
 obj-$(CONFIG_SX1) += omap_sx1.o
 obj-$(CONFIG_CHEETAH) += palm.o
diff --git a/hw/arm/netduinoplus2.c b/hw/arm/netduinoplus2.c
new file mode 100644
index 0000000000..4a75da8543
--- /dev/null
+++ b/hw/arm/netduinoplus2.c
@@ -0,0 +1,58 @@
+/*
+ * Netduino Plus 2 Machine Model
+ *
+ * Copyright (c) 2014 Alistair Francis <alistair@alistair23.me>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "hw/boards.h"
+#include "qemu/error-report.h"
+#include "hw/arm/stm32f405_soc.h"
+#include "hw/arm/boot.h"
+
+static void netduinoplus2_init(MachineState *machine)
+{
+    DeviceState *dev;
+    uint32_t kernel_entry;
+
+    dev = qdev_create(NULL, TYPE_STM32F405_SOC);
+    qdev_prop_set_string(dev, "cpu-type", ARM_CPU_TYPE_NAME("cortex-m4"));
+    object_property_set_bool(OBJECT(dev), true, "realized", &error_fatal);
+
+    kernel_entry = armv7m_load_kernel(ARM_CPU(first_cpu),
+                                      machine->kernel_filename,
+                                      FLASH_SIZE);
+
+    object_property_set_int(OBJECT(first_cpu), kernel_entry,
+                            "init-entry", &error_fatal);
+    object_property_set_int(OBJECT(first_cpu),
+                            SRAM_BASE_ADDRESS + (SRAM_SIZE * 2) / 3,
+                            "init-sp", &error_fatal);
+}
+
+static void netduinoplus2_machine_init(MachineClass *mc)
+{
+    mc->desc = "Netduino Plus 2 Machine";
+    mc->init = netduinoplus2_init;
+}
+
+DEFINE_MACHINE("netduinoplus2", netduinoplus2_machine_init)
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH v3 1/6] armv7m: Allow entry information to be returned
  2019-06-19  4:53 ` [Qemu-devel] [PATCH v3 1/6] armv7m: Allow entry information to be returned Alistair Francis
@ 2019-06-21 16:23   ` Philippe Mathieu-Daudé
  0 siblings, 0 replies; 9+ messages in thread
From: Philippe Mathieu-Daudé @ 2019-06-21 16:23 UTC (permalink / raw)
  To: Alistair Francis, qemu-devel, peter.maydell; +Cc: alistair23

On 6/19/19 6:53 AM, Alistair Francis wrote:
> Allow the kernel's entry point information to be returned when loading a
> kernel.
> 
> Signed-off-by: Alistair Francis <alistair@alistair23.me>

Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>

> ---
>  hw/arm/armv7m.c       | 4 +++-
>  include/hw/arm/boot.h | 4 +++-
>  2 files changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
> index b9efad6bac..8ee6291a47 100644
> --- a/hw/arm/armv7m.c
> +++ b/hw/arm/armv7m.c
> @@ -304,7 +304,7 @@ static void armv7m_reset(void *opaque)
>      cpu_reset(CPU(cpu));
>  }
>  
> -void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size)
> +uint64_t armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size)
>  {
>      int image_size;
>      uint64_t entry;
> @@ -351,6 +351,8 @@ void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size)
>       * board must call this function!
>       */
>      qemu_register_reset(armv7m_reset, cpu);
> +
> +    return entry;
>  }
>  
>  static Property bitband_properties[] = {
> diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h
> index c48cc4c2bc..4e4db0416c 100644
> --- a/include/hw/arm/boot.h
> +++ b/include/hw/arm/boot.h
> @@ -29,11 +29,13 @@ typedef enum {
>   * @kernel_filename: file to load
>   * @mem_size: mem_size: maximum image size to load
>   *
> + * returns: location of the kernel's entry point
> + *
>   * Load the guest image for an ARMv7M system. This must be called by
>   * any ARMv7M board. (This is necessary to ensure that the CPU resets
>   * correctly on system reset, as well as for kernel loading.)
>   */
> -void armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size);
> +uint64_t armv7m_load_kernel(ARMCPU *cpu, const char *kernel_filename, int mem_size);
>  
>  /* arm_boot.c */
>  struct arm_boot_info {
> 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH v3 2/6] target/arm: Allow setting M mode entry and sp
  2019-06-19  4:54 ` [Qemu-devel] [PATCH v3 2/6] target/arm: Allow setting M mode entry and sp Alistair Francis
@ 2019-06-21 16:38   ` Philippe Mathieu-Daudé
  2019-06-23 15:30     ` Alistair Francis
  0 siblings, 1 reply; 9+ messages in thread
From: Philippe Mathieu-Daudé @ 2019-06-21 16:38 UTC (permalink / raw)
  To: Alistair Francis, qemu-devel, peter.maydell; +Cc: alistair23

Hi Alistair,

On 6/19/19 6:54 AM, Alistair Francis wrote:
> Add M mode initial entry PC and SP properties.
> 
> Signed-off-by: Alistair Francis <alistair@alistair23.me>
> ---
>  target/arm/cpu.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
>  target/arm/cpu.h |  3 +++
>  2 files changed, 50 insertions(+)
> 
> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> index 376db154f0..1d83972ab1 100644
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -301,6 +301,9 @@ static void arm_cpu_reset(CPUState *s)
>               */
>              initial_msp = ldl_p(rom);
>              initial_pc = ldl_p(rom + 4);
> +        } else if (cpu->init_sp || cpu->init_entry) {
> +            initial_msp = cpu->init_sp;
> +            initial_pc = cpu->init_entry;
>          } else {
>              /* Address zero not covered by a ROM blob, or the ROM blob
>               * is in non-modifiable memory and this is a second reset after
> @@ -801,6 +804,38 @@ static void arm_set_init_svtor(Object *obj, Visitor *v, const char *name,
>      visit_type_uint32(v, name, &cpu->init_svtor, errp);
>  }
>  
> +static void arm_get_init_sp(Object *obj, Visitor *v, const char *name,
> +                            void *opaque, Error **errp)
> +{
> +    ARMCPU *cpu = ARM_CPU(obj);
> +
> +    visit_type_uint32(v, name, &cpu->init_sp, errp);
> +}
> +
> +static void arm_set_init_sp(Object *obj, Visitor *v, const char *name,
> +                            void *opaque, Error **errp)
> +{
> +    ARMCPU *cpu = ARM_CPU(obj);
> +
> +    visit_type_uint32(v, name, &cpu->init_sp, errp);
> +}
> +
> +static void arm_get_init_entry(Object *obj, Visitor *v, const char *name,
> +                            void *opaque, Error **errp)
> +{
> +    ARMCPU *cpu = ARM_CPU(obj);
> +
> +    visit_type_uint32(v, name, &cpu->init_entry, errp);
> +}
> +
> +static void arm_set_init_entry(Object *obj, Visitor *v, const char *name,
> +                            void *opaque, Error **errp)
> +{
> +    ARMCPU *cpu = ARM_CPU(obj);
> +
> +    visit_type_uint32(v, name, &cpu->init_entry, errp);
> +}
> +
>  void arm_cpu_post_init(Object *obj)
>  {
>      ARMCPU *cpu = ARM_CPU(obj);
> @@ -913,6 +948,18 @@ void arm_cpu_post_init(Object *obj)
>          object_property_add(obj, "init-svtor", "uint32",
>                              arm_get_init_svtor, arm_set_init_svtor,
>                              NULL, NULL, &error_abort);
> +    } else {
> +        /*
> +         * M profile: initial value of the SP and entry. We can't just use
> +         * a simple DEFINE_PROP_UINT32 for this because we want to permit
> +         * the property to be set after realize.
> +         */

This comment is mostly a copy of the other if() branch, maybe you can
extract one generic comment for the 2 cases.

> +        object_property_add(obj, "init-sp", "uint32",
> +                            arm_get_init_sp, arm_set_init_sp,
> +                            NULL, NULL, &error_abort);
> +        object_property_add(obj, "init-entry", "uint32",
> +                            arm_get_init_entry, arm_set_init_entry,
> +                            NULL, NULL, &error_abort);

I'm having difficulties to test your patch :( I tried:

$ arm-softmmu/qemu-system-arm -M emcraft-sf2 \
  -device loader,file=/networking.uImage,cpu-num=0 \
  -d in_asm,int,mmu \
  -global cpu.init-sp=0x2000fff0 \
  -global cpu.init-entry=0xa0008001
PMSA MPU lookup for execute at 0xa0008000 mmu_idx 65 -> Miss (prot rw-)
Taking exception 3 [Prefetch Abort]
...with CFSR.IACCVIOL
PMSA MPU lookup for writing at 0x2000ffd0 mmu_idx 65 -> Hit (prot rwx)
PMSA MPU lookup for writing at 0x2000ffd4 mmu_idx 65 -> Hit (prot rwx)
PMSA MPU lookup for writing at 0x2000ffd8 mmu_idx 65 -> Hit (prot rwx)
PMSA MPU lookup for writing at 0x2000ffdc mmu_idx 65 -> Hit (prot rwx)
PMSA MPU lookup for writing at 0x2000ffe0 mmu_idx 65 -> Hit (prot rwx)
PMSA MPU lookup for writing at 0x2000ffe4 mmu_idx 65 -> Hit (prot rwx)
PMSA MPU lookup for writing at 0x2000ffe8 mmu_idx 65 -> Hit (prot rwx)
PMSA MPU lookup for writing at 0x2000ffec mmu_idx 65 -> Hit (prot rwx)
...taking pending nonsecure exception 3
PMSA MPU lookup for execute at 0x00000000 mmu_idx 67 -> Hit (prot rwx)
----------------
IN:
PMSA MPU lookup for reading at 0x00000000 mmu_idx 67 -> Hit (prot rwx)
0x00000000:  00000000  andeq    r0, r0, r0

Taking exception 18 [v7M INVSTATE UsageFault]
qemu: fatal: Lockup: can't escalate 3 to HardFault (current priority -1)

R00=00000000 R01=00000000 R02=00000000 R03=00000000
R04=00000000 R05=00000000 R06=00000000 R07=00000000
R08=00000000 R09=00000000 R10=00000000 R11=00000000
R12=00000000 R13=2000ffd0 R14=fffffff9 R15=00000000
XPSR=40000003 -Z-- A handler
FPSCR: 00000000
Aborted (core dumped)

(same without setting cpu.init-entry).

Downloaded "Prebuilt Linux image ready to be loaded to the M2S-FG484
SOM" here: https://emcraft.com/products/255#software

$ file networking.uImage
networking.uImage: u-boot legacy uImage, Linux-2.6.33-cortexm-1.14.3,
Linux/ARM, OS Kernel Image (Not compressed), 2299232 bytes, Wed Nov 11
14:19:53 2015, Load Address: 0xA0008000, Entry Point: 0xA0008001, Header
CRC: 0x419AA120, Data CRC: 0x1C34C4BE

This board memory map is:

(qemu) info mtree
address-space: memory
  0000000000000000-ffffffffffffffff (prio -1, i/o): system
    0000000000000000-000000000003ffff (prio 0, i/o): alias MSF2.eNVM
    0000000020000000-000000002000ffff (prio 0, ram): MSF2.eSRAM
    0000000040000000-000000004000001f (prio 0, i/o): serial
    0000000040001000-000000004000103f (prio 0, i/o): mss-spi
    0000000040002000-0000000040002fff (prio -1000, i/o): i2c_0
    0000000040003000-0000000040003fff (prio -1000, i/o): dma
    0000000040004000-000000004000402f (prio 0, i/o): mss-timer
    0000000040005000-0000000040005fff (prio -1000, i/o): watchdog
    0000000040011000-000000004001103f (prio 0, i/o): mss-spi
    0000000040012000-0000000040012fff (prio -1000, i/o): i2c_1
    0000000040013000-0000000040013fff (prio -1000, i/o): gpio
    0000000040014000-0000000040014fff (prio -1000, i/o): hs-dma
    0000000040015000-0000000040015fff (prio -1000, i/o): can
    0000000040017000-0000000040017fff (prio -1000, i/o): rtc
    0000000040020000-000000004002ffff (prio -1000, i/o): apb_config
    0000000040038000-00000000400382ff (prio 0, i/o): msf2-sysreg
    0000000040041000-0000000040041fff (prio -1000, i/o): emac
    0000000040043000-0000000040043fff (prio -1000, i/o): usb
    0000000060000000-000000006003ffff (prio 0, rom): MSF2.eNVM
    00000000a0000000-00000000a3ffffff (prio 0, ram): ddr-ram

So I set cpu.init-sp close to the end of the SRAM (0x2000fff0).

Without your patch:

PMSA MPU lookup for execute at 0xa0008000 mmu_idx 65 -> Miss (prot rw-)
Taking exception 3 [Prefetch Abort]
...with CFSR.IACCVIOL
PMSA MPU lookup for writing at 0xffffffe0 mmu_idx 65 -> Hit (prot rw-)
...BusFault with BFSR.STKERR
...taking pending nonsecure exception 3
PMSA MPU lookup for execute at 0x00000000 mmu_idx 67 -> Hit (prot rwx)
----------------
IN:
PMSA MPU lookup for reading at 0x00000000 mmu_idx 67 -> Hit (prot rwx)
0x00000000:  00000000  andeq    r0, r0, r0

Taking exception 18 [v7M INVSTATE UsageFault]
qemu: fatal: Lockup: can't escalate 3 to HardFault (current priority -1)

R00=00000000 R01=00000000 R02=00000000 R03=00000000
R04=00000000 R05=00000000 R06=00000000 R07=00000000
R08=00000000 R09=00000000 R10=00000000 R11=00000000
R12=00000000 R13=ffffffe0 R14=fffffff9 R15=00000000
XPSR=40000003 -Z-- A handler
FPSCR: 00000000
Aborted (core dumped)

304             } else if (cpu->init_sp || cpu->init_entry) {
(gdb)
305                 initial_msp = cpu->init_sp;
(gdb)
306                 initial_pc = cpu->init_entry;
(gdb)
317             env->regs[13] = initial_msp & 0xFFFFFFFC;
(gdb) p/x initial_msp
$1 = 0x2000fff0
(gdb) p/x initial_pc
$2 = 0xa0008001
(gdb) n
318             env->regs[15] = initial_pc & ~1;
(gdb)
319             env->thumb = initial_pc & 1;

I don't understand where I get $pc reset...

>      }
>  
>      qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property,
> diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> index f9da672be5..290fac19d3 100644
> --- a/target/arm/cpu.h
> +++ b/target/arm/cpu.h
> @@ -805,6 +805,9 @@ struct ARMCPU {
>       */
>      uint32_t psci_conduit;
>  
> +    /* For M, initial value of the entry and SP */
> +    uint32_t init_sp, init_entry;
> +
>      /* For v8M, initial value of the Secure VTOR */
>      uint32_t init_svtor;
>  
> 


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PATCH v3 2/6] target/arm: Allow setting M mode entry and sp
  2019-06-21 16:38   ` Philippe Mathieu-Daudé
@ 2019-06-23 15:30     ` Alistair Francis
  0 siblings, 0 replies; 9+ messages in thread
From: Alistair Francis @ 2019-06-23 15:30 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé; +Cc: peter.maydell, Alistair Francis, qemu-devel

On Fri, Jun 21, 2019 at 9:38 AM Philippe Mathieu-Daudé
<philmd@redhat.com> wrote:
>
> Hi Alistair,
>
> On 6/19/19 6:54 AM, Alistair Francis wrote:
> > Add M mode initial entry PC and SP properties.
> >
> > Signed-off-by: Alistair Francis <alistair@alistair23.me>
> > ---
> >  target/arm/cpu.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
> >  target/arm/cpu.h |  3 +++
> >  2 files changed, 50 insertions(+)
> >
> > diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> > index 376db154f0..1d83972ab1 100644
> > --- a/target/arm/cpu.c
> > +++ b/target/arm/cpu.c
> > @@ -301,6 +301,9 @@ static void arm_cpu_reset(CPUState *s)
> >               */
> >              initial_msp = ldl_p(rom);
> >              initial_pc = ldl_p(rom + 4);
> > +        } else if (cpu->init_sp || cpu->init_entry) {
> > +            initial_msp = cpu->init_sp;
> > +            initial_pc = cpu->init_entry;
> >          } else {
> >              /* Address zero not covered by a ROM blob, or the ROM blob
> >               * is in non-modifiable memory and this is a second reset after
> > @@ -801,6 +804,38 @@ static void arm_set_init_svtor(Object *obj, Visitor *v, const char *name,
> >      visit_type_uint32(v, name, &cpu->init_svtor, errp);
> >  }
> >
> > +static void arm_get_init_sp(Object *obj, Visitor *v, const char *name,
> > +                            void *opaque, Error **errp)
> > +{
> > +    ARMCPU *cpu = ARM_CPU(obj);
> > +
> > +    visit_type_uint32(v, name, &cpu->init_sp, errp);
> > +}
> > +
> > +static void arm_set_init_sp(Object *obj, Visitor *v, const char *name,
> > +                            void *opaque, Error **errp)
> > +{
> > +    ARMCPU *cpu = ARM_CPU(obj);
> > +
> > +    visit_type_uint32(v, name, &cpu->init_sp, errp);
> > +}
> > +
> > +static void arm_get_init_entry(Object *obj, Visitor *v, const char *name,
> > +                            void *opaque, Error **errp)
> > +{
> > +    ARMCPU *cpu = ARM_CPU(obj);
> > +
> > +    visit_type_uint32(v, name, &cpu->init_entry, errp);
> > +}
> > +
> > +static void arm_set_init_entry(Object *obj, Visitor *v, const char *name,
> > +                            void *opaque, Error **errp)
> > +{
> > +    ARMCPU *cpu = ARM_CPU(obj);
> > +
> > +    visit_type_uint32(v, name, &cpu->init_entry, errp);
> > +}
> > +
> >  void arm_cpu_post_init(Object *obj)
> >  {
> >      ARMCPU *cpu = ARM_CPU(obj);
> > @@ -913,6 +948,18 @@ void arm_cpu_post_init(Object *obj)
> >          object_property_add(obj, "init-svtor", "uint32",
> >                              arm_get_init_svtor, arm_set_init_svtor,
> >                              NULL, NULL, &error_abort);
> > +    } else {
> > +        /*
> > +         * M profile: initial value of the SP and entry. We can't just use
> > +         * a simple DEFINE_PROP_UINT32 for this because we want to permit
> > +         * the property to be set after realize.
> > +         */
>
> This comment is mostly a copy of the other if() branch, maybe you can
> extract one generic comment for the 2 cases.

Good point, I have updated it.

>
> > +        object_property_add(obj, "init-sp", "uint32",
> > +                            arm_get_init_sp, arm_set_init_sp,
> > +                            NULL, NULL, &error_abort);
> > +        object_property_add(obj, "init-entry", "uint32",
> > +                            arm_get_init_entry, arm_set_init_entry,
> > +                            NULL, NULL, &error_abort);
>
> I'm having difficulties to test your patch :( I tried:
>
> $ arm-softmmu/qemu-system-arm -M emcraft-sf2 \
>   -device loader,file=/networking.uImage,cpu-num=0 \
>   -d in_asm,int,mmu \
>   -global cpu.init-sp=0x2000fff0 \
>   -global cpu.init-entry=0xa0008001
> PMSA MPU lookup for execute at 0xa0008000 mmu_idx 65 -> Miss (prot rw-)
> Taking exception 3 [Prefetch Abort]
> ...with CFSR.IACCVIOL
> PMSA MPU lookup for writing at 0x2000ffd0 mmu_idx 65 -> Hit (prot rwx)
> PMSA MPU lookup for writing at 0x2000ffd4 mmu_idx 65 -> Hit (prot rwx)
> PMSA MPU lookup for writing at 0x2000ffd8 mmu_idx 65 -> Hit (prot rwx)
> PMSA MPU lookup for writing at 0x2000ffdc mmu_idx 65 -> Hit (prot rwx)
> PMSA MPU lookup for writing at 0x2000ffe0 mmu_idx 65 -> Hit (prot rwx)
> PMSA MPU lookup for writing at 0x2000ffe4 mmu_idx 65 -> Hit (prot rwx)
> PMSA MPU lookup for writing at 0x2000ffe8 mmu_idx 65 -> Hit (prot rwx)
> PMSA MPU lookup for writing at 0x2000ffec mmu_idx 65 -> Hit (prot rwx)
> ...taking pending nonsecure exception 3
> PMSA MPU lookup for execute at 0x00000000 mmu_idx 67 -> Hit (prot rwx)
> ----------------
> IN:
> PMSA MPU lookup for reading at 0x00000000 mmu_idx 67 -> Hit (prot rwx)
> 0x00000000:  00000000  andeq    r0, r0, r0
>
> Taking exception 18 [v7M INVSTATE UsageFault]
> qemu: fatal: Lockup: can't escalate 3 to HardFault (current priority -1)
>
> R00=00000000 R01=00000000 R02=00000000 R03=00000000
> R04=00000000 R05=00000000 R06=00000000 R07=00000000
> R08=00000000 R09=00000000 R10=00000000 R11=00000000
> R12=00000000 R13=2000ffd0 R14=fffffff9 R15=00000000
> XPSR=40000003 -Z-- A handler
> FPSCR: 00000000
> Aborted (core dumped)
>
> (same without setting cpu.init-entry).
>
> Downloaded "Prebuilt Linux image ready to be loaded to the M2S-FG484
> SOM" here: https://emcraft.com/products/255#software
>
> $ file networking.uImage
> networking.uImage: u-boot legacy uImage, Linux-2.6.33-cortexm-1.14.3,
> Linux/ARM, OS Kernel Image (Not compressed), 2299232 bytes, Wed Nov 11
> 14:19:53 2015, Load Address: 0xA0008000, Entry Point: 0xA0008001, Header
> CRC: 0x419AA120, Data CRC: 0x1C34C4BE
>
> This board memory map is:
>
> (qemu) info mtree
> address-space: memory
>   0000000000000000-ffffffffffffffff (prio -1, i/o): system
>     0000000000000000-000000000003ffff (prio 0, i/o): alias MSF2.eNVM
>     0000000020000000-000000002000ffff (prio 0, ram): MSF2.eSRAM
>     0000000040000000-000000004000001f (prio 0, i/o): serial
>     0000000040001000-000000004000103f (prio 0, i/o): mss-spi
>     0000000040002000-0000000040002fff (prio -1000, i/o): i2c_0
>     0000000040003000-0000000040003fff (prio -1000, i/o): dma
>     0000000040004000-000000004000402f (prio 0, i/o): mss-timer
>     0000000040005000-0000000040005fff (prio -1000, i/o): watchdog
>     0000000040011000-000000004001103f (prio 0, i/o): mss-spi
>     0000000040012000-0000000040012fff (prio -1000, i/o): i2c_1
>     0000000040013000-0000000040013fff (prio -1000, i/o): gpio
>     0000000040014000-0000000040014fff (prio -1000, i/o): hs-dma
>     0000000040015000-0000000040015fff (prio -1000, i/o): can
>     0000000040017000-0000000040017fff (prio -1000, i/o): rtc
>     0000000040020000-000000004002ffff (prio -1000, i/o): apb_config
>     0000000040038000-00000000400382ff (prio 0, i/o): msf2-sysreg
>     0000000040041000-0000000040041fff (prio -1000, i/o): emac
>     0000000040043000-0000000040043fff (prio -1000, i/o): usb
>     0000000060000000-000000006003ffff (prio 0, rom): MSF2.eNVM
>     00000000a0000000-00000000a3ffffff (prio 0, ram): ddr-ram
>
> So I set cpu.init-sp close to the end of the SRAM (0x2000fff0).
>
> Without your patch:
>
> PMSA MPU lookup for execute at 0xa0008000 mmu_idx 65 -> Miss (prot rw-)
> Taking exception 3 [Prefetch Abort]
> ...with CFSR.IACCVIOL
> PMSA MPU lookup for writing at 0xffffffe0 mmu_idx 65 -> Hit (prot rw-)
> ...BusFault with BFSR.STKERR
> ...taking pending nonsecure exception 3
> PMSA MPU lookup for execute at 0x00000000 mmu_idx 67 -> Hit (prot rwx)
> ----------------
> IN:
> PMSA MPU lookup for reading at 0x00000000 mmu_idx 67 -> Hit (prot rwx)
> 0x00000000:  00000000  andeq    r0, r0, r0
>
> Taking exception 18 [v7M INVSTATE UsageFault]
> qemu: fatal: Lockup: can't escalate 3 to HardFault (current priority -1)
>
> R00=00000000 R01=00000000 R02=00000000 R03=00000000
> R04=00000000 R05=00000000 R06=00000000 R07=00000000
> R08=00000000 R09=00000000 R10=00000000 R11=00000000
> R12=00000000 R13=ffffffe0 R14=fffffff9 R15=00000000
> XPSR=40000003 -Z-- A handler
> FPSCR: 00000000
> Aborted (core dumped)
>
> 304             } else if (cpu->init_sp || cpu->init_entry) {
> (gdb)
> 305                 initial_msp = cpu->init_sp;
> (gdb)
> 306                 initial_pc = cpu->init_entry;
> (gdb)
> 317             env->regs[13] = initial_msp & 0xFFFFFFFC;
> (gdb) p/x initial_msp
> $1 = 0x2000fff0
> (gdb) p/x initial_pc
> $2 = 0xa0008001
> (gdb) n
> 318             env->regs[15] = initial_pc & ~1;
> (gdb)
> 319             env->thumb = initial_pc & 1;
>
> I don't understand where I get $pc reset...

Thanks for testing!

I'm a little confused with whats going on here, it doesn't work
without my patch and with my patch it still doesn't work? From the GDB
output it looks like the value setting is working in the reset, are
you sure those are the correct values?

I haven't tested with the emcraft-sf2 machine as I am focused on the
STM. For the STM this is all read when the elf is loaded and I'm not
manually setting anything.

Alistair

>
> >      }
> >
> >      qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property,
> > diff --git a/target/arm/cpu.h b/target/arm/cpu.h
> > index f9da672be5..290fac19d3 100644
> > --- a/target/arm/cpu.h
> > +++ b/target/arm/cpu.h
> > @@ -805,6 +805,9 @@ struct ARMCPU {
> >       */
> >      uint32_t psci_conduit;
> >
> > +    /* For M, initial value of the entry and SP */
> > +    uint32_t init_sp, init_entry;
> > +
> >      /* For v8M, initial value of the Secure VTOR */
> >      uint32_t init_svtor;
> >
> >


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2019-06-23 15:33 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <cover.1560919807.git.alistair@alistair23.me>
2019-06-19  4:53 ` [Qemu-devel] [PATCH v3 1/6] armv7m: Allow entry information to be returned Alistair Francis
2019-06-21 16:23   ` Philippe Mathieu-Daudé
2019-06-19  4:54 ` [Qemu-devel] [PATCH v3 2/6] target/arm: Allow setting M mode entry and sp Alistair Francis
2019-06-21 16:38   ` Philippe Mathieu-Daudé
2019-06-23 15:30     ` Alistair Francis
2019-06-19  4:54 ` [Qemu-devel] [PATCH v3 3/6] hw/misc: Add the STM32F4xx Sysconfig device Alistair Francis
2019-06-19  4:54 ` [Qemu-devel] [PATCH v3 4/6] hw/misc: Add the STM32F4xx EXTI device Alistair Francis
2019-06-19  4:54 ` [Qemu-devel] [PATCH v3 5/6] hw/arm: Add the STM32F4xx SoC Alistair Francis
2019-06-19  4:54 ` [Qemu-devel] [PATCH v3 6/6] hw/arm: Add the Netduino Plus 2 Alistair Francis

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).