All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [RFC v1 0/6]  Netduino 2 Machine Model
@ 2014-09-09  8:23 Alistair Francis
  2014-09-09  8:23 ` [Qemu-devel] [RFC v1 1/6] stm32f205_timer: Add the stm32f205 SoC Timer2 to 5 Alistair Francis
                   ` (6 more replies)
  0 siblings, 7 replies; 25+ messages in thread
From: Alistair Francis @ 2014-09-09  8:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, peter.crosthwaite, konstanty

This patch series adds the Netduino 2 Machine to QEMU

Information on the board is avalible at:
http://www.netduino.com/netduino2/specs.htm

The git tree can be found at:
https://github.com/alistair23/qemu/tree/netduino2.1

This is a fully implemented machine, except for the hack
changes that have been made to armv7_init. See that individual
patch for more information

This is based on my original patch series to add the
Netduino Plus 2 Machine to QEMU. This can be seen at:
http://lists.nongnu.org/archive/html/qemu-devel/2014-08/msg04026.html

As this is a completly different machine I have decided to restart
the version numbers

Some example code that runs on QEMU is avaliable at:
at: https://github.com/alistair23/CSSE3010-QEMU-Examples

I have more devices in the works, I figured I would just start
with these three

Alistair Francis (6):
  stm32f205_timer: Add the stm32f205 SoC Timer2 to 5
  stm32f205_USART: Add the stm32f205 SoC USART Controller
  stm32f205_SYSCFG: Add the stm32f205 SYSCFG
  target_arm: Update armv7_init to support more parameters
  stm32f205: Add the SoC
  netduino2: Add the Netduino 2 Machine

 default-configs/arm-softmmu.mak    |   1 +
 hw/arm/Makefile.objs               |   2 +-
 hw/arm/armv7m.c                    |  33 +++-
 hw/arm/netduino2.c                 |  60 +++++++
 hw/arm/stellaris.c                 |   2 +-
 hw/arm/stm32f205_soc.c             | 140 ++++++++++++++++
 hw/char/Makefile.objs              |   1 +
 hw/char/stm32f205_usart.c          | 205 +++++++++++++++++++++++
 hw/misc/Makefile.objs              |   1 +
 hw/misc/stm32f205_syscfg.c         | 160 ++++++++++++++++++
 hw/timer/Makefile.objs             |   1 +
 hw/timer/stm32f205_timer.c         | 334 +++++++++++++++++++++++++++++++++++++
 include/hw/arm/arm.h               |   3 +-
 include/hw/arm/stm32f205_soc.h     |  61 +++++++
 include/hw/char/stm32f205_usart.h  |  64 +++++++
 include/hw/misc/stm32f205_syscfg.h |  59 +++++++
 include/hw/timer/stm32f205_timer.h |  84 ++++++++++
 17 files changed, 1201 insertions(+), 10 deletions(-)
 create mode 100644 hw/arm/netduino2.c
 create mode 100644 hw/arm/stm32f205_soc.c
 create mode 100644 hw/char/stm32f205_usart.c
 create mode 100644 hw/misc/stm32f205_syscfg.c
 create mode 100644 hw/timer/stm32f205_timer.c
 create mode 100644 include/hw/arm/stm32f205_soc.h
 create mode 100644 include/hw/char/stm32f205_usart.h
 create mode 100644 include/hw/misc/stm32f205_syscfg.h
 create mode 100644 include/hw/timer/stm32f205_timer.h

-- 
1.9.1

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

* [Qemu-devel] [RFC v1 1/6] stm32f205_timer: Add the stm32f205 SoC Timer2 to 5
  2014-09-09  8:23 [Qemu-devel] [RFC v1 0/6] Netduino 2 Machine Model Alistair Francis
@ 2014-09-09  8:23 ` Alistair Francis
  2014-09-09 12:44   ` Peter Crosthwaite
  2014-09-09  8:24 ` [Qemu-devel] [RFC v1 2/6] stm32f205_USART: Add the stm32f205 SoC USART Controller Alistair Francis
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 25+ messages in thread
From: Alistair Francis @ 2014-09-09  8:23 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, peter.crosthwaite, konstanty

This patch adds the stm32f205 timers: TIM2, TIM3, TIM4 and TIM5
to QEMU.

Signed-off-by: Alistair Francis <alistair23@gmail.com>
---
V2:
 - Small changes to functionality and style. Thanks to Peter C
 - Rename for the Netduino 2 and it's SoC

 default-configs/arm-softmmu.mak    |   1 +
 hw/timer/Makefile.objs             |   1 +
 hw/timer/stm32f205_timer.c         | 334 +++++++++++++++++++++++++++++++++++++
 include/hw/timer/stm32f205_timer.h |  84 ++++++++++
 4 files changed, 420 insertions(+)
 create mode 100644 hw/timer/stm32f205_timer.c
 create mode 100644 include/hw/timer/stm32f205_timer.h

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index f3513fa..8550084 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -78,6 +78,7 @@ CONFIG_NSERIES=y
 CONFIG_REALVIEW=y
 CONFIG_ZAURUS=y
 CONFIG_ZYNQ=y
+CONFIG_NETDUINO2=y
 
 CONFIG_VERSATILE_PCI=y
 CONFIG_VERSATILE_I2C=y
diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index 2c86c3d..ce68c4a 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -17,6 +17,7 @@ common-obj-$(CONFIG_IMX) += imx_epit.o
 common-obj-$(CONFIG_IMX) += imx_gpt.o
 common-obj-$(CONFIG_LM32) += lm32_timer.o
 common-obj-$(CONFIG_MILKYMIST) += milkymist-sysctl.o
+common-obj-$(CONFIG_NETDUINO2) += stm32f205_timer.o
 
 obj-$(CONFIG_EXYNOS4) += exynos4210_mct.o
 obj-$(CONFIG_EXYNOS4) += exynos4210_pwm.o
diff --git a/hw/timer/stm32f205_timer.c b/hw/timer/stm32f205_timer.c
new file mode 100644
index 0000000..bbeaf6b
--- /dev/null
+++ b/hw/timer/stm32f205_timer.c
@@ -0,0 +1,334 @@
+/*
+ * STM32F205xx Timer 2 to 5
+ *
+ * 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 "hw/timer/stm32f205_timer.h"
+
+#ifndef ST_TIM2_5_ERR_DEBUG
+#define ST_TIM2_5_ERR_DEBUG 0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+    if (ST_TIM2_5_ERR_DEBUG >= lvl) { \
+        fprintf(stderr, "stm32f205xx_timer: %s:" fmt, __func__, ## args); \
+    } \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+static void stm32f205xx_timer_update(Stm32f205TimerState *s)
+{
+    s->tim_sr |= 1;
+    qemu_irq_pulse(s->irq);
+}
+
+static void stm32f205xx_timer_interrupt(void *opaque)
+{
+    Stm32f205TimerState *s = (Stm32f205TimerState *)opaque;
+
+    DB_PRINT("Interrupt in: %s\n", __func__);
+
+    if (s->tim_dier == 0x01 && s->tim_cr1 & TIM_CR1_CEN) {
+        stm32f205xx_timer_update(s);
+    }
+}
+
+static uint32_t stm32f205xx_timer_get_count(Stm32f205TimerState *s)
+{
+    int64_t now = qemu_clock_get_ns(rtc_clock);
+    return s->tick_offset + now / get_ticks_per_sec();
+}
+
+static void stm32f205xx_timer_set_alarm(Stm32f205TimerState *s)
+{
+    uint32_t ticks;
+
+    DB_PRINT("Alarm raised in: %s at 0x%x\n", __func__, s->tim_cr1);
+
+    ticks = s->tim_arr - stm32f205xx_timer_get_count(s)/
+                         (s->tim_psc + 1);
+    DB_PRINT("Alarm set in %u ticks\n", ticks);
+
+    if (ticks == 0) {
+        timer_del(s->timer);
+        stm32f205xx_timer_interrupt(s);
+    } else {
+        int64_t now = qemu_clock_get_ns(rtc_clock) / get_ticks_per_sec();
+        timer_mod(s->timer, now + (int64_t)ticks);
+        DB_PRINT("Wait Time: 0x%x\n", (uint32_t) (now + ticks));
+    }
+}
+
+static void stm32f205xx_timer_reset(DeviceState *dev)
+{
+    struct Stm32f205TimerState *s = STM32F205xxTIMER(dev);
+
+    s->tim_cr1 = 0;
+    s->tim_cr2 = 0;
+    s->tim_smcr = 0;
+    s->tim_dier = 0;
+    s->tim_sr = 0;
+    s->tim_egr = 0;
+    s->tim_ccmr1 = 0;
+    s->tim_ccmr2 = 0;
+    s->tim_ccer = 0;
+    s->tim_cnt = 0;
+    s->tim_psc = 0;
+    s->tim_arr = 0;
+    s->tim_ccr1 = 0;
+    s->tim_ccr2 = 0;
+    s->tim_ccr3 = 0;
+    s->tim_ccr4 = 0;
+    s->tim_dcr = 0;
+    s->tim_dmar = 0;
+    s->tim_or = 0;
+}
+
+static uint64_t stm32f205xx_timer_read(void *opaque, hwaddr offset,
+                           unsigned size)
+{
+    Stm32f205TimerState *s = (Stm32f205TimerState *)opaque;
+
+    DB_PRINT("Read 0x%x\n", (uint) offset);
+
+    switch (offset) {
+    case TIM_CR1:
+        return s->tim_cr1;
+    case TIM_CR2:
+        return s->tim_cr2;
+    case TIM_SMCR:
+        return s->tim_smcr;
+    case TIM_DIER:
+        return s->tim_dier;
+    case TIM_SR:
+        return s->tim_sr;
+    case TIM_EGR:
+        return s->tim_egr;
+    case TIM_CCMR1:
+        return s->tim_ccmr1;
+    case TIM_CCMR2:
+        return s->tim_ccmr2;
+    case TIM_CCER:
+        return s->tim_ccer;
+    case TIM_CNT:
+        return s->tim_cnt;
+    case TIM_PSC:
+        return s->tim_psc;
+    case TIM_ARR:
+        return s->tim_arr;
+    case TIM_CCR1:
+        return s->tim_ccr1;
+    case TIM_CCR2:
+        return s->tim_ccr2;
+    case TIM_CCR3:
+        return s->tim_ccr3;
+    case TIM_CCR4:
+        return s->tim_ccr4;
+    case TIM_DCR:
+        return s->tim_dcr;
+    case TIM_DMAR:
+        return s->tim_dmar;
+    case TIM_OR:
+        return s->tim_or;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "STM32F205xx_timer2_5_write: Bad offset %x\n",
+                      (int) offset);
+    }
+
+    return 0;
+}
+
+static void stm32f205xx_timer_write(void *opaque, hwaddr offset,
+                        uint64_t val64, unsigned size)
+{
+    Stm32f205TimerState *s = (Stm32f205TimerState *)opaque;
+    uint32_t value = (uint32_t) val64;
+
+    DB_PRINT("Write 0x%x, 0x%x\n", value, (uint) offset);
+
+    switch (offset) {
+    case TIM_CR1:
+        s->tim_cr1 = value;
+        return;
+    case TIM_CR2:
+        s->tim_cr2 = value;
+        return;
+    case TIM_SMCR:
+        s->tim_smcr = value;
+        return;
+    case TIM_DIER:
+        s->tim_dier = value;
+        return;
+    case TIM_SR:
+        s->tim_sr &= value;
+        stm32f205xx_timer_set_alarm(s);
+        return;
+    case TIM_EGR:
+        s->tim_egr = value;
+        return;
+    case TIM_CCMR1:
+        s->tim_ccmr1 = value;
+        return;
+    case TIM_CCMR2:
+        s->tim_ccmr2 = value;
+        return;
+    case TIM_CCER:
+        s->tim_ccer = value;
+        return;
+    case TIM_CNT:
+        s->tim_cnt = value;
+        stm32f205xx_timer_set_alarm(s);
+        return;
+    case TIM_PSC:
+        s->tim_psc = value;
+        return;
+    case TIM_ARR:
+        s->tim_arr = value;
+        stm32f205xx_timer_set_alarm(s);
+        return;
+    case TIM_CCR1:
+        s->tim_ccr1 = value;
+        return;
+    case TIM_CCR2:
+        s->tim_ccr2 = value;
+        return;
+    case TIM_CCR3:
+        s->tim_ccr3 = value;
+        return;
+    case TIM_CCR4:
+        s->tim_ccr4 = value;
+        return;
+    case TIM_DCR:
+        s->tim_dcr = value;
+        return;
+    case TIM_DMAR:
+        s->tim_dmar = value;
+        return;
+    case TIM_OR:
+        s->tim_or = value;
+        return;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "STM32F205xx_timer2_5_write: Bad offset %x\n",
+                      (int) offset);
+    }
+}
+
+static const MemoryRegionOps stm32f205xx_timer_ops = {
+    .read = stm32f205xx_timer_read,
+    .write = stm32f205xx_timer_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void stm32f205xx_timer_init(Object *obj)
+{
+    Stm32f205TimerState *s = STM32F205xxTIMER(obj);
+    struct tm tm;
+
+    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
+
+    memory_region_init_io(&s->iomem, obj, &stm32f205xx_timer_ops, s,
+                          "stm32f205xx_timer", 0x2000);
+    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
+
+    qemu_get_timedate(&tm, 0);
+    s->tick_offset = mktimegm(&tm) -
+        qemu_clock_get_ns(rtc_clock) / get_ticks_per_sec();
+
+    s->timer = timer_new_ns(rtc_clock, stm32f205xx_timer_interrupt, s);
+}
+
+static void stm32f205xx_timer_pre_save(void *opaque)
+{
+    Stm32f205TimerState *s = (Stm32f205TimerState *)opaque;
+
+    int64_t delta = qemu_clock_get_ns(rtc_clock) -
+                    qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+    s->tick_offset_vmstate = s->tick_offset + delta / get_ticks_per_sec();
+}
+
+static int stm32f205xx_timer_post_load(void *opaque, int version_id)
+{
+    Stm32f205TimerState *s = (Stm32f205TimerState *)opaque;
+
+    int64_t delta = qemu_clock_get_ns(rtc_clock) -
+                    qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
+    s->tick_offset = s->tick_offset_vmstate - delta / get_ticks_per_sec();
+    stm32f205xx_timer_set_alarm(s);
+    return 0;
+}
+
+static const VMStateDescription vmstate_stm32f205xx_timer = {
+    .name = "stm32f205xx_timer",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .pre_save = stm32f205xx_timer_pre_save,
+    .post_load = stm32f205xx_timer_post_load,
+    .fields = (VMStateField[]) {
+        VMSTATE_UINT32(tick_offset_vmstate, Stm32f205TimerState),
+        VMSTATE_UINT32(tim_cr1, Stm32f205TimerState),
+        VMSTATE_UINT32(tim_cr2, Stm32f205TimerState),
+        VMSTATE_UINT32(tim_smcr, Stm32f205TimerState),
+        VMSTATE_UINT32(tim_dier, Stm32f205TimerState),
+        VMSTATE_UINT32(tim_sr, Stm32f205TimerState),
+        VMSTATE_UINT32(tim_egr, Stm32f205TimerState),
+        VMSTATE_UINT32(tim_ccmr1, Stm32f205TimerState),
+        VMSTATE_UINT32(tim_ccmr1, Stm32f205TimerState),
+        VMSTATE_UINT32(tim_ccer, Stm32f205TimerState),
+        VMSTATE_UINT32(tim_cnt, Stm32f205TimerState),
+        VMSTATE_UINT32(tim_psc, Stm32f205TimerState),
+        VMSTATE_UINT32(tim_arr, Stm32f205TimerState),
+        VMSTATE_UINT32(tim_ccr1, Stm32f205TimerState),
+        VMSTATE_UINT32(tim_ccr2, Stm32f205TimerState),
+        VMSTATE_UINT32(tim_ccr3, Stm32f205TimerState),
+        VMSTATE_UINT32(tim_ccr4, Stm32f205TimerState),
+        VMSTATE_UINT32(tim_dcr, Stm32f205TimerState),
+        VMSTATE_UINT32(tim_dmar, Stm32f205TimerState),
+        VMSTATE_UINT32(tim_or, Stm32f205TimerState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void stm32f205xx_timer_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->vmsd = &vmstate_stm32f205xx_timer;
+    dc->reset = stm32f205xx_timer_reset;
+}
+
+static const TypeInfo stm32f205xx_timer_info = {
+    .name          = TYPE_STM32F205_TIMER,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(Stm32f205TimerState),
+    .instance_init = stm32f205xx_timer_init,
+    .class_init    = stm32f205xx_timer_class_init,
+};
+
+static void stm32f205xx_timer_register_types(void)
+{
+    type_register_static(&stm32f205xx_timer_info);
+}
+
+type_init(stm32f205xx_timer_register_types)
diff --git a/include/hw/timer/stm32f205_timer.h b/include/hw/timer/stm32f205_timer.h
new file mode 100644
index 0000000..b8ba1ad
--- /dev/null
+++ b/include/hw/timer/stm32f205_timer.h
@@ -0,0 +1,84 @@
+/*
+ * STM32F205xx Timer 2 to 5
+ *
+ * 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 "hw/sysbus.h"
+#include "qemu/timer.h"
+#include "sysemu/sysemu.h"
+
+#define TIM_CR1      0x00
+#define TIM_CR2      0x04
+#define TIM_SMCR     0x08
+#define TIM_DIER     0x0C
+#define TIM_SR       0x10
+#define TIM_EGR      0x14
+#define TIM_CCMR1    0x18
+#define TIM_CCMR2    0x1C
+#define TIM_CCER     0x20
+#define TIM_CNT      0x24
+#define TIM_PSC      0x28
+#define TIM_ARR      0x2C
+#define TIM_CCR1     0x34
+#define TIM_CCR2     0x38
+#define TIM_CCR3     0x3C
+#define TIM_CCR4     0x40
+#define TIM_DCR      0x48
+#define TIM_DMAR     0x4C
+#define TIM_OR       0x50
+
+#define TIM_CR1_CEN   1
+
+#define TYPE_STM32F205_TIMER "stm32f205xx-timer"
+#define STM32F205xxTIMER(obj) OBJECT_CHECK(Stm32f205TimerState, (obj), \
+                              TYPE_STM32F205_TIMER)
+
+typedef struct Stm32f205TimerState {
+    SysBusDevice parent_obj;
+
+    MemoryRegion iomem;
+    QEMUTimer *timer;
+    qemu_irq irq;
+
+    uint32_t tick_offset_vmstate;
+    uint32_t tick_offset;
+
+    uint32_t tim_cr1;
+    uint32_t tim_cr2;
+    uint32_t tim_smcr;
+    uint32_t tim_dier;
+    uint32_t tim_sr;
+    uint32_t tim_egr;
+    uint32_t tim_ccmr1;
+    uint32_t tim_ccmr2;
+    uint32_t tim_ccer;
+    uint32_t tim_cnt;
+    uint32_t tim_psc;
+    uint32_t tim_arr;
+    uint32_t tim_ccr1;
+    uint32_t tim_ccr2;
+    uint32_t tim_ccr3;
+    uint32_t tim_ccr4;
+    uint32_t tim_dcr;
+    uint32_t tim_dmar;
+    uint32_t tim_or;
+} Stm32f205TimerState;
-- 
1.9.1

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

* [Qemu-devel] [RFC v1 2/6] stm32f205_USART: Add the stm32f205 SoC USART Controller
  2014-09-09  8:23 [Qemu-devel] [RFC v1 0/6] Netduino 2 Machine Model Alistair Francis
  2014-09-09  8:23 ` [Qemu-devel] [RFC v1 1/6] stm32f205_timer: Add the stm32f205 SoC Timer2 to 5 Alistair Francis
@ 2014-09-09  8:24 ` Alistair Francis
  2014-09-09 13:21   ` Peter Crosthwaite
  2014-09-09  8:24 ` [Qemu-devel] [RFC v1 3/6] stm32f205_SYSCFG: Add the stm32f205 SYSCFG Alistair Francis
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 25+ messages in thread
From: Alistair Francis @ 2014-09-09  8:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, peter.crosthwaite, konstanty

This patch adds the stm32f205 USART controller
(UART also uses the same controller).

Signed-off-by: Alistair Francis <alistair23@gmail.com>
---
V2:
 - Small changes thanks to Peter C
 - Rename for the Netduino 2 and it's SoC

 hw/char/Makefile.objs             |   1 +
 hw/char/stm32f205_usart.c         | 205 ++++++++++++++++++++++++++++++++++++++
 include/hw/char/stm32f205_usart.h |  64 ++++++++++++
 3 files changed, 270 insertions(+)
 create mode 100644 hw/char/stm32f205_usart.c
 create mode 100644 include/hw/char/stm32f205_usart.h

diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
index 317385d..b1f7e80 100644
--- a/hw/char/Makefile.objs
+++ b/hw/char/Makefile.objs
@@ -15,6 +15,7 @@ obj-$(CONFIG_OMAP) += omap_uart.o
 obj-$(CONFIG_SH4) += sh_serial.o
 obj-$(CONFIG_PSERIES) += spapr_vty.o
 obj-$(CONFIG_DIGIC) += digic-uart.o
+obj-$(CONFIG_NETDUINO2) += stm32f205_usart.o
 
 common-obj-$(CONFIG_ETRAXFS) += etraxfs_ser.o
 common-obj-$(CONFIG_ISA_DEBUG) += debugcon.o
diff --git a/hw/char/stm32f205_usart.c b/hw/char/stm32f205_usart.c
new file mode 100644
index 0000000..c042b4b
--- /dev/null
+++ b/hw/char/stm32f205_usart.c
@@ -0,0 +1,205 @@
+/*
+ * STM32F205xx USART
+ *
+ * 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 "hw/char/stm32f205_usart.h"
+
+#ifndef STM_USART_ERR_DEBUG
+#define STM_USART_ERR_DEBUG 0
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+    if (STM_USART_ERR_DEBUG >= lvl) { \
+        fprintf(stderr, "stm32f205xx_usart: %s:" fmt, __func__, ## args); \
+    } \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+static int usart_can_receive(void *opaque)
+{
+    Stm32f205UsartState *s = opaque;
+
+    if (s->usart_cr1 & USART_CR1_UE && s->usart_cr1 & USART_CR1_TE) {
+        return 1;
+    }
+
+    return 0;
+}
+
+static void usart_receive(void *opaque, const uint8_t *buf, int size)
+{
+    Stm32f205UsartState *s = opaque;
+
+    s->usart_dr = *buf;
+
+    s->usart_sr |= USART_SR_RXNE;
+
+    if (s->usart_cr1 & USART_CR1_RXNEIE) {
+        qemu_set_irq(s->irq, 1);
+    }
+
+    DB_PRINT("Receiving: %c\n", s->usart_dr);
+}
+
+static void usart_reset(DeviceState *dev)
+{
+    Stm32f205UsartState *s = STM32F205xx_USART(dev);
+
+    s->usart_sr = 0x00C00000;
+    s->usart_dr = 0x00000000;
+    s->usart_brr = 0x00000000;
+    s->usart_cr1 = 0x00000000;
+    s->usart_cr2 = 0x00000000;
+    s->usart_cr3 = 0x00000000;
+    s->usart_gtpr = 0x00000000;
+}
+
+static uint64_t stm32f205xx_usart_read(void *opaque, hwaddr addr,
+                                    unsigned int size)
+{
+    Stm32f205UsartState *s = opaque;
+    uint64_t retvalue;
+
+    DB_PRINT("Read 0x%x\n", (uint) addr);
+
+    switch (addr) {
+    case USART_SR:
+        retvalue = s->usart_sr;
+        s->usart_sr &= (USART_SR_TC ^ 0xFFFF);
+        return retvalue;
+    case USART_DR:
+        DB_PRINT("Value: 0x%x, %c\n", s->usart_dr, (char) s->usart_dr);
+        s->usart_sr |= USART_SR_TXE;
+        return s->usart_dr & 0x3FF;
+    case USART_BRR:
+        return s->usart_brr;
+    case USART_CR1:
+        return s->usart_cr1;
+    case USART_CR2:
+        return s->usart_cr2;
+    case USART_CR3:
+        return s->usart_cr3;
+    case USART_GTPR:
+        return s->usart_gtpr;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "STM32F205xx_usart_read: Bad offset %x\n", (int)addr);
+        return 0;
+    }
+
+    return 0;
+}
+
+static void stm32f205xx_usart_write(void *opaque, hwaddr addr,
+                       uint64_t val64, unsigned int size)
+{
+    Stm32f205UsartState *s = opaque;
+    uint32_t value = (uint32_t) val64;
+    unsigned char ch;
+
+    DB_PRINT("Write 0x%x, 0x%x\n", value, (uint) addr);
+
+    switch (addr) {
+    case USART_SR:
+        if (value <= 0x3FF) {
+            s->usart_sr = value;
+        } else {
+            s->usart_sr &= value;
+        }
+        return;
+    case USART_DR:
+        if (value < 0xF000) {
+            ch = value;
+            if (s->chr) {
+                qemu_chr_fe_write(s->chr, &ch, 1);
+            }
+            s->usart_sr |= USART_SR_TC;
+        }
+        return;
+    case USART_BRR:
+        s->usart_brr = value;
+        return;
+    case USART_CR1:
+        s->usart_cr1 = value;
+        return;
+    case USART_CR2:
+        s->usart_cr2 = value;
+        return;
+    case USART_CR3:
+        s->usart_cr3 = value;
+        return;
+    case USART_GTPR:
+        s->usart_gtpr = value;
+        return;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "STM32F205xx_usart_write: Bad offset %x\n", (int)addr);
+    }
+}
+
+static const MemoryRegionOps stm32f205xx_usart_ops = {
+    .read = stm32f205xx_usart_read,
+    .write = stm32f205xx_usart_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void stm32f205xx_usart_init(Object *obj)
+{
+    Stm32f205UsartState *s = STM32F205xx_USART(obj);
+
+    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
+
+    memory_region_init_io(&s->mmio, obj, &stm32f205xx_usart_ops, s,
+                          TYPE_STM32F205_USART, 0x2000);
+    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
+
+    s->chr = qemu_char_get_next_serial();
+
+    if (s->chr) {
+        qemu_chr_add_handlers(s->chr, usart_can_receive, usart_receive,
+                              NULL, s);
+    }
+}
+
+static void stm32f205xx_usart_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->reset = usart_reset;
+}
+
+static const TypeInfo stm32f205xx_usart_info = {
+    .name          = TYPE_STM32F205_USART,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(Stm32f205UsartState),
+    .instance_init = stm32f205xx_usart_init,
+    .class_init    = stm32f205xx_usart_class_init,
+};
+
+static void stm32f205xx_usart_register_types(void)
+{
+    type_register_static(&stm32f205xx_usart_info);
+}
+
+type_init(stm32f205xx_usart_register_types)
diff --git a/include/hw/char/stm32f205_usart.h b/include/hw/char/stm32f205_usart.h
new file mode 100644
index 0000000..ceb92b7
--- /dev/null
+++ b/include/hw/char/stm32f205_usart.h
@@ -0,0 +1,64 @@
+/*
+ * STM32F205xx USART
+ *
+ * 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 "hw/sysbus.h"
+#include "sysemu/char.h"
+#include "hw/hw.h"
+
+#define USART_SR   0x00
+#define USART_DR   0x04
+#define USART_BRR  0x08
+#define USART_CR1  0x0C
+#define USART_CR2  0x10
+#define USART_CR3  0x14
+#define USART_GTPR 0x18
+
+#define USART_SR_TXE  (1 << 7)
+#define USART_SR_TC   (1 << 6)
+#define USART_SR_RXNE (1 << 5)
+
+#define USART_CR1_UE  (1 << 13)
+#define USART_CR1_RXNEIE  (1 << 5)
+#define USART_CR1_TE  (1 << 3)
+
+#define TYPE_STM32F205_USART "stm32f205xx-usart"
+#define STM32F205xx_USART(obj) \
+    OBJECT_CHECK(Stm32f205UsartState, (obj), TYPE_STM32F205_USART)
+
+typedef struct {
+    SysBusDevice parent_obj;
+
+    MemoryRegion mmio;
+
+    uint32_t usart_sr;
+    uint32_t usart_dr;
+    uint32_t usart_brr;
+    uint32_t usart_cr1;
+    uint32_t usart_cr2;
+    uint32_t usart_cr3;
+    uint32_t usart_gtpr;
+
+    CharDriverState *chr;
+    qemu_irq irq;
+} Stm32f205UsartState;
-- 
1.9.1

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

* [Qemu-devel] [RFC v1 3/6] stm32f205_SYSCFG: Add the stm32f205 SYSCFG
  2014-09-09  8:23 [Qemu-devel] [RFC v1 0/6] Netduino 2 Machine Model Alistair Francis
  2014-09-09  8:23 ` [Qemu-devel] [RFC v1 1/6] stm32f205_timer: Add the stm32f205 SoC Timer2 to 5 Alistair Francis
  2014-09-09  8:24 ` [Qemu-devel] [RFC v1 2/6] stm32f205_USART: Add the stm32f205 SoC USART Controller Alistair Francis
@ 2014-09-09  8:24 ` Alistair Francis
  2014-09-09  8:24 ` [Qemu-devel] [RFC v1 4/6] target_arm: Update armv7_init to support more parameters Alistair Francis
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 25+ messages in thread
From: Alistair Francis @ 2014-09-09  8:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, peter.crosthwaite, konstanty

This patch adds the stm32f205 System Configuration
Controller. This is used to configure what memory is mapped
at address 0 (although that is not supported) as well
as configure how the EXTI interrupts work (also not
supported at the moment).

This device is not required for basic examples, but more
complex systems will require it (as well as the EXTI device)

Signed-off-by: Alistair Francis <alistair23@gmail.com>
---
V2:
 - Update the commit message
 - Small changes thanks to Peter C
 - Rename for the Netduino 2 and it's SoC

 hw/misc/Makefile.objs              |   1 +
 hw/misc/stm32f205_syscfg.c         | 160 +++++++++++++++++++++++++++++++++++++
 include/hw/misc/stm32f205_syscfg.h |  59 ++++++++++++++
 3 files changed, 220 insertions(+)
 create mode 100644 hw/misc/stm32f205_syscfg.c
 create mode 100644 include/hw/misc/stm32f205_syscfg.h

diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 979e532..83a7703 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -39,5 +39,6 @@ obj-$(CONFIG_OMAP) += omap_sdrc.o
 obj-$(CONFIG_OMAP) += omap_tap.o
 obj-$(CONFIG_SLAVIO) += slavio_misc.o
 obj-$(CONFIG_ZYNQ) += zynq_slcr.o
+obj-$(CONFIG_NETDUINO2) += stm32f205_syscfg.o
 
 obj-$(CONFIG_PVPANIC) += pvpanic.o
diff --git a/hw/misc/stm32f205_syscfg.c b/hw/misc/stm32f205_syscfg.c
new file mode 100644
index 0000000..226bf74
--- /dev/null
+++ b/hw/misc/stm32f205_syscfg.c
@@ -0,0 +1,160 @@
+/*
+ * STM32F205xx 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 "hw/misc/stm32f205_syscfg.h"
+
+#ifndef STM_SYSCFG_ERR_DEBUG
+#define STM_SYSCFG_ERR_DEBUG 1
+#endif
+
+#define DB_PRINT_L(lvl, fmt, args...) do { \
+    if (STM_SYSCFG_ERR_DEBUG >= lvl) { \
+        fprintf(stderr, "stm32f205xx_syscfg: %s:" fmt, __func__, ## args); \
+    } \
+} while (0);
+
+#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
+
+static void syscfg_reset(DeviceState *dev)
+{
+    Stm32f205SyscfgState *s = STM32F205xx_SYSCFG(dev);
+
+    s->syscfg_memrmp = 0x00000000;
+    s->syscfg_pmc = 0x00000000;
+    s->syscfg_exticr1 = 0x00000000;
+    s->syscfg_exticr2 = 0x00000000;
+    s->syscfg_exticr3 = 0x00000000;
+    s->syscfg_exticr4 = 0x00000000;
+    s->syscfg_cmpcr = 0x00000000;
+}
+
+static uint64_t stm32f205xx_syscfg_read(void *opaque, hwaddr addr,
+                                     unsigned int size)
+{
+    Stm32f205SyscfgState *s = opaque;
+
+    DB_PRINT("0x%x\n", (uint) addr);
+
+    switch (addr) {
+    case SYSCFG_MEMRMP:
+        return s->syscfg_memrmp;
+    case SYSCFG_PMC:
+        return s->syscfg_pmc;
+    case SYSCFG_EXTICR1:
+        return s->syscfg_exticr1;
+    case SYSCFG_EXTICR2:
+        return s->syscfg_exticr2;
+    case SYSCFG_EXTICR3:
+        return s->syscfg_exticr3;
+    case SYSCFG_EXTICR4:
+        return s->syscfg_exticr4;
+    case SYSCFG_CMPCR:
+        return s->syscfg_cmpcr;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "STM32F205xx_syscfg_read: Bad offset %x\n", (int)addr);
+        return 0;
+    }
+
+    return 0;
+}
+
+static void stm32f205xx_syscfg_write(void *opaque, hwaddr addr,
+                       uint64_t val64, unsigned int size)
+{
+    Stm32f205SyscfgState *s = opaque;
+    uint32_t value = (uint32_t) val64;
+
+    DB_PRINT("0x%x, 0x%x\n", value, (uint) addr);
+
+    switch (addr) {
+    case SYSCFG_MEMRMP:
+        qemu_log_mask(LOG_UNIMP,
+                      "STM32F205xx_syscfg_write: Changeing the memory " \
+                      "mapping isn't supported in QEMU\n");
+        return;
+    case SYSCFG_PMC:
+        qemu_log_mask(LOG_UNIMP,
+                      "STM32F205xx_syscfg_write: Peripheral mode " \
+                      "configuration isn't supported in QEMU\n");
+        return;
+    case SYSCFG_EXTICR1:
+        s->syscfg_exticr1 = (value & 0xFF);
+        return;
+    case SYSCFG_EXTICR2:
+        s->syscfg_exticr2 = (value & 0xFF);
+        return;
+    case SYSCFG_EXTICR3:
+        s->syscfg_exticr3 = (value & 0xFF);
+        return;
+    case SYSCFG_EXTICR4:
+        s->syscfg_exticr4 = (value & 0xFF);
+        return;
+    case SYSCFG_CMPCR:
+        s->syscfg_cmpcr = value;
+        return;
+    default:
+        qemu_log_mask(LOG_GUEST_ERROR,
+                      "STM32F205xx_syscfg_write: Bad offset %x\n", (int)addr);
+    }
+}
+
+static const MemoryRegionOps stm32f205xx_syscfg_ops = {
+    .read = stm32f205xx_syscfg_read,
+    .write = stm32f205xx_syscfg_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static void stm32f205xx_syscfg_init(Object *obj)
+{
+    Stm32f205SyscfgState *s = STM32F205xx_SYSCFG(obj);
+
+    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
+
+    memory_region_init_io(&s->mmio, obj, &stm32f205xx_syscfg_ops, s,
+                          TYPE_STM32F205_SYSCFG, 0x2000);
+    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
+}
+
+static void stm32f205xx_syscfg_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->reset = syscfg_reset;
+}
+
+static const TypeInfo stm32f205xx_syscfg_info = {
+    .name          = TYPE_STM32F205_SYSCFG,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(Stm32f205SyscfgState),
+    .instance_init = stm32f205xx_syscfg_init,
+    .class_init    = stm32f205xx_syscfg_class_init,
+};
+
+static void stm32f205xx_syscfg_register_types(void)
+{
+    type_register_static(&stm32f205xx_syscfg_info);
+}
+
+type_init(stm32f205xx_syscfg_register_types)
diff --git a/include/hw/misc/stm32f205_syscfg.h b/include/hw/misc/stm32f205_syscfg.h
new file mode 100644
index 0000000..ab26c89
--- /dev/null
+++ b/include/hw/misc/stm32f205_syscfg.h
@@ -0,0 +1,59 @@
+/*
+ * STM32F205xx 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_ST_SYSCFG_H
+#define HW_ST_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_STM32F205_SYSCFG "stm32f205xx-syscfg"
+#define STM32F205xx_SYSCFG(obj) \
+    OBJECT_CHECK(Stm32f205SyscfgState, (obj), TYPE_STM32F205_SYSCFG)
+
+typedef struct {
+    SysBusDevice parent_obj;
+
+    MemoryRegion mmio;
+
+    uint32_t syscfg_memrmp;
+    uint32_t syscfg_pmc;
+    uint32_t syscfg_exticr1;
+    uint32_t syscfg_exticr2;
+    uint32_t syscfg_exticr3;
+    uint32_t syscfg_exticr4;
+    uint32_t syscfg_cmpcr;
+
+    qemu_irq irq;
+} Stm32f205SyscfgState;
+
+#endif
-- 
1.9.1

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

* [Qemu-devel] [RFC v1 4/6] target_arm: Update armv7_init to support more parameters
  2014-09-09  8:23 [Qemu-devel] [RFC v1 0/6] Netduino 2 Machine Model Alistair Francis
                   ` (2 preceding siblings ...)
  2014-09-09  8:24 ` [Qemu-devel] [RFC v1 3/6] stm32f205_SYSCFG: Add the stm32f205 SYSCFG Alistair Francis
@ 2014-09-09  8:24 ` Alistair Francis
  2014-09-09 13:35   ` Peter Crosthwaite
  2014-09-09  8:24 ` [Qemu-devel] [RFC v1 5/6] stm32f205: Add the SoC Alistair Francis
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 25+ messages in thread
From: Alistair Francis @ 2014-09-09  8:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, peter.crosthwaite, konstanty

This patch is a hack

This patch makes the smallest number of changes possible to extend
armv7m_init() so that it can be used to init the Netduino 2.

Signed-off-by: Alistair Francis <alistair23@gmail.com>
---

I understand that this is probably not the way that everyone would
like this done. What I do want to know though, is what the prefered
method for extending this function would be? I am expecting that it
will have to be a QOM device that can be attached.

 hw/arm/armv7m.c      | 33 ++++++++++++++++++++++++++-------
 hw/arm/stellaris.c   |  2 +-
 include/hw/arm/arm.h |  3 ++-
 3 files changed, 29 insertions(+), 9 deletions(-)

diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index aedef13..e4f7d8c 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -155,11 +155,21 @@ static void armv7m_bitband_init(void)
 
 /* Board init.  */
 
+typedef struct ARMV7MResetArgs {
+    ARMCPU *cpu;
+    uint32_t reset_sp;
+    uint32_t reset_pc;
+} ARMV7MResetArgs;
+
 static void armv7m_reset(void *opaque)
 {
-    ARMCPU *cpu = opaque;
+    ARMV7MResetArgs *args = opaque;
+
+    cpu_reset(CPU(args->cpu));
 
-    cpu_reset(CPU(cpu));
+    args->cpu->env.regs[13] = args->reset_sp & 0xFFFFFFFC;
+    args->cpu->env.thumb = args->reset_pc & 1;
+    args->cpu->env.regs[15] = args->reset_pc & ~1;
 }
 
 /* Init CPU and memory for a v7-M based board.
@@ -167,14 +177,15 @@ static void armv7m_reset(void *opaque)
    Returns the NVIC array.  */
 
 qemu_irq *armv7m_init(MemoryRegion *system_memory,
-                      int flash_size, int sram_size,
+                      int flash_size, uint64_t flash_base,
+                      int sram_size, int num_irq,
                       const char *kernel_filename, const char *cpu_model)
 {
     ARMCPU *cpu;
     CPUARMState *env;
     DeviceState *nvic;
     /* FIXME: make this local state.  */
-    static qemu_irq pic[64];
+    qemu_irq *pic = g_new(qemu_irq, num_irq);
     int image_size;
     uint64_t entry;
     uint64_t lowaddr;
@@ -183,6 +194,7 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory,
     MemoryRegion *sram = g_new(MemoryRegion, 1);
     MemoryRegion *flash = g_new(MemoryRegion, 1);
     MemoryRegion *hack = g_new(MemoryRegion, 1);
+    ARMV7MResetArgs reset_args;
 
     flash_size *= 1024;
     sram_size *= 1024;
@@ -213,18 +225,19 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory,
     memory_region_init_ram(flash, NULL, "armv7m.flash", flash_size);
     vmstate_register_ram_global(flash);
     memory_region_set_readonly(flash, true);
-    memory_region_add_subregion(system_memory, 0, flash);
+    memory_region_add_subregion(system_memory, flash_base, flash);
     memory_region_init_ram(sram, NULL, "armv7m.sram", sram_size);
     vmstate_register_ram_global(sram);
     memory_region_add_subregion(system_memory, 0x20000000, sram);
     armv7m_bitband_init();
 
     nvic = qdev_create(NULL, "armv7m_nvic");
+    qdev_prop_set_uint32(nvic, "num-irq", num_irq);
     env->nvic = nvic;
     qdev_init_nofail(nvic);
     sysbus_connect_irq(SYS_BUS_DEVICE(nvic), 0,
                        qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
-    for (i = 0; i < 64; i++) {
+    for (i = 0; i < num_irq; i++) {
         pic[i] = qdev_get_gpio_in(nvic, i);
     }
 
@@ -259,7 +272,13 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory,
     vmstate_register_ram_global(hack);
     memory_region_add_subregion(system_memory, 0xfffff000, hack);
 
-    qemu_register_reset(armv7m_reset, cpu);
+    reset_args = (ARMV7MResetArgs) {
+        .cpu = cpu,
+        .reset_pc = entry,
+        .reset_sp = (0x20000000 + ((192 * 1024) * 2)/3),
+    };
+    qemu_register_reset(armv7m_reset,
+                        g_memdup(&reset_args, sizeof(reset_args)));
     return pic;
 }
 
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
index 64bd4b4..41dc712 100644
--- a/hw/arm/stellaris.c
+++ b/hw/arm/stellaris.c
@@ -1223,7 +1223,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
     flash_size = ((board->dc0 & 0xffff) + 1) << 1;
     sram_size = (board->dc0 >> 18) + 1;
     pic = armv7m_init(get_system_memory(),
-                      flash_size, sram_size, kernel_filename, cpu_model);
+                      flash_size, 0, sram_size, 64, kernel_filename, cpu_model);
 
     if (board->dc1 & (1 << 16)) {
         dev = sysbus_create_varargs(TYPE_STELLARIS_ADC, 0x40038000,
diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h
index cefc9e6..72f0266 100644
--- a/include/hw/arm/arm.h
+++ b/include/hw/arm/arm.h
@@ -16,7 +16,8 @@
 
 /* armv7m.c */
 qemu_irq *armv7m_init(MemoryRegion *system_memory,
-                      int flash_size, int sram_size,
+                      int flash_size, uint64_t flash_base,
+                      int sram_size, int num_irq,
                       const char *kernel_filename, const char *cpu_model);
 
 /* arm_boot.c */
-- 
1.9.1

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

* [Qemu-devel] [RFC v1 5/6] stm32f205: Add the SoC
  2014-09-09  8:23 [Qemu-devel] [RFC v1 0/6] Netduino 2 Machine Model Alistair Francis
                   ` (3 preceding siblings ...)
  2014-09-09  8:24 ` [Qemu-devel] [RFC v1 4/6] target_arm: Update armv7_init to support more parameters Alistair Francis
@ 2014-09-09  8:24 ` Alistair Francis
  2014-09-09 13:50   ` Peter Crosthwaite
  2014-09-09  8:24 ` [Qemu-devel] [RFC v1 6/6] netduino2: Add the Netduino 2 Machine Alistair Francis
  2014-09-09 18:24 ` [Qemu-devel] [RFC v1 0/6] Netduino 2 Machine Model Peter Maydell
  6 siblings, 1 reply; 25+ messages in thread
From: Alistair Francis @ 2014-09-09  8:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, peter.crosthwaite, konstanty

This patch adds the stm32f205 SoC. This will be used by the
Netduino 2 to create a machine

Signed-off-by: Alistair Francis <alistair23@gmail.com>
---

 hw/arm/Makefile.objs           |   2 +-
 hw/arm/stm32f205_soc.c         | 140 +++++++++++++++++++++++++++++++++++++++++
 include/hw/arm/stm32f205_soc.h |  61 ++++++++++++++++++
 3 files changed, 202 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/stm32f205_soc.c
 create mode 100644 include/hw/arm/stm32f205_soc.h

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 6088e53..673feef 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -2,7 +2,7 @@ obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o
 obj-$(CONFIG_DIGIC) += digic_boards.o
 obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o
 obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o
-obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o
+obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o stm32f205_soc.o
 
 obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
 obj-$(CONFIG_DIGIC) += digic.o
diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c
new file mode 100644
index 0000000..da36f61
--- /dev/null
+++ b/hw/arm/stm32f205_soc.c
@@ -0,0 +1,140 @@
+/*
+ * STM32F205xx 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 "hw/arm/stm32f205_soc.h"
+
+#define FLASH_BASE_ADDRESS 0x08000000
+#define FLASH_SIZE 1024
+#define SRAM_BASE_ADDRESS 0x20000000
+#define SRAM_SIZE 192
+
+static void stm32f205_soc_initfn(Object *obj)
+{
+    STM32F205State *s = STM32F205_SOC(obj);
+    int i;
+
+    object_initialize(&s->syscfg, sizeof(s->syscfg), TYPE_STM32F205_SYSCFG);
+    qdev_set_parent_bus(DEVICE(&s->syscfg), sysbus_get_default());
+
+    for (i = 0; i < 5; i++) {
+        object_initialize(&s->usart[i], sizeof(s->usart[i]),
+                          TYPE_STM32F205_USART);
+        qdev_set_parent_bus(DEVICE(&s->usart[i]), sysbus_get_default());
+    }
+
+    for (i = 0; i < 4; i++) {
+        object_initialize(&s->timer[i], sizeof(s->timer[i]),
+                          TYPE_STM32F205_TIMER);
+        qdev_set_parent_bus(DEVICE(&s->timer[i]), sysbus_get_default());
+    }
+}
+
+static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
+{
+    static const uint32_t timer_addr[] = { 0x40000000, 0x40000400,
+        0x40000800, 0x40000C00 };
+    static const uint32_t usart_addr[] = { 0x40011000, 0x40004400,
+        0x40004800, 0x40004C00, 0x40005000, 0x40011400 };
+
+    static const int timer_irq[] = {28, 29, 30, 50};
+    static const int usart_irq[] = {37, 38, 39, 52, 53, 71, 82, 83};
+
+    STM32F205State *s = STM32F205_SOC(dev_soc);
+    DeviceState *syscfgdev, *usartdev, *timerdev;
+    SysBusDevice *syscfgbusdev, *usartbusdev, *timerbusdev;
+    qemu_irq *pic;;
+    Error *err = NULL;
+    int i;
+
+    pic = armv7m_init(get_system_memory(),
+                      FLASH_SIZE, FLASH_BASE_ADDRESS, SRAM_SIZE, 96,
+                      s->kernel_filename, s->cpu_model);
+
+    /* System configuration controller */
+    syscfgdev = DEVICE(&s->syscfg);
+    syscfgdev->id = "stm32f205xx-syscfg";
+    object_property_set_bool(OBJECT(&s->syscfg), true, "realized", &err);
+    if (err != NULL) {
+        error_propagate(errp, err);
+        return;
+    }
+    syscfgbusdev = SYS_BUS_DEVICE(syscfgdev);
+    sysbus_mmio_map(syscfgbusdev, 0, 0x40013800);
+    sysbus_connect_irq(syscfgbusdev, 0, pic[71]);
+
+    /* Attach a UART (uses USART registers) and USART controllers */
+    for (i = 0; i < 5; i++) {
+        usartdev = DEVICE(&(s->usart[i]));
+        object_property_set_bool(OBJECT(&s->usart[i]), true, "realized", &err);
+        if (err != NULL) {
+            error_propagate(errp, err);
+            return;
+        }
+        usartbusdev = SYS_BUS_DEVICE(usartdev);
+        sysbus_mmio_map(usartbusdev, 0, usart_addr[i]);
+        sysbus_connect_irq(usartbusdev, 0, pic[usart_irq[i]]);
+    }
+
+    /* Timer 2 to 5 */
+    for (i = 0; i < 4; i++) {
+        timerdev = DEVICE(&(s->timer[i]));
+        object_property_set_bool(OBJECT(&s->timer[i]), true, "realized", &err);
+        if (err != NULL) {
+            error_propagate(errp, err);
+            return;
+        }
+        timerbusdev = SYS_BUS_DEVICE(timerdev);
+        sysbus_mmio_map(timerbusdev, 0, timer_addr[i]);
+        sysbus_connect_irq(timerbusdev, 0, pic[timer_irq[i]]);
+    }
+}
+
+static Property stm32f205_soc_properties[] = {
+    DEFINE_PROP_STRING("kernel-filename", STM32F205State, kernel_filename),
+    DEFINE_PROP_STRING("cpu-model", STM32F205State, cpu_model),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void stm32f205_soc_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->realize = stm32f205_soc_realize;
+    dc->props = stm32f205_soc_properties;
+}
+
+static const TypeInfo stm32f205_soc_info = {
+    .name          = TYPE_STM32F205_SOC,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(STM32F205State),
+    .instance_init = stm32f205_soc_initfn,
+    .class_init    = stm32f205_soc_class_init,
+};
+
+static void stm32f205_soc_types(void)
+{
+    type_register_static(&stm32f205_soc_info);
+}
+
+type_init(stm32f205_soc_types)
diff --git a/include/hw/arm/stm32f205_soc.h b/include/hw/arm/stm32f205_soc.h
new file mode 100644
index 0000000..d989b10
--- /dev/null
+++ b/include/hw/arm/stm32f205_soc.h
@@ -0,0 +1,61 @@
+/*
+ * STM32F205xx 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_STM32F205SOC_H
+#define HW_ARM_STM32F205SOC_H
+
+#include "hw/sysbus.h"
+#include "hw/arm/arm.h"
+#include "hw/ssi.h"
+#include "hw/devices.h"
+#include "qemu/timer.h"
+#include "net/net.h"
+#include "elf.h"
+#include "hw/loader.h"
+#include "hw/boards.h"
+#include "exec/address-spaces.h"
+#include "qemu/error-report.h"
+#include "sysemu/qtest.h"
+#include "hw/misc/stm32f205_syscfg.h"
+#include "hw/timer/stm32f205_timer.h"
+#include "hw/char/stm32f205_usart.h"
+
+#define TYPE_STM32F205_SOC "stm32f205_soc"
+#define STM32F205_SOC(obj) \
+    OBJECT_CHECK(STM32F205State, (obj), TYPE_STM32F205_SOC)
+
+typedef struct STM32F205State {
+    /*< private >*/
+    SysBusDevice parent_obj;
+    /*< public >*/
+
+    char *kernel_filename;
+    char *cpu_model;
+
+    Stm32f205SyscfgState syscfg;
+    Stm32f205UsartState usart[5];
+    Stm32f205TimerState timer[5];
+} STM32F205State;
+
+#endif
-- 
1.9.1

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

* [Qemu-devel] [RFC v1 6/6] netduino2: Add the Netduino 2 Machine
  2014-09-09  8:23 [Qemu-devel] [RFC v1 0/6] Netduino 2 Machine Model Alistair Francis
                   ` (4 preceding siblings ...)
  2014-09-09  8:24 ` [Qemu-devel] [RFC v1 5/6] stm32f205: Add the SoC Alistair Francis
@ 2014-09-09  8:24 ` Alistair Francis
  2014-09-09 18:24 ` [Qemu-devel] [RFC v1 0/6] Netduino 2 Machine Model Peter Maydell
  6 siblings, 0 replies; 25+ messages in thread
From: Alistair Francis @ 2014-09-09  8:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, peter.crosthwaite, konstanty

This patch adds the Netduino 2 Machine.

This is a Cortex-M3 based machine. Information can be found at:
http://www.netduino.com/netduino2/specs.htm

Signed-off-by: Alistair Francis <alistair23@gmail.com>
---

 hw/arm/Makefile.objs |  2 +-
 hw/arm/netduino2.c   | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/netduino2.c

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 673feef..eb12353 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -2,7 +2,7 @@ obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o
 obj-$(CONFIG_DIGIC) += digic_boards.o
 obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o
 obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o
-obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o stm32f205_soc.o
+obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o netduino2.o stm32f205_soc.o
 
 obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
 obj-$(CONFIG_DIGIC) += digic.o
diff --git a/hw/arm/netduino2.c b/hw/arm/netduino2.c
new file mode 100644
index 0000000..08101db
--- /dev/null
+++ b/hw/arm/netduino2.c
@@ -0,0 +1,60 @@
+/*
+ * Netduino 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 "hw/arm/stm32f205_soc.h"
+
+static void netduino2_init(MachineState *machine)
+{
+    DeviceState *dev;
+    const char *cpu_model = machine->cpu_model;
+    Error *err = NULL;
+
+    if (!cpu_model) {
+        cpu_model = "cortex-m3";
+    }
+
+    dev = qdev_create(NULL, TYPE_STM32F205_SOC);
+    if (machine->kernel_filename) {
+        qdev_prop_set_string(dev, "kernel-filename", machine->kernel_filename);
+    }
+    qdev_prop_set_string(dev, "cpu-model", cpu_model);
+    object_property_set_bool(OBJECT(dev), true, "realized", &err);
+    if (err != NULL) {
+        error_report("%s", error_get_pretty(err));
+        exit(1);
+    }
+}
+
+static QEMUMachine netduino2_machine = {
+    .name = "netduino2",
+    .desc = "Netduino 2 Machine",
+    .init = netduino2_init,
+};
+
+static void netduino2_machine_init(void)
+{
+    qemu_register_machine(&netduino2_machine);
+}
+
+machine_init(netduino2_machine_init);
-- 
1.9.1

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

* Re: [Qemu-devel] [RFC v1 1/6] stm32f205_timer: Add the stm32f205 SoC Timer2 to 5
  2014-09-09  8:23 ` [Qemu-devel] [RFC v1 1/6] stm32f205_timer: Add the stm32f205 SoC Timer2 to 5 Alistair Francis
@ 2014-09-09 12:44   ` Peter Crosthwaite
  2014-09-09 23:52     ` Alistair Francis
  0 siblings, 1 reply; 25+ messages in thread
From: Peter Crosthwaite @ 2014-09-09 12:44 UTC (permalink / raw)
  To: Alistair Francis
  Cc: Peter Maydell, qemu-devel@nongnu.org Developers, Konstanty Bialkowski

On Tue, Sep 9, 2014 at 6:23 PM, Alistair Francis <alistair23@gmail.com> wrote:
> This patch adds the stm32f205 timers: TIM2, TIM3, TIM4 and TIM5
> to QEMU.
>
> Signed-off-by: Alistair Francis <alistair23@gmail.com>
> ---
> V2:
>  - Small changes to functionality and style. Thanks to Peter C
>  - Rename for the Netduino 2 and it's SoC
>
>  default-configs/arm-softmmu.mak    |   1 +
>  hw/timer/Makefile.objs             |   1 +
>  hw/timer/stm32f205_timer.c         | 334 +++++++++++++++++++++++++++++++++++++
>  include/hw/timer/stm32f205_timer.h |  84 ++++++++++
>  4 files changed, 420 insertions(+)
>  create mode 100644 hw/timer/stm32f205_timer.c
>  create mode 100644 include/hw/timer/stm32f205_timer.h
>
> diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
> index f3513fa..8550084 100644
> --- a/default-configs/arm-softmmu.mak
> +++ b/default-configs/arm-softmmu.mak
> @@ -78,6 +78,7 @@ CONFIG_NSERIES=y
>  CONFIG_REALVIEW=y
>  CONFIG_ZAURUS=y
>  CONFIG_ZYNQ=y
> +CONFIG_NETDUINO2=y
>

I think we were moving aware from SoC level shared configs, i.e. it's
ok to have a confing per-dev in the arm-softmmu defconfig. You also
want to avoid tying the device (and the SoC) to netduino as much as
possible so even if CONFIG_NETDUINO existed it would simply set
another config for STM etc. Easiest to just go flat with one config
per dev (the ZYNQ example right above does do it wrong too :( ).

>  CONFIG_VERSATILE_PCI=y
>  CONFIG_VERSATILE_I2C=y
> diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
> index 2c86c3d..ce68c4a 100644
> --- a/hw/timer/Makefile.objs
> +++ b/hw/timer/Makefile.objs
> @@ -17,6 +17,7 @@ common-obj-$(CONFIG_IMX) += imx_epit.o
>  common-obj-$(CONFIG_IMX) += imx_gpt.o
>  common-obj-$(CONFIG_LM32) += lm32_timer.o
>  common-obj-$(CONFIG_MILKYMIST) += milkymist-sysctl.o
> +common-obj-$(CONFIG_NETDUINO2) += stm32f205_timer.o
>
>  obj-$(CONFIG_EXYNOS4) += exynos4210_mct.o
>  obj-$(CONFIG_EXYNOS4) += exynos4210_pwm.o
> diff --git a/hw/timer/stm32f205_timer.c b/hw/timer/stm32f205_timer.c
> new file mode 100644
> index 0000000..bbeaf6b
> --- /dev/null
> +++ b/hw/timer/stm32f205_timer.c
> @@ -0,0 +1,334 @@
> +/*
> + * STM32F205xx Timer 2 to 5
> + *

Looking at the TRM i notice some of the other timers may be similar.
Are TIM9-14 potentially modellable with a slight parameterisation of
this?

I think its ok in first series to limit functionality to TIM2-5 but
you should soften the naming, probably just to stm32f205_timer
throughout (removing all ref to TIM2-5) and leave this 2-5 1/8 9-13
configury to the SoC level.

> + * 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 "hw/timer/stm32f205_timer.h"
> +
> +#ifndef ST_TIM2_5_ERR_DEBUG
> +#define ST_TIM2_5_ERR_DEBUG 0
> +#endif
> +
> +#define DB_PRINT_L(lvl, fmt, args...) do { \
> +    if (ST_TIM2_5_ERR_DEBUG >= lvl) { \
> +        fprintf(stderr, "stm32f205xx_timer: %s:" fmt, __func__, ## args); \

qemu_log()

> +    } \
> +} while (0);
> +
> +#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
> +
> +static void stm32f205xx_timer_update(Stm32f205TimerState *s)
> +{
> +    s->tim_sr |= 1;
> +    qemu_irq_pulse(s->irq);
> +}

This only serves the purpose of interrupt assertion on the timer
callback below and is single use. Just inline it.

> +
> +static void stm32f205xx_timer_interrupt(void *opaque)
> +{
> +    Stm32f205TimerState *s = (Stm32f205TimerState *)opaque;
> +

No explicit cast needed.

> +    DB_PRINT("Interrupt in: %s\n", __func__);
> +
> +    if (s->tim_dier == 0x01 && s->tim_cr1 & TIM_CR1_CEN) {

The UIE bit of dier is only a single bit so you should use a mask and
macro (just like with & TIM_CR1_CEN).

> +        stm32f205xx_timer_update(s);
> +    }
> +}
> +
> +static uint32_t stm32f205xx_timer_get_count(Stm32f205TimerState *s)
> +{
> +    int64_t now = qemu_clock_get_ns(rtc_clock);

Why use the RTC rather than the virtual clock? Most timer use the
virtual unless they are explicitly an RTC device (does TIMx have RTC
capability?)

> +    return s->tick_offset + now / get_ticks_per_sec();
> +}
> +
> +static void stm32f205xx_timer_set_alarm(Stm32f205TimerState *s)
> +{
> +    uint32_t ticks;
> +
> +    DB_PRINT("Alarm raised in: %s at 0x%x\n", __func__, s->tim_cr1);
> +
> +    ticks = s->tim_arr - stm32f205xx_timer_get_count(s)/
> +                         (s->tim_psc + 1);
> +    DB_PRINT("Alarm set in %u ticks\n", ticks);
> +
> +    if (ticks == 0) {
> +        timer_del(s->timer);
> +        stm32f205xx_timer_interrupt(s);
> +    } else {
> +        int64_t now = qemu_clock_get_ns(rtc_clock) / get_ticks_per_sec();

You should avoid two now calculations in the one callback. You have
already crunched a now in timer_get_count() above and you do it again
here. As timer_get_count is low (single?) use you can just inline to
get now as a calculate-once local var.

> +        timer_mod(s->timer, now + (int64_t)ticks);
> +        DB_PRINT("Wait Time: 0x%x\n", (uint32_t) (now + ticks));
> +    }
> +}
> +
> +static void stm32f205xx_timer_reset(DeviceState *dev)
> +{
> +    struct Stm32f205TimerState *s = STM32F205xxTIMER(dev);
> +

No struct needed.

> +    s->tim_cr1 = 0;
> +    s->tim_cr2 = 0;
> +    s->tim_smcr = 0;
> +    s->tim_dier = 0;
> +    s->tim_sr = 0;
> +    s->tim_egr = 0;
> +    s->tim_ccmr1 = 0;
> +    s->tim_ccmr2 = 0;
> +    s->tim_ccer = 0;
> +    s->tim_cnt = 0;
> +    s->tim_psc = 0;
> +    s->tim_arr = 0;
> +    s->tim_ccr1 = 0;
> +    s->tim_ccr2 = 0;
> +    s->tim_ccr3 = 0;
> +    s->tim_ccr4 = 0;
> +    s->tim_dcr = 0;
> +    s->tim_dmar = 0;
> +    s->tim_or = 0;
> +}
> +
> +static uint64_t stm32f205xx_timer_read(void *opaque, hwaddr offset,
> +                           unsigned size)
> +{
> +    Stm32f205TimerState *s = (Stm32f205TimerState *)opaque;
> +

No explicit cast.

> +    DB_PRINT("Read 0x%x\n", (uint) offset);

HWADDR_PRIx instead of cast.

> +
> +    switch (offset) {
> +    case TIM_CR1:
> +        return s->tim_cr1;
> +    case TIM_CR2:
> +        return s->tim_cr2;
> +    case TIM_SMCR:
> +        return s->tim_smcr;
> +    case TIM_DIER:
> +        return s->tim_dier;
> +    case TIM_SR:
> +        return s->tim_sr;
> +    case TIM_EGR:
> +        return s->tim_egr;
> +    case TIM_CCMR1:
> +        return s->tim_ccmr1;
> +    case TIM_CCMR2:
> +        return s->tim_ccmr2;
> +    case TIM_CCER:
> +        return s->tim_ccer;
> +    case TIM_CNT:
> +        return s->tim_cnt;
> +    case TIM_PSC:
> +        return s->tim_psc;
> +    case TIM_ARR:
> +        return s->tim_arr;
> +    case TIM_CCR1:
> +        return s->tim_ccr1;
> +    case TIM_CCR2:
> +        return s->tim_ccr2;
> +    case TIM_CCR3:
> +        return s->tim_ccr3;
> +    case TIM_CCR4:
> +        return s->tim_ccr4;
> +    case TIM_DCR:
> +        return s->tim_dcr;
> +    case TIM_DMAR:
> +        return s->tim_dmar;
> +    case TIM_OR:
> +        return s->tim_or;
> +    default:
> +        qemu_log_mask(LOG_GUEST_ERROR,
> +                      "STM32F205xx_timer2_5_write: Bad offset %x\n",
> +                      (int) offset);

same.

> +    }
> +
> +    return 0;
> +}
> +
> +static void stm32f205xx_timer_write(void *opaque, hwaddr offset,
> +                        uint64_t val64, unsigned size)
> +{
> +    Stm32f205TimerState *s = (Stm32f205TimerState *)opaque;
> +    uint32_t value = (uint32_t) val64;

Casts not needed.

> +
> +    DB_PRINT("Write 0x%x, 0x%x\n", value, (uint) offset);
> +
> +    switch (offset) {
> +    case TIM_CR1:
> +        s->tim_cr1 = value;
> +        return;
> +    case TIM_CR2:
> +        s->tim_cr2 = value;
> +        return;
> +    case TIM_SMCR:
> +        s->tim_smcr = value;
> +        return;
> +    case TIM_DIER:
> +        s->tim_dier = value;
> +        return;
> +    case TIM_SR:
> +        s->tim_sr &= value;
> +        stm32f205xx_timer_set_alarm(s);
> +        return;
> +    case TIM_EGR:
> +        s->tim_egr = value;
> +        return;
> +    case TIM_CCMR1:
> +        s->tim_ccmr1 = value;
> +        return;
> +    case TIM_CCMR2:
> +        s->tim_ccmr2 = value;
> +        return;
> +    case TIM_CCER:
> +        s->tim_ccer = value;
> +        return;
> +    case TIM_CNT:
> +        s->tim_cnt = value;
> +        stm32f205xx_timer_set_alarm(s);
> +        return;
> +    case TIM_PSC:
> +        s->tim_psc = value;
> +        return;
> +    case TIM_ARR:
> +        s->tim_arr = value;
> +        stm32f205xx_timer_set_alarm(s);
> +        return;
> +    case TIM_CCR1:
> +        s->tim_ccr1 = value;
> +        return;
> +    case TIM_CCR2:
> +        s->tim_ccr2 = value;
> +        return;
> +    case TIM_CCR3:
> +        s->tim_ccr3 = value;
> +        return;
> +    case TIM_CCR4:
> +        s->tim_ccr4 = value;
> +        return;
> +    case TIM_DCR:
> +        s->tim_dcr = value;
> +        return;
> +    case TIM_DMAR:
> +        s->tim_dmar = value;
> +        return;
> +    case TIM_OR:
> +        s->tim_or = value;
> +        return;
> +    default:
> +        qemu_log_mask(LOG_GUEST_ERROR,
> +                      "STM32F205xx_timer2_5_write: Bad offset %x\n",
> +                      (int) offset);
> +    }
> +}
> +
> +static const MemoryRegionOps stm32f205xx_timer_ops = {
> +    .read = stm32f205xx_timer_read,
> +    .write = stm32f205xx_timer_write,
> +    .endianness = DEVICE_NATIVE_ENDIAN,
> +};
> +
> +static void stm32f205xx_timer_init(Object *obj)
> +{
> +    Stm32f205TimerState *s = STM32F205xxTIMER(obj);
> +    struct tm tm;
> +
> +    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
> +
> +    memory_region_init_io(&s->iomem, obj, &stm32f205xx_timer_ops, s,
> +                          "stm32f205xx_timer", 0x2000);
> +    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
> +
> +    qemu_get_timedate(&tm, 0);
> +    s->tick_offset = mktimegm(&tm) -
> +        qemu_clock_get_ns(rtc_clock) / get_ticks_per_sec();
> +
> +    s->timer = timer_new_ns(rtc_clock, stm32f205xx_timer_interrupt, s);
> +}
> +
> +static void stm32f205xx_timer_pre_save(void *opaque)
> +{
> +    Stm32f205TimerState *s = (Stm32f205TimerState *)opaque;
> +
> +    int64_t delta = qemu_clock_get_ns(rtc_clock) -
> +                    qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);

Blank line here.

> +    s->tick_offset_vmstate = s->tick_offset + delta / get_ticks_per_sec();
> +}
> +
> +static int stm32f205xx_timer_post_load(void *opaque, int version_id)
> +{
> +    Stm32f205TimerState *s = (Stm32f205TimerState *)opaque;
> +
> +    int64_t delta = qemu_clock_get_ns(rtc_clock) -
> +                    qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);

Blank line here.

> +    s->tick_offset = s->tick_offset_vmstate - delta / get_ticks_per_sec();
> +    stm32f205xx_timer_set_alarm(s);
> +    return 0;
> +}
> +
> +static const VMStateDescription vmstate_stm32f205xx_timer = {
> +    .name = "stm32f205xx_timer",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .pre_save = stm32f205xx_timer_pre_save,
> +    .post_load = stm32f205xx_timer_post_load,
> +    .fields = (VMStateField[]) {
> +        VMSTATE_UINT32(tick_offset_vmstate, Stm32f205TimerState),
> +        VMSTATE_UINT32(tim_cr1, Stm32f205TimerState),
> +        VMSTATE_UINT32(tim_cr2, Stm32f205TimerState),
> +        VMSTATE_UINT32(tim_smcr, Stm32f205TimerState),
> +        VMSTATE_UINT32(tim_dier, Stm32f205TimerState),
> +        VMSTATE_UINT32(tim_sr, Stm32f205TimerState),
> +        VMSTATE_UINT32(tim_egr, Stm32f205TimerState),
> +        VMSTATE_UINT32(tim_ccmr1, Stm32f205TimerState),
> +        VMSTATE_UINT32(tim_ccmr1, Stm32f205TimerState),
> +        VMSTATE_UINT32(tim_ccer, Stm32f205TimerState),
> +        VMSTATE_UINT32(tim_cnt, Stm32f205TimerState),
> +        VMSTATE_UINT32(tim_psc, Stm32f205TimerState),
> +        VMSTATE_UINT32(tim_arr, Stm32f205TimerState),
> +        VMSTATE_UINT32(tim_ccr1, Stm32f205TimerState),
> +        VMSTATE_UINT32(tim_ccr2, Stm32f205TimerState),
> +        VMSTATE_UINT32(tim_ccr3, Stm32f205TimerState),
> +        VMSTATE_UINT32(tim_ccr4, Stm32f205TimerState),
> +        VMSTATE_UINT32(tim_dcr, Stm32f205TimerState),
> +        VMSTATE_UINT32(tim_dmar, Stm32f205TimerState),
> +        VMSTATE_UINT32(tim_or, Stm32f205TimerState),
> +        VMSTATE_END_OF_LIST()
> +    }
> +};
> +
> +static void stm32f205xx_timer_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +
> +    dc->vmsd = &vmstate_stm32f205xx_timer;
> +    dc->reset = stm32f205xx_timer_reset;
> +}
> +
> +static const TypeInfo stm32f205xx_timer_info = {
> +    .name          = TYPE_STM32F205_TIMER,
> +    .parent        = TYPE_SYS_BUS_DEVICE,
> +    .instance_size = sizeof(Stm32f205TimerState),
> +    .instance_init = stm32f205xx_timer_init,
> +    .class_init    = stm32f205xx_timer_class_init,
> +};
> +
> +static void stm32f205xx_timer_register_types(void)
> +{
> +    type_register_static(&stm32f205xx_timer_info);
> +}
> +
> +type_init(stm32f205xx_timer_register_types)
> diff --git a/include/hw/timer/stm32f205_timer.h b/include/hw/timer/stm32f205_timer.h
> new file mode 100644
> index 0000000..b8ba1ad
> --- /dev/null
> +++ b/include/hw/timer/stm32f205_timer.h
> @@ -0,0 +1,84 @@
> +/*
> + * STM32F205xx Timer 2 to 5
> + *
> + * 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 "hw/sysbus.h"
> +#include "qemu/timer.h"
> +#include "sysemu/sysemu.h"
> +
> +#define TIM_CR1      0x00
> +#define TIM_CR2      0x04
> +#define TIM_SMCR     0x08
> +#define TIM_DIER     0x0C
> +#define TIM_SR       0x10
> +#define TIM_EGR      0x14
> +#define TIM_CCMR1    0x18
> +#define TIM_CCMR2    0x1C
> +#define TIM_CCER     0x20
> +#define TIM_CNT      0x24
> +#define TIM_PSC      0x28
> +#define TIM_ARR      0x2C
> +#define TIM_CCR1     0x34
> +#define TIM_CCR2     0x38
> +#define TIM_CCR3     0x3C
> +#define TIM_CCR4     0x40
> +#define TIM_DCR      0x48
> +#define TIM_DMAR     0x4C
> +#define TIM_OR       0x50
> +
> +#define TIM_CR1_CEN   1
> +
> +#define TYPE_STM32F205_TIMER "stm32f205xx-timer"
> +#define STM32F205xxTIMER(obj) OBJECT_CHECK(Stm32f205TimerState, (obj), \
> +                              TYPE_STM32F205_TIMER)
> +
> +typedef struct Stm32f205TimerState {

STM

/*< private >*/

> +    SysBusDevice parent_obj;
> +

/*< public >*/

Regards,
Peter

> +    MemoryRegion iomem;
> +    QEMUTimer *timer;
> +    qemu_irq irq;
> +
> +    uint32_t tick_offset_vmstate;
> +    uint32_t tick_offset;
> +
> +    uint32_t tim_cr1;
> +    uint32_t tim_cr2;
> +    uint32_t tim_smcr;
> +    uint32_t tim_dier;
> +    uint32_t tim_sr;
> +    uint32_t tim_egr;
> +    uint32_t tim_ccmr1;
> +    uint32_t tim_ccmr2;
> +    uint32_t tim_ccer;
> +    uint32_t tim_cnt;
> +    uint32_t tim_psc;
> +    uint32_t tim_arr;
> +    uint32_t tim_ccr1;
> +    uint32_t tim_ccr2;
> +    uint32_t tim_ccr3;
> +    uint32_t tim_ccr4;
> +    uint32_t tim_dcr;
> +    uint32_t tim_dmar;
> +    uint32_t tim_or;
> +} Stm32f205TimerState;
> --
> 1.9.1
>
>

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

* Re: [Qemu-devel] [RFC v1 2/6] stm32f205_USART: Add the stm32f205 SoC USART Controller
  2014-09-09  8:24 ` [Qemu-devel] [RFC v1 2/6] stm32f205_USART: Add the stm32f205 SoC USART Controller Alistair Francis
@ 2014-09-09 13:21   ` Peter Crosthwaite
  2014-09-10 10:55     ` Alistair Francis
  0 siblings, 1 reply; 25+ messages in thread
From: Peter Crosthwaite @ 2014-09-09 13:21 UTC (permalink / raw)
  To: Alistair Francis
  Cc: Peter Maydell, qemu-devel@nongnu.org Developers, Konstanty Bialkowski

On Tue, Sep 9, 2014 at 6:24 PM, Alistair Francis <alistair23@gmail.com> wrote:
> This patch adds the stm32f205 USART controller
> (UART also uses the same controller).
>
> Signed-off-by: Alistair Francis <alistair23@gmail.com>
> ---
> V2:
>  - Small changes thanks to Peter C
>  - Rename for the Netduino 2 and it's SoC
>
>  hw/char/Makefile.objs             |   1 +
>  hw/char/stm32f205_usart.c         | 205 ++++++++++++++++++++++++++++++++++++++
>  include/hw/char/stm32f205_usart.h |  64 ++++++++++++
>  3 files changed, 270 insertions(+)
>  create mode 100644 hw/char/stm32f205_usart.c
>  create mode 100644 include/hw/char/stm32f205_usart.h
>
> diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
> index 317385d..b1f7e80 100644
> --- a/hw/char/Makefile.objs
> +++ b/hw/char/Makefile.objs
> @@ -15,6 +15,7 @@ obj-$(CONFIG_OMAP) += omap_uart.o
>  obj-$(CONFIG_SH4) += sh_serial.o
>  obj-$(CONFIG_PSERIES) += spapr_vty.o
>  obj-$(CONFIG_DIGIC) += digic-uart.o
> +obj-$(CONFIG_NETDUINO2) += stm32f205_usart.o
>
>  common-obj-$(CONFIG_ETRAXFS) += etraxfs_ser.o
>  common-obj-$(CONFIG_ISA_DEBUG) += debugcon.o
> diff --git a/hw/char/stm32f205_usart.c b/hw/char/stm32f205_usart.c
> new file mode 100644
> index 0000000..c042b4b
> --- /dev/null
> +++ b/hw/char/stm32f205_usart.c
> @@ -0,0 +1,205 @@
> +/*
> + * STM32F205xx USART
> + *
> + * 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 "hw/char/stm32f205_usart.h"
> +
> +#ifndef STM_USART_ERR_DEBUG
> +#define STM_USART_ERR_DEBUG 0
> +#endif
> +
> +#define DB_PRINT_L(lvl, fmt, args...) do { \
> +    if (STM_USART_ERR_DEBUG >= lvl) { \
> +        fprintf(stderr, "stm32f205xx_usart: %s:" fmt, __func__, ## args); \
> +    } \
> +} while (0);
> +
> +#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
> +
> +static int usart_can_receive(void *opaque)
> +{
> +    Stm32f205UsartState *s = opaque;
> +
> +    if (s->usart_cr1 & USART_CR1_UE && s->usart_cr1 & USART_CR1_TE) {
> +        return 1;
> +    }

So it's usual to block a UART on the fifo filling rather than the
master enable switches. Corking the fifo on the master enable means
QEMU will buffer UART input long-term until the guest turns the fifo
on, where in reality the hardware should just drop the chars. We
should do something similar.

The reason (as far as I know anyways) for can_recieve and giving qemu
serial false closed-loop implementation (network has it too) is to
deal with large amounts of instantaneous data in situations where the
real-time delays on real-hardware would give natural bandwidth
limiting. Thus the main app of can-recieve 0-return is 'your pumping
serial data way too fast such that my fifo is full and real hardware
would never go that fast'.

Also, did you me the RE bit rather than the TE bit?

> +
> +    return 0;
> +}
> +
> +static void usart_receive(void *opaque, const uint8_t *buf, int size)
> +{
> +    Stm32f205UsartState *s = opaque;
> +
> +    s->usart_dr = *buf;
> +
> +    s->usart_sr |= USART_SR_RXNE;
> +

This might be a good condition to block can_recieve on - the
USART_SR_RXNE. And if the enables are off, just drop the char.

> +    if (s->usart_cr1 & USART_CR1_RXNEIE) {
> +        qemu_set_irq(s->irq, 1);
> +    }
> +
> +    DB_PRINT("Receiving: %c\n", s->usart_dr);
> +}
> +
> +static void usart_reset(DeviceState *dev)

stm32f..._ prefix to function name. For consistency and makes gdb
breakpoints slightly easier if function names are globally unique.

> +{
> +    Stm32f205UsartState *s = STM32F205xx_USART(dev);
> +
> +    s->usart_sr = 0x00C00000;
> +    s->usart_dr = 0x00000000;
> +    s->usart_brr = 0x00000000;
> +    s->usart_cr1 = 0x00000000;
> +    s->usart_cr2 = 0x00000000;
> +    s->usart_cr3 = 0x00000000;
> +    s->usart_gtpr = 0x00000000;
> +}
> +
> +static uint64_t stm32f205xx_usart_read(void *opaque, hwaddr addr,
> +                                    unsigned int size)
> +{
> +    Stm32f205UsartState *s = opaque;
> +    uint64_t retvalue;
> +
> +    DB_PRINT("Read 0x%x\n", (uint) addr);
> +
> +    switch (addr) {
> +    case USART_SR:
> +        retvalue = s->usart_sr;
> +        s->usart_sr &= (USART_SR_TC ^ 0xFFFF);

This register seems to be a mix of clear-to-read, read-only and rsvd.
Just use &= ~MASK to implement clear on read which look to be the
intention here. I don't see the significance of bits 15 downto 0 and
why they behave different to 31 downto 16 here?

This is probably also where you need to repoll for can_receive blocked
chars as well (assuming you make condition change I recommended above.

 qemu_chr_accept_input(s->chr)

> +        return retvalue;
> +    case USART_DR:
> +        DB_PRINT("Value: 0x%x, %c\n", s->usart_dr, (char) s->usart_dr);
> +        s->usart_sr |= USART_SR_TXE;
> +        return s->usart_dr & 0x3FF;
> +    case USART_BRR:
> +        return s->usart_brr;
> +    case USART_CR1:
> +        return s->usart_cr1;
> +    case USART_CR2:
> +        return s->usart_cr2;
> +    case USART_CR3:
> +        return s->usart_cr3;
> +    case USART_GTPR:
> +        return s->usart_gtpr;
> +    default:
> +        qemu_log_mask(LOG_GUEST_ERROR,
> +                      "STM32F205xx_usart_read: Bad offset %x\n", (int)addr);
> +        return 0;
> +    }
> +
> +    return 0;
> +}
> +
> +static void stm32f205xx_usart_write(void *opaque, hwaddr addr,
> +                       uint64_t val64, unsigned int size)
> +{
> +    Stm32f205UsartState *s = opaque;
> +    uint32_t value = (uint32_t) val64;
> +    unsigned char ch;
> +
> +    DB_PRINT("Write 0x%x, 0x%x\n", value, (uint) addr);
> +
> +    switch (addr) {
> +    case USART_SR:
> +        if (value <= 0x3FF) {
> +            s->usart_sr = value;
> +        } else {
> +            s->usart_sr &= value;
> +        }
> +        return;
> +    case USART_DR:
> +        if (value < 0xF000) {
> +            ch = value;
> +            if (s->chr) {
> +                qemu_chr_fe_write(s->chr, &ch, 1);

If the backend gets busy this will drop chars. You can either
implement the closed loop callbacks (kinda hard - check serial.c) or
use qemu_chr_fe_write all to get a blocking implementation.

> +            }
> +            s->usart_sr |= USART_SR_TC;
> +        }
> +        return;
> +    case USART_BRR:
> +        s->usart_brr = value;
> +        return;
> +    case USART_CR1:
> +        s->usart_cr1 = value;
> +        return;
> +    case USART_CR2:
> +        s->usart_cr2 = value;
> +        return;
> +    case USART_CR3:
> +        s->usart_cr3 = value;
> +        return;
> +    case USART_GTPR:
> +        s->usart_gtpr = value;
> +        return;
> +    default:
> +        qemu_log_mask(LOG_GUEST_ERROR,
> +                      "STM32F205xx_usart_write: Bad offset %x\n", (int)addr);
> +    }
> +}
> +
> +static const MemoryRegionOps stm32f205xx_usart_ops = {
> +    .read = stm32f205xx_usart_read,
> +    .write = stm32f205xx_usart_write,
> +    .endianness = DEVICE_NATIVE_ENDIAN,
> +};
> +
> +static void stm32f205xx_usart_init(Object *obj)
> +{
> +    Stm32f205UsartState *s = STM32F205xx_USART(obj);
> +
> +    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
> +
> +    memory_region_init_io(&s->mmio, obj, &stm32f205xx_usart_ops, s,
> +                          TYPE_STM32F205_USART, 0x2000);
> +    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
> +
> +    s->chr = qemu_char_get_next_serial();
> +
> +    if (s->chr) {
> +        qemu_chr_add_handlers(s->chr, usart_can_receive, usart_receive,
> +                              NULL, s);
> +    }
> +}
> +
> +static void stm32f205xx_usart_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +
> +    dc->reset = usart_reset;
> +}
> +
> +static const TypeInfo stm32f205xx_usart_info = {
> +    .name          = TYPE_STM32F205_USART,
> +    .parent        = TYPE_SYS_BUS_DEVICE,
> +    .instance_size = sizeof(Stm32f205UsartState),
> +    .instance_init = stm32f205xx_usart_init,
> +    .class_init    = stm32f205xx_usart_class_init,
> +};
> +
> +static void stm32f205xx_usart_register_types(void)
> +{
> +    type_register_static(&stm32f205xx_usart_info);
> +}
> +
> +type_init(stm32f205xx_usart_register_types)
> diff --git a/include/hw/char/stm32f205_usart.h b/include/hw/char/stm32f205_usart.h
> new file mode 100644
> index 0000000..ceb92b7
> --- /dev/null
> +++ b/include/hw/char/stm32f205_usart.h
> @@ -0,0 +1,64 @@
> +/*
> + * STM32F205xx USART
> + *
> + * 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 "hw/sysbus.h"
> +#include "sysemu/char.h"
> +#include "hw/hw.h"
> +
> +#define USART_SR   0x00
> +#define USART_DR   0x04
> +#define USART_BRR  0x08
> +#define USART_CR1  0x0C
> +#define USART_CR2  0x10
> +#define USART_CR3  0x14
> +#define USART_GTPR 0x18
> +
> +#define USART_SR_TXE  (1 << 7)
> +#define USART_SR_TC   (1 << 6)
> +#define USART_SR_RXNE (1 << 5)
> +
> +#define USART_CR1_UE  (1 << 13)
> +#define USART_CR1_RXNEIE  (1 << 5)
> +#define USART_CR1_TE  (1 << 3)
> +
> +#define TYPE_STM32F205_USART "stm32f205xx-usart"
> +#define STM32F205xx_USART(obj) \
> +    OBJECT_CHECK(Stm32f205UsartState, (obj), TYPE_STM32F205_USART)
> +
> +typedef struct {

/*< private >*/

> +    SysBusDevice parent_obj;
> +

/*< public >*/

> +    MemoryRegion mmio;
> +
> +    uint32_t usart_sr;
> +    uint32_t usart_dr;
> +    uint32_t usart_brr;
> +    uint32_t usart_cr1;
> +    uint32_t usart_cr2;
> +    uint32_t usart_cr3;
> +    uint32_t usart_gtpr;
> +
> +    CharDriverState *chr;
> +    qemu_irq irq;
> +} Stm32f205UsartState;

STM

A few general styling comments from prev patch (mainly a few casts)
apply here as well.

Regards,
Peter

> --
> 1.9.1
>
>

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

* Re: [Qemu-devel] [RFC v1 4/6] target_arm: Update armv7_init to support more parameters
  2014-09-09  8:24 ` [Qemu-devel] [RFC v1 4/6] target_arm: Update armv7_init to support more parameters Alistair Francis
@ 2014-09-09 13:35   ` Peter Crosthwaite
  2014-09-09 13:59     ` Peter Maydell
  2014-09-09 14:03     ` Martin Galvan
  0 siblings, 2 replies; 25+ messages in thread
From: Peter Crosthwaite @ 2014-09-09 13:35 UTC (permalink / raw)
  To: Alistair Francis, Martin Galvan
  Cc: Peter Maydell, qemu-devel@nongnu.org Developers, Konstanty Bialkowski

On Tue, Sep 9, 2014 at 6:24 PM, Alistair Francis <alistair23@gmail.com> wrote:
> This patch is a hack
>
> This patch makes the smallest number of changes possible to extend
> armv7m_init() so that it can be used to init the Netduino 2.
>

s/Netduino/STM

> Signed-off-by: Alistair Francis <alistair23@gmail.com>
> ---
>
> I understand that this is probably not the way that everyone would
> like this done. What I do want to know though, is what the prefered
> method for extending this function would be? I am expecting that it
> will have to be a QOM device that can be attached.
>

That would be nice, but we might get there a shorter way first. A
bigger question to me is what is the content of this device supposed
to be?

>  hw/arm/armv7m.c      | 33 ++++++++++++++++++++++++++-------
>  hw/arm/stellaris.c   |  2 +-
>  include/hw/arm/arm.h |  3 ++-
>  3 files changed, 29 insertions(+), 9 deletions(-)
>
> diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
> index aedef13..e4f7d8c 100644
> --- a/hw/arm/armv7m.c
> +++ b/hw/arm/armv7m.c
> @@ -155,11 +155,21 @@ static void armv7m_bitband_init(void)
>
>  /* Board init.  */
>
> +typedef struct ARMV7MResetArgs {
> +    ARMCPU *cpu;
> +    uint32_t reset_sp;
> +    uint32_t reset_pc;
> +} ARMV7MResetArgs;
> +
>  static void armv7m_reset(void *opaque)
>  {
> -    ARMCPU *cpu = opaque;
> +    ARMV7MResetArgs *args = opaque;
> +
> +    cpu_reset(CPU(args->cpu));
>
> -    cpu_reset(CPU(cpu));
> +    args->cpu->env.regs[13] = args->reset_sp & 0xFFFFFFFC;
> +    args->cpu->env.thumb = args->reset_pc & 1;
> +    args->cpu->env.regs[15] = args->reset_pc & ~1;
>  }
>
>  /* Init CPU and memory for a v7-M based board.
> @@ -167,14 +177,15 @@ static void armv7m_reset(void *opaque)
>     Returns the NVIC array.  */
>
>  qemu_irq *armv7m_init(MemoryRegion *system_memory,
> -                      int flash_size, int sram_size,
> +                      int flash_size, uint64_t flash_base,

Does ARMv7M actually mandate the existence of RAM and flash like this
at all? Given the complex setup of STM (with the memory aliases etc)
I'm now of the belief that all RAM and FLASH init should be handled by
the SoC level.

Can we just remove flash and RAM from this fn completely and push the
memory_region_init calls up to stellaris?

> +                      int sram_size, int num_irq,
>                        const char *kernel_filename, const char *cpu_model)
>  {
>      ARMCPU *cpu;
>      CPUARMState *env;
>      DeviceState *nvic;
>      /* FIXME: make this local state.  */
> -    static qemu_irq pic[64];
> +    qemu_irq *pic = g_new(qemu_irq, num_irq);
>      int image_size;
>      uint64_t entry;
>      uint64_t lowaddr;
> @@ -183,6 +194,7 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory,
>      MemoryRegion *sram = g_new(MemoryRegion, 1);
>      MemoryRegion *flash = g_new(MemoryRegion, 1);
>      MemoryRegion *hack = g_new(MemoryRegion, 1);
> +    ARMV7MResetArgs reset_args;
>
>      flash_size *= 1024;
>      sram_size *= 1024;
> @@ -213,18 +225,19 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory,
>      memory_region_init_ram(flash, NULL, "armv7m.flash", flash_size);
>      vmstate_register_ram_global(flash);
>      memory_region_set_readonly(flash, true);
> -    memory_region_add_subregion(system_memory, 0, flash);
> +    memory_region_add_subregion(system_memory, flash_base, flash);
>      memory_region_init_ram(sram, NULL, "armv7m.sram", sram_size);
>      vmstate_register_ram_global(sram);
>      memory_region_add_subregion(system_memory, 0x20000000, sram);
>      armv7m_bitband_init();
>
>      nvic = qdev_create(NULL, "armv7m_nvic");
> +    qdev_prop_set_uint32(nvic, "num-irq", num_irq);
>      env->nvic = nvic;
>      qdev_init_nofail(nvic);
>      sysbus_connect_irq(SYS_BUS_DEVICE(nvic), 0,
>                         qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
> -    for (i = 0; i < 64; i++) {
> +    for (i = 0; i < num_irq; i++) {
>          pic[i] = qdev_get_gpio_in(nvic, i);
>      }
>
> @@ -259,7 +272,13 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory,
>      vmstate_register_ram_global(hack);
>      memory_region_add_subregion(system_memory, 0xfffff000, hack);
>
> -    qemu_register_reset(armv7m_reset, cpu);
> +    reset_args = (ARMV7MResetArgs) {
> +        .cpu = cpu,
> +        .reset_pc = entry,
> +        .reset_sp = (0x20000000 + ((192 * 1024) * 2)/3),

Why is the manual sp setting needed? I thought the V7M specific CPU
reset code handled this? Does Martins ARMv7M ROM reset patch help by
any chance?

Regards,
Peter

> +    };
> +    qemu_register_reset(armv7m_reset,
> +                        g_memdup(&reset_args, sizeof(reset_args)));
>      return pic;
>  }
>
> diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
> index 64bd4b4..41dc712 100644
> --- a/hw/arm/stellaris.c
> +++ b/hw/arm/stellaris.c
> @@ -1223,7 +1223,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
>      flash_size = ((board->dc0 & 0xffff) + 1) << 1;
>      sram_size = (board->dc0 >> 18) + 1;
>      pic = armv7m_init(get_system_memory(),
> -                      flash_size, sram_size, kernel_filename, cpu_model);
> +                      flash_size, 0, sram_size, 64, kernel_filename, cpu_model);
>
>      if (board->dc1 & (1 << 16)) {
>          dev = sysbus_create_varargs(TYPE_STELLARIS_ADC, 0x40038000,
> diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h
> index cefc9e6..72f0266 100644
> --- a/include/hw/arm/arm.h
> +++ b/include/hw/arm/arm.h
> @@ -16,7 +16,8 @@
>
>  /* armv7m.c */
>  qemu_irq *armv7m_init(MemoryRegion *system_memory,
> -                      int flash_size, int sram_size,
> +                      int flash_size, uint64_t flash_base,
> +                      int sram_size, int num_irq,
>                        const char *kernel_filename, const char *cpu_model);
>
>  /* arm_boot.c */
> --
> 1.9.1
>
>

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

* Re: [Qemu-devel] [RFC v1 5/6] stm32f205: Add the SoC
  2014-09-09  8:24 ` [Qemu-devel] [RFC v1 5/6] stm32f205: Add the SoC Alistair Francis
@ 2014-09-09 13:50   ` Peter Crosthwaite
  2014-09-10  7:31     ` Alistair Francis
  0 siblings, 1 reply; 25+ messages in thread
From: Peter Crosthwaite @ 2014-09-09 13:50 UTC (permalink / raw)
  To: Alistair Francis
  Cc: Peter Maydell, qemu-devel@nongnu.org Developers, Konstanty Bialkowski

On Tue, Sep 9, 2014 at 6:24 PM, Alistair Francis <alistair23@gmail.com> wrote:
> This patch adds the stm32f205 SoC. This will be used by the
> Netduino 2 to create a machine
>
> Signed-off-by: Alistair Francis <alistair23@gmail.com>
> ---
>
>  hw/arm/Makefile.objs           |   2 +-
>  hw/arm/stm32f205_soc.c         | 140 +++++++++++++++++++++++++++++++++++++++++
>  include/hw/arm/stm32f205_soc.h |  61 ++++++++++++++++++
>  3 files changed, 202 insertions(+), 1 deletion(-)
>  create mode 100644 hw/arm/stm32f205_soc.c
>  create mode 100644 include/hw/arm/stm32f205_soc.h
>
> diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
> index 6088e53..673feef 100644
> --- a/hw/arm/Makefile.objs
> +++ b/hw/arm/Makefile.objs
> @@ -2,7 +2,7 @@ obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o
>  obj-$(CONFIG_DIGIC) += digic_boards.o
>  obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o
>  obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o
> -obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o
> +obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o stm32f205_soc.o

New obj-y line.

>
>  obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
>  obj-$(CONFIG_DIGIC) += digic.o
> diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c
> new file mode 100644
> index 0000000..da36f61
> --- /dev/null
> +++ b/hw/arm/stm32f205_soc.c
> @@ -0,0 +1,140 @@
> +/*
> + * STM32F205xx 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 "hw/arm/stm32f205_soc.h"
> +
> +#define FLASH_BASE_ADDRESS 0x08000000
> +#define FLASH_SIZE 1024
> +#define SRAM_BASE_ADDRESS 0x20000000
> +#define SRAM_SIZE 192
> +
> +static void stm32f205_soc_initfn(Object *obj)
> +{
> +    STM32F205State *s = STM32F205_SOC(obj);
> +    int i;
> +
> +    object_initialize(&s->syscfg, sizeof(s->syscfg), TYPE_STM32F205_SYSCFG);
> +    qdev_set_parent_bus(DEVICE(&s->syscfg), sysbus_get_default());
> +
> +    for (i = 0; i < 5; i++) {
> +        object_initialize(&s->usart[i], sizeof(s->usart[i]),
> +                          TYPE_STM32F205_USART);
> +        qdev_set_parent_bus(DEVICE(&s->usart[i]), sysbus_get_default());
> +    }
> +
> +    for (i = 0; i < 4; i++) {
> +        object_initialize(&s->timer[i], sizeof(s->timer[i]),
> +                          TYPE_STM32F205_TIMER);
> +        qdev_set_parent_bus(DEVICE(&s->timer[i]), sysbus_get_default());
> +    }
> +}
> +
> +static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
> +{
> +    static const uint32_t timer_addr[] = { 0x40000000, 0x40000400,
> +        0x40000800, 0x40000C00 };

You should add a comment about how you only model TIM2-5. This list is
to grow significantly in a fuller implementation.

> +    static const uint32_t usart_addr[] = { 0x40011000, 0x40004400,
> +        0x40004800, 0x40004C00, 0x40005000, 0x40011400 };
> +

Just put the static consts up top of the file so the are easily
spotted as self documentation.

> +    static const int timer_irq[] = {28, 29, 30, 50};
> +    static const int usart_irq[] = {37, 38, 39, 52, 53, 71, 82, 83};
> +
> +    STM32F205State *s = STM32F205_SOC(dev_soc);
> +    DeviceState *syscfgdev, *usartdev, *timerdev;
> +    SysBusDevice *syscfgbusdev, *usartbusdev, *timerbusdev;
> +    qemu_irq *pic;;
> +    Error *err = NULL;
> +    int i;
> +
> +    pic = armv7m_init(get_system_memory(),
> +                      FLASH_SIZE, FLASH_BASE_ADDRESS, SRAM_SIZE, 96,
> +                      s->kernel_filename, s->cpu_model);
> +
> +    /* System configuration controller */
> +    syscfgdev = DEVICE(&s->syscfg);
> +    syscfgdev->id = "stm32f205xx-syscfg";

Why you need to set the legacy qdev id string? If its needed I would
expect this to be init stage rather than realize.

> +    object_property_set_bool(OBJECT(&s->syscfg), true, "realized", &err);
> +    if (err != NULL) {
> +        error_propagate(errp, err);
> +        return;
> +    }
> +    syscfgbusdev = SYS_BUS_DEVICE(syscfgdev);
> +    sysbus_mmio_map(syscfgbusdev, 0, 0x40013800);
> +    sysbus_connect_irq(syscfgbusdev, 0, pic[71]);
> +
> +    /* Attach a UART (uses USART registers) and USART controllers */
> +    for (i = 0; i < 5; i++) {
> +        usartdev = DEVICE(&(s->usart[i]));
> +        object_property_set_bool(OBJECT(&s->usart[i]), true, "realized", &err);
> +        if (err != NULL) {
> +            error_propagate(errp, err);
> +            return;
> +        }
> +        usartbusdev = SYS_BUS_DEVICE(usartdev);
> +        sysbus_mmio_map(usartbusdev, 0, usart_addr[i]);
> +        sysbus_connect_irq(usartbusdev, 0, pic[usart_irq[i]]);
> +    }
> +
> +    /* Timer 2 to 5 */
> +    for (i = 0; i < 4; i++) {
> +        timerdev = DEVICE(&(s->timer[i]));
> +        object_property_set_bool(OBJECT(&s->timer[i]), true, "realized", &err);
> +        if (err != NULL) {
> +            error_propagate(errp, err);
> +            return;
> +        }
> +        timerbusdev = SYS_BUS_DEVICE(timerdev);
> +        sysbus_mmio_map(timerbusdev, 0, timer_addr[i]);
> +        sysbus_connect_irq(timerbusdev, 0, pic[timer_irq[i]]);
> +    }
> +}
> +
> +static Property stm32f205_soc_properties[] = {
> +    DEFINE_PROP_STRING("kernel-filename", STM32F205State, kernel_filename),
> +    DEFINE_PROP_STRING("cpu-model", STM32F205State, cpu_model),

Is it really configurable? You can drop cpu-model parameterisation
unless STM have similar socs with different processor you are
targetting?

> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static void stm32f205_soc_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *dc = DEVICE_CLASS(klass);
> +
> +    dc->realize = stm32f205_soc_realize;
> +    dc->props = stm32f205_soc_properties;
> +}
> +
> +static const TypeInfo stm32f205_soc_info = {
> +    .name          = TYPE_STM32F205_SOC,
> +    .parent        = TYPE_SYS_BUS_DEVICE,
> +    .instance_size = sizeof(STM32F205State),
> +    .instance_init = stm32f205_soc_initfn,
> +    .class_init    = stm32f205_soc_class_init,
> +};
> +
> +static void stm32f205_soc_types(void)
> +{
> +    type_register_static(&stm32f205_soc_info);
> +}
> +
> +type_init(stm32f205_soc_types)
> diff --git a/include/hw/arm/stm32f205_soc.h b/include/hw/arm/stm32f205_soc.h
> new file mode 100644
> index 0000000..d989b10
> --- /dev/null
> +++ b/include/hw/arm/stm32f205_soc.h
> @@ -0,0 +1,61 @@
> +/*
> + * STM32F205xx 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_STM32F205SOC_H
> +#define HW_ARM_STM32F205SOC_H
> +
> +#include "hw/sysbus.h"
> +#include "hw/arm/arm.h"
> +#include "hw/ssi.h"
> +#include "hw/devices.h"
> +#include "qemu/timer.h"
> +#include "net/net.h"
> +#include "elf.h"
> +#include "hw/loader.h"
> +#include "hw/boards.h"
> +#include "exec/address-spaces.h"
> +#include "qemu/error-report.h"
> +#include "sysemu/qtest.h"
> +#include "hw/misc/stm32f205_syscfg.h"
> +#include "hw/timer/stm32f205_timer.h"
> +#include "hw/char/stm32f205_usart.h"
> +
> +#define TYPE_STM32F205_SOC "stm32f205_soc"
> +#define STM32F205_SOC(obj) \
> +    OBJECT_CHECK(STM32F205State, (obj), TYPE_STM32F205_SOC)
> +
> +typedef struct STM32F205State {
> +    /*< private >*/
> +    SysBusDevice parent_obj;
> +    /*< public >*/
> +
> +    char *kernel_filename;
> +    char *cpu_model;
> +
> +    Stm32f205SyscfgState syscfg;
> +    Stm32f205UsartState usart[5];
> +    Stm32f205TimerState timer[5];

You can macrofiy these magic "5"s. STM_NUM_UARTS etc.

Regards,
Peter

> +} STM32F205State;
> +
> +#endif
> --
> 1.9.1
>
>

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

* Re: [Qemu-devel] [RFC v1 4/6] target_arm: Update armv7_init to support more parameters
  2014-09-09 13:35   ` Peter Crosthwaite
@ 2014-09-09 13:59     ` Peter Maydell
  2014-09-09 23:39       ` Alistair Francis
  2014-09-09 14:03     ` Martin Galvan
  1 sibling, 1 reply; 25+ messages in thread
From: Peter Maydell @ 2014-09-09 13:59 UTC (permalink / raw)
  To: Peter Crosthwaite
  Cc: Konstanty Bialkowski, Alistair Francis, Martin Galvan,
	qemu-devel@nongnu.org Developers

On 9 September 2014 14:35, Peter Crosthwaite
<peter.crosthwaite@xilinx.com> wrote:
> Does ARMv7M actually mandate the existence of RAM and flash like this
> at all?

No. It does have a well defined address map that pretty
strongly suggests that you ought to have flash and RAM
at certain addresses, but the flash and RAM are not part
of the CPU core itself.

(Bitbanding, on the other hand, is part of the CPU core
and the memory region setup for it should stay in this
function.)

> Given the complex setup of STM (with the memory aliases etc)
> I'm now of the belief that all RAM and FLASH init should be handled by
> the SoC level.

Agreed.

-- PMM

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

* Re: [Qemu-devel] [RFC v1 4/6] target_arm: Update armv7_init to support more parameters
  2014-09-09 13:35   ` Peter Crosthwaite
  2014-09-09 13:59     ` Peter Maydell
@ 2014-09-09 14:03     ` Martin Galvan
  2014-09-09 23:43       ` Alistair Francis
  1 sibling, 1 reply; 25+ messages in thread
From: Martin Galvan @ 2014-09-09 14:03 UTC (permalink / raw)
  To: Peter Crosthwaite
  Cc: Konstanty Bialkowski, Alistair Francis,
	qemu-devel@nongnu.org Developers, Peter Maydell

>> @@ -259,7 +272,13 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory,
>>      vmstate_register_ram_global(hack);
>>      memory_region_add_subregion(system_memory, 0xfffff000, hack);
>>
>> -    qemu_register_reset(armv7m_reset, cpu);
>> +    reset_args = (ARMV7MResetArgs) {
>> +        .cpu = cpu,
>> +        .reset_pc = entry,
>> +        .reset_sp = (0x20000000 + ((192 * 1024) * 2)/3),
>
> Why is the manual sp setting needed? I thought the V7M specific CPU
> reset code handled this? Does Martins ARMv7M ROM reset patch help by
> any chance?
>
> Regards,
> Peter

Indeed, I don't think that would be necessary with my patch. What are
those hardcoded magic numbers?

-- 


Martín Galván

Software Engineer

Taller Technologies Argentina


San Lorenzo 47, 3rd Floor, Office 5

Córdoba, Argentina

Phone: 54 351 4217888 / +54 351 4218211

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

* Re: [Qemu-devel] [RFC v1 0/6] Netduino 2 Machine Model
  2014-09-09  8:23 [Qemu-devel] [RFC v1 0/6] Netduino 2 Machine Model Alistair Francis
                   ` (5 preceding siblings ...)
  2014-09-09  8:24 ` [Qemu-devel] [RFC v1 6/6] netduino2: Add the Netduino 2 Machine Alistair Francis
@ 2014-09-09 18:24 ` Peter Maydell
  2014-09-09 23:31   ` Alistair Francis
  6 siblings, 1 reply; 25+ messages in thread
From: Peter Maydell @ 2014-09-09 18:24 UTC (permalink / raw)
  To: Alistair Francis; +Cc: Peter Crosthwaite, QEMU Developers, Konstanty Bialkowski

On 9 September 2014 09:23, Alistair Francis <alistair23@gmail.com> wrote:
> This patch series adds the Netduino 2 Machine to QEMU
>
> Information on the board is avalible at:
> http://www.netduino.com/netduino2/specs.htm
>
> The git tree can be found at:
> https://github.com/alistair23/qemu/tree/netduino2.1
>
> This is a fully implemented machine, except for the hack
> changes that have been made to armv7_init. See that individual
> patch for more information

Most significantly, this is Cortex-M3 based, which
sidesteps the awkward questions about whether we need
to implement the M4 floating point. Cool.

thanks
-- PMM

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

* Re: [Qemu-devel] [RFC v1 0/6] Netduino 2 Machine Model
  2014-09-09 18:24 ` [Qemu-devel] [RFC v1 0/6] Netduino 2 Machine Model Peter Maydell
@ 2014-09-09 23:31   ` Alistair Francis
  0 siblings, 0 replies; 25+ messages in thread
From: Alistair Francis @ 2014-09-09 23:31 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Peter Crosthwaite, QEMU Developers, Konstanty Bialkowski

On Wed, Sep 10, 2014 at 4:24 AM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 9 September 2014 09:23, Alistair Francis <alistair23@gmail.com> wrote:
>> This patch series adds the Netduino 2 Machine to QEMU
>>
>> Information on the board is avalible at:
>> http://www.netduino.com/netduino2/specs.htm
>>
>> The git tree can be found at:
>> https://github.com/alistair23/qemu/tree/netduino2.1
>>
>> This is a fully implemented machine, except for the hack
>> changes that have been made to armv7_init. See that individual
>> patch for more information
>
> Most significantly, this is Cortex-M3 based, which
> sidesteps the awkward questions about whether we need
> to implement the M4 floating point. Cool.

Yeah and it is almost exactly the same, at least for what I'm
interested in

Thanks,

Alistair

>
> thanks
> -- PMM

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

* Re: [Qemu-devel] [RFC v1 4/6] target_arm: Update armv7_init to support more parameters
  2014-09-09 13:59     ` Peter Maydell
@ 2014-09-09 23:39       ` Alistair Francis
  2014-09-10 12:01         ` Peter Crosthwaite
  0 siblings, 1 reply; 25+ messages in thread
From: Alistair Francis @ 2014-09-09 23:39 UTC (permalink / raw)
  To: Peter Maydell
  Cc: Konstanty Bialkowski, Peter Crosthwaite, Martin Galvan,
	qemu-devel@nongnu.org Developers

On Tue, Sep 9, 2014 at 11:59 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
> On 9 September 2014 14:35, Peter Crosthwaite
> <peter.crosthwaite@xilinx.com> wrote:
>> Does ARMv7M actually mandate the existence of RAM and flash like this
>> at all?
>
> No. It does have a well defined address map that pretty
> strongly suggests that you ought to have flash and RAM
> at certain addresses, but the flash and RAM are not part
> of the CPU core itself.
>
> (Bitbanding, on the other hand, is part of the CPU core
> and the memory region setup for it should stay in this
> function.)
>
>> Given the complex setup of STM (with the memory aliases etc)
>> I'm now of the belief that all RAM and FLASH init should be handled by
>> the SoC level.
>
> Agreed.

That makes everything so much easier. I was stuck at how to do the
memory aliasing.
I will move the memory region inits out of the function and put them into
the SoC level.

Is everyone happy enough with then using the armv7_init function as I
have in this
patch (except with out the Flash and SRAM parts)? So both Stellaris
and STM32F205
call the function. The only change from the current implementation
would be the number
of interrupt lines, which would become a parameter.

Thanks,

Alistair

>
> -- PMM

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

* Re: [Qemu-devel] [RFC v1 4/6] target_arm: Update armv7_init to support more parameters
  2014-09-09 14:03     ` Martin Galvan
@ 2014-09-09 23:43       ` Alistair Francis
  2014-09-10 12:32         ` Martin Galvan
  0 siblings, 1 reply; 25+ messages in thread
From: Alistair Francis @ 2014-09-09 23:43 UTC (permalink / raw)
  To: Martin Galvan
  Cc: Peter Maydell, Peter Crosthwaite,
	qemu-devel@nongnu.org Developers, Konstanty Bialkowski

On Wed, Sep 10, 2014 at 12:03 AM, Martin Galvan
<martin.galvan@tallertechnologies.com> wrote:
>>> @@ -259,7 +272,13 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory,
>>>      vmstate_register_ram_global(hack);
>>>      memory_region_add_subregion(system_memory, 0xfffff000, hack);
>>>
>>> -    qemu_register_reset(armv7m_reset, cpu);
>>> +    reset_args = (ARMV7MResetArgs) {
>>> +        .cpu = cpu,
>>> +        .reset_pc = entry,
>>> +        .reset_sp = (0x20000000 + ((192 * 1024) * 2)/3),
>>
>> Why is the manual sp setting needed? I thought the V7M specific CPU
>> reset code handled this? Does Martins ARMv7M ROM reset patch help by
>> any chance?
>>
>> Regards,
>> Peter
>
> Indeed, I don't think that would be necessary with my patch. What are
> those hardcoded magic numbers?

The hard coded numbers are there basically there because they worked at
one point and I haven't removed them yet. There is also no memory aliasing,
so this gets around out of memory access errors from QEMU.

I haven't had to chance to try your patch yet Martin, but hopefully it removes
the need for any of the reset changes I made.

Thanks,

Alistair

>
> --
>
>
> Martín Galván
>
> Software Engineer
>
> Taller Technologies Argentina
>
>
> San Lorenzo 47, 3rd Floor, Office 5
>
> Córdoba, Argentina
>
> Phone: 54 351 4217888 / +54 351 4218211

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

* Re: [Qemu-devel] [RFC v1 1/6] stm32f205_timer: Add the stm32f205 SoC Timer2 to 5
  2014-09-09 12:44   ` Peter Crosthwaite
@ 2014-09-09 23:52     ` Alistair Francis
  2014-09-10 12:07       ` Peter Crosthwaite
  0 siblings, 1 reply; 25+ messages in thread
From: Alistair Francis @ 2014-09-09 23:52 UTC (permalink / raw)
  To: Peter Crosthwaite
  Cc: Peter Maydell, qemu-devel@nongnu.org Developers, Konstanty Bialkowski

On Tue, Sep 9, 2014 at 10:44 PM, Peter Crosthwaite
<peter.crosthwaite@xilinx.com> wrote:
> On Tue, Sep 9, 2014 at 6:23 PM, Alistair Francis <alistair23@gmail.com> wrote:
>> This patch adds the stm32f205 timers: TIM2, TIM3, TIM4 and TIM5
>> to QEMU.
>>
>> Signed-off-by: Alistair Francis <alistair23@gmail.com>
>> ---
>> V2:
>>  - Small changes to functionality and style. Thanks to Peter C
>>  - Rename for the Netduino 2 and it's SoC
>>
>>  default-configs/arm-softmmu.mak    |   1 +
>>  hw/timer/Makefile.objs             |   1 +
>>  hw/timer/stm32f205_timer.c         | 334 +++++++++++++++++++++++++++++++++++++
>>  include/hw/timer/stm32f205_timer.h |  84 ++++++++++
>>  4 files changed, 420 insertions(+)
>>  create mode 100644 hw/timer/stm32f205_timer.c
>>  create mode 100644 include/hw/timer/stm32f205_timer.h
>>
>> diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
>> index f3513fa..8550084 100644
>> --- a/default-configs/arm-softmmu.mak
>> +++ b/default-configs/arm-softmmu.mak
>> @@ -78,6 +78,7 @@ CONFIG_NSERIES=y
>>  CONFIG_REALVIEW=y
>>  CONFIG_ZAURUS=y
>>  CONFIG_ZYNQ=y
>> +CONFIG_NETDUINO2=y
>>
>
> I think we were moving aware from SoC level shared configs, i.e. it's
> ok to have a confing per-dev in the arm-softmmu defconfig. You also
> want to avoid tying the device (and the SoC) to netduino as much as
> possible so even if CONFIG_NETDUINO existed it would simply set
> another config for STM etc. Easiest to just go flat with one config
> per dev (the ZYNQ example right above does do it wrong too :( ).

Ok, I will add a config for each device

>
>>  CONFIG_VERSATILE_PCI=y
>>  CONFIG_VERSATILE_I2C=y
>> diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
>> index 2c86c3d..ce68c4a 100644
>> --- a/hw/timer/Makefile.objs
>> +++ b/hw/timer/Makefile.objs
>> @@ -17,6 +17,7 @@ common-obj-$(CONFIG_IMX) += imx_epit.o
>>  common-obj-$(CONFIG_IMX) += imx_gpt.o
>>  common-obj-$(CONFIG_LM32) += lm32_timer.o
>>  common-obj-$(CONFIG_MILKYMIST) += milkymist-sysctl.o
>> +common-obj-$(CONFIG_NETDUINO2) += stm32f205_timer.o
>>
>>  obj-$(CONFIG_EXYNOS4) += exynos4210_mct.o
>>  obj-$(CONFIG_EXYNOS4) += exynos4210_pwm.o
>> diff --git a/hw/timer/stm32f205_timer.c b/hw/timer/stm32f205_timer.c
>> new file mode 100644
>> index 0000000..bbeaf6b
>> --- /dev/null
>> +++ b/hw/timer/stm32f205_timer.c
>> @@ -0,0 +1,334 @@
>> +/*
>> + * STM32F205xx Timer 2 to 5
>> + *
>
> Looking at the TRM i notice some of the other timers may be similar.
> Are TIM9-14 potentially modellable with a slight parameterisation of
> this?
>
> I think its ok in first series to limit functionality to TIM2-5 but
> you should soften the naming, probably just to stm32f205_timer
> throughout (removing all ref to TIM2-5) and leave this 2-5 1/8 9-13
> configury to the SoC level.

I haven't looked at the other timers yet, I think they are all very similar.
Ok, I will soften the naming

>
>> + * 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 "hw/timer/stm32f205_timer.h"
>> +
>> +#ifndef ST_TIM2_5_ERR_DEBUG
>> +#define ST_TIM2_5_ERR_DEBUG 0
>> +#endif
>> +
>> +#define DB_PRINT_L(lvl, fmt, args...) do { \
>> +    if (ST_TIM2_5_ERR_DEBUG >= lvl) { \
>> +        fprintf(stderr, "stm32f205xx_timer: %s:" fmt, __func__, ## args); \
>
> qemu_log()

Yep

>
>> +    } \
>> +} while (0);
>> +
>> +#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
>> +
>> +static void stm32f205xx_timer_update(Stm32f205TimerState *s)
>> +{
>> +    s->tim_sr |= 1;
>> +    qemu_irq_pulse(s->irq);
>> +}
>
> This only serves the purpose of interrupt assertion on the timer
> callback below and is single use. Just inline it.

Ok, will do

>
>> +
>> +static void stm32f205xx_timer_interrupt(void *opaque)
>> +{
>> +    Stm32f205TimerState *s = (Stm32f205TimerState *)opaque;
>> +
>
> No explicit cast needed.

Will fix all

>
>> +    DB_PRINT("Interrupt in: %s\n", __func__);
>> +
>> +    if (s->tim_dier == 0x01 && s->tim_cr1 & TIM_CR1_CEN) {
>
> The UIE bit of dier is only a single bit so you should use a mask and
> macro (just like with & TIM_CR1_CEN).

Yep, I don't know why that isn't

>
>> +        stm32f205xx_timer_update(s);
>> +    }
>> +}
>> +
>> +static uint32_t stm32f205xx_timer_get_count(Stm32f205TimerState *s)
>> +{
>> +    int64_t now = qemu_clock_get_ns(rtc_clock);
>
> Why use the RTC rather than the virtual clock? Most timer use the
> virtual unless they are explicitly an RTC device (does TIMx have RTC
> capability?)

The timer I used as an example did this. I'll check the data sheet
and see if I can change it to virtual

>
>> +    return s->tick_offset + now / get_ticks_per_sec();
>> +}
>> +
>> +static void stm32f205xx_timer_set_alarm(Stm32f205TimerState *s)
>> +{
>> +    uint32_t ticks;
>> +
>> +    DB_PRINT("Alarm raised in: %s at 0x%x\n", __func__, s->tim_cr1);
>> +
>> +    ticks = s->tim_arr - stm32f205xx_timer_get_count(s)/
>> +                         (s->tim_psc + 1);
>> +    DB_PRINT("Alarm set in %u ticks\n", ticks);
>> +
>> +    if (ticks == 0) {
>> +        timer_del(s->timer);
>> +        stm32f205xx_timer_interrupt(s);
>> +    } else {
>> +        int64_t now = qemu_clock_get_ns(rtc_clock) / get_ticks_per_sec();
>
> You should avoid two now calculations in the one callback. You have
> already crunched a now in timer_get_count() above and you do it again
> here. As timer_get_count is low (single?) use you can just inline to
> get now as a calculate-once local var.

Will fix

>
>> +        timer_mod(s->timer, now + (int64_t)ticks);
>> +        DB_PRINT("Wait Time: 0x%x\n", (uint32_t) (now + ticks));
>> +    }
>> +}
>> +
>> +static void stm32f205xx_timer_reset(DeviceState *dev)
>> +{
>> +    struct Stm32f205TimerState *s = STM32F205xxTIMER(dev);
>> +
>
> No struct needed.

Will fix

>
>> +    s->tim_cr1 = 0;
>> +    s->tim_cr2 = 0;
>> +    s->tim_smcr = 0;
>> +    s->tim_dier = 0;
>> +    s->tim_sr = 0;
>> +    s->tim_egr = 0;
>> +    s->tim_ccmr1 = 0;
>> +    s->tim_ccmr2 = 0;
>> +    s->tim_ccer = 0;
>> +    s->tim_cnt = 0;
>> +    s->tim_psc = 0;
>> +    s->tim_arr = 0;
>> +    s->tim_ccr1 = 0;
>> +    s->tim_ccr2 = 0;
>> +    s->tim_ccr3 = 0;
>> +    s->tim_ccr4 = 0;
>> +    s->tim_dcr = 0;
>> +    s->tim_dmar = 0;
>> +    s->tim_or = 0;
>> +}
>> +
>> +static uint64_t stm32f205xx_timer_read(void *opaque, hwaddr offset,
>> +                           unsigned size)
>> +{
>> +    Stm32f205TimerState *s = (Stm32f205TimerState *)opaque;
>> +
>
> No explicit cast.
>
>> +    DB_PRINT("Read 0x%x\n", (uint) offset);
>
> HWADDR_PRIx instead of cast.

What do you mean by HWADDR_PRIx?

>
>> +
>> +    switch (offset) {
>> +    case TIM_CR1:
>> +        return s->tim_cr1;
>> +    case TIM_CR2:
>> +        return s->tim_cr2;
>> +    case TIM_SMCR:
>> +        return s->tim_smcr;
>> +    case TIM_DIER:
>> +        return s->tim_dier;
>> +    case TIM_SR:
>> +        return s->tim_sr;
>> +    case TIM_EGR:
>> +        return s->tim_egr;
>> +    case TIM_CCMR1:
>> +        return s->tim_ccmr1;
>> +    case TIM_CCMR2:
>> +        return s->tim_ccmr2;
>> +    case TIM_CCER:
>> +        return s->tim_ccer;
>> +    case TIM_CNT:
>> +        return s->tim_cnt;
>> +    case TIM_PSC:
>> +        return s->tim_psc;
>> +    case TIM_ARR:
>> +        return s->tim_arr;
>> +    case TIM_CCR1:
>> +        return s->tim_ccr1;
>> +    case TIM_CCR2:
>> +        return s->tim_ccr2;
>> +    case TIM_CCR3:
>> +        return s->tim_ccr3;
>> +    case TIM_CCR4:
>> +        return s->tim_ccr4;
>> +    case TIM_DCR:
>> +        return s->tim_dcr;
>> +    case TIM_DMAR:
>> +        return s->tim_dmar;
>> +    case TIM_OR:
>> +        return s->tim_or;
>> +    default:
>> +        qemu_log_mask(LOG_GUEST_ERROR,
>> +                      "STM32F205xx_timer2_5_write: Bad offset %x\n",
>> +                      (int) offset);
>
> same.
>
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>> +static void stm32f205xx_timer_write(void *opaque, hwaddr offset,
>> +                        uint64_t val64, unsigned size)
>> +{
>> +    Stm32f205TimerState *s = (Stm32f205TimerState *)opaque;
>> +    uint32_t value = (uint32_t) val64;
>
> Casts not needed.
>
>> +
>> +    DB_PRINT("Write 0x%x, 0x%x\n", value, (uint) offset);
>> +
>> +    switch (offset) {
>> +    case TIM_CR1:
>> +        s->tim_cr1 = value;
>> +        return;
>> +    case TIM_CR2:
>> +        s->tim_cr2 = value;
>> +        return;
>> +    case TIM_SMCR:
>> +        s->tim_smcr = value;
>> +        return;
>> +    case TIM_DIER:
>> +        s->tim_dier = value;
>> +        return;
>> +    case TIM_SR:
>> +        s->tim_sr &= value;
>> +        stm32f205xx_timer_set_alarm(s);
>> +        return;
>> +    case TIM_EGR:
>> +        s->tim_egr = value;
>> +        return;
>> +    case TIM_CCMR1:
>> +        s->tim_ccmr1 = value;
>> +        return;
>> +    case TIM_CCMR2:
>> +        s->tim_ccmr2 = value;
>> +        return;
>> +    case TIM_CCER:
>> +        s->tim_ccer = value;
>> +        return;
>> +    case TIM_CNT:
>> +        s->tim_cnt = value;
>> +        stm32f205xx_timer_set_alarm(s);
>> +        return;
>> +    case TIM_PSC:
>> +        s->tim_psc = value;
>> +        return;
>> +    case TIM_ARR:
>> +        s->tim_arr = value;
>> +        stm32f205xx_timer_set_alarm(s);
>> +        return;
>> +    case TIM_CCR1:
>> +        s->tim_ccr1 = value;
>> +        return;
>> +    case TIM_CCR2:
>> +        s->tim_ccr2 = value;
>> +        return;
>> +    case TIM_CCR3:
>> +        s->tim_ccr3 = value;
>> +        return;
>> +    case TIM_CCR4:
>> +        s->tim_ccr4 = value;
>> +        return;
>> +    case TIM_DCR:
>> +        s->tim_dcr = value;
>> +        return;
>> +    case TIM_DMAR:
>> +        s->tim_dmar = value;
>> +        return;
>> +    case TIM_OR:
>> +        s->tim_or = value;
>> +        return;
>> +    default:
>> +        qemu_log_mask(LOG_GUEST_ERROR,
>> +                      "STM32F205xx_timer2_5_write: Bad offset %x\n",
>> +                      (int) offset);
>> +    }
>> +}
>> +
>> +static const MemoryRegionOps stm32f205xx_timer_ops = {
>> +    .read = stm32f205xx_timer_read,
>> +    .write = stm32f205xx_timer_write,
>> +    .endianness = DEVICE_NATIVE_ENDIAN,
>> +};
>> +
>> +static void stm32f205xx_timer_init(Object *obj)
>> +{
>> +    Stm32f205TimerState *s = STM32F205xxTIMER(obj);
>> +    struct tm tm;
>> +
>> +    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
>> +
>> +    memory_region_init_io(&s->iomem, obj, &stm32f205xx_timer_ops, s,
>> +                          "stm32f205xx_timer", 0x2000);
>> +    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
>> +
>> +    qemu_get_timedate(&tm, 0);
>> +    s->tick_offset = mktimegm(&tm) -
>> +        qemu_clock_get_ns(rtc_clock) / get_ticks_per_sec();
>> +
>> +    s->timer = timer_new_ns(rtc_clock, stm32f205xx_timer_interrupt, s);
>> +}
>> +
>> +static void stm32f205xx_timer_pre_save(void *opaque)
>> +{
>> +    Stm32f205TimerState *s = (Stm32f205TimerState *)opaque;
>> +
>> +    int64_t delta = qemu_clock_get_ns(rtc_clock) -
>> +                    qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
>
> Blank line here.
>
>> +    s->tick_offset_vmstate = s->tick_offset + delta / get_ticks_per_sec();
>> +}
>> +
>> +static int stm32f205xx_timer_post_load(void *opaque, int version_id)
>> +{
>> +    Stm32f205TimerState *s = (Stm32f205TimerState *)opaque;
>> +
>> +    int64_t delta = qemu_clock_get_ns(rtc_clock) -
>> +                    qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
>
> Blank line here.
>
>> +    s->tick_offset = s->tick_offset_vmstate - delta / get_ticks_per_sec();
>> +    stm32f205xx_timer_set_alarm(s);
>> +    return 0;
>> +}
>> +
>> +static const VMStateDescription vmstate_stm32f205xx_timer = {
>> +    .name = "stm32f205xx_timer",
>> +    .version_id = 1,
>> +    .minimum_version_id = 1,
>> +    .pre_save = stm32f205xx_timer_pre_save,
>> +    .post_load = stm32f205xx_timer_post_load,
>> +    .fields = (VMStateField[]) {
>> +        VMSTATE_UINT32(tick_offset_vmstate, Stm32f205TimerState),
>> +        VMSTATE_UINT32(tim_cr1, Stm32f205TimerState),
>> +        VMSTATE_UINT32(tim_cr2, Stm32f205TimerState),
>> +        VMSTATE_UINT32(tim_smcr, Stm32f205TimerState),
>> +        VMSTATE_UINT32(tim_dier, Stm32f205TimerState),
>> +        VMSTATE_UINT32(tim_sr, Stm32f205TimerState),
>> +        VMSTATE_UINT32(tim_egr, Stm32f205TimerState),
>> +        VMSTATE_UINT32(tim_ccmr1, Stm32f205TimerState),
>> +        VMSTATE_UINT32(tim_ccmr1, Stm32f205TimerState),
>> +        VMSTATE_UINT32(tim_ccer, Stm32f205TimerState),
>> +        VMSTATE_UINT32(tim_cnt, Stm32f205TimerState),
>> +        VMSTATE_UINT32(tim_psc, Stm32f205TimerState),
>> +        VMSTATE_UINT32(tim_arr, Stm32f205TimerState),
>> +        VMSTATE_UINT32(tim_ccr1, Stm32f205TimerState),
>> +        VMSTATE_UINT32(tim_ccr2, Stm32f205TimerState),
>> +        VMSTATE_UINT32(tim_ccr3, Stm32f205TimerState),
>> +        VMSTATE_UINT32(tim_ccr4, Stm32f205TimerState),
>> +        VMSTATE_UINT32(tim_dcr, Stm32f205TimerState),
>> +        VMSTATE_UINT32(tim_dmar, Stm32f205TimerState),
>> +        VMSTATE_UINT32(tim_or, Stm32f205TimerState),
>> +        VMSTATE_END_OF_LIST()
>> +    }
>> +};
>> +
>> +static void stm32f205xx_timer_class_init(ObjectClass *klass, void *data)
>> +{
>> +    DeviceClass *dc = DEVICE_CLASS(klass);
>> +
>> +    dc->vmsd = &vmstate_stm32f205xx_timer;
>> +    dc->reset = stm32f205xx_timer_reset;
>> +}
>> +
>> +static const TypeInfo stm32f205xx_timer_info = {
>> +    .name          = TYPE_STM32F205_TIMER,
>> +    .parent        = TYPE_SYS_BUS_DEVICE,
>> +    .instance_size = sizeof(Stm32f205TimerState),
>> +    .instance_init = stm32f205xx_timer_init,
>> +    .class_init    = stm32f205xx_timer_class_init,
>> +};
>> +
>> +static void stm32f205xx_timer_register_types(void)
>> +{
>> +    type_register_static(&stm32f205xx_timer_info);
>> +}
>> +
>> +type_init(stm32f205xx_timer_register_types)
>> diff --git a/include/hw/timer/stm32f205_timer.h b/include/hw/timer/stm32f205_timer.h
>> new file mode 100644
>> index 0000000..b8ba1ad
>> --- /dev/null
>> +++ b/include/hw/timer/stm32f205_timer.h
>> @@ -0,0 +1,84 @@
>> +/*
>> + * STM32F205xx Timer 2 to 5
>> + *
>> + * 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 "hw/sysbus.h"
>> +#include "qemu/timer.h"
>> +#include "sysemu/sysemu.h"
>> +
>> +#define TIM_CR1      0x00
>> +#define TIM_CR2      0x04
>> +#define TIM_SMCR     0x08
>> +#define TIM_DIER     0x0C
>> +#define TIM_SR       0x10
>> +#define TIM_EGR      0x14
>> +#define TIM_CCMR1    0x18
>> +#define TIM_CCMR2    0x1C
>> +#define TIM_CCER     0x20
>> +#define TIM_CNT      0x24
>> +#define TIM_PSC      0x28
>> +#define TIM_ARR      0x2C
>> +#define TIM_CCR1     0x34
>> +#define TIM_CCR2     0x38
>> +#define TIM_CCR3     0x3C
>> +#define TIM_CCR4     0x40
>> +#define TIM_DCR      0x48
>> +#define TIM_DMAR     0x4C
>> +#define TIM_OR       0x50
>> +
>> +#define TIM_CR1_CEN   1
>> +
>> +#define TYPE_STM32F205_TIMER "stm32f205xx-timer"
>> +#define STM32F205xxTIMER(obj) OBJECT_CHECK(Stm32f205TimerState, (obj), \
>> +                              TYPE_STM32F205_TIMER)
>> +
>> +typedef struct Stm32f205TimerState {
>
> STM
>
> /*< private >*/
>
>> +    SysBusDevice parent_obj;
>> +
>
> /*< public >*/
>

Will do

Thanks,

Alistair

> Regards,
> Peter
>
>> +    MemoryRegion iomem;
>> +    QEMUTimer *timer;
>> +    qemu_irq irq;
>> +
>> +    uint32_t tick_offset_vmstate;
>> +    uint32_t tick_offset;
>> +
>> +    uint32_t tim_cr1;
>> +    uint32_t tim_cr2;
>> +    uint32_t tim_smcr;
>> +    uint32_t tim_dier;
>> +    uint32_t tim_sr;
>> +    uint32_t tim_egr;
>> +    uint32_t tim_ccmr1;
>> +    uint32_t tim_ccmr2;
>> +    uint32_t tim_ccer;
>> +    uint32_t tim_cnt;
>> +    uint32_t tim_psc;
>> +    uint32_t tim_arr;
>> +    uint32_t tim_ccr1;
>> +    uint32_t tim_ccr2;
>> +    uint32_t tim_ccr3;
>> +    uint32_t tim_ccr4;
>> +    uint32_t tim_dcr;
>> +    uint32_t tim_dmar;
>> +    uint32_t tim_or;
>> +} Stm32f205TimerState;
>> --
>> 1.9.1
>>
>>

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

* Re: [Qemu-devel] [RFC v1 5/6] stm32f205: Add the SoC
  2014-09-09 13:50   ` Peter Crosthwaite
@ 2014-09-10  7:31     ` Alistair Francis
  0 siblings, 0 replies; 25+ messages in thread
From: Alistair Francis @ 2014-09-10  7:31 UTC (permalink / raw)
  To: Peter Crosthwaite
  Cc: Peter Maydell, qemu-devel@nongnu.org Developers, Konstanty Bialkowski

On Tue, Sep 9, 2014 at 11:50 PM, Peter Crosthwaite
<peter.crosthwaite@xilinx.com> wrote:
> On Tue, Sep 9, 2014 at 6:24 PM, Alistair Francis <alistair23@gmail.com> wrote:
>> This patch adds the stm32f205 SoC. This will be used by the
>> Netduino 2 to create a machine
>>
>> Signed-off-by: Alistair Francis <alistair23@gmail.com>
>> ---
>>
>>  hw/arm/Makefile.objs           |   2 +-
>>  hw/arm/stm32f205_soc.c         | 140 +++++++++++++++++++++++++++++++++++++++++
>>  include/hw/arm/stm32f205_soc.h |  61 ++++++++++++++++++
>>  3 files changed, 202 insertions(+), 1 deletion(-)
>>  create mode 100644 hw/arm/stm32f205_soc.c
>>  create mode 100644 include/hw/arm/stm32f205_soc.h
>>
>> diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
>> index 6088e53..673feef 100644
>> --- a/hw/arm/Makefile.objs
>> +++ b/hw/arm/Makefile.objs
>> @@ -2,7 +2,7 @@ obj-y += boot.o collie.o exynos4_boards.o gumstix.o highbank.o
>>  obj-$(CONFIG_DIGIC) += digic_boards.o
>>  obj-y += integratorcp.o kzm.o mainstone.o musicpal.o nseries.o
>>  obj-y += omap_sx1.o palm.o realview.o spitz.o stellaris.o
>> -obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o
>> +obj-y += tosa.o versatilepb.o vexpress.o virt.o xilinx_zynq.o z2.o stm32f205_soc.o
>
> New obj-y line.
>
>>
>>  obj-y += armv7m.o exynos4210.o pxa2xx.o pxa2xx_gpio.o pxa2xx_pic.o
>>  obj-$(CONFIG_DIGIC) += digic.o
>> diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c
>> new file mode 100644
>> index 0000000..da36f61
>> --- /dev/null
>> +++ b/hw/arm/stm32f205_soc.c
>> @@ -0,0 +1,140 @@
>> +/*
>> + * STM32F205xx 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 "hw/arm/stm32f205_soc.h"
>> +
>> +#define FLASH_BASE_ADDRESS 0x08000000
>> +#define FLASH_SIZE 1024
>> +#define SRAM_BASE_ADDRESS 0x20000000
>> +#define SRAM_SIZE 192
>> +
>> +static void stm32f205_soc_initfn(Object *obj)
>> +{
>> +    STM32F205State *s = STM32F205_SOC(obj);
>> +    int i;
>> +
>> +    object_initialize(&s->syscfg, sizeof(s->syscfg), TYPE_STM32F205_SYSCFG);
>> +    qdev_set_parent_bus(DEVICE(&s->syscfg), sysbus_get_default());
>> +
>> +    for (i = 0; i < 5; i++) {
>> +        object_initialize(&s->usart[i], sizeof(s->usart[i]),
>> +                          TYPE_STM32F205_USART);
>> +        qdev_set_parent_bus(DEVICE(&s->usart[i]), sysbus_get_default());
>> +    }
>> +
>> +    for (i = 0; i < 4; i++) {
>> +        object_initialize(&s->timer[i], sizeof(s->timer[i]),
>> +                          TYPE_STM32F205_TIMER);
>> +        qdev_set_parent_bus(DEVICE(&s->timer[i]), sysbus_get_default());
>> +    }
>> +}
>> +
>> +static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp)
>> +{
>> +    static const uint32_t timer_addr[] = { 0x40000000, 0x40000400,
>> +        0x40000800, 0x40000C00 };
>
> You should add a comment about how you only model TIM2-5. This list is
> to grow significantly in a fuller implementation.
>
>> +    static const uint32_t usart_addr[] = { 0x40011000, 0x40004400,
>> +        0x40004800, 0x40004C00, 0x40005000, 0x40011400 };
>> +
>
> Just put the static consts up top of the file so the are easily
> spotted as self documentation.
>
>> +    static const int timer_irq[] = {28, 29, 30, 50};
>> +    static const int usart_irq[] = {37, 38, 39, 52, 53, 71, 82, 83};
>> +
>> +    STM32F205State *s = STM32F205_SOC(dev_soc);
>> +    DeviceState *syscfgdev, *usartdev, *timerdev;
>> +    SysBusDevice *syscfgbusdev, *usartbusdev, *timerbusdev;
>> +    qemu_irq *pic;;
>> +    Error *err = NULL;
>> +    int i;
>> +
>> +    pic = armv7m_init(get_system_memory(),
>> +                      FLASH_SIZE, FLASH_BASE_ADDRESS, SRAM_SIZE, 96,
>> +                      s->kernel_filename, s->cpu_model);
>> +
>> +    /* System configuration controller */
>> +    syscfgdev = DEVICE(&s->syscfg);
>> +    syscfgdev->id = "stm32f205xx-syscfg";
>
> Why you need to set the legacy qdev id string? If its needed I would
> expect this to be init stage rather than realize.

That was just left it from testing, will remove.

>
>> +    object_property_set_bool(OBJECT(&s->syscfg), true, "realized", &err);
>> +    if (err != NULL) {
>> +        error_propagate(errp, err);
>> +        return;
>> +    }
>> +    syscfgbusdev = SYS_BUS_DEVICE(syscfgdev);
>> +    sysbus_mmio_map(syscfgbusdev, 0, 0x40013800);
>> +    sysbus_connect_irq(syscfgbusdev, 0, pic[71]);
>> +
>> +    /* Attach a UART (uses USART registers) and USART controllers */
>> +    for (i = 0; i < 5; i++) {
>> +        usartdev = DEVICE(&(s->usart[i]));
>> +        object_property_set_bool(OBJECT(&s->usart[i]), true, "realized", &err);
>> +        if (err != NULL) {
>> +            error_propagate(errp, err);
>> +            return;
>> +        }
>> +        usartbusdev = SYS_BUS_DEVICE(usartdev);
>> +        sysbus_mmio_map(usartbusdev, 0, usart_addr[i]);
>> +        sysbus_connect_irq(usartbusdev, 0, pic[usart_irq[i]]);
>> +    }
>> +
>> +    /* Timer 2 to 5 */
>> +    for (i = 0; i < 4; i++) {
>> +        timerdev = DEVICE(&(s->timer[i]));
>> +        object_property_set_bool(OBJECT(&s->timer[i]), true, "realized", &err);
>> +        if (err != NULL) {
>> +            error_propagate(errp, err);
>> +            return;
>> +        }
>> +        timerbusdev = SYS_BUS_DEVICE(timerdev);
>> +        sysbus_mmio_map(timerbusdev, 0, timer_addr[i]);
>> +        sysbus_connect_irq(timerbusdev, 0, pic[timer_irq[i]]);
>> +    }
>> +}
>> +
>> +static Property stm32f205_soc_properties[] = {
>> +    DEFINE_PROP_STRING("kernel-filename", STM32F205State, kernel_filename),
>> +    DEFINE_PROP_STRING("cpu-model", STM32F205State, cpu_model),
>
> Is it really configurable? You can drop cpu-model parameterisation
> unless STM have similar socs with different processor you are
> targetting?

It's not configurable, I just thought QEMU allowed the CPU to be specified

Thanks,

Alistair

>
>> +    DEFINE_PROP_END_OF_LIST(),
>> +};
>> +
>> +static void stm32f205_soc_class_init(ObjectClass *klass, void *data)
>> +{
>> +    DeviceClass *dc = DEVICE_CLASS(klass);
>> +
>> +    dc->realize = stm32f205_soc_realize;
>> +    dc->props = stm32f205_soc_properties;
>> +}
>> +
>> +static const TypeInfo stm32f205_soc_info = {
>> +    .name          = TYPE_STM32F205_SOC,
>> +    .parent        = TYPE_SYS_BUS_DEVICE,
>> +    .instance_size = sizeof(STM32F205State),
>> +    .instance_init = stm32f205_soc_initfn,
>> +    .class_init    = stm32f205_soc_class_init,
>> +};
>> +
>> +static void stm32f205_soc_types(void)
>> +{
>> +    type_register_static(&stm32f205_soc_info);
>> +}
>> +
>> +type_init(stm32f205_soc_types)
>> diff --git a/include/hw/arm/stm32f205_soc.h b/include/hw/arm/stm32f205_soc.h
>> new file mode 100644
>> index 0000000..d989b10
>> --- /dev/null
>> +++ b/include/hw/arm/stm32f205_soc.h
>> @@ -0,0 +1,61 @@
>> +/*
>> + * STM32F205xx 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_STM32F205SOC_H
>> +#define HW_ARM_STM32F205SOC_H
>> +
>> +#include "hw/sysbus.h"
>> +#include "hw/arm/arm.h"
>> +#include "hw/ssi.h"
>> +#include "hw/devices.h"
>> +#include "qemu/timer.h"
>> +#include "net/net.h"
>> +#include "elf.h"
>> +#include "hw/loader.h"
>> +#include "hw/boards.h"
>> +#include "exec/address-spaces.h"
>> +#include "qemu/error-report.h"
>> +#include "sysemu/qtest.h"
>> +#include "hw/misc/stm32f205_syscfg.h"
>> +#include "hw/timer/stm32f205_timer.h"
>> +#include "hw/char/stm32f205_usart.h"
>> +
>> +#define TYPE_STM32F205_SOC "stm32f205_soc"
>> +#define STM32F205_SOC(obj) \
>> +    OBJECT_CHECK(STM32F205State, (obj), TYPE_STM32F205_SOC)
>> +
>> +typedef struct STM32F205State {
>> +    /*< private >*/
>> +    SysBusDevice parent_obj;
>> +    /*< public >*/
>> +
>> +    char *kernel_filename;
>> +    char *cpu_model;
>> +
>> +    Stm32f205SyscfgState syscfg;
>> +    Stm32f205UsartState usart[5];
>> +    Stm32f205TimerState timer[5];
>
> You can macrofiy these magic "5"s. STM_NUM_UARTS etc.
>
> Regards,
> Peter
>
>> +} STM32F205State;
>> +
>> +#endif
>> --
>> 1.9.1
>>
>>

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

* Re: [Qemu-devel] [RFC v1 2/6] stm32f205_USART: Add the stm32f205 SoC USART Controller
  2014-09-09 13:21   ` Peter Crosthwaite
@ 2014-09-10 10:55     ` Alistair Francis
  0 siblings, 0 replies; 25+ messages in thread
From: Alistair Francis @ 2014-09-10 10:55 UTC (permalink / raw)
  To: Peter Crosthwaite
  Cc: Peter Maydell, qemu-devel@nongnu.org Developers, Konstanty Bialkowski

On Tue, Sep 9, 2014 at 11:21 PM, Peter Crosthwaite
<peter.crosthwaite@xilinx.com> wrote:
> On Tue, Sep 9, 2014 at 6:24 PM, Alistair Francis <alistair23@gmail.com> wrote:
>> This patch adds the stm32f205 USART controller
>> (UART also uses the same controller).
>>
>> Signed-off-by: Alistair Francis <alistair23@gmail.com>
>> ---
>> V2:
>>  - Small changes thanks to Peter C
>>  - Rename for the Netduino 2 and it's SoC
>>
>>  hw/char/Makefile.objs             |   1 +
>>  hw/char/stm32f205_usart.c         | 205 ++++++++++++++++++++++++++++++++++++++
>>  include/hw/char/stm32f205_usart.h |  64 ++++++++++++
>>  3 files changed, 270 insertions(+)
>>  create mode 100644 hw/char/stm32f205_usart.c
>>  create mode 100644 include/hw/char/stm32f205_usart.h
>>
>> diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
>> index 317385d..b1f7e80 100644
>> --- a/hw/char/Makefile.objs
>> +++ b/hw/char/Makefile.objs
>> @@ -15,6 +15,7 @@ obj-$(CONFIG_OMAP) += omap_uart.o
>>  obj-$(CONFIG_SH4) += sh_serial.o
>>  obj-$(CONFIG_PSERIES) += spapr_vty.o
>>  obj-$(CONFIG_DIGIC) += digic-uart.o
>> +obj-$(CONFIG_NETDUINO2) += stm32f205_usart.o
>>
>>  common-obj-$(CONFIG_ETRAXFS) += etraxfs_ser.o
>>  common-obj-$(CONFIG_ISA_DEBUG) += debugcon.o
>> diff --git a/hw/char/stm32f205_usart.c b/hw/char/stm32f205_usart.c
>> new file mode 100644
>> index 0000000..c042b4b
>> --- /dev/null
>> +++ b/hw/char/stm32f205_usart.c
>> @@ -0,0 +1,205 @@
>> +/*
>> + * STM32F205xx USART
>> + *
>> + * 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 "hw/char/stm32f205_usart.h"
>> +
>> +#ifndef STM_USART_ERR_DEBUG
>> +#define STM_USART_ERR_DEBUG 0
>> +#endif
>> +
>> +#define DB_PRINT_L(lvl, fmt, args...) do { \
>> +    if (STM_USART_ERR_DEBUG >= lvl) { \
>> +        fprintf(stderr, "stm32f205xx_usart: %s:" fmt, __func__, ## args); \
>> +    } \
>> +} while (0);
>> +
>> +#define DB_PRINT(fmt, args...) DB_PRINT_L(1, fmt, ## args)
>> +
>> +static int usart_can_receive(void *opaque)
>> +{
>> +    Stm32f205UsartState *s = opaque;
>> +
>> +    if (s->usart_cr1 & USART_CR1_UE && s->usart_cr1 & USART_CR1_TE) {
>> +        return 1;
>> +    }
>
> So it's usual to block a UART on the fifo filling rather than the
> master enable switches. Corking the fifo on the master enable means
> QEMU will buffer UART input long-term until the guest turns the fifo
> on, where in reality the hardware should just drop the chars. We
> should do something similar.
>
> The reason (as far as I know anyways) for can_recieve and giving qemu
> serial false closed-loop implementation (network has it too) is to
> deal with large amounts of instantaneous data in situations where the
> real-time delays on real-hardware would give natural bandwidth
> limiting. Thus the main app of can-recieve 0-return is 'your pumping
> serial data way too fast such that my fifo is full and real hardware
> would never go that fast'.

Ok, that makes sense. I can add blocking based on the USART_SR_RXNE bit

>
> Also, did you me the RE bit rather than the TE bit?

Yes, good spot

>
>> +
>> +    return 0;
>> +}
>> +
>> +static void usart_receive(void *opaque, const uint8_t *buf, int size)
>> +{
>> +    Stm32f205UsartState *s = opaque;
>> +
>> +    s->usart_dr = *buf;
>> +
>> +    s->usart_sr |= USART_SR_RXNE;
>> +
>
> This might be a good condition to block can_recieve on - the
> USART_SR_RXNE. And if the enables are off, just drop the char.
>
>> +    if (s->usart_cr1 & USART_CR1_RXNEIE) {
>> +        qemu_set_irq(s->irq, 1);
>> +    }
>> +
>> +    DB_PRINT("Receiving: %c\n", s->usart_dr);
>> +}
>> +
>> +static void usart_reset(DeviceState *dev)
>
> stm32f..._ prefix to function name. For consistency and makes gdb
> breakpoints slightly easier if function names are globally unique.

Yep, will fix in all patches

>
>> +{
>> +    Stm32f205UsartState *s = STM32F205xx_USART(dev);
>> +
>> +    s->usart_sr = 0x00C00000;
>> +    s->usart_dr = 0x00000000;
>> +    s->usart_brr = 0x00000000;
>> +    s->usart_cr1 = 0x00000000;
>> +    s->usart_cr2 = 0x00000000;
>> +    s->usart_cr3 = 0x00000000;
>> +    s->usart_gtpr = 0x00000000;
>> +}
>> +
>> +static uint64_t stm32f205xx_usart_read(void *opaque, hwaddr addr,
>> +                                    unsigned int size)
>> +{
>> +    Stm32f205UsartState *s = opaque;
>> +    uint64_t retvalue;
>> +
>> +    DB_PRINT("Read 0x%x\n", (uint) addr);
>> +
>> +    switch (addr) {
>> +    case USART_SR:
>> +        retvalue = s->usart_sr;
>> +        s->usart_sr &= (USART_SR_TC ^ 0xFFFF);
>
> This register seems to be a mix of clear-to-read, read-only and rsvd.
> Just use &= ~MASK to implement clear on read which look to be the
> intention here. I don't see the significance of bits 15 downto 0 and
> why they behave different to 31 downto 16 here?

Fixed

>
> This is probably also where you need to repoll for can_receive blocked
> chars as well (assuming you make condition change I recommended above.
>
>  qemu_chr_accept_input(s->chr)
>

Yep, will do

>> +        return retvalue;
>> +    case USART_DR:
>> +        DB_PRINT("Value: 0x%x, %c\n", s->usart_dr, (char) s->usart_dr);
>> +        s->usart_sr |= USART_SR_TXE;
>> +        return s->usart_dr & 0x3FF;
>> +    case USART_BRR:
>> +        return s->usart_brr;
>> +    case USART_CR1:
>> +        return s->usart_cr1;
>> +    case USART_CR2:
>> +        return s->usart_cr2;
>> +    case USART_CR3:
>> +        return s->usart_cr3;
>> +    case USART_GTPR:
>> +        return s->usart_gtpr;
>> +    default:
>> +        qemu_log_mask(LOG_GUEST_ERROR,
>> +                      "STM32F205xx_usart_read: Bad offset %x\n", (int)addr);
>> +        return 0;
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>> +static void stm32f205xx_usart_write(void *opaque, hwaddr addr,
>> +                       uint64_t val64, unsigned int size)
>> +{
>> +    Stm32f205UsartState *s = opaque;
>> +    uint32_t value = (uint32_t) val64;
>> +    unsigned char ch;
>> +
>> +    DB_PRINT("Write 0x%x, 0x%x\n", value, (uint) addr);
>> +
>> +    switch (addr) {
>> +    case USART_SR:
>> +        if (value <= 0x3FF) {
>> +            s->usart_sr = value;
>> +        } else {
>> +            s->usart_sr &= value;
>> +        }
>> +        return;
>> +    case USART_DR:
>> +        if (value < 0xF000) {
>> +            ch = value;
>> +            if (s->chr) {
>> +                qemu_chr_fe_write(s->chr, &ch, 1);
>
> If the backend gets busy this will drop chars. You can either
> implement the closed loop callbacks (kinda hard - check serial.c) or
> use qemu_chr_fe_write all to get a blocking implementation.
>

Thanks, I didn't know about that function

>> +            }
>> +            s->usart_sr |= USART_SR_TC;
>> +        }
>> +        return;
>> +    case USART_BRR:
>> +        s->usart_brr = value;
>> +        return;
>> +    case USART_CR1:
>> +        s->usart_cr1 = value;
>> +        return;
>> +    case USART_CR2:
>> +        s->usart_cr2 = value;
>> +        return;
>> +    case USART_CR3:
>> +        s->usart_cr3 = value;
>> +        return;
>> +    case USART_GTPR:
>> +        s->usart_gtpr = value;
>> +        return;
>> +    default:
>> +        qemu_log_mask(LOG_GUEST_ERROR,
>> +                      "STM32F205xx_usart_write: Bad offset %x\n", (int)addr);
>> +    }
>> +}
>> +
>> +static const MemoryRegionOps stm32f205xx_usart_ops = {
>> +    .read = stm32f205xx_usart_read,
>> +    .write = stm32f205xx_usart_write,
>> +    .endianness = DEVICE_NATIVE_ENDIAN,
>> +};
>> +
>> +static void stm32f205xx_usart_init(Object *obj)
>> +{
>> +    Stm32f205UsartState *s = STM32F205xx_USART(obj);
>> +
>> +    sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq);
>> +
>> +    memory_region_init_io(&s->mmio, obj, &stm32f205xx_usart_ops, s,
>> +                          TYPE_STM32F205_USART, 0x2000);
>> +    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
>> +
>> +    s->chr = qemu_char_get_next_serial();
>> +
>> +    if (s->chr) {
>> +        qemu_chr_add_handlers(s->chr, usart_can_receive, usart_receive,
>> +                              NULL, s);
>> +    }
>> +}
>> +
>> +static void stm32f205xx_usart_class_init(ObjectClass *klass, void *data)
>> +{
>> +    DeviceClass *dc = DEVICE_CLASS(klass);
>> +
>> +    dc->reset = usart_reset;
>> +}
>> +
>> +static const TypeInfo stm32f205xx_usart_info = {
>> +    .name          = TYPE_STM32F205_USART,
>> +    .parent        = TYPE_SYS_BUS_DEVICE,
>> +    .instance_size = sizeof(Stm32f205UsartState),
>> +    .instance_init = stm32f205xx_usart_init,
>> +    .class_init    = stm32f205xx_usart_class_init,
>> +};
>> +
>> +static void stm32f205xx_usart_register_types(void)
>> +{
>> +    type_register_static(&stm32f205xx_usart_info);
>> +}
>> +
>> +type_init(stm32f205xx_usart_register_types)
>> diff --git a/include/hw/char/stm32f205_usart.h b/include/hw/char/stm32f205_usart.h
>> new file mode 100644
>> index 0000000..ceb92b7
>> --- /dev/null
>> +++ b/include/hw/char/stm32f205_usart.h
>> @@ -0,0 +1,64 @@
>> +/*
>> + * STM32F205xx USART
>> + *
>> + * 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 "hw/sysbus.h"
>> +#include "sysemu/char.h"
>> +#include "hw/hw.h"
>> +
>> +#define USART_SR   0x00
>> +#define USART_DR   0x04
>> +#define USART_BRR  0x08
>> +#define USART_CR1  0x0C
>> +#define USART_CR2  0x10
>> +#define USART_CR3  0x14
>> +#define USART_GTPR 0x18
>> +
>> +#define USART_SR_TXE  (1 << 7)
>> +#define USART_SR_TC   (1 << 6)
>> +#define USART_SR_RXNE (1 << 5)
>> +
>> +#define USART_CR1_UE  (1 << 13)
>> +#define USART_CR1_RXNEIE  (1 << 5)
>> +#define USART_CR1_TE  (1 << 3)
>> +
>> +#define TYPE_STM32F205_USART "stm32f205xx-usart"
>> +#define STM32F205xx_USART(obj) \
>> +    OBJECT_CHECK(Stm32f205UsartState, (obj), TYPE_STM32F205_USART)
>> +
>> +typedef struct {
>
> /*< private >*/
>
>> +    SysBusDevice parent_obj;
>> +
>
> /*< public >*/
>
>> +    MemoryRegion mmio;
>> +
>> +    uint32_t usart_sr;
>> +    uint32_t usart_dr;
>> +    uint32_t usart_brr;
>> +    uint32_t usart_cr1;
>> +    uint32_t usart_cr2;
>> +    uint32_t usart_cr3;
>> +    uint32_t usart_gtpr;
>> +
>> +    CharDriverState *chr;
>> +    qemu_irq irq;
>> +} Stm32f205UsartState;
>
> STM
>
> A few general styling comments from prev patch (mainly a few casts)
> apply here as well.

Thanks,

Alistair

>
> Regards,
> Peter
>
>> --
>> 1.9.1
>>
>>

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

* Re: [Qemu-devel] [RFC v1 4/6] target_arm: Update armv7_init to support more parameters
  2014-09-09 23:39       ` Alistair Francis
@ 2014-09-10 12:01         ` Peter Crosthwaite
  0 siblings, 0 replies; 25+ messages in thread
From: Peter Crosthwaite @ 2014-09-10 12:01 UTC (permalink / raw)
  To: Alistair Francis
  Cc: qemu-devel@nongnu.org Developers, Peter Maydell,
	Konstanty Bialkowski, Martin Galvan

On Wed, Sep 10, 2014 at 9:39 AM, Alistair Francis <alistair23@gmail.com> wrote:
> On Tue, Sep 9, 2014 at 11:59 PM, Peter Maydell <peter.maydell@linaro.org> wrote:
>> On 9 September 2014 14:35, Peter Crosthwaite
>> <peter.crosthwaite@xilinx.com> wrote:
>>> Does ARMv7M actually mandate the existence of RAM and flash like this
>>> at all?
>>
>> No. It does have a well defined address map that pretty
>> strongly suggests that you ought to have flash and RAM
>> at certain addresses, but the flash and RAM are not part
>> of the CPU core itself.
>>
>> (Bitbanding, on the other hand, is part of the CPU core
>> and the memory region setup for it should stay in this
>> function.)
>>
>>> Given the complex setup of STM (with the memory aliases etc)
>>> I'm now of the belief that all RAM and FLASH init should be handled by
>>> the SoC level.
>>
>> Agreed.
>
> That makes everything so much easier. I was stuck at how to do the
> memory aliasing.
> I will move the memory region inits out of the function and put them into
> the SoC level.
>

Sounds ok to me.

Regards,
Peter

> Is everyone happy enough with then using the armv7_init function as I
> have in this
> patch (except with out the Flash and SRAM parts)? So both Stellaris
> and STM32F205
> call the function. The only change from the current implementation
> would be the number
> of interrupt lines, which would become a parameter.
>
> Thanks,
>
> Alistair
>
>>
>> -- PMM
>

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

* Re: [Qemu-devel] [RFC v1 1/6] stm32f205_timer: Add the stm32f205 SoC Timer2 to 5
  2014-09-09 23:52     ` Alistair Francis
@ 2014-09-10 12:07       ` Peter Crosthwaite
  2014-09-10 13:16         ` Alistair Francis
  0 siblings, 1 reply; 25+ messages in thread
From: Peter Crosthwaite @ 2014-09-10 12:07 UTC (permalink / raw)
  To: Alistair Francis
  Cc: Peter Maydell, qemu-devel@nongnu.org Developers, Konstanty Bialkowski

On Wed, Sep 10, 2014 at 9:52 AM, Alistair Francis <alistair23@gmail.com> wrote:
> On Tue, Sep 9, 2014 at 10:44 PM, Peter Crosthwaite
> <peter.crosthwaite@xilinx.com> wrote:
>> On Tue, Sep 9, 2014 at 6:23 PM, Alistair Francis <alistair23@gmail.com> wrote:
>>> This patch adds the stm32f205 timers: TIM2, TIM3, TIM4 and TIM5
>>> to QEMU.
>>>
>>> Signed-off-by: Alistair Francis <alistair23@gmail.com>
>>> ---
>>> V2:
>>>  - Small changes to functionality and style. Thanks to Peter C
>>>  - Rename for the Netduino 2 and it's SoC
>>>

>>> +#include "hw/timer/stm32f205_timer.h"
>>> +
>>> +    DB_PRINT("Read 0x%x\n", (uint) offset);
>>
>> HWADDR_PRIx instead of cast.
>
> What do you mean by HWADDR_PRIx?
>

If you want to use a hwaddr in printfery there is a special % format
for it. Here is an example:

hw/char/serial.c:    DPRINTF("read addr=0x%" HWADDR_PRIx "
val=0x%02x\n", addr, ret);

Regards,
Peter

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

* Re: [Qemu-devel] [RFC v1 4/6] target_arm: Update armv7_init to support more parameters
  2014-09-09 23:43       ` Alistair Francis
@ 2014-09-10 12:32         ` Martin Galvan
  2014-09-10 13:53           ` Alistair Francis
  0 siblings, 1 reply; 25+ messages in thread
From: Martin Galvan @ 2014-09-10 12:32 UTC (permalink / raw)
  To: Alistair Francis
  Cc: Peter Maydell, Peter Crosthwaite,
	qemu-devel@nongnu.org Developers, Konstanty Bialkowski

On Tue, Sep 9, 2014 at 8:43 PM, Alistair Francis <alistair23@gmail.com> wrote:
> On Wed, Sep 10, 2014 at 12:03 AM, Martin Galvan
> <martin.galvan@tallertechnologies.com> wrote:
>>>> @@ -259,7 +272,13 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory,
>>>>      vmstate_register_ram_global(hack);
>>>>      memory_region_add_subregion(system_memory, 0xfffff000, hack);
>>>>
>>>> -    qemu_register_reset(armv7m_reset, cpu);
>>>> +    reset_args = (ARMV7MResetArgs) {
>>>> +        .cpu = cpu,
>>>> +        .reset_pc = entry,
>>>> +        .reset_sp = (0x20000000 + ((192 * 1024) * 2)/3),
>>>
>>> Why is the manual sp setting needed? I thought the V7M specific CPU
>>> reset code handled this? Does Martins ARMv7M ROM reset patch help by
>>> any chance?
>>>
>>> Regards,
>>> Peter
>>
>> Indeed, I don't think that would be necessary with my patch. What are
>> those hardcoded magic numbers?
>
> The hard coded numbers are there basically there because they worked at
> one point and I haven't removed them yet. There is also no memory aliasing,
> so this gets around out of memory access errors from QEMU.
>
> I haven't had to chance to try your patch yet Martin, but hopefully it removes
> the need for any of the reset changes I made.

My patch deals with the initial MSP, PC and Thumb values not being set
correctly on reset. I don't know if it's in the main tree yet, but you
can see it here:

https://patchwork.ozlabs.org/patch/386497/

-- 

Martín Galván

Software Engineer

Taller Technologies Argentina


San Lorenzo 47, 3rd Floor, Office 5

Córdoba, Argentina

Phone: 54 351 4217888 / +54 351 4218211

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

* Re: [Qemu-devel] [RFC v1 1/6] stm32f205_timer: Add the stm32f205 SoC Timer2 to 5
  2014-09-10 12:07       ` Peter Crosthwaite
@ 2014-09-10 13:16         ` Alistair Francis
  0 siblings, 0 replies; 25+ messages in thread
From: Alistair Francis @ 2014-09-10 13:16 UTC (permalink / raw)
  To: Peter Crosthwaite
  Cc: Peter Maydell, qemu-devel@nongnu.org Developers, Konstanty Bialkowski

On Wed, Sep 10, 2014 at 10:07 PM, Peter Crosthwaite
<peter.crosthwaite@xilinx.com> wrote:
> On Wed, Sep 10, 2014 at 9:52 AM, Alistair Francis <alistair23@gmail.com> wrote:
>> On Tue, Sep 9, 2014 at 10:44 PM, Peter Crosthwaite
>> <peter.crosthwaite@xilinx.com> wrote:
>>> On Tue, Sep 9, 2014 at 6:23 PM, Alistair Francis <alistair23@gmail.com> wrote:
>>>> This patch adds the stm32f205 timers: TIM2, TIM3, TIM4 and TIM5
>>>> to QEMU.
>>>>
>>>> Signed-off-by: Alistair Francis <alistair23@gmail.com>
>>>> ---
>>>> V2:
>>>>  - Small changes to functionality and style. Thanks to Peter C
>>>>  - Rename for the Netduino 2 and it's SoC
>>>>
>
>>>> +#include "hw/timer/stm32f205_timer.h"
>>>> +
>>>> +    DB_PRINT("Read 0x%x\n", (uint) offset);
>>>
>>> HWADDR_PRIx instead of cast.
>>
>> What do you mean by HWADDR_PRIx?
>>
>
> If you want to use a hwaddr in printfery there is a special % format
> for it. Here is an example:
>
> hw/char/serial.c:    DPRINTF("read addr=0x%" HWADDR_PRIx "
> val=0x%02x\n", addr, ret);

I never knew that was there

Thanks,

Alistair

>
> Regards,
> Peter

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

* Re: [Qemu-devel] [RFC v1 4/6] target_arm: Update armv7_init to support more parameters
  2014-09-10 12:32         ` Martin Galvan
@ 2014-09-10 13:53           ` Alistair Francis
  0 siblings, 0 replies; 25+ messages in thread
From: Alistair Francis @ 2014-09-10 13:53 UTC (permalink / raw)
  To: Martin Galvan
  Cc: Peter Maydell, Peter Crosthwaite,
	qemu-devel@nongnu.org Developers, Konstanty Bialkowski

On Wed, Sep 10, 2014 at 10:32 PM, Martin Galvan
<martin.galvan@tallertechnologies.com> wrote:
> On Tue, Sep 9, 2014 at 8:43 PM, Alistair Francis <alistair23@gmail.com> wrote:
>> On Wed, Sep 10, 2014 at 12:03 AM, Martin Galvan
>> <martin.galvan@tallertechnologies.com> wrote:
>>>>> @@ -259,7 +272,13 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory,
>>>>>      vmstate_register_ram_global(hack);
>>>>>      memory_region_add_subregion(system_memory, 0xfffff000, hack);
>>>>>
>>>>> -    qemu_register_reset(armv7m_reset, cpu);
>>>>> +    reset_args = (ARMV7MResetArgs) {
>>>>> +        .cpu = cpu,
>>>>> +        .reset_pc = entry,
>>>>> +        .reset_sp = (0x20000000 + ((192 * 1024) * 2)/3),
>>>>
>>>> Why is the manual sp setting needed? I thought the V7M specific CPU
>>>> reset code handled this? Does Martins ARMv7M ROM reset patch help by
>>>> any chance?
>>>>
>>>> Regards,
>>>> Peter
>>>
>>> Indeed, I don't think that would be necessary with my patch. What are
>>> those hardcoded magic numbers?
>>
>> The hard coded numbers are there basically there because they worked at
>> one point and I haven't removed them yet. There is also no memory aliasing,
>> so this gets around out of memory access errors from QEMU.
>>
>> I haven't had to chance to try your patch yet Martin, but hopefully it removes
>> the need for any of the reset changes I made.
>
> My patch deals with the initial MSP, PC and Thumb values not being set
> correctly on reset. I don't know if it's in the main tree yet, but you
> can see it here:
>
> https://patchwork.ozlabs.org/patch/386497/

Thanks for that. It doesn't seem to completely fix my problem though.
I will continue to look into it tomorrow but it looks like rom_ptr() is
returning NULL and then the PC address is set to 0 instead
of 0x801328d (which is the ELF entry point). I can remove the hard
coded values from this patch though, thanks to your patch.

Thanks,

Alistair

>
> --
>
> Martín Galván
>
> Software Engineer
>
> Taller Technologies Argentina
>
>
> San Lorenzo 47, 3rd Floor, Office 5
>
> Córdoba, Argentina
>
> Phone: 54 351 4217888 / +54 351 4218211

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

end of thread, other threads:[~2014-09-10 13:54 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-09  8:23 [Qemu-devel] [RFC v1 0/6] Netduino 2 Machine Model Alistair Francis
2014-09-09  8:23 ` [Qemu-devel] [RFC v1 1/6] stm32f205_timer: Add the stm32f205 SoC Timer2 to 5 Alistair Francis
2014-09-09 12:44   ` Peter Crosthwaite
2014-09-09 23:52     ` Alistair Francis
2014-09-10 12:07       ` Peter Crosthwaite
2014-09-10 13:16         ` Alistair Francis
2014-09-09  8:24 ` [Qemu-devel] [RFC v1 2/6] stm32f205_USART: Add the stm32f205 SoC USART Controller Alistair Francis
2014-09-09 13:21   ` Peter Crosthwaite
2014-09-10 10:55     ` Alistair Francis
2014-09-09  8:24 ` [Qemu-devel] [RFC v1 3/6] stm32f205_SYSCFG: Add the stm32f205 SYSCFG Alistair Francis
2014-09-09  8:24 ` [Qemu-devel] [RFC v1 4/6] target_arm: Update armv7_init to support more parameters Alistair Francis
2014-09-09 13:35   ` Peter Crosthwaite
2014-09-09 13:59     ` Peter Maydell
2014-09-09 23:39       ` Alistair Francis
2014-09-10 12:01         ` Peter Crosthwaite
2014-09-09 14:03     ` Martin Galvan
2014-09-09 23:43       ` Alistair Francis
2014-09-10 12:32         ` Martin Galvan
2014-09-10 13:53           ` Alistair Francis
2014-09-09  8:24 ` [Qemu-devel] [RFC v1 5/6] stm32f205: Add the SoC Alistair Francis
2014-09-09 13:50   ` Peter Crosthwaite
2014-09-10  7:31     ` Alistair Francis
2014-09-09  8:24 ` [Qemu-devel] [RFC v1 6/6] netduino2: Add the Netduino 2 Machine Alistair Francis
2014-09-09 18:24 ` [Qemu-devel] [RFC v1 0/6] Netduino 2 Machine Model Peter Maydell
2014-09-09 23:31   ` Alistair Francis

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.